1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +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;
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;

View File

@ -31,7 +31,6 @@ constexpr size_t NumBufferedScans = 2048;
id<MTLRenderPipelineState> _gouraudPipeline;
// Buffers.
id<MTLBuffer> _quadBuffer; // i.e. four vertices defining a quad.
id<MTLBuffer> _uniformsBuffer;
id<MTLBuffer> _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<MTLLibrary> 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];

View File

@ -9,9 +9,6 @@
#include <metal_stdlib>
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
);