mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-20 21:30:59 +00:00
Enforces across-the-board supersampling.
I'm damned if I can figure out how to talk an MTKView, or Metal in general, into supersampling so as a first effort this does it in software.
This commit is contained in:
parent
7dd4c67304
commit
d7972a7b86
@ -189,10 +189,11 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
id<MTLCommandQueue> _commandQueue;
|
||||
|
||||
// Pipelines.
|
||||
id<MTLRenderPipelineState> _composePipeline; // For rendering to the composition texture.
|
||||
id<MTLRenderPipelineState> _outputPipeline; // For drawing to the frame buffer.
|
||||
id<MTLRenderPipelineState> _copyPipeline; // For copying the frame buffer to the visible surface.
|
||||
id<MTLRenderPipelineState> _clearPipeline; // For applying additional inter-frame clearing (cf. the stencil).
|
||||
id<MTLRenderPipelineState> _composePipeline; // For rendering to the composition texture.
|
||||
id<MTLRenderPipelineState> _outputPipeline; // For drawing to the frame buffer.
|
||||
id<MTLRenderPipelineState> _copyPipeline; // For copying from one texture to another.
|
||||
id<MTLRenderPipelineState> _supersamplePipeline; // For resampling from one texture to one that is 1/4 as large.
|
||||
id<MTLRenderPipelineState> _clearPipeline; // For applying additional inter-frame clearing (cf. the stencil).
|
||||
|
||||
// Buffers.
|
||||
id<MTLBuffer> _uniformsBuffer; // A static buffer, containing a copy of the Uniforms struct.
|
||||
@ -315,6 +316,9 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"copyFragment"];
|
||||
_copyPipeline = [_view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil];
|
||||
|
||||
pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"supersampleFragment"];
|
||||
_supersamplePipeline = [_view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil];
|
||||
|
||||
pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"clearFragment"];
|
||||
pipelineDescriptor.stencilAttachmentPixelFormat = MTLPixelFormatStencil8;
|
||||
_clearPipeline = [_view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil];
|
||||
@ -360,8 +364,9 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
}
|
||||
|
||||
- (void)updateSizeBuffersToSize:(CGSize)size {
|
||||
const NSUInteger frameBufferWidth = NSUInteger(size.width * _view.layer.contentsScale);
|
||||
const NSUInteger frameBufferHeight = NSUInteger(size.height * _view.layer.contentsScale);
|
||||
// TODO: above what size threshold is supersampling no longer desired?
|
||||
const NSUInteger frameBufferWidth = NSUInteger(size.width * _view.layer.contentsScale) * 2;
|
||||
const NSUInteger frameBufferHeight = NSUInteger(size.height * _view.layer.contentsScale) * 2;
|
||||
|
||||
// Generate a framebuffer and a stencil.
|
||||
MTLTextureDescriptor *const textureDescriptor = [MTLTextureDescriptor
|
||||
@ -1080,7 +1085,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
view.currentRenderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionDontCare;
|
||||
id<MTLRenderCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor:view.currentRenderPassDescriptor];
|
||||
|
||||
[encoder setRenderPipelineState:_copyPipeline];
|
||||
[encoder setRenderPipelineState:_supersamplePipeline];
|
||||
[encoder setVertexTexture:_frameBuffer atIndex:0];
|
||||
[encoder setFragmentTexture:_frameBuffer atIndex:0];
|
||||
|
||||
|
@ -390,6 +390,19 @@ DeclareShaders(Red4Green4Blue4, ushort)
|
||||
DeclareShaders(Red2Green2Blue2, ushort)
|
||||
DeclareShaders(Red1Green1Blue1, ushort)
|
||||
|
||||
// Assumes a 2 -> 1 scaling on both axes; if ever I figure out how to get Metal to do hardware supersampling
|
||||
// then this fragment shader can be removed.
|
||||
fragment half4 supersampleFragment(CopyInterpolator vert [[stage_in]], texture2d<half> texture [[texture(0)]]) {
|
||||
// TODO: can't I do better than this by being careful about positioning and using the linearSampler?
|
||||
|
||||
return (
|
||||
texture.sample(standardSampler, vert.textureCoordinates + float2(0.5f, -1.0f)) +
|
||||
texture.sample(standardSampler, vert.textureCoordinates + float2(0.5f, 1.0f)) +
|
||||
texture.sample(standardSampler, vert.textureCoordinates + float2(-1.0f, 0.5f)) +
|
||||
texture.sample(standardSampler, vert.textureCoordinates + float2(1.0f, -0.5f))
|
||||
) * half(0.25f);
|
||||
}
|
||||
|
||||
fragment half4 copyFragment(CopyInterpolator vert [[stage_in]], texture2d<half> texture [[texture(0)]]) {
|
||||
return texture.sample(standardSampler, vert.textureCoordinates);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user