Mac: Implement blocky and smooth rendering modes in Metal renderer

This commit is contained in:
Michael Buckley 2019-12-26 11:41:47 -08:00
parent b12ca3e9e3
commit 303642e122
2 changed files with 31 additions and 20 deletions

View File

@ -147,27 +147,26 @@ static void S9xInitMetal (void)
glScreenH = glScreenBounds.size.height; glScreenH = glScreenBounds.size.height;
metalLayer = (CAMetalLayer *)s9xView.layer; metalLayer = (CAMetalLayer *)s9xView.layer;
//metalLayer.presentsWithTransaction = YES;
metalDevice = s9xView.device; metalDevice = s9xView.device;
metalCommandQueue = [metalDevice newCommandQueue];
NSError *error = nil; NSError *error = nil;
id<MTLLibrary> defaultLibrary = [metalDevice newDefaultLibraryWithBundle:[NSBundle bundleForClass:[S9xEngine class]] error:&error]; id<MTLLibrary> 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]; metalPipelineState = [metalDevice newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error];
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];
if (metalPipelineState == nil) if (metalPipelineState == nil)
{ {
NSLog(@"%@",error); NSLog(@"%@",error);
} }
metalCommandQueue = [metalDevice newCommandQueue];
} }
static void S9xDeinitMetal (void) static void S9xDeinitMetal (void)
@ -314,12 +313,12 @@ static void S9xPutImageMetal (int width, int height, uint16 *buffer16)
CGSize layerSize = metalLayer.bounds.size; CGSize layerSize = metalLayer.bounds.size;
MTLTextureDescriptor *descriptor = [MTLTextureDescriptor new]; MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor new];
descriptor.pixelFormat = MTLPixelFormatRGBA8Unorm; textureDescriptor.pixelFormat = MTLPixelFormatRGBA8Unorm;
descriptor.width = width; textureDescriptor.width = width;
descriptor.height = height; 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]; [metalTexture replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:buffer bytesPerRow:width * 4];
free(buffer); free(buffer);
@ -340,6 +339,7 @@ static void S9xPutImageMetal (int width, int height, uint16 *buffer16)
}; };
id<MTLBuffer> vertexBuffer = [metalDevice newBufferWithBytes:verticies length:sizeof(verticies) options:MTLResourceStorageModeShared]; id<MTLBuffer> vertexBuffer = [metalDevice newBufferWithBytes:verticies length:sizeof(verticies) options:MTLResourceStorageModeShared];
id<MTLBuffer> fragmentBuffer = [metalDevice newBufferWithBytes:&videoMode length:sizeof(videoMode) options:MTLResourceStorageModeShared];
id<MTLCommandBuffer> commandBuffer = [metalCommandQueue commandBuffer]; id<MTLCommandBuffer> commandBuffer = [metalCommandQueue commandBuffer];
commandBuffer.label = @"Snes9x command buffer"; commandBuffer.label = @"Snes9x command buffer";
@ -374,6 +374,7 @@ static void S9xPutImageMetal (int width, int height, uint16 *buffer16)
atIndex:1]; atIndex:1];
[renderEncoder setFragmentTexture:metalTexture atIndex:0]; [renderEncoder setFragmentTexture:metalTexture atIndex:0];
[renderEncoder setFragmentBuffer:fragmentBuffer offset:0 atIndex:1];
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6]; [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];

View File

@ -43,10 +43,20 @@ vertexShader(uint vertexID [[ vertex_id ]], constant MetalVertex *vertexArray [[
} }
fragment float4 fragment float4
samplingShader(RasterizerData in [[stage_in]], texture2d<half> colorTexture [[ texture(0) ]]) fragmentShader(RasterizerData in [[stage_in]], texture2d<half> colorTexture [[ texture(0) ]], constant int *videoModePointer [[ buffer(1) ]])
{ {
constexpr sampler textureSampler (mag_filter::nearest, min_filter::nearest); int videoMode = int(*videoModePointer);
const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);
return float4(colorSample); 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);
}
} }