From 303642e122fdf320c5b1a8530e47598676c1cf42 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Thu, 26 Dec 2019 11:41:47 -0800 Subject: [PATCH] Mac: Implement blocky and smooth rendering modes in Metal renderer --- macosx/mac-render.mm | 31 ++++++++++++++++--------------- macosx/shaders.metal | 20 +++++++++++++++----- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/macosx/mac-render.mm b/macosx/mac-render.mm index c7b16cde..74e7b1cf 100644 --- a/macosx/mac-render.mm +++ b/macosx/mac-render.mm @@ -147,27 +147,26 @@ static void S9xInitMetal (void) glScreenH = glScreenBounds.size.height; metalLayer = (CAMetalLayer *)s9xView.layer; - //metalLayer.presentsWithTransaction = YES; metalDevice = s9xView.device; + + metalCommandQueue = [metalDevice newCommandQueue]; NSError *error = nil; id defaultLibrary = [metalDevice newDefaultLibraryWithBundle:[NSBundle bundleForClass:[S9xEngine class]] error:&error]; + + MTLRenderPipelineDescriptor *pipelineDescriptor = [MTLRenderPipelineDescriptor new]; + pipelineDescriptor.label = @"Snes9x Pipeline"; + pipelineDescriptor.vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"]; + pipelineDescriptor.colorAttachments[0].pixelFormat = s9xView.colorPixelFormat; + pipelineDescriptor.fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"]; - MTLRenderPipelineDescriptor *descriptor = [MTLRenderPipelineDescriptor new]; - descriptor.label = @"Snes9x Pipeline"; - descriptor.vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"]; - descriptor.fragmentFunction = [defaultLibrary newFunctionWithName:@"samplingShader"]; - descriptor.colorAttachments[0].pixelFormat = s9xView.colorPixelFormat; - - metalPipelineState = [metalDevice newRenderPipelineStateWithDescriptor:descriptor error:&error]; + metalPipelineState = [metalDevice newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error]; if (metalPipelineState == nil) { NSLog(@"%@",error); } - - metalCommandQueue = [metalDevice newCommandQueue]; } static void S9xDeinitMetal (void) @@ -314,12 +313,12 @@ static void S9xPutImageMetal (int width, int height, uint16 *buffer16) CGSize layerSize = metalLayer.bounds.size; - MTLTextureDescriptor *descriptor = [MTLTextureDescriptor new]; - descriptor.pixelFormat = MTLPixelFormatRGBA8Unorm; - descriptor.width = width; - descriptor.height = height; + MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor new]; + textureDescriptor.pixelFormat = MTLPixelFormatRGBA8Unorm; + textureDescriptor.width = width; + textureDescriptor.height = height; - metalTexture = [metalDevice newTextureWithDescriptor:descriptor]; + metalTexture = [metalDevice newTextureWithDescriptor:textureDescriptor]; [metalTexture replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:buffer bytesPerRow:width * 4]; free(buffer); @@ -340,6 +339,7 @@ static void S9xPutImageMetal (int width, int height, uint16 *buffer16) }; id vertexBuffer = [metalDevice newBufferWithBytes:verticies length:sizeof(verticies) options:MTLResourceStorageModeShared]; + id fragmentBuffer = [metalDevice newBufferWithBytes:&videoMode length:sizeof(videoMode) options:MTLResourceStorageModeShared]; id commandBuffer = [metalCommandQueue commandBuffer]; commandBuffer.label = @"Snes9x command buffer"; @@ -374,6 +374,7 @@ static void S9xPutImageMetal (int width, int height, uint16 *buffer16) atIndex:1]; [renderEncoder setFragmentTexture:metalTexture atIndex:0]; + [renderEncoder setFragmentBuffer:fragmentBuffer offset:0 atIndex:1]; [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6]; diff --git a/macosx/shaders.metal b/macosx/shaders.metal index b2b1f4ce..d29eecbe 100644 --- a/macosx/shaders.metal +++ b/macosx/shaders.metal @@ -43,10 +43,20 @@ vertexShader(uint vertexID [[ vertex_id ]], constant MetalVertex *vertexArray [[ } fragment float4 -samplingShader(RasterizerData in [[stage_in]], texture2d colorTexture [[ texture(0) ]]) +fragmentShader(RasterizerData in [[stage_in]], texture2d colorTexture [[ texture(0) ]], constant int *videoModePointer [[ buffer(1) ]]) { - constexpr sampler textureSampler (mag_filter::nearest, min_filter::nearest); - const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate); - return float4(colorSample); + int videoMode = int(*videoModePointer); + + if ( videoMode == 0) + { + constexpr sampler textureSampler (mag_filter::nearest, min_filter::nearest); + const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate); + return float4(colorSample); + } + else + { + constexpr sampler textureSampler (mag_filter::linear, min_filter::linear); + const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate); + return float4(colorSample); + } } -