mirror of https://github.com/snes9xgit/snes9x.git
Mac: Implement blocky and smooth rendering modes in Metal renderer
This commit is contained in:
parent
b12ca3e9e3
commit
303642e122
|
@ -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 *descriptor = [MTLRenderPipelineDescriptor new];
|
MTLRenderPipelineDescriptor *pipelineDescriptor = [MTLRenderPipelineDescriptor new];
|
||||||
descriptor.label = @"Snes9x Pipeline";
|
pipelineDescriptor.label = @"Snes9x Pipeline";
|
||||||
descriptor.vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
|
pipelineDescriptor.vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
|
||||||
descriptor.fragmentFunction = [defaultLibrary newFunctionWithName:@"samplingShader"];
|
pipelineDescriptor.colorAttachments[0].pixelFormat = s9xView.colorPixelFormat;
|
||||||
descriptor.colorAttachments[0].pixelFormat = s9xView.colorPixelFormat;
|
pipelineDescriptor.fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"];
|
||||||
|
|
||||||
metalPipelineState = [metalDevice newRenderPipelineStateWithDescriptor:descriptor error:&error];
|
metalPipelineState = [metalDevice newRenderPipelineStateWithDescriptor:pipelineDescriptor 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];
|
||||||
|
|
||||||
|
|
|
@ -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) ]])
|
||||||
|
{
|
||||||
|
int videoMode = int(*videoModePointer);
|
||||||
|
|
||||||
|
if ( videoMode == 0)
|
||||||
{
|
{
|
||||||
constexpr sampler textureSampler (mag_filter::nearest, min_filter::nearest);
|
constexpr sampler textureSampler (mag_filter::nearest, min_filter::nearest);
|
||||||
const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);
|
const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);
|
||||||
return float4(colorSample);
|
return float4(colorSample);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
constexpr sampler textureSampler (mag_filter::linear, min_filter::linear);
|
||||||
|
const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);
|
||||||
|
return float4(colorSample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue