1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-04 01:57:54 +00:00

Eliminates the quad buffer.

Vertices can be adduced from vertex ID.
This commit is contained in:
Thomas Harte 2020-08-08 17:12:49 -04:00
parent 38960a08d6
commit edf41b06fd
3 changed files with 13 additions and 40 deletions

View File

@ -5169,6 +5169,7 @@
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -5220,6 +5221,7 @@
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_SWIFT3_OBJC_INFERENCE = Default;

View File

@ -31,7 +31,6 @@ constexpr size_t NumBufferedScans = 2048;
id<MTLRenderPipelineState> _gouraudPipeline; id<MTLRenderPipelineState> _gouraudPipeline;
// Buffers. // Buffers.
id<MTLBuffer> _quadBuffer; // i.e. four vertices defining a quad.
id<MTLBuffer> _uniformsBuffer; id<MTLBuffer> _uniformsBuffer;
id<MTLBuffer> _scansBuffer; id<MTLBuffer> _scansBuffer;
@ -44,15 +43,6 @@ constexpr size_t NumBufferedScans = 2048;
if(self) { if(self) {
_commandQueue = [view.device newCommandQueue]; _commandQueue = [view.device newCommandQueue];
// Install the standard quad.
constexpr float vertices[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
};
_quadBuffer = [view.device newBufferWithBytes:vertices length:sizeof(vertices) options:MTLResourceCPUCacheModeDefaultCache];
// Allocate space for uniforms. // Allocate space for uniforms.
_uniformsBuffer = [view.device newBufferWithLength:16 options:MTLResourceCPUCacheModeWriteCombined]; _uniformsBuffer = [view.device newBufferWithLength:16 options:MTLResourceCPUCacheModeWriteCombined];
_uniforms.scale[0] = 1024; _uniforms.scale[0] = 1024;
@ -67,22 +57,12 @@ constexpr size_t NumBufferedScans = 2048;
options:MTLResourceCPUCacheModeWriteCombined | MTLResourceStorageModeShared]; options:MTLResourceCPUCacheModeWriteCombined | MTLResourceStorageModeShared];
[self setTestScans]; [self setTestScans];
// The quad buffer has only 2d positions; the scan buffer is a bit more complicated
MTLVertexDescriptor *vertexDescriptor = [[MTLVertexDescriptor alloc] init];
vertexDescriptor.attributes[0].bufferIndex = 0;
vertexDescriptor.attributes[0].offset = 0;
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2;
vertexDescriptor.layouts[0].stride = sizeof(float)*2;
// TODO: shouldn't I need to explain the Scan layout, too? Or do these things not need to be specified when compatible?
// Generate TEST pipeline. // Generate TEST pipeline.
id<MTLLibrary> library = [view.device newDefaultLibrary]; id<MTLLibrary> library = [view.device newDefaultLibrary];
MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanVertexMain"]; pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanVertexMain"];
pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMain"]; pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMain"];
pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat; pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat;
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
_gouraudPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil]; _gouraudPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil];
} }
@ -134,9 +114,8 @@ constexpr size_t NumBufferedScans = 2048;
// Drawing. Just the test triangle, as described above. // Drawing. Just the test triangle, as described above.
[encoder setRenderPipelineState:_gouraudPipeline]; [encoder setRenderPipelineState:_gouraudPipeline];
[encoder setVertexBuffer:_quadBuffer offset:0 atIndex:0]; [encoder setVertexBuffer:_scansBuffer offset:0 atIndex:0];
[encoder setVertexBuffer:_uniformsBuffer offset:0 atIndex:1]; [encoder setVertexBuffer:_uniformsBuffer offset:0 atIndex:1];
[encoder setVertexBuffer:_scansBuffer offset:0 atIndex:2];
[encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4 instanceCount:2]; [encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4 instanceCount:2];

View File

@ -9,9 +9,6 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
// These two structs are the same, but defined separately as an artefact
// of my learning process, and the fact that they soon won't be.
struct Uniforms { struct Uniforms {
// This is used to scale scan positions, i.e. it provides the range // This is used to scale scan positions, i.e. it provides the range
// for mapping from scan-style integer positions into eye space. // for mapping from scan-style integer positions into eye space.
@ -40,11 +37,6 @@ struct Scan {
uint32_t dataYAndLine [[attribute(7)]]; uint32_t dataYAndLine [[attribute(7)]];
}; };
// This is a custom thing defining one corner of a quad.
struct QuadInputVertex {
float2 position [[attribute(0)]];
};
struct ColouredVertex { struct ColouredVertex {
float4 position [[position]]; float4 position [[position]];
}; };
@ -52,28 +44,28 @@ struct ColouredVertex {
// MARK: - Scan shaders; these do final output to the display. // MARK: - Scan shaders; these do final output to the display.
vertex ColouredVertex scanVertexMain( QuadInputVertex vert [[stage_in]], vertex ColouredVertex scanVertexMain( constant Uniforms &uniforms [[buffer(1)]],
constant Uniforms &uniforms [[buffer(1)]], constant Scan *scans [[buffer(0)]],
constant Scan *scans [[buffer(2)]], uint instanceID [[instance_id]],
ushort instance [[instance_id]]) { uint vertexID [[vertex_id]]) {
// Unpack start and end vertices; little-endian numbers are assumed here. // Unpack start and end vertices; little-endian numbers are assumed here.
const float2 start = float2( const float2 start = float2(
float(scans[instance].startPosition & 0xffff) / float(uniforms.scale.x), float(scans[instanceID].startPosition & 0xffff) / float(uniforms.scale.x),
float(scans[instance].startPosition >> 16) / float(uniforms.scale.y) float(scans[instanceID].startPosition >> 16) / float(uniforms.scale.y)
); );
const float2 end = float2( const float2 end = float2(
float(scans[instance].endPosition & 0xffff) / float(uniforms.scale.x), float(scans[instanceID].endPosition & 0xffff) / float(uniforms.scale.x),
float(scans[instance].endPosition >> 16) / float(uniforms.scale.y) float(scans[instanceID].endPosition >> 16) / float(uniforms.scale.y)
); );
// Calculate the tangent and normal. // Calculate the tangent and normal.
const float2 tangent = end - start; const float2 tangent = (end - start);
const float2 normal = float2(-tangent.y, tangent.x) / length(tangent); const float2 normal = float2(-tangent.y, tangent.x) / length(tangent);
// Hence determine this quad's real shape. // Hence determine this quad's real shape.
ColouredVertex output; ColouredVertex output;
output.position = float4( output.position = float4(
((start + vert.position.x * tangent + vert.position.y * normal * uniforms.lineWidth) * float2(2.0, -2.0) + float2(-1.0, 1.0)) * float2(uniforms.aspectRatioMultiplier, 1.0), ((start + (float(vertexID&2) * 0.5) * tangent + (float(vertexID&1) - 0.5) * normal * uniforms.lineWidth) * float2(2.0, -2.0) + float2(-1.0, 1.0)) * float2(uniforms.aspectRatioMultiplier, 1.0),
0.0, 0.0,
1.0 1.0
); );