From edf41b06fd9be57106b8a95e919daa6f2ed327c0 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 8 Aug 2020 17:12:49 -0400 Subject: [PATCH] Eliminates the quad buffer. Vertices can be adduced from vertex ID. --- .../Clock Signal.xcodeproj/project.pbxproj | 2 ++ .../Clock Signal/ScanTarget/CSScanTarget.mm | 23 +-------------- .../Clock Signal/ScanTarget/ScanTarget.metal | 28 +++++++------------ 3 files changed, 13 insertions(+), 40 deletions(-) diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 569160397..7d3950137 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -5169,6 +5169,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -5220,6 +5221,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm index 9ba322226..e0d43e632 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm +++ b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm @@ -31,7 +31,6 @@ constexpr size_t NumBufferedScans = 2048; id _gouraudPipeline; // Buffers. - id _quadBuffer; // i.e. four vertices defining a quad. id _uniformsBuffer; id _scansBuffer; @@ -44,15 +43,6 @@ constexpr size_t NumBufferedScans = 2048; if(self) { _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. _uniformsBuffer = [view.device newBufferWithLength:16 options:MTLResourceCPUCacheModeWriteCombined]; _uniforms.scale[0] = 1024; @@ -67,22 +57,12 @@ constexpr size_t NumBufferedScans = 2048; options:MTLResourceCPUCacheModeWriteCombined | MTLResourceStorageModeShared]; [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. id library = [view.device newDefaultLibrary]; MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanVertexMain"]; pipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"scanFragmentMain"]; pipelineDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat; - pipelineDescriptor.vertexDescriptor = vertexDescriptor; _gouraudPipeline = [view.device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:nil]; } @@ -134,9 +114,8 @@ constexpr size_t NumBufferedScans = 2048; // Drawing. Just the test triangle, as described above. [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:_scansBuffer offset:0 atIndex:2]; [encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4 instanceCount:2]; diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal index f64876228..dd839dbc5 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal +++ b/OSBindings/Mac/Clock Signal/ScanTarget/ScanTarget.metal @@ -9,9 +9,6 @@ #include 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 { // This is used to scale scan positions, i.e. it provides the range // for mapping from scan-style integer positions into eye space. @@ -40,11 +37,6 @@ struct Scan { uint32_t dataYAndLine [[attribute(7)]]; }; -// This is a custom thing defining one corner of a quad. -struct QuadInputVertex { - float2 position [[attribute(0)]]; -}; - struct ColouredVertex { float4 position [[position]]; }; @@ -52,28 +44,28 @@ struct ColouredVertex { // MARK: - Scan shaders; these do final output to the display. -vertex ColouredVertex scanVertexMain( QuadInputVertex vert [[stage_in]], - constant Uniforms &uniforms [[buffer(1)]], - constant Scan *scans [[buffer(2)]], - ushort instance [[instance_id]]) { +vertex ColouredVertex scanVertexMain( constant Uniforms &uniforms [[buffer(1)]], + constant Scan *scans [[buffer(0)]], + uint instanceID [[instance_id]], + uint vertexID [[vertex_id]]) { // Unpack start and end vertices; little-endian numbers are assumed here. const float2 start = float2( - float(scans[instance].startPosition & 0xffff) / float(uniforms.scale.x), - float(scans[instance].startPosition >> 16) / float(uniforms.scale.y) + float(scans[instanceID].startPosition & 0xffff) / float(uniforms.scale.x), + float(scans[instanceID].startPosition >> 16) / float(uniforms.scale.y) ); const float2 end = float2( - float(scans[instance].endPosition & 0xffff) / float(uniforms.scale.x), - float(scans[instance].endPosition >> 16) / float(uniforms.scale.y) + float(scans[instanceID].endPosition & 0xffff) / float(uniforms.scale.x), + float(scans[instanceID].endPosition >> 16) / float(uniforms.scale.y) ); // 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); // Hence determine this quad's real shape. ColouredVertex output; 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, 1.0 );