From b510c668c575f3269fad8f042a32b42ba784d562 Mon Sep 17 00:00:00 2001 From: Daniel Barber Date: Fri, 28 Feb 2025 02:43:30 -0500 Subject: [PATCH 1/6] Fixed kinc_g5_command_list_set_vertex_buffers Now uses all buffers like in the Vulkan backend. --- .../kinc/backend/graphics5/commandlist.m.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h index f81407dbc..44fc26e7b 100644 --- a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h +++ b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h @@ -166,8 +166,20 @@ void kinc_g5_command_list_set_blend_constant(kinc_g5_command_list_t *list, float [encoder setBlendColorRed:r green:g blue:b alpha:a]; } -void kinc_g5_command_list_set_vertex_buffers(kinc_g5_command_list_t *list, struct kinc_g5_vertex_buffer **buffers, int *offsets, int count) { - kinc_g5_internal_vertex_buffer_set(buffers[0], offsets[0]); +void kinc_g5_command_list_set_vertex_buffers(kinc_g5_command_list_t *list, struct kinc_g5_vertex_buffer **vertexBuffers, int *offsets_, int count) { + // the only thing kinc_g5_internal_vertex_buffer_set really does is + // storing a pointer to a single current vertex buffer, but with the + // proper implementation there can more than one current buffer + //kinc_g5_internal_vertex_buffer_set(buffers[0], offsets[0]); + id encoder = getMetalEncoder(); + // Array to store Metal buffers and offsets in bytes + id buffers[count]; + NSUInteger offsets[count]; + for (int i = 0; i < count; ++i) { + buffers[i] = (__bridge id)vertexBuffers[i]->impl.mtlBuffer; + offsets[i] = (NSUInteger)(offsets_[i] * kinc_g5_vertex_buffer_stride(vertexBuffers[i])); + } + [encoder setVertexBuffers:buffers offsets:offsets withRange:NSMakeRange(0, count)]; } void kinc_g5_command_list_set_index_buffer(kinc_g5_command_list_t *list, struct kinc_g5_index_buffer *buffer) { From bd204cff118392273008d10c0201b7ef4b3bb9be Mon Sep 17 00:00:00 2001 From: Daniel Barber Date: Fri, 28 Feb 2025 02:49:40 -0500 Subject: [PATCH 2/6] Refactored kinc_g5_pipeline_compile Correctly assembles vertexDescriptor with correct offsets and strides, as well as perInstance and perVertex step functions. --- .../kinc/backend/graphics5/pipeline.m.h | 287 +++++++++--------- 1 file changed, 151 insertions(+), 136 deletions(-) diff --git a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h index 05408bea8..53c8b51b1 100644 --- a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h +++ b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h @@ -165,148 +165,163 @@ void kinc_g5_pipeline_compile(kinc_g5_pipeline_t *pipeline) { renderPipelineDesc.depthAttachmentPixelFormat = MTLPixelFormatInvalid; renderPipelineDesc.stencilAttachmentPixelFormat = MTLPixelFormatInvalid; - float offset = 0; - MTLVertexDescriptor *vertexDescriptor = [[MTLVertexDescriptor alloc] init]; - - for (int i = 0; i < pipeline->inputLayout[0]->size; ++i) { - int index = findAttributeIndex(renderPipelineDesc.vertexFunction.vertexAttributes, pipeline->inputLayout[0]->elements[i].name); - - if (index < 0) { - kinc_log(KINC_LOG_LEVEL_WARNING, "Could not find vertex attribute %s\n", pipeline->inputLayout[0]->elements[i].name); - } - - if (index >= 0) { - vertexDescriptor.attributes[index].bufferIndex = 0; - vertexDescriptor.attributes[index].offset = offset; + uint32_t bindings_count = 0; + for (int i = 0; i < 16; ++i) { + if (pipeline->inputLayout[i] == NULL) { + break; } + bindings_count++; + } + + for (uint32_t binding_index = 0; binding_index < bindings_count; ++binding_index) { + uint32_t offset = 0; + uint32_t stride = 0; + for (uint32_t attribute_index = 0; attribute_index < pipeline->inputLayout[binding_index]->size; ++attribute_index) { + kinc_g5_vertex_element_t element = pipeline->inputLayout[binding_index]->elements[attribute_index]; + int index = findAttributeIndex(renderPipelineDesc.vertexFunction.vertexAttributes, element.name); + + if (index < 0) { + kinc_log(KINC_LOG_LEVEL_WARNING, "Could not find vertex attribute %s\n", element.name); + } - offset += kinc_g4_vertex_data_size(pipeline->inputLayout[0]->elements[i].data); - if (index >= 0) { - switch (pipeline->inputLayout[0]->elements[i].data) { - case KINC_G4_VERTEX_DATA_NONE: - assert(false); - break; - case KINC_G4_VERTEX_DATA_F32_1X: - vertexDescriptor.attributes[index].format = MTLVertexFormatFloat; - break; - case KINC_G4_VERTEX_DATA_F32_2X: - vertexDescriptor.attributes[index].format = MTLVertexFormatFloat2; - break; - case KINC_G4_VERTEX_DATA_F32_3X: - vertexDescriptor.attributes[index].format = MTLVertexFormatFloat3; - break; - case KINC_G4_VERTEX_DATA_F32_4X: - vertexDescriptor.attributes[index].format = MTLVertexFormatFloat4; - break; - case KINC_G4_VERTEX_DATA_F32_4X4: - assert(false); - break; - case KINC_G4_VERTEX_DATA_I8_1X: - vertexDescriptor.attributes[index].format = MTLVertexFormatChar; - break; - case KINC_G4_VERTEX_DATA_U8_1X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUChar; - break; - case KINC_G4_VERTEX_DATA_I8_1X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatCharNormalized; - break; - case KINC_G4_VERTEX_DATA_U8_1X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatUCharNormalized; - break; - case KINC_G4_VERTEX_DATA_I8_2X: - vertexDescriptor.attributes[index].format = MTLVertexFormatChar2; - break; - case KINC_G4_VERTEX_DATA_U8_2X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUChar2; - break; - case KINC_G4_VERTEX_DATA_I8_2X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatChar2Normalized; - break; - case KINC_G4_VERTEX_DATA_U8_2X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatUChar2Normalized; - break; - case KINC_G4_VERTEX_DATA_I8_4X: - vertexDescriptor.attributes[index].format = MTLVertexFormatChar4; - break; - case KINC_G4_VERTEX_DATA_U8_4X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUChar4; - break; - case KINC_G4_VERTEX_DATA_I8_4X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatChar4Normalized; - break; - case KINC_G4_VERTEX_DATA_U8_4X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatUChar4Normalized; - break; - case KINC_G4_VERTEX_DATA_I16_1X: - vertexDescriptor.attributes[index].format = MTLVertexFormatShort; - break; - case KINC_G4_VERTEX_DATA_U16_1X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUShort; - break; - case KINC_G4_VERTEX_DATA_I16_1X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatShortNormalized; - break; - case KINC_G4_VERTEX_DATA_U16_1X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatUShortNormalized; - break; - case KINC_G4_VERTEX_DATA_I16_2X: - vertexDescriptor.attributes[index].format = MTLVertexFormatShort2; - break; - case KINC_G4_VERTEX_DATA_U16_2X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUShort2; - break; - case KINC_G4_VERTEX_DATA_I16_2X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatShort2Normalized; - break; - case KINC_G4_VERTEX_DATA_U16_2X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatUShort2Normalized; - break; - case KINC_G4_VERTEX_DATA_I16_4X: - vertexDescriptor.attributes[index].format = MTLVertexFormatShort4; - break; - case KINC_G4_VERTEX_DATA_U16_4X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUShort4; - break; - case KINC_G4_VERTEX_DATA_I16_4X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatShort4Normalized; - break; - case KINC_G4_VERTEX_DATA_U16_4X_NORMALIZED: - vertexDescriptor.attributes[index].format = MTLVertexFormatUShort4Normalized; - break; - case KINC_G4_VERTEX_DATA_I32_1X: - vertexDescriptor.attributes[index].format = MTLVertexFormatInt; - break; - case KINC_G4_VERTEX_DATA_U32_1X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUInt; - break; - case KINC_G4_VERTEX_DATA_I32_2X: - vertexDescriptor.attributes[index].format = MTLVertexFormatInt2; - break; - case KINC_G4_VERTEX_DATA_U32_2X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUInt2; - break; - case KINC_G4_VERTEX_DATA_I32_3X: - vertexDescriptor.attributes[index].format = MTLVertexFormatInt3; - break; - case KINC_G4_VERTEX_DATA_U32_3X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUInt3; - break; - case KINC_G4_VERTEX_DATA_I32_4X: - vertexDescriptor.attributes[index].format = MTLVertexFormatInt4; - break; - case KINC_G4_VERTEX_DATA_U32_4X: - vertexDescriptor.attributes[index].format = MTLVertexFormatUInt4; - break; - default: - assert(false); - break; + if(index >= 0) { + //kinc_log(KINC_LOG_LEVEL_INFO, "Adding attribute: %s", element.name); + //kinc_log(KINC_LOG_LEVEL_INFO, "Index: %i", index); + //kinc_log(KINC_LOG_LEVEL_INFO, "Instanced: %s", pipeline->inputLayout[binding_index]->instanced ? "true" : "false"); + vertexDescriptor.attributes[index].bufferIndex = binding_index; + vertexDescriptor.attributes[index].offset = offset; + offset += kinc_g4_vertex_data_size(element.data); + stride += kinc_g4_vertex_data_size(element.data); + + switch (element.data) { + case KINC_G4_VERTEX_DATA_NONE: + assert(false); + break; + case KINC_G4_VERTEX_DATA_F32_1X: + vertexDescriptor.attributes[index].format = MTLVertexFormatFloat; + break; + case KINC_G4_VERTEX_DATA_F32_2X: + vertexDescriptor.attributes[index].format = MTLVertexFormatFloat2; + break; + case KINC_G4_VERTEX_DATA_F32_3X: + vertexDescriptor.attributes[index].format = MTLVertexFormatFloat3; + break; + case KINC_G4_VERTEX_DATA_F32_4X: + vertexDescriptor.attributes[index].format = MTLVertexFormatFloat4; + break; + case KINC_G4_VERTEX_DATA_F32_4X4: + assert(false); + break; + case KINC_G4_VERTEX_DATA_I8_1X: + vertexDescriptor.attributes[index].format = MTLVertexFormatChar; + break; + case KINC_G4_VERTEX_DATA_U8_1X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUChar; + break; + case KINC_G4_VERTEX_DATA_I8_1X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatCharNormalized; + break; + case KINC_G4_VERTEX_DATA_U8_1X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatUCharNormalized; + break; + case KINC_G4_VERTEX_DATA_I8_2X: + vertexDescriptor.attributes[index].format = MTLVertexFormatChar2; + break; + case KINC_G4_VERTEX_DATA_U8_2X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUChar2; + break; + case KINC_G4_VERTEX_DATA_I8_2X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatChar2Normalized; + break; + case KINC_G4_VERTEX_DATA_U8_2X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatUChar2Normalized; + break; + case KINC_G4_VERTEX_DATA_I8_4X: + vertexDescriptor.attributes[index].format = MTLVertexFormatChar4; + break; + case KINC_G4_VERTEX_DATA_U8_4X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUChar4; + break; + case KINC_G4_VERTEX_DATA_I8_4X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatChar4Normalized; + break; + case KINC_G4_VERTEX_DATA_U8_4X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatUChar4Normalized; + break; + case KINC_G4_VERTEX_DATA_I16_1X: + vertexDescriptor.attributes[index].format = MTLVertexFormatShort; + break; + case KINC_G4_VERTEX_DATA_U16_1X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUShort; + break; + case KINC_G4_VERTEX_DATA_I16_1X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatShortNormalized; + break; + case KINC_G4_VERTEX_DATA_U16_1X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatUShortNormalized; + break; + case KINC_G4_VERTEX_DATA_I16_2X: + vertexDescriptor.attributes[index].format = MTLVertexFormatShort2; + break; + case KINC_G4_VERTEX_DATA_U16_2X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUShort2; + break; + case KINC_G4_VERTEX_DATA_I16_2X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatShort2Normalized; + break; + case KINC_G4_VERTEX_DATA_U16_2X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatUShort2Normalized; + break; + case KINC_G4_VERTEX_DATA_I16_4X: + vertexDescriptor.attributes[index].format = MTLVertexFormatShort4; + break; + case KINC_G4_VERTEX_DATA_U16_4X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUShort4; + break; + case KINC_G4_VERTEX_DATA_I16_4X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatShort4Normalized; + break; + case KINC_G4_VERTEX_DATA_U16_4X_NORMALIZED: + vertexDescriptor.attributes[index].format = MTLVertexFormatUShort4Normalized; + break; + case KINC_G4_VERTEX_DATA_I32_1X: + vertexDescriptor.attributes[index].format = MTLVertexFormatInt; + break; + case KINC_G4_VERTEX_DATA_U32_1X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUInt; + break; + case KINC_G4_VERTEX_DATA_I32_2X: + vertexDescriptor.attributes[index].format = MTLVertexFormatInt2; + break; + case KINC_G4_VERTEX_DATA_U32_2X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUInt2; + break; + case KINC_G4_VERTEX_DATA_I32_3X: + vertexDescriptor.attributes[index].format = MTLVertexFormatInt3; + break; + case KINC_G4_VERTEX_DATA_U32_3X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUInt3; + break; + case KINC_G4_VERTEX_DATA_I32_4X: + vertexDescriptor.attributes[index].format = MTLVertexFormatInt4; + break; + case KINC_G4_VERTEX_DATA_U32_4X: + vertexDescriptor.attributes[index].format = MTLVertexFormatUInt4; + break; + default: + assert(false); + break; + } } } + + vertexDescriptor.layouts[binding_index].stride = stride; + vertexDescriptor.layouts[binding_index].stepFunction = pipeline->inputLayout[binding_index]->instanced ? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex; + // stepRate default is 1, so we probably don’t need this. + // I also think kinc doesn't allow a step rate to be set + // vertexDescriptor.layouts[binding_index].stepRate = 1; } - vertexDescriptor.layouts[0].stride = offset; - vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; - renderPipelineDesc.vertexDescriptor = vertexDescriptor; NSError *errors = nil; From 165bd8d14eb1d58f05ebce11ae29e66bf37da0b8 Mon Sep 17 00:00:00 2001 From: Daniel Barber Date: Fri, 28 Feb 2025 02:53:53 -0500 Subject: [PATCH 3/6] Added back missing line --- .../Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h index 53c8b51b1..cb305cedb 100644 --- a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h +++ b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h @@ -165,6 +165,8 @@ void kinc_g5_pipeline_compile(kinc_g5_pipeline_t *pipeline) { renderPipelineDesc.depthAttachmentPixelFormat = MTLPixelFormatInvalid; renderPipelineDesc.stencilAttachmentPixelFormat = MTLPixelFormatInvalid; + MTLVertexDescriptor *vertexDescriptor = [[MTLVertexDescriptor alloc] init]; + uint32_t bindings_count = 0; for (int i = 0; i < 16; ++i) { if (pipeline->inputLayout[i] == NULL) { From 121d4f9f08ef49dec659d9064c5c04ff98ac8b99 Mon Sep 17 00:00:00 2001 From: Daniel Barber Date: Fri, 28 Feb 2025 18:57:18 -0500 Subject: [PATCH 4/6] Make constant vertex buffer last of all vertex buffers. --- .../Metal/Sources/kinc/backend/graphics5/commandlist.m.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h index 44fc26e7b..8295d1132 100644 --- a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h +++ b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h @@ -18,6 +18,8 @@ id getMetalDevice(void); id getMetalQueue(void); id getMetalEncoder(void); +static uint32_t lastVertexBufferCount = 0; + void kinc_g5_internal_new_render_pass(kinc_g5_render_target_t **renderTargets, int count, bool wait, unsigned clear_flags, unsigned color, float depth, int stencil); void kinc_g5_internal_pipeline_set(kinc_g5_pipeline_t *pipeline); @@ -157,6 +159,7 @@ void kinc_g5_command_list_disable_scissor(kinc_g5_command_list_t *list) { } void kinc_g5_command_list_set_pipeline(kinc_g5_command_list_t *list, struct kinc_g5_pipeline *pipeline) { + lastVertexBufferCount = 0; kinc_g5_internal_pipeline_set(pipeline); lastPipeline = pipeline; } @@ -180,6 +183,7 @@ void kinc_g5_command_list_set_vertex_buffers(kinc_g5_command_list_t *list, struc offsets[i] = (NSUInteger)(offsets_[i] * kinc_g5_vertex_buffer_stride(vertexBuffers[i])); } [encoder setVertexBuffers:buffers offsets:offsets withRange:NSMakeRange(0, count)]; + lastVertexBufferCount = count; } void kinc_g5_command_list_set_index_buffer(kinc_g5_command_list_t *list, struct kinc_g5_index_buffer *buffer) { @@ -281,7 +285,8 @@ void kinc_g5_command_list_wait_for_execution_to_finish(kinc_g5_command_list_t *l void kinc_g5_command_list_set_vertex_constant_buffer(kinc_g5_command_list_t *list, struct kinc_g5_constant_buffer *buffer, int offset, size_t size) { id buf = (__bridge id)buffer->impl._buffer; id encoder = getMetalEncoder(); - [encoder setVertexBuffer:buf offset:offset atIndex:1]; + //[encoder setVertexBuffer:buf offset:offset atIndex:1]; + [encoder setVertexBuffer:buf offset:offset atIndex:lastVertexBufferCount]; } void kinc_g5_command_list_set_fragment_constant_buffer(kinc_g5_command_list_t *list, struct kinc_g5_constant_buffer *buffer, int offset, size_t size) { From 0bcdbbda7e44da010101f15ca6ed7040d6469a8b Mon Sep 17 00:00:00 2001 From: Daniel Barber Date: Wed, 5 Mar 2025 18:34:31 -0500 Subject: [PATCH 5/6] Modified vertex buffer indexes and removed unused variable. --- .../kinc/backend/graphics5/commandlist.m.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h index 8295d1132..bf3e8f892 100644 --- a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h +++ b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/commandlist.m.h @@ -18,8 +18,6 @@ id getMetalDevice(void); id getMetalQueue(void); id getMetalEncoder(void); -static uint32_t lastVertexBufferCount = 0; - void kinc_g5_internal_new_render_pass(kinc_g5_render_target_t **renderTargets, int count, bool wait, unsigned clear_flags, unsigned color, float depth, int stencil); void kinc_g5_internal_pipeline_set(kinc_g5_pipeline_t *pipeline); @@ -159,7 +157,6 @@ void kinc_g5_command_list_disable_scissor(kinc_g5_command_list_t *list) { } void kinc_g5_command_list_set_pipeline(kinc_g5_command_list_t *list, struct kinc_g5_pipeline *pipeline) { - lastVertexBufferCount = 0; kinc_g5_internal_pipeline_set(pipeline); lastPipeline = pipeline; } @@ -170,9 +167,10 @@ void kinc_g5_command_list_set_blend_constant(kinc_g5_command_list_t *list, float } void kinc_g5_command_list_set_vertex_buffers(kinc_g5_command_list_t *list, struct kinc_g5_vertex_buffer **vertexBuffers, int *offsets_, int count) { - // the only thing kinc_g5_internal_vertex_buffer_set really does is - // storing a pointer to a single current vertex buffer, but with the - // proper implementation there can more than one current buffer + // The only thing kinc_g5_internal_vertex_buffer_set really does is + // store a pointer to a single current vertex buffer, but with the + // new implementation there can more than one current buffer so I + // think this can be removed. //kinc_g5_internal_vertex_buffer_set(buffers[0], offsets[0]); id encoder = getMetalEncoder(); // Array to store Metal buffers and offsets in bytes @@ -182,8 +180,7 @@ void kinc_g5_command_list_set_vertex_buffers(kinc_g5_command_list_t *list, struc buffers[i] = (__bridge id)vertexBuffers[i]->impl.mtlBuffer; offsets[i] = (NSUInteger)(offsets_[i] * kinc_g5_vertex_buffer_stride(vertexBuffers[i])); } - [encoder setVertexBuffers:buffers offsets:offsets withRange:NSMakeRange(0, count)]; - lastVertexBufferCount = count; + [encoder setVertexBuffers:buffers offsets:offsets withRange:NSMakeRange(1, count)]; } void kinc_g5_command_list_set_index_buffer(kinc_g5_command_list_t *list, struct kinc_g5_index_buffer *buffer) { @@ -285,8 +282,7 @@ void kinc_g5_command_list_wait_for_execution_to_finish(kinc_g5_command_list_t *l void kinc_g5_command_list_set_vertex_constant_buffer(kinc_g5_command_list_t *list, struct kinc_g5_constant_buffer *buffer, int offset, size_t size) { id buf = (__bridge id)buffer->impl._buffer; id encoder = getMetalEncoder(); - //[encoder setVertexBuffer:buf offset:offset atIndex:1]; - [encoder setVertexBuffer:buf offset:offset atIndex:lastVertexBufferCount]; + [encoder setVertexBuffer:buf offset:offset atIndex:0]; } void kinc_g5_command_list_set_fragment_constant_buffer(kinc_g5_command_list_t *list, struct kinc_g5_constant_buffer *buffer, int offset, size_t size) { From 316c46a01c3cf00ff233797b05c2b9b6951d4625 Mon Sep 17 00:00:00 2001 From: Daniel Barber Date: Wed, 5 Mar 2025 18:36:16 -0500 Subject: [PATCH 6/6] Changed binding and buffer indexes to account for vertex data buffer being in positions 1 to n --- .../Metal/Sources/kinc/backend/graphics5/pipeline.m.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h index cb305cedb..ca810059f 100644 --- a/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h +++ b/Backends/Graphics5/Metal/Sources/kinc/backend/graphics5/pipeline.m.h @@ -190,7 +190,7 @@ void kinc_g5_pipeline_compile(kinc_g5_pipeline_t *pipeline) { //kinc_log(KINC_LOG_LEVEL_INFO, "Adding attribute: %s", element.name); //kinc_log(KINC_LOG_LEVEL_INFO, "Index: %i", index); //kinc_log(KINC_LOG_LEVEL_INFO, "Instanced: %s", pipeline->inputLayout[binding_index]->instanced ? "true" : "false"); - vertexDescriptor.attributes[index].bufferIndex = binding_index; + vertexDescriptor.attributes[index].bufferIndex = binding_index + 1; vertexDescriptor.attributes[index].offset = offset; offset += kinc_g4_vertex_data_size(element.data); stride += kinc_g4_vertex_data_size(element.data); @@ -317,8 +317,8 @@ void kinc_g5_pipeline_compile(kinc_g5_pipeline_t *pipeline) { } } - vertexDescriptor.layouts[binding_index].stride = stride; - vertexDescriptor.layouts[binding_index].stepFunction = pipeline->inputLayout[binding_index]->instanced ? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex; + vertexDescriptor.layouts[binding_index + 1].stride = stride; + vertexDescriptor.layouts[binding_index + 1].stepFunction = pipeline->inputLayout[binding_index]->instanced ? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex; // stepRate default is 1, so we probably don’t need this. // I also think kinc doesn't allow a step rate to be set // vertexDescriptor.layouts[binding_index].stepRate = 1;