From 8a2228e3f7651600955eac0695eea5645c6262e3 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Wed, 12 Feb 2025 00:39:31 +0100 Subject: [PATCH 1/5] Make Metal not crash --- .../Metal/Sources/kope/metal/commandlist.m | 36 +++++++++++-------- .../Metal/Sources/kope/metal/device.m | 10 ++++-- .../Sources/kope/metal/device_functions.h | 2 ++ .../Metal/Sources/kope/metal/metalunit.m | 2 ++ 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m b/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m index 0c4b33091..9d743fae6 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m @@ -17,22 +17,23 @@ void kope_metal_command_list_destroy(kope_g5_command_list *list) {} void kope_metal_command_list_begin_render_pass(kope_g5_command_list *list, const kope_g5_render_pass_parameters *parameters) { id texture = (__bridge id)parameters->color_attachments[0].texture.texture->metal.texture; - MTLRenderPassDescriptor *renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; - renderPassDescriptor.colorAttachments[0].texture = texture; - renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; - renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; - renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0); - renderPassDescriptor.depthAttachment.clearDepth = 1; - renderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear; - renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionStore; - renderPassDescriptor.depthAttachment.texture = nil; // depthTexture; - renderPassDescriptor.stencilAttachment.clearStencil = 0; - renderPassDescriptor.stencilAttachment.loadAction = MTLLoadActionDontCare; - renderPassDescriptor.stencilAttachment.storeAction = MTLStoreActionDontCare; - renderPassDescriptor.stencilAttachment.texture = nil; // depthTexture; + + MTLRenderPassDescriptor *render_pass_descriptor = [MTLRenderPassDescriptor renderPassDescriptor]; + render_pass_descriptor.colorAttachments[0].texture = texture; + render_pass_descriptor.colorAttachments[0].loadAction = MTLLoadActionClear; + render_pass_descriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0); + render_pass_descriptor.depthAttachment.clearDepth = 1; + render_pass_descriptor.depthAttachment.loadAction = MTLLoadActionClear; + render_pass_descriptor.depthAttachment.storeAction = MTLStoreActionStore; + render_pass_descriptor.depthAttachment.texture = nil; // depthTexture; + render_pass_descriptor.stencilAttachment.clearStencil = 0; + render_pass_descriptor.stencilAttachment.loadAction = MTLLoadActionDontCare; + render_pass_descriptor.stencilAttachment.storeAction = MTLStoreActionDontCare; + render_pass_descriptor.stencilAttachment.texture = nil; // depthTexture; id command_buffer = (__bridge id)list->metal.command_buffer; - list->metal.render_command_encoder = (__bridge_retained void *)[command_buffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + list->metal.render_command_encoder = (__bridge_retained void *)[command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor]; } void kope_metal_command_list_end_render_pass(kope_g5_command_list *list) { @@ -42,7 +43,12 @@ void kope_metal_command_list_end_render_pass(kope_g5_command_list *list) { } void kope_metal_command_list_present(kope_g5_command_list *list) { - //[command_buffer presentDrawable:drawable]; + id command_buffer = (__bridge id)list->metal.command_buffer; + + CAMetalLayer *metal_layer = getMetalLayer(); + id drawable = [metal_layer nextDrawable]; + + [command_buffer presentDrawable:drawable]; } void kope_metal_command_list_set_index_buffer(kope_g5_command_list *list, kope_g5_buffer *buffer, kope_g5_index_format index_format, uint64_t offset, diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/device.m b/Backends/Graphics5/Metal/Sources/kope/metal/device.m index 06b893dad..a09e8c3a9 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/device.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/device.m @@ -10,8 +10,6 @@ #include -CAMetalLayer *getMetalLayer(void); - void kope_metal_device_create(kope_g5_device *device, const kope_g5_device_wishlist *wishlist) { id metal_device = MTLCreateSystemDefaultDevice(); getMetalLayer().device = metal_device; @@ -58,9 +56,17 @@ void kope_metal_device_create_texture(kope_g5_device *device, const kope_g5_text return &framebuffer; } +kope_g5_texture_format kope_metal_device_framebuffer_format(kope_g5_device *device) { + return KOPE_G5_TEXTURE_FORMAT_RGBA8_UNORM; +} + void kope_metal_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list) { id command_buffer = (__bridge id)list->metal.command_buffer; [command_buffer commit]; + + id command_queue = (__bridge id)list->metal.command_queue; + command_buffer = [command_queue commandBuffer]; + list->metal.command_buffer = (__bridge_retained void *)[command_queue commandBuffer]; } void kope_metal_device_wait_until_idle(kope_g5_device *device) {} diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/device_functions.h b/Backends/Graphics5/Metal/Sources/kope/metal/device_functions.h index 1586c4940..e1efdcda6 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/device_functions.h +++ b/Backends/Graphics5/Metal/Sources/kope/metal/device_functions.h @@ -30,6 +30,8 @@ void kope_metal_device_create_sampler(kope_g5_device *device, const kope_g5_samp kope_g5_texture *kope_metal_device_get_framebuffer(kope_g5_device *device); +kope_g5_texture_format kope_metal_device_framebuffer_format(kope_g5_device *device); + void kope_metal_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list); void kope_metal_device_wait_until_idle(kope_g5_device *device); diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m b/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m index db845511b..8a687bb0f 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m @@ -6,6 +6,8 @@ #import +CAMetalLayer *getMetalLayer(void); + #include "buffer.m" #include "commandlist.m" #include "descriptorset.m" From 6233ddff6e5b6c9435d3c4e844c04562ad472d59 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Wed, 12 Feb 2025 01:06:47 +0100 Subject: [PATCH 2/5] Issue Metal draw commands --- .../Metal/Sources/kope/metal/commandlist.m | 34 ++++++++++++++++--- .../Sources/kope/metal/commandlist_structs.h | 2 ++ .../Metal/Sources/kope/metal/metalunit.m | 1 + .../Metal/Sources/kope/metal/pipeline.m | 20 ++++++++++- .../Sources/kope/metal/pipeline_structs.h | 2 +- 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m b/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m index 9d743fae6..818477702 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m @@ -52,17 +52,43 @@ void kope_metal_command_list_present(kope_g5_command_list *list) { } void kope_metal_command_list_set_index_buffer(kope_g5_command_list *list, kope_g5_buffer *buffer, kope_g5_index_format index_format, uint64_t offset, - uint64_t size) {} + uint64_t size) { + list->metal.index_buffer = buffer->metal.buffer; + list->metal.sixteen_bit_indices = index_format == KOPE_G5_INDEX_FORMAT_UINT16 ? true : false; +} void kope_metal_command_list_set_vertex_buffer(kope_g5_command_list *list, uint32_t slot, kope_metal_buffer *buffer, uint64_t offset, uint64_t size, - uint64_t stride) {} + uint64_t stride) { + id metal_buffer = (__bridge id)buffer->buffer; + + id render_command_encoder = (__bridge id)list->metal.render_command_encoder; + [render_command_encoder setVertexBuffer:metal_buffer offset:offset atIndex:slot]; +} -void kope_metal_command_list_set_render_pipeline(kope_g5_command_list *list, kope_metal_render_pipeline *pipeline) {} +void kope_metal_command_list_set_render_pipeline(kope_g5_command_list *list, kope_metal_render_pipeline *pipeline) { + id metal_pipeline = (__bridge id)pipeline->pipeline; + + id render_command_encoder = (__bridge id)list->metal.render_command_encoder; + [render_command_encoder setRenderPipelineState:metal_pipeline]; +} void kope_metal_command_list_draw(kope_g5_command_list *list, uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) {} void kope_metal_command_list_draw_indexed(kope_g5_command_list *list, uint32_t index_count, uint32_t instance_count, uint32_t first_index, int32_t base_vertex, - uint32_t first_instance) {} + uint32_t first_instance) { + id index_buffer = (__bridge id)list->metal.index_buffer; + + id render_command_encoder = (__bridge id)list->metal.render_command_encoder; + + [render_command_encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle + indexCount:index_count + indexType:(list->metal.sixteen_bit_indices ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32) + indexBuffer:index_buffer + indexBufferOffset:first_index + instanceCount:instance_count + baseVertex:base_vertex + baseInstance:first_instance]; +} void kope_metal_command_list_set_descriptor_table(kope_g5_command_list *list, uint32_t table_index, kope_metal_descriptor_set *set, kope_g5_buffer **dynamic_buffers, uint32_t *dynamic_offsets, uint32_t *dynamic_sizes) {} diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/commandlist_structs.h b/Backends/Graphics5/Metal/Sources/kope/metal/commandlist_structs.h index ca6509e3a..8ee926537 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/commandlist_structs.h +++ b/Backends/Graphics5/Metal/Sources/kope/metal/commandlist_structs.h @@ -23,6 +23,8 @@ typedef struct kope_metal_command_list { void *command_queue; void *command_buffer; void *render_command_encoder; + void *index_buffer; + bool sixteen_bit_indices; } kope_metal_command_list; #ifdef __cplusplus diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m b/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m index 8a687bb0f..ac3bb704c 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m @@ -7,6 +7,7 @@ #import CAMetalLayer *getMetalLayer(void); +id getMetalLibrary(void); #include "buffer.m" #include "commandlist.m" diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m index e90c249b5..46f375257 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m @@ -3,7 +3,25 @@ #include -void kope_metal_render_pipeline_init(kope_metal_device *device, kope_metal_render_pipeline *pipe, const kope_metal_render_pipeline_parameters *parameters) {} +void kope_metal_render_pipeline_init(kope_metal_device *device, kope_metal_render_pipeline *pipe, const kope_metal_render_pipeline_parameters *parameters) { + id vertex_function = [getMetalLibrary() newFunctionWithName:[NSString stringWithCString:parameters->vertex.shader.function_name encoding:NSUTF8StringEncoding]]; + id fragment_function = [getMetalLibrary() newFunctionWithName:[NSString stringWithCString:parameters->fragment.shader.function_name encoding:NSUTF8StringEncoding]]; + + MTLRenderPipelineDescriptor *render_pipeline_descriptor = [[MTLRenderPipelineDescriptor alloc] init]; + render_pipeline_descriptor.vertexFunction = vertex_function; + render_pipeline_descriptor.fragmentFunction = fragment_function; + + // TODO + + NSError *errors = nil; + MTLRenderPipelineReflection *reflection = nil; + id metal_device = (__bridge id)device->device; + + pipe->pipeline = (__bridge_retained void *)[metal_device newRenderPipelineStateWithDescriptor:render_pipeline_descriptor + options:MTLPipelineOptionBufferTypeInfo + reflection:&reflection + error:&errors]; +} void kope_metal_render_pipeline_destroy(kope_metal_render_pipeline *pipe) {} diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline_structs.h b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline_structs.h index 03c86616a..c85d9cced 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline_structs.h +++ b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline_structs.h @@ -196,7 +196,7 @@ typedef struct kope_metal_render_pipeline_parameters { } kope_metal_render_pipeline_parameters; typedef struct kope_metal_render_pipeline { - int nothing; + void *pipeline; } kope_metal_render_pipeline; typedef struct kope_metal_compute_pipeline_parameters { From 90416ce6553e94e1bd2b4860170a4a3dbd3fe6a1 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Wed, 12 Feb 2025 01:20:42 +0100 Subject: [PATCH 3/5] Update Kong --- Tools/linux_arm | 2 +- Tools/linux_arm64 | 2 +- Tools/linux_x64 | 2 +- Tools/macos | 2 +- Tools/windows_x64 | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Tools/linux_arm b/Tools/linux_arm index 1d970b9c3..bb760d42e 160000 --- a/Tools/linux_arm +++ b/Tools/linux_arm @@ -1 +1 @@ -Subproject commit 1d970b9c348459b0eff4857aa650ba8834ccdab1 +Subproject commit bb760d42e4dd75f030cf6c60999217f2fb363e2e diff --git a/Tools/linux_arm64 b/Tools/linux_arm64 index b2089ac62..5fbe01102 160000 --- a/Tools/linux_arm64 +++ b/Tools/linux_arm64 @@ -1 +1 @@ -Subproject commit b2089ac62e7b5dde84d2145fc74d3ae6031fa205 +Subproject commit 5fbe011028bc7f2a7e83a77e77ac14b9cfc9e203 diff --git a/Tools/linux_x64 b/Tools/linux_x64 index 244b26811..90103fe34 160000 --- a/Tools/linux_x64 +++ b/Tools/linux_x64 @@ -1 +1 @@ -Subproject commit 244b268111021b59e57259df682101efe25a14a8 +Subproject commit 90103fe3443ec994390f3bef2a789c19efb4bce9 diff --git a/Tools/macos b/Tools/macos index a8c3aed89..0d47d242f 160000 --- a/Tools/macos +++ b/Tools/macos @@ -1 +1 @@ -Subproject commit a8c3aed894ad52356a0551bcd7a8b43c5ca8756e +Subproject commit 0d47d242f69674c12f8a0dfe83ed276545f9992c diff --git a/Tools/windows_x64 b/Tools/windows_x64 index 965d056ef..8889a8432 160000 --- a/Tools/windows_x64 +++ b/Tools/windows_x64 @@ -1 +1 @@ -Subproject commit 965d056ef13180281a21ba5cb9a0b018fc3216a3 +Subproject commit 8889a8432cc1db8a0c38cfb0ca4d0feb8706a887 From a1ddf4060b67e78f67f804a7e30568b603db3c57 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Wed, 12 Feb 2025 01:25:43 +0100 Subject: [PATCH 4/5] Format code --- .../Metal/Sources/kope/metal/commandlist.m | 28 +++++++++---------- .../Metal/Sources/kope/metal/device.m | 2 +- .../Metal/Sources/kope/metal/pipeline.m | 20 +++++++------ 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m b/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m index 818477702..828c56baa 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/commandlist.m @@ -17,7 +17,7 @@ void kope_metal_command_list_destroy(kope_g5_command_list *list) {} void kope_metal_command_list_begin_render_pass(kope_g5_command_list *list, const kope_g5_render_pass_parameters *parameters) { id texture = (__bridge id)parameters->color_attachments[0].texture.texture->metal.texture; - + MTLRenderPassDescriptor *render_pass_descriptor = [MTLRenderPassDescriptor renderPassDescriptor]; render_pass_descriptor.colorAttachments[0].texture = texture; render_pass_descriptor.colorAttachments[0].loadAction = MTLLoadActionClear; @@ -44,10 +44,10 @@ void kope_metal_command_list_end_render_pass(kope_g5_command_list *list) { void kope_metal_command_list_present(kope_g5_command_list *list) { id command_buffer = (__bridge id)list->metal.command_buffer; - + CAMetalLayer *metal_layer = getMetalLayer(); id drawable = [metal_layer nextDrawable]; - + [command_buffer presentDrawable:drawable]; } @@ -60,14 +60,14 @@ void kope_metal_command_list_set_index_buffer(kope_g5_command_list *list, kope_g void kope_metal_command_list_set_vertex_buffer(kope_g5_command_list *list, uint32_t slot, kope_metal_buffer *buffer, uint64_t offset, uint64_t size, uint64_t stride) { id metal_buffer = (__bridge id)buffer->buffer; - + id render_command_encoder = (__bridge id)list->metal.render_command_encoder; [render_command_encoder setVertexBuffer:metal_buffer offset:offset atIndex:slot]; } void kope_metal_command_list_set_render_pipeline(kope_g5_command_list *list, kope_metal_render_pipeline *pipeline) { id metal_pipeline = (__bridge id)pipeline->pipeline; - + id render_command_encoder = (__bridge id)list->metal.render_command_encoder; [render_command_encoder setRenderPipelineState:metal_pipeline]; } @@ -77,17 +77,17 @@ void kope_metal_command_list_draw(kope_g5_command_list *list, uint32_t vertex_co void kope_metal_command_list_draw_indexed(kope_g5_command_list *list, uint32_t index_count, uint32_t instance_count, uint32_t first_index, int32_t base_vertex, uint32_t first_instance) { id index_buffer = (__bridge id)list->metal.index_buffer; - + id render_command_encoder = (__bridge id)list->metal.render_command_encoder; - + [render_command_encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle - indexCount:index_count - indexType:(list->metal.sixteen_bit_indices ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32) - indexBuffer:index_buffer - indexBufferOffset:first_index - instanceCount:instance_count - baseVertex:base_vertex - baseInstance:first_instance]; + indexCount:index_count + indexType:list->metal.sixteen_bit_indices ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32 + indexBuffer:index_buffer + indexBufferOffset:first_index + instanceCount:instance_count + baseVertex:base_vertex + baseInstance:first_instance]; } void kope_metal_command_list_set_descriptor_table(kope_g5_command_list *list, uint32_t table_index, kope_metal_descriptor_set *set, diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/device.m b/Backends/Graphics5/Metal/Sources/kope/metal/device.m index a09e8c3a9..c82ddf89e 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/device.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/device.m @@ -63,7 +63,7 @@ kope_g5_texture_format kope_metal_device_framebuffer_format(kope_g5_device *devi void kope_metal_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list) { id command_buffer = (__bridge id)list->metal.command_buffer; [command_buffer commit]; - + id command_queue = (__bridge id)list->metal.command_queue; command_buffer = [command_queue commandBuffer]; list->metal.command_buffer = (__bridge_retained void *)[command_queue commandBuffer]; diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m index 46f375257..78aa0d879 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m @@ -4,23 +4,25 @@ #include void kope_metal_render_pipeline_init(kope_metal_device *device, kope_metal_render_pipeline *pipe, const kope_metal_render_pipeline_parameters *parameters) { - id vertex_function = [getMetalLibrary() newFunctionWithName:[NSString stringWithCString:parameters->vertex.shader.function_name encoding:NSUTF8StringEncoding]]; - id fragment_function = [getMetalLibrary() newFunctionWithName:[NSString stringWithCString:parameters->fragment.shader.function_name encoding:NSUTF8StringEncoding]]; - + id vertex_function = [getMetalLibrary() newFunctionWithName:[NSString stringWithCString:parameters->vertex.shader.function_name + encoding:NSUTF8StringEncoding]]; + id fragment_function = [getMetalLibrary() newFunctionWithName:[NSString stringWithCString:parameters->fragment.shader.function_name + encoding:NSUTF8StringEncoding]]; + MTLRenderPipelineDescriptor *render_pipeline_descriptor = [[MTLRenderPipelineDescriptor alloc] init]; render_pipeline_descriptor.vertexFunction = vertex_function; render_pipeline_descriptor.fragmentFunction = fragment_function; - + // TODO - + NSError *errors = nil; MTLRenderPipelineReflection *reflection = nil; id metal_device = (__bridge id)device->device; - + pipe->pipeline = (__bridge_retained void *)[metal_device newRenderPipelineStateWithDescriptor:render_pipeline_descriptor - options:MTLPipelineOptionBufferTypeInfo - reflection:&reflection - error:&errors]; + options:MTLPipelineOptionBufferTypeInfo + reflection:&reflection + error:&errors]; } void kope_metal_render_pipeline_destroy(kope_metal_render_pipeline *pipe) {} From ce365bb197de3c8dfb7e3c5820888ce0aefaa7e9 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Thu, 13 Feb 2025 00:54:01 +0100 Subject: [PATCH 5/5] Make Metal run the first sample --- .../Metal/Sources/kope/metal/device.m | 2 +- .../Metal/Sources/kope/metal/metalunit.h | 8 + .../Metal/Sources/kope/metal/metalunit.m | 9 - .../Metal/Sources/kope/metal/pipeline.m | 350 +++++++++++++++++- .../Sources/kope/metal/pipeline_structs.h | 2 +- .../Sources/kinc/backend/BasicOpenGLView.m.h | 1 + .../macOS/Sources/kinc/backend/system.m.h | 4 - 7 files changed, 357 insertions(+), 19 deletions(-) diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/device.m b/Backends/Graphics5/Metal/Sources/kope/metal/device.m index a09e8c3a9..c7795f317 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/device.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/device.m @@ -57,7 +57,7 @@ void kope_metal_device_create_texture(kope_g5_device *device, const kope_g5_text } kope_g5_texture_format kope_metal_device_framebuffer_format(kope_g5_device *device) { - return KOPE_G5_TEXTURE_FORMAT_RGBA8_UNORM; + return KOPE_G5_TEXTURE_FORMAT_BGRA8_UNORM; } void kope_metal_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list) { diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.h b/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.h index f2fea1f68..8f64965d4 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.h +++ b/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.h @@ -1,4 +1,12 @@ #ifndef KOPE_METAL_UNIT_HEADER #define KOPE_METAL_UNIT_HEADER +#include + +#include + +#import + +CAMetalLayer *getMetalLayer(void); + #endif diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m b/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m index ac3bb704c..fac0cbae8 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/metalunit.m @@ -1,14 +1,5 @@ #include "metalunit.h" -#include - -#include - -#import - -CAMetalLayer *getMetalLayer(void); -id getMetalLibrary(void); - #include "buffer.m" #include "commandlist.m" #include "descriptorset.m" diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m index 46f375257..5477ab64f 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m +++ b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline.m @@ -1,22 +1,364 @@ #include "pipeline_functions.h" #include "pipeline_structs.h" +#include "metalunit.h" + #include +static MTLBlendFactor convert_blending_factor(kope_metal_blend_factor factor) { + switch (factor) { + case KOPE_METAL_BLEND_FACTOR_ONE: + return MTLBlendFactorOne; + case KOPE_METAL_BLEND_FACTOR_ZERO: + return MTLBlendFactorZero; + case KOPE_METAL_BLEND_FACTOR_SRC_ALPHA: + return MTLBlendFactorSourceAlpha; + case KOPE_METAL_BLEND_FACTOR_DST_ALPHA: + return MTLBlendFactorDestinationAlpha; + case KOPE_METAL_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: + return MTLBlendFactorOneMinusSourceAlpha; + case KOPE_METAL_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: + return MTLBlendFactorOneMinusDestinationAlpha; + case KOPE_METAL_BLEND_FACTOR_SRC: + return MTLBlendFactorSourceColor; + case KOPE_METAL_BLEND_FACTOR_DST: + return MTLBlendFactorDestinationColor; + case KOPE_METAL_BLEND_FACTOR_ONE_MINUS_SRC: + return MTLBlendFactorOneMinusSourceColor; + case KOPE_METAL_BLEND_FACTOR_ONE_MINUS_DST: + return MTLBlendFactorOneMinusDestinationColor; + case KOPE_METAL_BLEND_FACTOR_CONSTANT: + return MTLBlendFactorBlendColor; + case KOPE_METAL_BLEND_FACTOR_ONE_MINUS_CONSTANT: + return MTLBlendFactorOneMinusBlendColor; + case KOPE_METAL_BLEND_FACTOR_SRC_ALPHA_SATURATED: + return MTLBlendFactorSourceAlphaSaturated; + } +} + +static MTLBlendOperation convert_blending_operation(kope_metal_blend_operation op) { + switch (op) { + case KOPE_METAL_BLEND_OPERATION_ADD: + return MTLBlendOperationAdd; + case KOPE_METAL_BLEND_OPERATION_SUBTRACT: + return MTLBlendOperationSubtract; + case KOPE_METAL_BLEND_OPERATION_REVERSE_SUBTRACT: + return MTLBlendOperationReverseSubtract; + case KOPE_METAL_BLEND_OPERATION_MIN: + return MTLBlendOperationMin; + case KOPE_METAL_BLEND_OPERATION_MAX: + return MTLBlendOperationMax; + } +} + +static MTLPixelFormat convert_format(kope_g5_texture_format format) { + switch (format) { + case KOPE_G5_TEXTURE_FORMAT_R8_UNORM: + return MTLPixelFormatR8Unorm; + case KOPE_G5_TEXTURE_FORMAT_R8_SNORM: + return MTLPixelFormatR8Snorm; + case KOPE_G5_TEXTURE_FORMAT_R8_UINT: + return MTLPixelFormatR8Uint; + case KOPE_G5_TEXTURE_FORMAT_R8_SINT: + return MTLPixelFormatR8Sint; + case KOPE_G5_TEXTURE_FORMAT_R16_UINT: + return MTLPixelFormatR16Uint; + case KOPE_G5_TEXTURE_FORMAT_R16_SINT: + return MTLPixelFormatR16Sint; + case KOPE_G5_TEXTURE_FORMAT_R16_FLOAT: + return MTLPixelFormatR16Float; + case KOPE_G5_TEXTURE_FORMAT_RG8_UNORM: + return MTLPixelFormatRG8Unorm; + case KOPE_G5_TEXTURE_FORMAT_RG8_SNORM: + return MTLPixelFormatRG8Snorm; + case KOPE_G5_TEXTURE_FORMAT_RG8_UINT: + return MTLPixelFormatRG8Uint; + case KOPE_G5_TEXTURE_FORMAT_RG8_SINT: + return MTLPixelFormatRG8Sint; + case KOPE_G5_TEXTURE_FORMAT_R32_UINT: + return MTLPixelFormatR32Uint; + case KOPE_G5_TEXTURE_FORMAT_R32_SINT: + return MTLPixelFormatR32Sint; + case KOPE_G5_TEXTURE_FORMAT_R32_FLOAT: + return MTLPixelFormatR32Float; + case KOPE_G5_TEXTURE_FORMAT_RG16_UINT: + return MTLPixelFormatRG16Uint; + case KOPE_G5_TEXTURE_FORMAT_RG16_SINT: + return MTLPixelFormatRG16Sint; + case KOPE_G5_TEXTURE_FORMAT_RG16_FLOAT: + return MTLPixelFormatRG16Float; + case KOPE_G5_TEXTURE_FORMAT_RGBA8_UNORM: + return MTLPixelFormatRGBA8Unorm; + case KOPE_G5_TEXTURE_FORMAT_RGBA8_UNORM_SRGB: + return MTLPixelFormatRGBA8Unorm_sRGB; + case KOPE_G5_TEXTURE_FORMAT_RGBA8_SNORM: + return MTLPixelFormatRGBA8Unorm; + case KOPE_G5_TEXTURE_FORMAT_RGBA8_UINT: + return MTLPixelFormatRGBA8Uint; + case KOPE_G5_TEXTURE_FORMAT_RGBA8_SINT: + return MTLPixelFormatRGBA8Sint; + case KOPE_G5_TEXTURE_FORMAT_BGRA8_UNORM: + return MTLPixelFormatBGRA8Unorm; + case KOPE_G5_TEXTURE_FORMAT_BGRA8_UNORM_SRGB: + return MTLPixelFormatBGRA8Unorm_sRGB; + case KOPE_G5_TEXTURE_FORMAT_RGB9E5U_FLOAT: + return MTLPixelFormatRGB9E5Float; + case KOPE_G5_TEXTURE_FORMAT_RGB10A2_UINT: + return MTLPixelFormatRGB10A2Uint; + case KOPE_G5_TEXTURE_FORMAT_RGB10A2_UNORM: + return MTLPixelFormatRGB10A2Unorm; + case KOPE_G5_TEXTURE_FORMAT_RG11B10U_FLOAT: + return MTLPixelFormatRG11B10Float; + case KOPE_G5_TEXTURE_FORMAT_RG32_UINT: + return MTLPixelFormatRG32Uint; + case KOPE_G5_TEXTURE_FORMAT_RG32_SINT: + return MTLPixelFormatRG32Sint; + case KOPE_G5_TEXTURE_FORMAT_RG32_FLOAT: + return MTLPixelFormatRG32Float; + case KOPE_G5_TEXTURE_FORMAT_RGBA16_UINT: + return MTLPixelFormatRGBA16Uint; + case KOPE_G5_TEXTURE_FORMAT_RGBA16_SINT: + return MTLPixelFormatRGBA16Sint; + case KOPE_G5_TEXTURE_FORMAT_RGBA16_FLOAT: + return MTLPixelFormatRGBA16Float; + case KOPE_G5_TEXTURE_FORMAT_RGBA32_UINT: + return MTLPixelFormatRGBA32Uint; + case KOPE_G5_TEXTURE_FORMAT_RGBA32_SINT: + return MTLPixelFormatRGBA32Sint; + case KOPE_G5_TEXTURE_FORMAT_RGBA32_FLOAT: + return MTLPixelFormatRGBA32Float; + case KOPE_G5_TEXTURE_FORMAT_DEPTH16_UNORM: + return MTLPixelFormatDepth16Unorm; + case KOPE_G5_TEXTURE_FORMAT_DEPTH24PLUS_NOTHING8: + case KOPE_G5_TEXTURE_FORMAT_DEPTH24PLUS_STENCIL8: + return MTLPixelFormatDepth24Unorm_Stencil8; + case KOPE_G5_TEXTURE_FORMAT_DEPTH32FLOAT: + return MTLPixelFormatDepth32Float; + case KOPE_G5_TEXTURE_FORMAT_DEPTH32FLOAT_STENCIL8_NOTHING24: + return MTLPixelFormatDepth32Float_Stencil8; + } +} + +static uint32_t vertex_attribute_size(kope_metal_vertex_format format) { + switch (format) { + case KOPE_METAL_VERTEX_FORMAT_UINT8X2: + return 2; + case KOPE_METAL_VERTEX_FORMAT_UINT8X4: + return 4; + case KOPE_METAL_VERTEX_FORMAT_SINT8X2: + return 2; + case KOPE_METAL_VERTEX_FORMAT_SINT8X4: + return 4; + case KOPE_METAL_VERTEX_FORMAT_UNORM8X2: + return 2; + case KOPE_METAL_VERTEX_FORMAT_UNORM8X4: + return 4; + case KOPE_METAL_VERTEX_FORMAT_SNORM8X2: + return 2; + case KOPE_METAL_VERTEX_FORMAT_SNORM8X4: + return 4; + case KOPE_METAL_VERTEX_FORMAT_UINT16X2: + return 4; + case KOPE_METAL_VERTEX_FORMAT_UINT16X4: + return 8; + case KOPE_METAL_VERTEX_FORMAT_SINT16X2: + return 4; + case KOPE_METAL_VERTEX_FORMAT_SINT16X4: + return 8; + case KOPE_METAL_VERTEX_FORMAT_UNORM16X2: + return 4; + case KOPE_METAL_VERTEX_FORMAT_UNORM16X4: + return 8; + case KOPE_METAL_VERTEX_FORMAT_SNORM16X2: + return 4; + case KOPE_METAL_VERTEX_FORMAT_SNORM16X4: + return 8; + case KOPE_METAL_VERTEX_FORMAT_FLOAT16X2: + return 4; + case KOPE_METAL_VERTEX_FORMAT_FLOAT16X4: + return 8; + case KOPE_METAL_VERTEX_FORMAT_FLOAT32: + return 4; + case KOPE_METAL_VERTEX_FORMAT_FLOAT32X2: + return 8; + case KOPE_METAL_VERTEX_FORMAT_FLOAT32X3: + return 12; + case KOPE_METAL_VERTEX_FORMAT_FLOAT32X4: + return 16; + case KOPE_METAL_VERTEX_FORMAT_UINT32: + return 4; + case KOPE_METAL_VERTEX_FORMAT_UINT32X2: + return 8; + case KOPE_METAL_VERTEX_FORMAT_UINT32X3: + return 12; + case KOPE_METAL_VERTEX_FORMAT_UINT32X4: + return 16; + case KOPE_METAL_VERTEX_FORMAT_SINT32: + return 4; + case KOPE_METAL_VERTEX_FORMAT_SINT32X2: + return 8; + case KOPE_METAL_VERTEX_FORMAT_SINT32X3: + return 12; + case KOPE_METAL_VERTEX_FORMAT_SINT32X4: + return 16; + case KOPE_METAL_VERTEX_FORMAT_UNORM10_10_10_2: + return 4; + } + + return 0; +} + + void kope_metal_render_pipeline_init(kope_metal_device *device, kope_metal_render_pipeline *pipe, const kope_metal_render_pipeline_parameters *parameters) { - id vertex_function = [getMetalLibrary() newFunctionWithName:[NSString stringWithCString:parameters->vertex.shader.function_name encoding:NSUTF8StringEncoding]]; - id fragment_function = [getMetalLibrary() newFunctionWithName:[NSString stringWithCString:parameters->fragment.shader.function_name encoding:NSUTF8StringEncoding]]; + id library = (__bridge id)device->library; + + id vertex_function = [library newFunctionWithName:[NSString stringWithCString:parameters->vertex.shader.function_name encoding:NSUTF8StringEncoding]]; + id fragment_function = [library newFunctionWithName:[NSString stringWithCString:parameters->fragment.shader.function_name encoding:NSUTF8StringEncoding]]; MTLRenderPipelineDescriptor *render_pipeline_descriptor = [[MTLRenderPipelineDescriptor alloc] init]; render_pipeline_descriptor.vertexFunction = vertex_function; render_pipeline_descriptor.fragmentFunction = fragment_function; - // TODO + for (int i = 0; i < parameters->fragment.targets_count; ++i) { + render_pipeline_descriptor.colorAttachments[i].pixelFormat = convert_format(parameters->fragment.targets[i].format); + + render_pipeline_descriptor.colorAttachments[i].blendingEnabled = + parameters->fragment.targets[i].blend.color.src_factor != KOPE_METAL_BLEND_FACTOR_ONE || parameters->fragment.targets[i].blend.color.dst_factor != KOPE_METAL_BLEND_FACTOR_ZERO || + parameters->fragment.targets[i].blend.alpha.src_factor != KOPE_METAL_BLEND_FACTOR_ONE || parameters->fragment.targets[i].blend.alpha.dst_factor != KOPE_METAL_BLEND_FACTOR_ZERO; + + render_pipeline_descriptor.colorAttachments[i].sourceRGBBlendFactor = convert_blending_factor(parameters->fragment.targets[i].blend.color.src_factor); + render_pipeline_descriptor.colorAttachments[i].destinationRGBBlendFactor = convert_blending_factor(parameters->fragment.targets[i].blend.color.dst_factor); + render_pipeline_descriptor.colorAttachments[i].rgbBlendOperation = convert_blending_operation(parameters->fragment.targets[i].blend.color.operation); + + render_pipeline_descriptor.colorAttachments[i].sourceAlphaBlendFactor = convert_blending_factor(parameters->fragment.targets[i].blend.alpha.src_factor); + render_pipeline_descriptor.colorAttachments[i].destinationAlphaBlendFactor = convert_blending_factor(parameters->fragment.targets[i].blend.alpha.dst_factor); + render_pipeline_descriptor.colorAttachments[i].alphaBlendOperation = convert_blending_operation(parameters->fragment.targets[i].blend.alpha.operation); + + render_pipeline_descriptor.colorAttachments[i].writeMask = parameters->fragment.targets[i].write_mask; + } + render_pipeline_descriptor.depthAttachmentPixelFormat = MTLPixelFormatInvalid; + render_pipeline_descriptor.stencilAttachmentPixelFormat = MTLPixelFormatInvalid; + + float offset = 0; + MTLVertexDescriptor *vertex_descriptor = [[MTLVertexDescriptor alloc] init]; + + uint32_t attributes_count = 0; + uint32_t bindings_count = 0; + for (int i = 0; i < parameters->vertex.buffers_count; ++i) { + attributes_count += (uint32_t)parameters->vertex.buffers[i].attributes_count; + ++bindings_count; + } + + for (uint32_t binding_index = 0; binding_index < bindings_count; ++binding_index) { + for (uint32_t attribute_index = 0; attribute_index < parameters->vertex.buffers[binding_index].attributes_count; ++attribute_index) { + kope_metal_vertex_attribute attribute = parameters->vertex.buffers[binding_index].attributes[attribute_index]; + + vertex_descriptor.attributes[attribute_index].bufferIndex = 0; + vertex_descriptor.attributes[attribute_index].offset = offset; + + offset += vertex_attribute_size(attribute.format); + + switch (attribute.format) { + case KOPE_METAL_VERTEX_FORMAT_FLOAT32: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatFloat; + break; + case KOPE_METAL_VERTEX_FORMAT_FLOAT32X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatFloat2; + break; + case KOPE_METAL_VERTEX_FORMAT_FLOAT32X3: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatFloat3; + break; + case KOPE_METAL_VERTEX_FORMAT_FLOAT32X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatFloat4; + break; + case KOPE_METAL_VERTEX_FORMAT_SINT8X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatChar2; + break; + case KOPE_METAL_VERTEX_FORMAT_UINT8X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUChar2; + break; + case KOPE_METAL_VERTEX_FORMAT_SNORM8X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatChar2Normalized; + break; + case KOPE_METAL_VERTEX_FORMAT_UNORM8X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUChar2Normalized; + break; + case KOPE_METAL_VERTEX_FORMAT_SINT8X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatChar4; + break; + case KOPE_METAL_VERTEX_FORMAT_UINT8X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUChar4; + break; + case KOPE_METAL_VERTEX_FORMAT_SNORM8X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatChar4Normalized; + break; + case KOPE_METAL_VERTEX_FORMAT_UNORM8X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUChar4Normalized; + break; + case KOPE_METAL_VERTEX_FORMAT_SINT16X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatShort2; + break; + case KOPE_METAL_VERTEX_FORMAT_UINT16X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUShort2; + break; + case KOPE_METAL_VERTEX_FORMAT_SNORM16X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatShort2Normalized; + break; + case KOPE_METAL_VERTEX_FORMAT_UNORM16X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUShort2Normalized; + break; + case KOPE_METAL_VERTEX_FORMAT_SINT16X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatShort4; + break; + case KOPE_METAL_VERTEX_FORMAT_UINT16X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUShort4; + break; + case KOPE_METAL_VERTEX_FORMAT_SNORM16X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatShort4Normalized; + break; + case KOPE_METAL_VERTEX_FORMAT_UNORM16X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUShort4Normalized; + break; + case KOPE_METAL_VERTEX_FORMAT_SINT32: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatInt; + break; + case KOPE_METAL_VERTEX_FORMAT_UINT32: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUInt; + break; + case KOPE_METAL_VERTEX_FORMAT_SINT32X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatInt2; + break; + case KOPE_METAL_VERTEX_FORMAT_UINT32X2: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUInt2; + break; + case KOPE_METAL_VERTEX_FORMAT_SINT32X3: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatInt3; + break; + case KOPE_METAL_VERTEX_FORMAT_UINT32X3: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUInt3; + break; + case KOPE_METAL_VERTEX_FORMAT_SINT32X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatInt4; + break; + case KOPE_METAL_VERTEX_FORMAT_UINT32X4: + vertex_descriptor.attributes[attribute_index].format = MTLVertexFormatUInt4; + break; + default: + assert(false); + break; + } + } + } + + vertex_descriptor.layouts[0].stride = offset; + vertex_descriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; + + render_pipeline_descriptor.vertexDescriptor = vertex_descriptor; NSError *errors = nil; MTLRenderPipelineReflection *reflection = nil; id metal_device = (__bridge id)device->device; - + pipe->pipeline = (__bridge_retained void *)[metal_device newRenderPipelineStateWithDescriptor:render_pipeline_descriptor options:MTLPipelineOptionBufferTypeInfo reflection:&reflection diff --git a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline_structs.h b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline_structs.h index c85d9cced..dbe0c20e6 100644 --- a/Backends/Graphics5/Metal/Sources/kope/metal/pipeline_structs.h +++ b/Backends/Graphics5/Metal/Sources/kope/metal/pipeline_structs.h @@ -39,7 +39,7 @@ typedef enum kope_metal_vertex_format { KOPE_METAL_VERTEX_FORMAT_UINT32X2, KOPE_METAL_VERTEX_FORMAT_UINT32X3, KOPE_METAL_VERTEX_FORMAT_UINT32X4, - KOPE_METAL_VERTEX_FORMAT_SIN32, + KOPE_METAL_VERTEX_FORMAT_SINT32, KOPE_METAL_VERTEX_FORMAT_SINT32X2, KOPE_METAL_VERTEX_FORMAT_SINT32X3, KOPE_METAL_VERTEX_FORMAT_SINT32X4, diff --git a/Backends/System/macOS/Sources/kinc/backend/BasicOpenGLView.m.h b/Backends/System/macOS/Sources/kinc/backend/BasicOpenGLView.m.h index 8e15947c7..4f72b76a3 100644 --- a/Backends/System/macOS/Sources/kinc/backend/BasicOpenGLView.m.h +++ b/Backends/System/macOS/Sources/kinc/backend/BasicOpenGLView.m.h @@ -434,6 +434,7 @@ static CAMetalLayer *metalLayer = NULL; metalLayer.opaque = YES; metalLayer.backgroundColor = nil; + #else device = MTLCreateSystemDefaultDevice(); commandQueue = [device newCommandQueue]; diff --git a/Backends/System/macOS/Sources/kinc/backend/system.m.h b/Backends/System/macOS/Sources/kinc/backend/system.m.h index 47de6176f..18b92546b 100644 --- a/Backends/System/macOS/Sources/kinc/backend/system.m.h +++ b/Backends/System/macOS/Sources/kinc/backend/system.m.h @@ -213,10 +213,6 @@ int kinc_init(const char *name, int width, int height, kinc_window_options_t *wi kinc_g4_internal_init(); kinc_g4_internal_init_window(windowId, frame->depth_bits, frame->stencil_bits, true); -#ifdef KINC_KONG - kong_init(); -#endif - return 0; }