From cf312e14a9818f09eb6b12ecd55594995c5b1341 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 19 May 2025 00:40:37 +0200 Subject: [PATCH] vkd3d-shader/msl: Handle SV_VERTEX_ID inputs. --- libs/vkd3d-shader/msl.c | 36 ++++++++++++++++--- tests/hlsl/nointerpolation.shader_test | 10 +++--- .../shader-interstage-interface.shader_test | 4 +-- tests/shader_runner_metal.m | 2 ++ 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index 649e01709..8b6a1e6b0 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -48,6 +48,7 @@ struct msl_generator const char *prefix; bool failed; + bool read_vertex_id; bool write_depth; const struct vkd3d_shader_interface_info *interface_info; @@ -1059,6 +1060,13 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) vkd3d_string_buffer_printf(buffer, "float4 position [[position]];\n"); continue; + case VKD3D_SHADER_SV_VERTEX_ID: + if (type != VKD3D_SHADER_TYPE_VERTEX) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled SV_VERTEX_ID in shader type #%x.", type); + gen->read_vertex_id = true; + continue; + case VKD3D_SHADER_SV_IS_FRONT_FACE: if (type != VKD3D_SHADER_TYPE_PIXEL) msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -1107,15 +1115,15 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) break; } - vkd3d_string_buffer_printf(buffer, "shader_in_%u ", i); + vkd3d_string_buffer_printf(buffer, "shader_in_%u [[", i); switch (type) { case VKD3D_SHADER_TYPE_VERTEX: - vkd3d_string_buffer_printf(gen->buffer, "[[attribute(%u)]]", e->target_location); + vkd3d_string_buffer_printf(gen->buffer, "attribute(%u)", e->target_location); break; case VKD3D_SHADER_TYPE_PIXEL: - vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location); + vkd3d_string_buffer_printf(gen->buffer, "user(locn%u)", e->target_location); break; default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -1129,13 +1137,16 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) case VKD3DSIM_LINEAR: case VKD3DSIM_NONE: break; + case VKD3DSIM_CONSTANT: + vkd3d_string_buffer_printf(gen->buffer, ", flat"); + break; default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); break; } - vkd3d_string_buffer_printf(buffer, ";\n"); + vkd3d_string_buffer_printf(buffer, "]];\n"); } vkd3d_string_buffer_printf(buffer, "};\n\n"); @@ -1289,6 +1300,12 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) vkd3d_string_buffer_printf(buffer, " = float4(input.position.xyz, 1.0f / input.position.w)"); break; + case VKD3D_SHADER_SV_VERTEX_ID: + msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = uint4(vertex_id, 0u, 0u, 0u)"); + break; + case VKD3D_SHADER_SV_IS_FRONT_FACE: msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); msl_print_write_mask(buffer, e->mask); @@ -1374,6 +1391,12 @@ static void msl_generate_entrypoint(struct msl_generator *gen) "constant descriptor *descriptors [[buffer(0)]],\n"); } + if (gen->read_vertex_id) + { + msl_print_indent(gen->buffer, 2); + vkd3d_string_buffer_printf(gen->buffer, "uint vertex_id [[vertex_id]],\n"); + } + msl_print_indent(gen->buffer, 2); vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix); @@ -1388,6 +1411,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen) msl_generate_entrypoint_prologue(gen); vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix); + if (gen->read_vertex_id) + vkd3d_string_buffer_printf(gen->buffer, ", vertex_id"); if (gen->write_depth) vkd3d_string_buffer_printf(gen->buffer, ", shader_out_depth"); if (gen->program->descriptors.descriptor_count) @@ -1449,6 +1474,9 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader "static void %s_main(thread vkd3d_vec4 *v, " "thread vkd3d_vec4 *o", gen->prefix); + + if (gen->read_vertex_id) + vkd3d_string_buffer_printf(gen->buffer, ", uint vertex_id"); if (gen->write_depth) vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth"); if (gen->program->descriptors.descriptor_count) diff --git a/tests/hlsl/nointerpolation.shader_test b/tests/hlsl/nointerpolation.shader_test index 03cab0f0c..b40526b4c 100644 --- a/tests/hlsl/nointerpolation.shader_test +++ b/tests/hlsl/nointerpolation.shader_test @@ -23,7 +23,7 @@ float4 main(nointerpolation float4 t : texcoord) : sv_target } [test] -todo(msl) draw triangle list 3 +draw triangle list 3 probe (0, 0, 640, 480) rgba (0.0, 1.0, 0.0, 1.0) [vertex shader] @@ -50,7 +50,7 @@ float4 main(ps_input input) : sv_target } [test] -todo(msl) draw triangle list 3 +draw triangle list 3 probe (0, 0, 640, 480) rgba (0.0, 1.0, 0.0, 1.0) [vertex shader] @@ -77,7 +77,7 @@ float4 main(nointerpolation ps_input input) : sv_target } [test] -todo(msl) draw triangle list 3 +draw triangle list 3 probe (0, 0, 640, 480) rgba (0.0, 1.0, 0.0, 1.0) [vertex shader] @@ -104,7 +104,7 @@ float4 main(centroid ps_input input) : sv_target } [test] -todo(msl) draw triangle list 3 +draw triangle list 3 probe (0, 0, 640, 480) rgba (0.0, 1.0, 0.0, 1.0) [vertex shader] @@ -135,7 +135,7 @@ shader model >= 4.0 shader model < 6.0 [test] -todo(msl) draw triangle list 3 +draw triangle list 3 probe (0, 0, 640, 480) rgba (0.0, 1.0, 0.0, 1.0) % Centroid for SM 6. diff --git a/tests/hlsl/shader-interstage-interface.shader_test b/tests/hlsl/shader-interstage-interface.shader_test index 5e246118f..e3c90e20f 100644 --- a/tests/hlsl/shader-interstage-interface.shader_test +++ b/tests/hlsl/shader-interstage-interface.shader_test @@ -192,7 +192,7 @@ format r32g32b32a32-sint size (2d, 640, 480) [test] -todo(msl) draw triangle strip 4 +draw triangle strip 4 todo(opengl) probe (0, 0) rgbai(-7000, -2, 0, 0) [pixel shader] @@ -206,7 +206,7 @@ format r32g32b32a32-uint size (2d, 640, 480) [test] -todo(msl) draw triangle strip 4 +draw triangle strip 4 probe (0, 0) rgbai(-7000, -2, 0, 0) [require] diff --git a/tests/shader_runner_metal.m b/tests/shader_runner_metal.m index 7d759b3f7..6e2062b60 100644 --- a/tests/shader_runner_metal.m +++ b/tests/shader_runner_metal.m @@ -89,6 +89,8 @@ static MTLVertexFormat get_metal_attribute_format(DXGI_FORMAT format) return MTLVertexFormatFloat4; case DXGI_FORMAT_R32G32_FLOAT: return MTLVertexFormatFloat2; + case DXGI_FORMAT_R32G32_SINT: + return MTLVertexFormatInt2; default: return MTLVertexFormatInvalid; }