From 7dfa9e8f819bb160e0cc0f14b565536a120f46a2 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 23 May 2025 16:53:38 +0200 Subject: [PATCH] vkd3d-shader/msl: Implement VKD3DSIH_DISCARD. --- libs/vkd3d-shader/msl.c | 30 +++++++++++++++++++++++++----- tests/hlsl/clip.shader_test | 12 ++++++------ tests/hlsl/discard.shader_test | 4 ++-- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index 948107886..47ea6ce1f 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -737,19 +737,36 @@ static void msl_begin_block(struct msl_generator *gen) ++gen->indent; } -static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +static void msl_print_condition(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, + enum vkd3d_shader_conditional_op op, const struct vkd3d_shader_src_param *arg) { const char *condition; struct msl_src src; - msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); + msl_src_init(&src, gen, arg, VKD3DSP_WRITEMASK_0); - msl_print_indent(gen->buffer, gen->indent); - condition = ins->flags == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; - vkd3d_string_buffer_printf(gen->buffer, "if (%s(%s))\n", condition, src.str->buffer); + condition = op == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; + vkd3d_string_buffer_printf(buffer, "if (%s(%s))\n", condition, src.str->buffer); msl_src_cleanup(&src, &gen->string_buffers); +} +static void msl_discard(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + /* Note that discard_fragment() in Metal 2.2 and earlier behaves like + * SPIR-V OpKill, while in Metal 2.3 and later it behaves like + * OpDemoteToHelperInvocationEXT. We assume we have at least Metal 3 + * here. */ + msl_print_indent(gen->buffer, gen->indent); + msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]); + msl_print_indent(gen->buffer, gen->indent + 1); + vkd3d_string_buffer_printf(gen->buffer, "discard_fragment();\n"); +} + +static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + msl_print_indent(gen->buffer, gen->indent); + msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]); msl_begin_block(gen); } @@ -1024,6 +1041,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_DEFAULT: msl_default(gen); break; + case VKD3DSIH_DISCARD: + msl_discard(gen, ins); + break; case VKD3DSIH_DIV: msl_binop(gen, ins, "/"); break; diff --git a/tests/hlsl/clip.shader_test b/tests/hlsl/clip.shader_test index f253fbcb8..bb7597cfd 100644 --- a/tests/hlsl/clip.shader_test +++ b/tests/hlsl/clip.shader_test @@ -9,20 +9,20 @@ float4 main() : sv_target [test] uniform 0 float4 1 2 3 4 -todo(glsl | msl) draw quad +todo(glsl) draw quad probe (0, 0) rgba (1, 2, 3, 4) uniform 0 float4 9 8 7 6 -todo(glsl | msl) draw quad +todo(glsl) draw quad probe (0, 0) rgba (9, 8, 7, 6) uniform 0 float4 -1 8 7 6 -todo(glsl | msl) draw quad +todo(glsl) draw quad probe (0, 0) rgba (9, 8, 7, 6) uniform 0 float4 9 0 7 6 -todo(glsl | msl) draw quad +todo(glsl) draw quad probe (0, 0) rgba (9, 0, 7, 6) uniform 0 float4 3 -8 3 0 -todo(glsl | msl) draw quad +todo(glsl) draw quad probe (0, 0) rgba (9, 0, 7, 6) uniform 0 float4 3 3 3 -1 -todo(glsl | msl) draw quad +todo(glsl) draw quad probe (0, 0) rgba (9, 0, 7, 6) diff --git a/tests/hlsl/discard.shader_test b/tests/hlsl/discard.shader_test index a62f74148..ae55fc42a 100644 --- a/tests/hlsl/discard.shader_test +++ b/tests/hlsl/discard.shader_test @@ -10,10 +10,10 @@ float4 main() : sv_target [test] uniform 0 float4 1 2 3 4 -todo(sm<4 | glsl | msl) draw quad +todo(sm<4 | glsl) draw quad probe (0, 0) rgba (1, 2, 3, 4) uniform 0 float4 9 8 7 6 -todo(sm<4 | glsl | msl) draw quad +todo(sm<4 | glsl) draw quad probe (0, 0) rgba (1, 2, 3, 4) [require]