diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm index 9d1097390..8d8b2bc7b 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm +++ b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm @@ -40,7 +40,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget; id _vertexShader; id _fragmentShader; - id _gouraudPipeline; + id _scanPipeline; // Buffers. id _uniformsBuffer; @@ -85,14 +85,6 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget; _scanTarget.set_write_area(reinterpret_cast(_writeAreaBuffer.contents)); _scanTarget.set_line_buffer(reinterpret_cast(_linesBuffer.contents), _lineMetadataBuffer, NumBufferedLines); _scanTarget.set_scan_buffer(reinterpret_cast(_scansBuffer.contents), NumBufferedScans); - - // Generate TEST pipeline. - id library = [view.device newDefaultLibrary]; - MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; - pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanVertexMain"]; - pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMain"]; - pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat; - _gouraudPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil]; } return self; @@ -115,11 +107,6 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget; @discussion Called on the delegate when it is asked to render into the view */ - (void)drawInMTKView:(nonnull MTKView *)view { - // Generate a command encoder for the view. - id commandBuffer = [_commandQueue commandBuffer]; - MTLRenderPassDescriptor *const descriptor = view.currentRenderPassDescriptor; - id encoder = [commandBuffer renderCommandEncoderWithDescriptor:descriptor]; - const Outputs::Display::ScanTarget::Modals *const newModals = _scanTarget.new_modals(); if(newModals) { uniforms()->scale[0] = newModals->output_scale.x; @@ -150,11 +137,25 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget; offset:0 bytesPerRow:BufferingScanTarget::WriteAreaWidth * _bytesPerInputPixel]; _totalTextureBytes = BufferingScanTarget::WriteAreaWidth * BufferingScanTarget::WriteAreaHeight * _bytesPerInputPixel; + + // Generate pipeline. + id library = [view.device newDefaultLibrary]; + MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; + pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanVertexMain"]; + pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMain"]; + pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat; + _scanPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil]; } - // Drawing. Just the test triangle, as described above. - [encoder setRenderPipelineState:_gouraudPipeline]; + // Generate a command encoder for the view. + id commandBuffer = [_commandQueue commandBuffer]; + MTLRenderPassDescriptor *const descriptor = view.currentRenderPassDescriptor; + id encoder = [commandBuffer renderCommandEncoderWithDescriptor:descriptor]; + // Drawing. Just scans. + [encoder setRenderPipelineState:_scanPipeline]; + + [encoder setFragmentTexture:_writeAreaTexture atIndex:0]; [encoder setVertexBuffer:_scansBuffer offset:0 atIndex:0]; [encoder setVertexBuffer:_uniformsBuffer offset:0 atIndex:1]; diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal index b75921fde..e54400af8 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal +++ b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal @@ -51,6 +51,7 @@ struct Line { // This is an intermediate struct, which is TEMPORARY. struct ColouredVertex { float4 position [[position]]; + float2 textureCoordinates; }; @@ -81,9 +82,16 @@ vertex ColouredVertex scanVertexMain( constant Uniforms &uniforms [[buffer(1)]], 0.0, 1.0 ); + output.textureCoordinates = float2( + mix(scans[instanceID].endPoints[0].dataOffset, scans[instanceID].endPoints[1].dataOffset, float((vertexID&2) >> 1)), + scans[instanceID].dataY); return output; } -fragment half4 scanFragmentMain(ColouredVertex vert [[stage_in]]) { - return half4(1.0); +fragment half4 scanFragmentMain(ColouredVertex vert [[stage_in]], texture2d texture [[texture(0)]]) { + constexpr sampler s(coord::pixel, + address::clamp_to_zero, // This really makes no difference here; anything Metal will accept will do. + filter::nearest); + + return half4(texture.sample(s, vert.textureCoordinates)); }