diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm index d07d9e3f1..926bc9494 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm +++ b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm @@ -85,6 +85,9 @@ 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); + + // Set initial aspect-ratio multiplier. + [self mtkView:view drawableSizeWillChange:view.drawableSize]; } return self; @@ -124,7 +127,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget; case 2: pixelFormat = MTLPixelFormatRG8Unorm; break; case 4: pixelFormat = MTLPixelFormatRGBA8Unorm; break; } - MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor + MTLTextureDescriptor *const textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixelFormat width:BufferingScanTarget::WriteAreaWidth height:BufferingScanTarget::WriteAreaHeight @@ -132,18 +135,29 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget; textureDescriptor.resourceOptions = SharedResourceOptionsTexture; // TODO: the call below is the only reason why this project now requires macOS 10.13; is it all that helpful versus just uploading each frame? + const NSUInteger bytesPerRow = BufferingScanTarget::WriteAreaWidth * _bytesPerInputPixel; _writeAreaTexture = [_writeAreaBuffer newTextureWithDescriptor:textureDescriptor offset:0 - bytesPerRow:BufferingScanTarget::WriteAreaWidth * _bytesPerInputPixel]; - _totalTextureBytes = BufferingScanTarget::WriteAreaWidth * BufferingScanTarget::WriteAreaHeight * _bytesPerInputPixel; + bytesPerRow:bytesPerRow]; + _totalTextureBytes = bytesPerRow * BufferingScanTarget::WriteAreaHeight; // 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; + + // TODO: logic somewhat more complicated than this, probably + pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanVertexMain"]; + switch(newModals->input_data_type) { + default: + pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMainRGB"]; + break; + case Outputs::Display::InputDataType::Luminance1: + pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMainL1"]; + break; + } + _scanPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil]; } diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal index 17af486dd..f2e81d258 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal +++ b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal @@ -88,10 +88,20 @@ vertex ColouredVertex scanVertexMain( constant Uniforms &uniforms [[buffer(1)]], return output; } -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); +namespace { + +constexpr sampler standardSampler( coord::pixel, + address::clamp_to_edge, // Although arbitrary, stick with this address mode for compatibility all the way to MTLFeatureSet_iOS_GPUFamily1_v1. + filter::nearest); - return half4(texture.sample(s, vert.textureCoordinates) * 32.0f); // Multiply by 32 is _TEMPORARY TEST CODE_ [/ nonsense]. +} + +// MARK: - Input formst to RGB conversions. + +fragment half4 scanFragmentMainRGB (ColouredVertex vert [[stage_in]], texture2d texture [[texture(0)]]) { + return half4(texture.sample(standardSampler, vert.textureCoordinates)); +} + +fragment half4 scanFragmentMainL1(ColouredVertex vert [[stage_in]], texture2d texture [[texture(0)]]) { + return half4(half3(texture.sample(standardSampler, vert.textureCoordinates).r * 255.0), 1.0); }