From cc517dd9491e0a6f2bc6b7bfc1af76d5948af7d6 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 11 Jun 2025 07:54:27 +1000 Subject: [PATCH] Updated vkd3d-latest patchset --- ...-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch | 2 +- ...-87ec2d98973432531d7d9d08dfc837376f9.patch | 2 +- ...-2b257caea94fce2a5ef58dd303de9d73563.patch | 2 +- ...-f1b36edc076117970b5a6d05a924b6c4248.patch | 2 +- ...-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch | 2 +- ...-8da518f2cd4021ef8d642bbb8050881d7ff.patch | 138 ++ ...-14477b1066cfd4d12ce044f98fea09507f3.patch | 2055 +++++++++++++++++ 7 files changed, 2198 insertions(+), 5 deletions(-) create mode 100644 patches/vkd3d-latest/0006-Updated-vkd3d-to-8da518f2cd4021ef8d642bbb8050881d7ff.patch create mode 100644 patches/vkd3d-latest/0007-Updated-vkd3d-to-14477b1066cfd4d12ce044f98fea09507f3.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch index 05963cf1..df7a5792 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch @@ -1,4 +1,4 @@ -From 40128154c0cefe020a9f8a6cf5da908339df493b Mon Sep 17 00:00:00 2001 +From 38ded2c6b1b3b587e3a23cd2190230e6acd86120 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 26 May 2025 07:03:34 +1000 Subject: [PATCH] Updated vkd3d to c4c7f10d99daa5d3efc036d74d5e09b6f1342407. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch index 85b64013..809bf762 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch @@ -1,4 +1,4 @@ -From 4b9f58f4f2577c30a1fa3b949217bcf5e525598f Mon Sep 17 00:00:00 2001 +From ba99d7169b0bea213655531ac66e714ca60a81f6 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 28 May 2025 07:14:59 +1000 Subject: [PATCH] Updated vkd3d to 87ec2d98973432531d7d9d08dfc837376f91844c. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch index 3cf17d02..dc4d17fd 100644 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch @@ -1,4 +1,4 @@ -From 5a866e3b406c57d7b78417110cb3685035fa4b15 Mon Sep 17 00:00:00 2001 +From 5b1f9a771641044d8cc5ed6ab8560f220ebd5b9e Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 3 Jun 2025 07:40:14 +1000 Subject: [PATCH] Updated vkd3d to 2b257caea94fce2a5ef58dd303de9d73563b9126. diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch index 9cf72b75..cb90e02f 100644 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch @@ -1,4 +1,4 @@ -From 6a86ff50e62add7c2739b6508518b5556dcd2289 Mon Sep 17 00:00:00 2001 +From 27ace4a398f2f56c420c3889f5874f17c6381790 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 5 Jun 2025 07:25:40 +1000 Subject: [PATCH] Updated vkd3d to f1b36edc076117970b5a6d05a924b6c4248e082f. diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch index b96c8594..50ff8a80 100644 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch @@ -1,4 +1,4 @@ -From 981c6b22b1d959588c16002c6176d72615c23cb0 Mon Sep 17 00:00:00 2001 +From 18df694d072cb411ab6187218cdc6d3e2c21d44b Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 6 Jun 2025 07:10:30 +1000 Subject: [PATCH] Updated vkd3d to d65be3d0c5698a1b0df7c39ec0eaa485a8bd35de. diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-8da518f2cd4021ef8d642bbb8050881d7ff.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-8da518f2cd4021ef8d642bbb8050881d7ff.patch new file mode 100644 index 00000000..e38d53ef --- /dev/null +++ b/patches/vkd3d-latest/0006-Updated-vkd3d-to-8da518f2cd4021ef8d642bbb8050881d7ff.patch @@ -0,0 +1,138 @@ +From 60ca99ec5f6b94c4128614cfdcae8cc4a0b9a9ee Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Tue, 10 Jun 2025 07:48:09 +1000 +Subject: [PATCH] Updated vkd3d to 8da518f2cd4021ef8d642bbb8050881d7ff490c1. + +--- + libs/vkd3d/libs/vkd3d-shader/msl.c | 45 +++++++++++++++++++++++++++++- + 1 file changed, 44 insertions(+), 1 deletion(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index 62981811ee4..b3e251eff28 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -382,6 +382,19 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu + return MSL_DATA_UNION; + } + ++ case VKD3DSPR_IDXTEMP: ++ vkd3d_string_buffer_printf(buffer, "x%u", reg->idx[0].offset); ++ msl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); ++ return MSL_DATA_UNION; ++ ++ case VKD3DSPR_SAMPLEMASK: ++ if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled sample coverage mask in shader type #%x.", ++ gen->program->shader_version.type); ++ vkd3d_string_buffer_printf(buffer, "o_mask"); ++ return MSL_DATA_FLOAT; ++ + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled register type %#x.", reg->type); +@@ -901,6 +914,14 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc + vkd3d_string_buffer_printf(gen->buffer, "return;\n"); + } + ++static void msl_dcl_indexable_temp(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "vkd3d_vec4 x%u[%u];\n", ++ ins->declaration.indexable_temp.register_idx, ++ ins->declaration.indexable_temp.register_size); ++} ++ + static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + gen->location = ins->location; +@@ -908,11 +929,15 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + switch (ins->opcode) + { + case VKD3DSIH_ADD: ++ case VKD3DSIH_IADD: + msl_binop(gen, ins, "+"); + break; + case VKD3DSIH_AND: + msl_binop(gen, ins, "&"); + break; ++ case VKD3DSIH_DCL_INDEXABLE_TEMP: ++ msl_dcl_indexable_temp(gen, ins); ++ break; + case VKD3DSIH_NOP: + break; + case VKD3DSIH_DIV: +@@ -933,6 +958,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_ENDIF: + msl_end_block(gen); + break; ++ case VKD3DSIH_EQO: + case VKD3DSIH_IEQ: + msl_relop(gen, ins, "=="); + break; +@@ -949,6 +975,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + msl_cast(gen, ins, "uint"); + break; + case VKD3DSIH_GEO: ++ case VKD3DSIH_IGE: + msl_relop(gen, ins, ">="); + break; + case VKD3DSIH_IF: +@@ -1276,6 +1303,12 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) + vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); + } + ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) ++ { ++ msl_print_indent(gen->buffer, 1); ++ vkd3d_string_buffer_printf(buffer, "uint shader_out_mask [[sample_mask]];\n"); ++ } ++ + vkd3d_string_buffer_printf(buffer, "};\n\n"); + } + +@@ -1371,6 +1404,9 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) + } + vkd3d_string_buffer_printf(buffer, ";\n"); + } ++ ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) ++ vkd3d_string_buffer_printf(gen->buffer, " output.shader_out_mask = as_type(o_mask);\n"); + } + + static void msl_generate_entrypoint(struct msl_generator *gen) +@@ -1414,6 +1450,9 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, 32); + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, 32); + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix); ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) ++ vkd3d_string_buffer_printf(gen->buffer, " float o_mask;\n"); ++ vkd3d_string_buffer_printf(gen->buffer, "\n"); + + msl_generate_entrypoint_prologue(gen); + +@@ -1422,9 +1461,11 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + vkd3d_string_buffer_printf(gen->buffer, ", vertex_id"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) + vkd3d_string_buffer_printf(gen->buffer, ", output.shader_out_depth"); ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) ++ vkd3d_string_buffer_printf(gen->buffer, ", o_mask"); + if (gen->program->descriptors.descriptor_count) + vkd3d_string_buffer_printf(gen->buffer, ", descriptors"); +- vkd3d_string_buffer_printf(gen->buffer, ");\n"); ++ vkd3d_string_buffer_printf(gen->buffer, ");\n\n"); + + msl_generate_entrypoint_epilogue(gen); + +@@ -1486,6 +1527,8 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + vkd3d_string_buffer_printf(gen->buffer, ", uint vertex_id"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) + vkd3d_string_buffer_printf(gen->buffer, ", thread float &o_depth"); ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) ++ vkd3d_string_buffer_printf(gen->buffer, ", thread float &o_mask"); + if (gen->program->descriptors.descriptor_count) + vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors"); + vkd3d_string_buffer_printf(gen->buffer, ")\n{\n"); +-- +2.47.2 + diff --git a/patches/vkd3d-latest/0007-Updated-vkd3d-to-14477b1066cfd4d12ce044f98fea09507f3.patch b/patches/vkd3d-latest/0007-Updated-vkd3d-to-14477b1066cfd4d12ce044f98fea09507f3.patch new file mode 100644 index 00000000..b6a3ebbb --- /dev/null +++ b/patches/vkd3d-latest/0007-Updated-vkd3d-to-14477b1066cfd4d12ce044f98fea09507f3.patch @@ -0,0 +1,2055 @@ +From 36be363d5d83d8854499d09d523a19952e422e29 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Wed, 11 Jun 2025 07:52:20 +1000 +Subject: [PATCH] Updated vkd3d to 14477b1066cfd4d12ce044f98fea09507f320251. + +--- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 332 +---------------- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 18 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 257 ++++++------- + libs/vkd3d/libs/vkd3d-shader/fx.c | 153 ++++---- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 6 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 342 +++++++++++++++++- + libs/vkd3d/libs/vkd3d-shader/msl.c | 126 ++++++- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 9 +- + 8 files changed, 701 insertions(+), 542 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index db60883f2a3..af5552635cb 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -27,336 +27,6 @@ + #include + #include + +-static const char * const shader_opcode_names[] = +-{ +- [VKD3DSIH_ABS ] = "abs", +- [VKD3DSIH_ACOS ] = "acos", +- [VKD3DSIH_ADD ] = "add", +- [VKD3DSIH_AND ] = "and", +- [VKD3DSIH_ASIN ] = "asin", +- [VKD3DSIH_ATAN ] = "atan", +- [VKD3DSIH_ATOMIC_AND ] = "atomic_and", +- [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", +- [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", +- [VKD3DSIH_ATOMIC_IMAX ] = "atomic_imax", +- [VKD3DSIH_ATOMIC_IMIN ] = "atomic_imin", +- [VKD3DSIH_ATOMIC_OR ] = "atomic_or", +- [VKD3DSIH_ATOMIC_UMAX ] = "atomic_umax", +- [VKD3DSIH_ATOMIC_UMIN ] = "atomic_umin", +- [VKD3DSIH_ATOMIC_XOR ] = "atomic_xor", +- [VKD3DSIH_BEM ] = "bem", +- [VKD3DSIH_BFI ] = "bfi", +- [VKD3DSIH_BFREV ] = "bfrev", +- [VKD3DSIH_BRANCH ] = "branch", +- [VKD3DSIH_BREAK ] = "break", +- [VKD3DSIH_BREAKC ] = "break", +- [VKD3DSIH_BREAKP ] = "breakp", +- [VKD3DSIH_BUFINFO ] = "bufinfo", +- [VKD3DSIH_CALL ] = "call", +- [VKD3DSIH_CALLNZ ] = "callnz", +- [VKD3DSIH_CASE ] = "case", +- [VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped", +- [VKD3DSIH_CMP ] = "cmp", +- [VKD3DSIH_CND ] = "cnd", +- [VKD3DSIH_CONTINUE ] = "continue", +- [VKD3DSIH_CONTINUEP ] = "continuec", +- [VKD3DSIH_COUNTBITS ] = "countbits", +- [VKD3DSIH_CRS ] = "crs", +- [VKD3DSIH_CUT ] = "cut", +- [VKD3DSIH_CUT_STREAM ] = "cut_stream", +- [VKD3DSIH_DADD ] = "dadd", +- [VKD3DSIH_DCL ] = "dcl", +- [VKD3DSIH_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer", +- [VKD3DSIH_DCL_FUNCTION_BODY ] = "dcl_function_body", +- [VKD3DSIH_DCL_FUNCTION_TABLE ] = "dcl_function_table", +- [VKD3DSIH_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags", +- [VKD3DSIH_DCL_GS_INSTANCES ] = "dcl_gs_instances", +- [VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count", +- [VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count", +- [VKD3DSIH_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor", +- [VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer", +- [VKD3DSIH_DCL_INDEX_RANGE ] = "dcl_index_range", +- [VKD3DSIH_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp", +- [VKD3DSIH_DCL_INPUT ] = "dcl_input", +- [VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count", +- [VKD3DSIH_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive", +- [VKD3DSIH_DCL_INPUT_PS ] = "dcl_input_ps", +- [VKD3DSIH_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv", +- [VKD3DSIH_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv", +- [VKD3DSIH_DCL_INPUT_SGV ] = "dcl_input_sgv", +- [VKD3DSIH_DCL_INPUT_SIV ] = "dcl_input_siv", +- [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface", +- [VKD3DSIH_DCL_OUTPUT ] = "dcl_output", +- [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", +- [VKD3DSIH_DCL_OUTPUT_SGV ] = "dcl_output_sgv", +- [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv", +- [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", +- [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw", +- [VKD3DSIH_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured", +- [VKD3DSIH_DCL_SAMPLER ] = "dcl_sampler", +- [VKD3DSIH_DCL_STREAM ] = "dcl_stream", +- [VKD3DSIH_DCL_TEMPS ] = "dcl_temps", +- [VKD3DSIH_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain", +- [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive", +- [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning", +- [VKD3DSIH_DCL_TGSM_RAW ] = "dcl_tgsm_raw", +- [VKD3DSIH_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured", +- [VKD3DSIH_DCL_THREAD_GROUP ] = "dcl_thread_group", +- [VKD3DSIH_DCL_UAV_RAW ] = "dcl_uav_raw", +- [VKD3DSIH_DCL_UAV_STRUCTURED ] = "dcl_uav_structured", +- [VKD3DSIH_DCL_UAV_TYPED ] = "dcl_uav_typed", +- [VKD3DSIH_DCL_VERTICES_OUT ] = "dcl_maxout", +- [VKD3DSIH_DDIV ] = "ddiv", +- [VKD3DSIH_DEF ] = "def", +- [VKD3DSIH_DEFAULT ] = "default", +- [VKD3DSIH_DEFB ] = "defb", +- [VKD3DSIH_DEFI ] = "defi", +- [VKD3DSIH_DEQO ] = "deq", +- [VKD3DSIH_DFMA ] = "dfma", +- [VKD3DSIH_DGEO ] = "dge", +- [VKD3DSIH_DISCARD ] = "discard", +- [VKD3DSIH_DIV ] = "div", +- [VKD3DSIH_DLT ] = "dlt", +- [VKD3DSIH_DMAX ] = "dmax", +- [VKD3DSIH_DMIN ] = "dmin", +- [VKD3DSIH_DMOV ] = "dmov", +- [VKD3DSIH_DMOVC ] = "dmovc", +- [VKD3DSIH_DMUL ] = "dmul", +- [VKD3DSIH_DNE ] = "dne", +- [VKD3DSIH_DP2 ] = "dp2", +- [VKD3DSIH_DP2ADD ] = "dp2add", +- [VKD3DSIH_DP3 ] = "dp3", +- [VKD3DSIH_DP4 ] = "dp4", +- [VKD3DSIH_DRCP ] = "drcp", +- [VKD3DSIH_DST ] = "dst", +- [VKD3DSIH_DSX ] = "dsx", +- [VKD3DSIH_DSX_COARSE ] = "deriv_rtx_coarse", +- [VKD3DSIH_DSX_FINE ] = "deriv_rtx_fine", +- [VKD3DSIH_DSY ] = "dsy", +- [VKD3DSIH_DSY_COARSE ] = "deriv_rty_coarse", +- [VKD3DSIH_DSY_FINE ] = "deriv_rty_fine", +- [VKD3DSIH_DTOF ] = "dtof", +- [VKD3DSIH_DTOI ] = "dtoi", +- [VKD3DSIH_DTOU ] = "dtou", +- [VKD3DSIH_ELSE ] = "else", +- [VKD3DSIH_EMIT ] = "emit", +- [VKD3DSIH_EMIT_STREAM ] = "emit_stream", +- [VKD3DSIH_ENDIF ] = "endif", +- [VKD3DSIH_ENDLOOP ] = "endloop", +- [VKD3DSIH_ENDREP ] = "endrep", +- [VKD3DSIH_ENDSWITCH ] = "endswitch", +- [VKD3DSIH_EQO ] = "eq", +- [VKD3DSIH_EQU ] = "eq_unord", +- [VKD3DSIH_EVAL_CENTROID ] = "eval_centroid", +- [VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index", +- [VKD3DSIH_EXP ] = "exp", +- [VKD3DSIH_EXPP ] = "expp", +- [VKD3DSIH_F16TOF32 ] = "f16tof32", +- [VKD3DSIH_F32TOF16 ] = "f32tof16", +- [VKD3DSIH_FCALL ] = "fcall", +- [VKD3DSIH_FIRSTBIT_HI ] = "firstbit_hi", +- [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo", +- [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi", +- [VKD3DSIH_FRC ] = "frc", +- [VKD3DSIH_FREM ] = "frem", +- [VKD3DSIH_FTOD ] = "ftod", +- [VKD3DSIH_FTOI ] = "ftoi", +- [VKD3DSIH_FTOU ] = "ftou", +- [VKD3DSIH_GATHER4 ] = "gather4", +- [VKD3DSIH_GATHER4_C ] = "gather4_c", +- [VKD3DSIH_GATHER4_C_S ] = "gather4_c_s", +- [VKD3DSIH_GATHER4_PO ] = "gather4_po", +- [VKD3DSIH_GATHER4_PO_C ] = "gather4_po_c", +- [VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s", +- [VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s", +- [VKD3DSIH_GATHER4_S ] = "gather4_s", +- [VKD3DSIH_GEO ] = "ge", +- [VKD3DSIH_GEU ] = "ge_unord", +- [VKD3DSIH_HCOS ] = "hcos", +- [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", +- [VKD3DSIH_HS_DECLS ] = "hs_decls", +- [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", +- [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", +- [VKD3DSIH_HSIN ] = "hsin", +- [VKD3DSIH_HTAN ] = "htan", +- [VKD3DSIH_IADD ] = "iadd", +- [VKD3DSIH_IBFE ] = "ibfe", +- [VKD3DSIH_IDIV ] = "idiv", +- [VKD3DSIH_IEQ ] = "ieq", +- [VKD3DSIH_IF ] = "if", +- [VKD3DSIH_IFC ] = "if", +- [VKD3DSIH_IGE ] = "ige", +- [VKD3DSIH_ILT ] = "ilt", +- [VKD3DSIH_IMAD ] = "imad", +- [VKD3DSIH_IMAX ] = "imax", +- [VKD3DSIH_IMIN ] = "imin", +- [VKD3DSIH_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc", +- [VKD3DSIH_IMM_ATOMIC_AND ] = "imm_atomic_and", +- [VKD3DSIH_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch", +- [VKD3DSIH_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume", +- [VKD3DSIH_IMM_ATOMIC_EXCH ] = "imm_atomic_exch", +- [VKD3DSIH_IMM_ATOMIC_IADD ] = "imm_atomic_iadd", +- [VKD3DSIH_IMM_ATOMIC_IMAX ] = "imm_atomic_imax", +- [VKD3DSIH_IMM_ATOMIC_IMIN ] = "imm_atomic_imin", +- [VKD3DSIH_IMM_ATOMIC_OR ] = "imm_atomic_or", +- [VKD3DSIH_IMM_ATOMIC_UMAX ] = "imm_atomic_umax", +- [VKD3DSIH_IMM_ATOMIC_UMIN ] = "imm_atomic_umin", +- [VKD3DSIH_IMM_ATOMIC_XOR ] = "imm_atomic_xor", +- [VKD3DSIH_IMUL ] = "imul", +- [VKD3DSIH_INE ] = "ine", +- [VKD3DSIH_INEG ] = "ineg", +- [VKD3DSIH_ISFINITE ] = "isfinite", +- [VKD3DSIH_ISHL ] = "ishl", +- [VKD3DSIH_ISHR ] = "ishr", +- [VKD3DSIH_ISINF ] = "isinf", +- [VKD3DSIH_ISNAN ] = "isnan", +- [VKD3DSIH_ITOD ] = "itod", +- [VKD3DSIH_ITOF ] = "itof", +- [VKD3DSIH_ITOI ] = "itoi", +- [VKD3DSIH_LABEL ] = "label", +- [VKD3DSIH_LD ] = "ld", +- [VKD3DSIH_LD2DMS ] = "ld2dms", +- [VKD3DSIH_LD2DMS_S ] = "ld2dms_s", +- [VKD3DSIH_LD_RAW ] = "ld_raw", +- [VKD3DSIH_LD_RAW_S ] = "ld_raw_s", +- [VKD3DSIH_LD_S ] = "ld_s", +- [VKD3DSIH_LD_STRUCTURED ] = "ld_structured", +- [VKD3DSIH_LD_STRUCTURED_S ] = "ld_structured_s", +- [VKD3DSIH_LD_UAV_TYPED ] = "ld_uav_typed", +- [VKD3DSIH_LD_UAV_TYPED_S ] = "ld_uav_typed_s", +- [VKD3DSIH_LIT ] = "lit", +- [VKD3DSIH_LOD ] = "lod", +- [VKD3DSIH_LOG ] = "log", +- [VKD3DSIH_LOGP ] = "logp", +- [VKD3DSIH_LOOP ] = "loop", +- [VKD3DSIH_LRP ] = "lrp", +- [VKD3DSIH_LTO ] = "lt", +- [VKD3DSIH_LTU ] = "lt_unord", +- [VKD3DSIH_M3x2 ] = "m3x2", +- [VKD3DSIH_M3x3 ] = "m3x3", +- [VKD3DSIH_M3x4 ] = "m3x4", +- [VKD3DSIH_M4x3 ] = "m4x3", +- [VKD3DSIH_M4x4 ] = "m4x4", +- [VKD3DSIH_MAD ] = "mad", +- [VKD3DSIH_MAX ] = "max", +- [VKD3DSIH_MIN ] = "min", +- [VKD3DSIH_MOV ] = "mov", +- [VKD3DSIH_MOVA ] = "mova", +- [VKD3DSIH_MOVC ] = "movc", +- [VKD3DSIH_MSAD ] = "msad", +- [VKD3DSIH_MUL ] = "mul", +- [VKD3DSIH_NEO ] = "ne_ord", +- [VKD3DSIH_NEU ] = "ne", +- [VKD3DSIH_NOP ] = "nop", +- [VKD3DSIH_NOT ] = "not", +- [VKD3DSIH_NRM ] = "nrm", +- [VKD3DSIH_OR ] = "or", +- [VKD3DSIH_ORD ] = "ord", +- [VKD3DSIH_PHASE ] = "phase", +- [VKD3DSIH_PHI ] = "phi", +- [VKD3DSIH_POW ] = "pow", +- [VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d", +- [VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x", +- [VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", +- [VKD3DSIH_QUAD_READ_LANE_AT ] = "quad_read_lane_at", +- [VKD3DSIH_RCP ] = "rcp", +- [VKD3DSIH_REP ] = "rep", +- [VKD3DSIH_RESINFO ] = "resinfo", +- [VKD3DSIH_RET ] = "ret", +- [VKD3DSIH_RETP ] = "retp", +- [VKD3DSIH_ROUND_NE ] = "round_ne", +- [VKD3DSIH_ROUND_NI ] = "round_ni", +- [VKD3DSIH_ROUND_PI ] = "round_pi", +- [VKD3DSIH_ROUND_Z ] = "round_z", +- [VKD3DSIH_RSQ ] = "rsq", +- [VKD3DSIH_SAMPLE ] = "sample", +- [VKD3DSIH_SAMPLE_B ] = "sample_b", +- [VKD3DSIH_SAMPLE_B_CL_S ] = "sample_b_cl_s", +- [VKD3DSIH_SAMPLE_C ] = "sample_c", +- [VKD3DSIH_SAMPLE_C_CL_S ] = "sample_c_cl_s", +- [VKD3DSIH_SAMPLE_C_LZ ] = "sample_c_lz", +- [VKD3DSIH_SAMPLE_C_LZ_S ] = "sample_c_lz_s", +- [VKD3DSIH_SAMPLE_CL_S ] = "sample_cl_s", +- [VKD3DSIH_SAMPLE_GRAD ] = "sample_d", +- [VKD3DSIH_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s", +- [VKD3DSIH_SAMPLE_INFO ] = "sample_info", +- [VKD3DSIH_SAMPLE_LOD ] = "sample_l", +- [VKD3DSIH_SAMPLE_LOD_S ] = "sample_l_s", +- [VKD3DSIH_SAMPLE_POS ] = "sample_pos", +- [VKD3DSIH_SETP ] = "setp", +- [VKD3DSIH_SGE ] = "sge", +- [VKD3DSIH_SGN ] = "sgn", +- [VKD3DSIH_SINCOS ] = "sincos", +- [VKD3DSIH_SLT ] = "slt", +- [VKD3DSIH_SQRT ] = "sqrt", +- [VKD3DSIH_STORE_RAW ] = "store_raw", +- [VKD3DSIH_STORE_STRUCTURED ] = "store_structured", +- [VKD3DSIH_STORE_UAV_TYPED ] = "store_uav_typed", +- [VKD3DSIH_SUB ] = "sub", +- [VKD3DSIH_SWAPC ] = "swapc", +- [VKD3DSIH_SWITCH ] = "switch", +- [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch", +- [VKD3DSIH_SYNC ] = "sync", +- [VKD3DSIH_TAN ] = "tan", +- [VKD3DSIH_TEX ] = "tex", +- [VKD3DSIH_TEXBEM ] = "texbem", +- [VKD3DSIH_TEXBEML ] = "texbeml", +- [VKD3DSIH_TEXCOORD ] = "texcoord", +- [VKD3DSIH_TEXCRD ] = "texcrd", +- [VKD3DSIH_TEXDEPTH ] = "texdepth", +- [VKD3DSIH_TEXDP3 ] = "texdp3", +- [VKD3DSIH_TEXDP3TEX ] = "texdp3tex", +- [VKD3DSIH_TEXKILL ] = "texkill", +- [VKD3DSIH_TEXLD ] = "texld", +- [VKD3DSIH_TEXLDD ] = "texldd", +- [VKD3DSIH_TEXLDL ] = "texldl", +- [VKD3DSIH_TEXM3x2DEPTH ] = "texm3x2depth", +- [VKD3DSIH_TEXM3x2PAD ] = "texm3x2pad", +- [VKD3DSIH_TEXM3x2TEX ] = "texm3x2tex", +- [VKD3DSIH_TEXM3x3 ] = "texm3x3", +- [VKD3DSIH_TEXM3x3DIFF ] = "texm3x3diff", +- [VKD3DSIH_TEXM3x3PAD ] = "texm3x3pad", +- [VKD3DSIH_TEXM3x3SPEC ] = "texm3x3spec", +- [VKD3DSIH_TEXM3x3TEX ] = "texm3x3tex", +- [VKD3DSIH_TEXM3x3VSPEC ] = "texm3x3vspec", +- [VKD3DSIH_TEXREG2AR ] = "texreg2ar", +- [VKD3DSIH_TEXREG2GB ] = "texreg2gb", +- [VKD3DSIH_TEXREG2RGB ] = "texreg2rgb", +- [VKD3DSIH_UBFE ] = "ubfe", +- [VKD3DSIH_UDIV ] = "udiv", +- [VKD3DSIH_UGE ] = "uge", +- [VKD3DSIH_ULT ] = "ult", +- [VKD3DSIH_UMAX ] = "umax", +- [VKD3DSIH_UMIN ] = "umin", +- [VKD3DSIH_UMUL ] = "umul", +- [VKD3DSIH_UNO ] = "uno", +- [VKD3DSIH_USHR ] = "ushr", +- [VKD3DSIH_UTOD ] = "utod", +- [VKD3DSIH_UTOF ] = "utof", +- [VKD3DSIH_UTOU ] = "utou", +- [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", +- [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", +- [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", +- [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", +- [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", +- [VKD3DSIH_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count", +- [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true", +- [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true", +- [VKD3DSIH_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane", +- [VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add", +- [VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax", +- [VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin", +- [VKD3DSIH_WAVE_OP_MAX ] = "wave_op_max", +- [VKD3DSIH_WAVE_OP_MIN ] = "wave_op_min", +- [VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul", +- [VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax", +- [VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin", +- [VKD3DSIH_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count", +- [VKD3DSIH_WAVE_READ_LANE_AT ] = "wave_read_lane_at", +- [VKD3DSIH_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first", +- [VKD3DSIH_XOR ] = "xor", +-}; +- + static const char * const shader_register_names[] = + { + [VKD3DSPR_ADDR ] = "a", +@@ -1750,7 +1420,7 @@ static void shader_dump_register_space(struct vkd3d_d3d_asm_compiler *compiler, + static void shader_print_opcode(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_opcode opcode) + { + vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s", compiler->colours.opcode, +- shader_opcode_names[opcode], compiler->colours.reset); ++ vsir_opcode_get_name(opcode, ""), compiler->colours.reset); + } + + static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler, +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index 05f46e264b9..c8291afcf6e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -1681,7 +1681,8 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ + if (!(info = shader_sm1_get_opcode_info_from_vsir(d3dbc, ins->opcode))) + { + vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE, +- "Opcode %#x not supported for shader profile.", ins->opcode); ++ "Instruction \"%s\" (%#x) is not supported for the current target.", ++ vsir_opcode_get_name(ins->opcode, ""), ins->opcode); + d3dbc->failed = true; + return NULL; + } +@@ -1689,16 +1690,16 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ + if (ins->dst_count != info->dst_count) + { + vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT, +- "Invalid destination count %u for vsir instruction %#x (expected %u).", +- ins->dst_count, ins->opcode, info->dst_count); ++ "Invalid destination parameter count %u for instruction \"%s\" (%#x); expected %u.", ++ ins->dst_count, vsir_opcode_get_name(ins->opcode, ""), ins->opcode, info->dst_count); + d3dbc->failed = true; + return NULL; + } + if (ins->src_count != info->src_count) + { + vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT, +- "Invalid source count %u for vsir instruction %#x (expected %u).", +- ins->src_count, ins->opcode, info->src_count); ++ "Invalid source parameter count %u for instruction \"%s\" (%#x); expected %u.", ++ ins->src_count, vsir_opcode_get_name(ins->opcode, ""), ins->opcode, info->src_count); + d3dbc->failed = true; + return NULL; + } +@@ -2029,8 +2030,8 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str + { + vkd3d_shader_error(d3dbc->message_context, &ins->location, + VKD3D_SHADER_ERROR_D3DBC_INVALID_WRITEMASK, +- "writemask %#x for vsir instruction with opcode %#x is not single component.", +- writemask, ins->opcode); ++ "Writemask %#x for instruction \"%s\" (%#x) is not single component.", ++ writemask, vsir_opcode_get_name(ins->opcode, ""), ins->opcode); + d3dbc->failed = true; + } + d3dbc_write_instruction(d3dbc, ins); +@@ -2038,7 +2039,8 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str + + default: + vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE, +- "vsir instruction with opcode %#x.", ins->opcode); ++ "Internal compiler error: Unhandled instruction \"%s\" (%#x).", ++ vsir_opcode_get_name(ins->opcode, ""), ins->opcode); + d3dbc->failed = true; + break; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 8c71176fb0b..1cbef387260 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -722,7 +722,6 @@ struct sm6_value + struct sm6_groupsharedmem_data groupsharedmem; + struct sm6_constant_data constant; + } u; +- struct vkd3d_shader_register reg; + }; + + struct dxil_record +@@ -2225,35 +2224,6 @@ static const char *sm6_parser_get_global_symbol_name(const struct sm6_parser *sm + return NULL; + } + +-static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg) +-{ +- if (!register_is_constant(reg) || (!data_type_is_integer(reg->data_type) && !data_type_is_bool(reg->data_type))) +- return UINT_MAX; +- +- if (reg->dimension == VSIR_DIMENSION_VEC4) +- WARN("Returning vec4.x.\n"); +- +- if (reg->type == VKD3DSPR_IMMCONST64) +- { +- if (reg->u.immconst_u64[0] > UINT_MAX) +- FIXME("Truncating 64-bit value.\n"); +- return reg->u.immconst_u64[0]; +- } +- +- return reg->u.immconst_u32[0]; +-} +- +-static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg) +-{ +- if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type)) +- return UINT64_MAX; +- +- if (reg->dimension == VSIR_DIMENSION_VEC4) +- WARN("Returning vec4.x.\n"); +- +- return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_u64[0] : reg->u.immconst_u32[0]; +-} +- + static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) + { + return value->value_type == VALUE_TYPE_FUNCTION; +@@ -2296,18 +2266,31 @@ static bool sm6_value_is_handle(const struct sm6_value *value) + + static inline bool sm6_value_is_constant(const struct sm6_value *value) + { +- return sm6_value_is_register(value) && register_is_constant(&value->reg); ++ return value->value_type == VALUE_TYPE_CONSTANT; + } + + static bool sm6_value_is_constant_zero(const struct sm6_value *value) + { +- /* Constant vectors do not occur. */ +- return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->reg); ++ if (value->value_type != VALUE_TYPE_CONSTANT || value->type->class != TYPE_CLASS_INTEGER) ++ return false; ++ ++ if (value->type->u.width == 64) ++ return value->u.constant.immconst.immconst_u64[0] == 0; ++ else ++ return value->u.constant.immconst.immconst_u32[0] == 0; + } + + static inline bool sm6_value_is_undef(const struct sm6_value *value) + { +- return sm6_value_is_register(value) && value->reg.type == VKD3DSPR_UNDEF; ++ switch (value->value_type) ++ { ++ case VALUE_TYPE_UNDEFINED: ++ case VALUE_TYPE_INVALID: ++ return true; ++ ++ default: ++ return false; ++ } + } + + static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count) +@@ -2326,7 +2309,7 @@ static bool sm6_value_is_data(const struct sm6_value *value) + + static bool sm6_value_is_ssa(const struct sm6_value *value) + { +- return sm6_value_is_register(value) && register_is_ssa(&value->reg); ++ return value->value_type == VALUE_TYPE_SSA; + } + + static bool sm6_value_is_numeric_array(const struct sm6_value *value) +@@ -2343,18 +2326,81 @@ static bool sm6_value_is_numeric_array(const struct sm6_value *value) + } + } + +-static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) ++static unsigned int sm6_value_get_constant_uint(const struct sm6_value *value, struct sm6_parser *sm6) + { + if (!sm6_value_is_constant(value)) ++ { ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, ++ "Invalid non-constant value."); + return UINT_MAX; +- return register_get_uint_value(&value->reg); ++ } ++ ++ if (value->type->class != TYPE_CLASS_INTEGER) ++ { ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, ++ "Invalid non-integer constant value."); ++ return UINT_MAX; ++ } ++ ++ if (value->type->u.width == 64) ++ { ++ uint64_t val = value->u.constant.immconst.immconst_u64[0]; ++ if (val > UINT_MAX) ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, ++ "Invalid 64-bit constant %"PRIu64" will be truncated do %u.", val, (unsigned int)val); ++ return val; ++ } ++ ++ return value->u.constant.immconst.immconst_u32[0]; + } + +-static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value) ++static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value, struct sm6_parser *sm6) + { + if (!sm6_value_is_constant(value)) ++ { ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, ++ "Invalid non-constant value."); + return UINT64_MAX; +- return register_get_uint64_value(&value->reg); ++ } ++ ++ if (value->type->class != TYPE_CLASS_INTEGER) ++ { ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, ++ "Invalid non-integer constant value."); ++ return UINT64_MAX; ++ } ++ ++ if (value->type->u.width == 64) ++ return value->u.constant.immconst.immconst_u64[0]; ++ else ++ return value->u.constant.immconst.immconst_u32[0]; ++} ++ ++static float sm6_value_get_constant_float(const struct sm6_value *value, struct sm6_parser *sm6) ++{ ++ if (!sm6_value_is_constant(value)) ++ { ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, ++ "Invalid non-constant value."); ++ return 0.0f; ++ } ++ ++ if (value->type->class != TYPE_CLASS_FLOAT) ++ { ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, ++ "Invalid non-floating-point constant value."); ++ return 0.0f; ++ } ++ ++ if (value->type->u.width == 64) ++ { ++ double val = value->u.constant.immconst.immconst_f64[0]; ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, ++ "Invalid double constant %lf will be truncated do float %f.", val, (float)val); ++ return val; ++ } ++ ++ return value->u.constant.immconst.immconst_f32[0]; + } + + static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) +@@ -2517,9 +2563,9 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value * + { + unsigned int id; + +- if (register_is_ssa(&value->reg) && value->reg.idx[0].offset) ++ if (value->value_type == VALUE_TYPE_SSA && value->u.ssa.id) + { +- id = value->reg.idx[0].offset; ++ id = value->u.ssa.id; + TRACE("Using forward-allocated id %u.\n", id); + } + else +@@ -2529,7 +2575,6 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value * + + value->value_type = VALUE_TYPE_SSA; + value->u.ssa.id = id; +- sm6_register_from_value(&value->reg, value, sm6); + } + + static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value) +@@ -2612,7 +2657,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, + { + if (address && sm6_value_is_constant(address)) + { +- idx->offset = sm6_value_get_constant_uint(address); ++ idx->offset = sm6_value_get_constant_uint(address, sm6); + idx->rel_addr = NULL; + } + else if (!address || sm6_value_is_undef(address)) +@@ -2966,7 +3011,6 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru + value->type = fwd_type; + value->value_type = VALUE_TYPE_SSA; + value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6); +- sm6_register_from_value(&value->reg, value, sm6); + } + } + +@@ -3055,23 +3099,6 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) + return value << 63; + } + +-static float register_get_float_value(const struct vkd3d_shader_register *reg) +-{ +- if (!register_is_constant(reg) || !data_type_is_floating_point(reg->data_type)) +- return 0.0; +- +- if (reg->dimension == VSIR_DIMENSION_VEC4) +- WARN("Returning vec4.x.\n"); +- +- if (reg->type == VKD3DSPR_IMMCONST64) +- { +- WARN("Truncating double to float.\n"); +- return reg->u.immconst_f64[0]; +- } +- +- return reg->u.immconst_f32[0]; +-} +- + static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, + const uint64_t *operands, struct sm6_parser *sm6) + { +@@ -3262,7 +3289,7 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + "Explicit pointee type for constexpr GEP does not match the element type."); + } + +- offset = sm6_value_get_constant_uint(operands[2]); ++ offset = sm6_value_get_constant_uint(operands[2], sm6); + if (!(gep_type = sm6_type_get_element_type_at_index(pointee_type, offset))) + { + WARN("Failed to get element type.\n"); +@@ -3282,8 +3309,6 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + index->index = operands[2]; + index->is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; + +- sm6_register_from_value(&dst->reg, dst, sm6); +- + return VKD3D_OK; + } + +@@ -3339,7 +3364,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + { + dst->value_type = VALUE_TYPE_CONSTANT; + memset(&dst->u.constant, 0, sizeof(dst->u.constant)); +- sm6_register_from_value(&dst->reg, dst, sm6); + } + break; + +@@ -3361,8 +3385,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + else + dst->u.constant.immconst.immconst_u64[0] = value; + +- sm6_register_from_value(&dst->reg, dst, sm6); +- + break; + + case CST_CODE_FLOAT: +@@ -3383,8 +3405,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + else + dst->u.constant.immconst.immconst_u64[0] = value; + +- sm6_register_from_value(&dst->reg, dst, sm6); +- + break; + + case CST_CODE_DATA: +@@ -3418,14 +3438,12 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + case CST_CODE_UNDEF: + dxil_record_validate_operand_max_count(record, 0, sm6); + dst->value_type = VALUE_TYPE_UNDEFINED; +- sm6_register_from_value(&dst->reg, dst, sm6); + break; + + default: + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Constant code %u is unhandled.", record->code); + dst->value_type = VALUE_TYPE_INVALID; +- sm6_register_from_value(&dst->reg, dst, sm6); + break; + } + +@@ -3500,8 +3518,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + type = dst->type; + *dst = *src; + dst->type = type; +- +- sm6_register_from_value(&dst->reg, dst, sm6); + break; + } + +@@ -3580,7 +3596,6 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru + + dst->value_type = VALUE_TYPE_IDXTEMP; + dst->u.idxtemp.id = ins->declaration.indexable_temp.register_idx; +- sm6_register_from_value(&dst->reg, dst, sm6); + } + + static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type, +@@ -3594,7 +3609,6 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 + dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; + dst->u.groupsharedmem.id = sm6->tgsm_count++; + dst->structure_stride = 0; +- sm6_register_from_value(&dst->reg, dst, sm6); + sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst, sm6); + ins->declaration.tgsm_raw.alignment = alignment; + byte_count = elem_type->u.width / 8u; +@@ -3619,7 +3633,6 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str + dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; + dst->u.groupsharedmem.id = sm6->tgsm_count++; + dst->structure_stride = elem_type->u.width / 8u; +- sm6_register_from_value(&dst->reg, dst, sm6); + sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst, sm6); + if (dst->structure_stride != 4) + { +@@ -3933,7 +3946,6 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + value->u.icb.id = icb->register_idx; + else + value->u.icb.id = 0; +- sm6_register_from_value(&value->reg, value, sm6); + } + + return VKD3D_OK; +@@ -4205,7 +4217,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec + if (!(size = sm6_parser_get_value_safe(sm6, record->operands[2]))) + return; + /* A size of 1 means one instance of type[0], i.e. one array. */ +- if (sm6_value_get_constant_uint(size) != 1) ++ if (sm6_value_get_constant_uint(size, sm6) != 1) + { + FIXME("Allocation size is not 1.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -4830,7 +4842,7 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ + + static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6) + { +- uint64_t code = sm6_value_get_constant_uint(operand); ++ uint64_t code = sm6_value_get_constant_uint(operand, sm6); + + switch (code) + { +@@ -4934,7 +4946,7 @@ static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic + enum dxil_sync_flags flags; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SYNC); +- flags = sm6_value_get_constant_uint(operands[0]); ++ flags = sm6_value_get_constant_uint(operands[0], sm6); + ins->flags = flags & (SYNC_THREAD_GROUP | SYNC_THREAD_GROUP_UAV); + if (flags & SYNC_GLOBAL_UAV) + ins->flags |= VKD3DSSF_GLOBAL_UAV; +@@ -4968,7 +4980,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu + "A dynamic update value for a UAV counter operation is not supported."); + return; + } +- i = sm6_value_get_constant_uint(operands[1]); ++ i = sm6_value_get_constant_uint(operands[1], sm6); + if (i != 1 && i != 255) + { + WARN("Unexpected update value %#x.\n", i); +@@ -5005,7 +5017,7 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int + if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], 3, NULL, state, &coord)) + return; + +- clamp = sm6_value_get_constant_uint(operands[5]); ++ clamp = sm6_value_get_constant_uint(operands[5], sm6); + + ins = state->ins; + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LOD); +@@ -5106,7 +5118,7 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa + if (!sm6_value_is_constant(address)) + return d; + +- register_index = sm6_value_get_constant_uint(address); ++ register_index = sm6_value_get_constant_uint(address, sm6); + if (register_index >= d->range.first && register_index <= d->range.last) + return d; + } +@@ -5123,8 +5135,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int + struct sm6_value *dst; + unsigned int id; + +- type = sm6_value_get_constant_uint(operands[0]); +- id = sm6_value_get_constant_uint(operands[1]); ++ type = sm6_value_get_constant_uint(operands[0], sm6); ++ id = sm6_value_get_constant_uint(operands[1], sm6); + if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2]))) + { + WARN("Failed to find resource type %#x, id %#x.\n", type, id); +@@ -5137,7 +5149,7 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int + dst->value_type = VALUE_TYPE_HANDLE; + dst->u.handle.d = d; + dst->u.handle.index = operands[2]; +- dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3]); ++ dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3], sm6); + + /* NOP is used to flag no instruction emitted. */ + ins->opcode = VKD3DSIH_NOP; +@@ -5155,7 +5167,7 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + +- i = sm6_value_get_constant_uint(operands[0]); ++ i = sm6_value_get_constant_uint(operands[0], sm6); + if (i >= MAX_GS_OUTPUT_STREAMS) + { + WARN("Invalid stream index %u.\n", i); +@@ -5196,7 +5208,7 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + +- if ((component_idx = sm6_value_get_constant_uint(operands[0])) >= 3) ++ if ((component_idx = sm6_value_get_constant_uint(operands[0], sm6)) >= 3) + { + WARN("Invalid component index %u.\n", component_idx); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -5265,8 +5277,8 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri + unsigned int row_index, column_index; + const struct signature_element *e; + +- row_index = sm6_value_get_constant_uint(operands[0]); +- column_index = sm6_value_get_constant_uint(operands[2]); ++ row_index = sm6_value_get_constant_uint(operands[0], sm6); ++ column_index = sm6_value_get_constant_uint(operands[2], sm6); + + signature = &sm6->p.program->input_signature; + if (row_index >= signature->element_count) +@@ -5353,7 +5365,7 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i + if (component_count > 1) + { + src_param->reg.dimension = VSIR_DIMENSION_VEC4; +- component_idx = sm6_value_get_constant_uint(operands[0]); ++ component_idx = sm6_value_get_constant_uint(operands[0], sm6); + } + src_param_init_scalar(src_param, component_idx); + +@@ -5508,8 +5520,8 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin + const struct shader_signature *signature; + const struct signature_element *e; + +- row_index = sm6_value_get_constant_uint(operands[0]); +- column_index = sm6_value_get_constant_uint(operands[2]); ++ row_index = sm6_value_get_constant_uint(operands[0], sm6); ++ column_index = sm6_value_get_constant_uint(operands[2], sm6); + + if (is_control_point && operands[3]->value_type == VALUE_TYPE_UNDEFINED) + { +@@ -5618,7 +5630,7 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic + enum vkd3d_shader_opcode opcode; + enum dxil_quad_op_kind quad_op; + +- quad_op = sm6_value_get_constant_uint(operands[1]); ++ quad_op = sm6_value_get_constant_uint(operands[1], sm6); + if ((opcode = dx_map_quad_op(quad_op)) == VKD3DSIH_INVALID) + { + FIXME("Unhandled quad op kind %u.\n", quad_op); +@@ -5652,7 +5664,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i + + if (op == DX_RAW_BUFFER_LOAD) + { +- write_mask = sm6_value_get_constant_uint(operands[3]); ++ write_mask = sm6_value_get_constant_uint(operands[3], sm6); + if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) + { + WARN("Invalid write mask %#x.\n", write_mask); +@@ -5695,7 +5707,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ + return; + raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; + +- write_mask = sm6_value_get_constant_uint(operands[7]); ++ write_mask = sm6_value_get_constant_uint(operands[7], sm6); + if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) + { + WARN("Invalid write mask %#x.\n", write_mask); +@@ -5721,7 +5733,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ + "Resource for a raw buffer store is not a raw or structured buffer."); + } + +- alignment = sm6_value_get_constant_uint(operands[8]); ++ alignment = sm6_value_get_constant_uint(operands[8], sm6); + if (alignment & (alignment - 1)) + { + FIXME("Invalid alignment %#x.\n", alignment); +@@ -5818,7 +5830,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr + "Resource for a typed buffer store is not a typed buffer."); + } + +- write_mask = sm6_value_get_constant_uint(operands[7]); ++ write_mask = sm6_value_get_constant_uint(operands[7], sm6); + if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) + { + WARN("Invalid write mask %#x.\n", write_mask); +@@ -5911,17 +5923,17 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in + instruction_dst_param_init_ssa_vector(ins, 2, sm6); + } + +-static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value) ++static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value, struct sm6_parser *sm6) + { +- return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value); ++ return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value, sm6); + } + + static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, + const struct sm6_value **operands, struct sm6_parser *sm6) + { +- ins->texel_offset.u = sm6_value_get_texel_offset(operands[0]); +- ins->texel_offset.v = sm6_value_get_texel_offset(operands[1]); +- ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]); ++ ins->texel_offset.u = sm6_value_get_texel_offset(operands[0], sm6); ++ ins->texel_offset.v = sm6_value_get_texel_offset(operands[1], sm6); ++ ins->texel_offset.w = sm6_value_get_texel_offset(operands[2], sm6); + } + + static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -6102,8 +6114,8 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr + const struct signature_element *e; + const struct sm6_value *value; + +- row_index = sm6_value_get_constant_uint(operands[0]); +- column_index = sm6_value_get_constant_uint(operands[2]); ++ row_index = sm6_value_get_constant_uint(operands[0], sm6); ++ column_index = sm6_value_get_constant_uint(operands[2], sm6); + + signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature; + if (row_index >= signature->element_count) +@@ -6203,7 +6215,7 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in + src_param_init_vector_from_handle(sm6, &src_params[1 + extended_offset], &resource->u.handle); + src_param_init_vector_from_handle(sm6, &src_params[2 + extended_offset], &sampler->u.handle); + /* Swizzle stored in the sampler parameter is the scalar component index to be gathered. */ +- swizzle = sm6_value_get_constant_uint(operands[8]); ++ swizzle = sm6_value_get_constant_uint(operands[8], sm6); + if (swizzle >= VKD3D_VEC4_SIZE) + { + WARN("Invalid swizzle %#x.\n", swizzle); +@@ -6277,7 +6289,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int + if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], 3, NULL, state, &coord)) + return; + +- write_mask = sm6_value_get_constant_uint(operands[8]); ++ write_mask = sm6_value_get_constant_uint(operands[8], sm6); + if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) + { + WARN("Invalid write mask %#x.\n", write_mask); +@@ -6351,7 +6363,7 @@ static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_i + enum dxil_wave_bit_op_kind wave_op; + enum vkd3d_shader_opcode opcode; + +- wave_op = sm6_value_get_constant_uint(operands[1]); ++ wave_op = sm6_value_get_constant_uint(operands[1], sm6); + + if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VKD3DSIH_INVALID) + return; +@@ -6398,8 +6410,8 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic + enum dxil_wave_op_kind wave_op; + bool is_signed; + +- wave_op = sm6_value_get_constant_uint(operands[1]); +- is_signed = !sm6_value_get_constant_uint(operands[2]); ++ wave_op = sm6_value_get_constant_uint(operands[1], sm6); ++ is_signed = !sm6_value_get_constant_uint(operands[2], sm6); + opcode = sm6_dx_map_wave_op(wave_op, is_signed, sm6_type_is_floating_point(operands[0]->type), sm6); + + if (opcode == VKD3DSIH_INVALID) +@@ -6687,7 +6699,6 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade + return; + + dst->value_type = VALUE_TYPE_INVALID; +- sm6_register_from_value(&dst->reg, dst, sm6); + } + + static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -6792,7 +6803,7 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor + "Expected a constant integer dx intrinsic function id."); + return; + } +- sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value), ++ sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value, sm6), + fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); + } + +@@ -6947,7 +6958,6 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor + { + *dst = *value; + dst->type = type; +- sm6_register_from_value(&dst->reg, dst, sm6); + return; + } + +@@ -7298,7 +7308,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + return; + + /* The first index is always zero, to form a simple pointer dereference. */ +- if (sm6_value_get_constant_uint(elem_value)) ++ if (sm6_value_get_constant_uint(elem_value, sm6)) + { + WARN("Expected constant zero.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -7318,7 +7328,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + return; + + /* If indexing is dynamic, just get the type at offset zero. */ +- elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value) : 0; ++ elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value, sm6) : 0; + type = sm6_type_get_element_type_at_index(pointee_type, elem_idx); + if (!type) + { +@@ -7347,8 +7357,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + index->index = elem_value; + index->is_in_bounds = record->operands[0]; + +- sm6_register_from_value(&dst->reg, dst, sm6); +- + ins->opcode = VKD3DSIH_NOP; + } + +@@ -7698,7 +7706,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec + "A switch case value is not a constant."); + } + +- terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src); ++ terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src, sm6); + } + + ins->opcode = VKD3DSIH_NOP; +@@ -7761,7 +7769,7 @@ static bool sm6_metadata_value_is_zero_or_undef(const struct sm6_metadata_value + && (sm6_value_is_undef(m->u.value) || sm6_value_is_constant_zero(m->u.value)); + } + +-static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, ++static bool sm6_metadata_get_uint_value(struct sm6_parser *sm6, + const struct sm6_metadata_value *m, unsigned int *u) + { + const struct sm6_value *value; +@@ -7775,12 +7783,12 @@ static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, + if (!sm6_type_is_integer(value->type)) + return false; + +- *u = sm6_value_get_constant_uint(value); ++ *u = sm6_value_get_constant_uint(value, sm6); + + return true; + } + +-static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, ++static bool sm6_metadata_get_uint64_value(struct sm6_parser *sm6, + const struct sm6_metadata_value *m, uint64_t *u) + { + const struct sm6_value *value; +@@ -7794,12 +7802,12 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, + if (!sm6_type_is_integer(value->type)) + return false; + +- *u = sm6_value_get_constant_uint(value); ++ *u = sm6_value_get_constant_uint(value, sm6); + + return true; + } + +-static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, ++static bool sm6_metadata_get_float_value(struct sm6_parser *sm6, + const struct sm6_metadata_value *m, float *f) + { + const struct sm6_value *value; +@@ -7813,7 +7821,7 @@ static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, + if (!sm6_type_is_floating_point(value->type)) + return false; + +- *f = register_get_float_value(&value->reg); ++ *f = sm6_value_get_constant_float(value, sm6); + + return true; + } +@@ -7999,7 +8007,6 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e + else if (metadata_node_get_unary_uint(node, &operand, sm6)) + { + dst->non_uniform = !!operand; +- sm6_register_from_value(&dst->reg, dst, sm6); + } + } + else +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index 90da8048b8e..9efaa0bc1fa 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -289,15 +289,6 @@ static void set_status(struct fx_write_context *fx, int status) + fx->status = status; + } + +-static void fx_print_string(struct vkd3d_string_buffer *buffer, const char *prefix, +- const char *s, size_t len) +-{ +- if (len) +- --len; /* Trim terminating null. */ +- vkd3d_string_buffer_printf(buffer, "%s", prefix); +- vkd3d_string_buffer_print_string_escaped(buffer, s, len); +-} +- + static uint32_t write_string(const char *string, struct fx_write_context *fx) + { + return fx->ops->write_string(string, fx); +@@ -770,7 +761,7 @@ static const struct rhs_named_value fx_2_filter_values[] = + { NULL } + }; + +-static const struct fx_2_state ++struct fx_2_state + { + const char *name; + enum hlsl_type_class class; +@@ -779,8 +770,9 @@ static const struct fx_2_state + uint32_t array_size; + uint32_t id; + const struct rhs_named_value *values; +-} +-fx_2_states[] = ++}; ++ ++static const struct fx_2_state fx_2_pass_states[] = + { + { "ZEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values }, + { "FillMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values }, +@@ -974,6 +966,23 @@ fx_2_states[] = + { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 176 }, + }; + ++static const struct fx_2_state fx_2_sampler_states[] = ++{ ++ { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 }, ++ { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values }, ++ { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values }, ++ { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values }, ++ { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 }, ++ { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values }, ++ { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values }, ++ { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values }, ++ { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 }, ++ { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 }, ++ { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 }, ++ { "SRGBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 }, ++ { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 }, ++}; ++ + static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) + { + struct vkd3d_bytecode_buffer *buffer = &fx->structured; +@@ -3648,20 +3657,43 @@ static void parse_fx_print_indent(struct fx_parser *parser) + vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); + } + +-static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset, uint32_t *size) ++static void fx_2_print_string_literal(struct fx_parser *parser, const char *prefix, ++ const char *s, uint32_t max_len, const char *suffix) + { +- const char *ptr; ++ uint32_t len; ++ ++ if (s) ++ len = strnlen(s, max_len); ++ if (!s || len == max_len) ++ { ++ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to parse a string entry."); ++ return; ++ } ++ ++ vkd3d_string_buffer_printf(&parser->buffer, "%s", prefix); ++ vkd3d_string_buffer_print_string_escaped(&parser->buffer, s, len); ++ vkd3d_string_buffer_printf(&parser->buffer, "%s", suffix); ++} + +- fx_parser_read_unstructured(parser, size, offset, sizeof(*size)); +- ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size); ++static void fx_2_parse_string_literal(struct fx_parser *parser, uint32_t offset, ++ bool unstructured, const char *prefix, const char *suffix) ++{ ++ uint32_t max_len; ++ const char *s; + +- if (!ptr) ++ if (unstructured) + { +- parser->failed = true; +- return ""; ++ fx_parser_read_unstructured(parser, &max_len, offset, sizeof(max_len)); ++ s = fx_parser_get_unstructured_ptr(parser, offset + 4, max_len); ++ } ++ else ++ { ++ max_len = fx_parser_read_u32(parser); ++ s = fx_parser_get_ptr(parser, max_len); ++ fx_parser_skip(parser, align(max_len, 4)); + } + +- return ptr; ++ fx_2_print_string_literal(parser, prefix, s, max_len, suffix); + } + + static unsigned int fx_get_fx_2_type_size(struct fx_parser *parser, uint32_t *offset) +@@ -3818,15 +3850,12 @@ static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset) + uint32_t semantic; + uint32_t element_count; + } var; +- const char *name; +- uint32_t size; + + fx_parser_read_unstructured(parser, &var, offset, sizeof(var)); + + fx_parse_fx_2_type(parser, offset); + +- name = fx_2_get_string(parser, var.name, &size); +- fx_print_string(&parser->buffer, " ", name, size); ++ fx_2_parse_string_literal(parser, var.name, true, " ", ""); + if (var.element_count) + vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count); + } +@@ -3840,7 +3869,8 @@ static bool is_fx_2_sampler(uint32_t type) + || type == D3DXPT_SAMPLERCUBE; + } + +-static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry); ++static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container, ++ const struct fx_assignment *entry); + + static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, + uint32_t offset) +@@ -3865,7 +3895,7 @@ static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, + fx_parser_read_unstructured(parser, &entry, offset, sizeof(entry)); + + parse_fx_print_indent(parser); +- fx_parse_fx_2_assignment(parser, &entry); ++ fx_parse_fx_2_assignment(parser, HLSL_CLASS_SAMPLER, &entry); + } + parse_fx_end_indent(parser); + parse_fx_print_indent(parser); +@@ -3943,15 +3973,29 @@ static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count) + vkd3d_string_buffer_printf(&parser->buffer, ">"); + } + +-static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry) ++static const struct fx_2_state *fx_2_get_state_by_id(enum hlsl_type_class container, uint32_t id) ++{ ++ const struct fx_2_state *table; ++ unsigned int count; ++ ++ count = container == HLSL_CLASS_PASS ? ARRAY_SIZE(fx_2_pass_states) : ARRAY_SIZE(fx_2_sampler_states); ++ table = container == HLSL_CLASS_PASS ? fx_2_pass_states : fx_2_sampler_states; ++ ++ /* State identifiers are sequential, no gaps */ ++ if (id >= table[0].id && id <= table[count - 1].id) ++ return &table[id - table[0].id]; ++ ++ return NULL; ++} ++ ++static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container, ++ const struct fx_assignment *entry) + { + const struct rhs_named_value *named_value = NULL; +- const struct fx_2_state *state = NULL; ++ const struct fx_2_state *state; + +- if (entry->id <= ARRAY_SIZE(fx_2_states)) ++ if ((state = fx_2_get_state_by_id(container, entry->id))) + { +- state = &fx_2_states[entry->id]; +- + vkd3d_string_buffer_printf(&parser->buffer, "%s", state->name); + if (state->array_size > 1) + vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry->lhs_index); +@@ -4028,18 +4072,14 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) + uint32_t annotation_count; + uint32_t assignment_count; + } pass; +- const char *name; +- uint32_t size; + + if (parser->failed) + return; + + fx_parser_read_u32s(parser, &technique, sizeof(technique)); + +- name = fx_2_get_string(parser, technique.name, &size); +- + parse_fx_print_indent(parser); +- fx_print_string(&parser->buffer, "technique ", name, size); ++ fx_2_parse_string_literal(parser, technique.name, true, "technique ", ""); + fx_parse_fx_2_annotations(parser, technique.annotation_count); + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); +@@ -4050,10 +4090,9 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) + for (uint32_t i = 0; i < technique.pass_count; ++i) + { + fx_parser_read_u32s(parser, &pass, sizeof(pass)); +- name = fx_2_get_string(parser, pass.name, &size); + + parse_fx_print_indent(parser); +- fx_print_string(&parser->buffer, "pass ", name, size); ++ fx_2_parse_string_literal(parser, pass.name, true, "pass ", ""); + fx_parse_fx_2_annotations(parser, pass.annotation_count); + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); +@@ -4067,7 +4106,7 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) + + parse_fx_print_indent(parser); + fx_parser_read_u32s(parser, &entry, sizeof(entry)); +- fx_parse_fx_2_assignment(parser, &entry); ++ fx_parse_fx_2_assignment(parser, HLSL_CLASS_PASS, &entry); + } + parse_fx_end_indent(parser); + +@@ -4189,8 +4228,7 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) + { + parse_fx_start_indent(parser); + parse_fx_print_indent(parser); +- fx_print_string(&parser->buffer, "\"", (const char *)data, size); +- vkd3d_string_buffer_printf(&parser->buffer, "\""); ++ fx_2_print_string_literal(parser, "\"", (const char *)data, size, "\""); + parse_fx_end_indent(parser); + } + else if (type == D3DXPT_PIXELSHADER || type == D3DXPT_VERTEXSHADER) +@@ -4230,20 +4268,16 @@ static void fx_dump_blob(struct fx_parser *parser, const void *blob, uint32_t si + } + } + +-static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size) ++static void fx_parse_fx_2_array_selector(struct fx_parser *parser) + { +- const uint8_t *end = parser->ptr + size; +- uint32_t name_size, blob_size = 0; ++ uint32_t size, blob_size = 0; + const void *blob = NULL; +- const char *name; ++ const uint8_t *end; + +- name_size = fx_parser_read_u32(parser); +- name = fx_parser_get_ptr(parser, name_size); +- fx_parser_skip(parser, name_size); ++ size = fx_parser_read_u32(parser); ++ end = parser->ptr + size; + +- if (!name || (uint8_t *)name >= end) +- fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, +- "Malformed name entry in the array selector."); ++ fx_2_parse_string_literal(parser, 0, false, "array \"", "\"\n"); + + if (parser->ptr <= end) + { +@@ -4257,11 +4291,6 @@ static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size + "Malformed blob entry in the array selector."); + } + +- if (name) +- { +- fx_print_string(&parser->buffer, "array \"", name, name_size); +- vkd3d_string_buffer_printf(&parser->buffer, "\"\n"); +- } + if (blob) + { + parse_fx_print_indent(parser); +@@ -4296,23 +4325,19 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) + state.technique, state.index, state.state); + } + +- size = fx_parser_read_u32(parser); +- + parse_fx_print_indent(parser); + + if (state.assignment_type == FX_2_ASSIGNMENT_PARAMETER) + { +- data = fx_parser_get_ptr(parser, size); +- fx_print_string(&parser->buffer, "parameter \"", data, size); +- vkd3d_string_buffer_printf(&parser->buffer, "\"\n"); +- fx_parser_skip(parser, align(size, 4)); ++ fx_2_parse_string_literal(parser, 0, false, "parameter \"", "\"\n"); + } + else if (state.assignment_type == FX_2_ASSIGNMENT_ARRAY_SELECTOR) + { +- fx_parse_fx_2_array_selector(parser, size); ++ fx_parse_fx_2_array_selector(parser); + } + else + { ++ size = fx_parser_read_u32(parser); + vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size); + data = fx_parser_get_ptr(parser, size); + fx_dump_blob(parser, data, size); +@@ -4718,6 +4743,8 @@ fx_4_fxlc_opcodes[] = + { 0x13a, "ceil" }, + { 0x200, "min" }, + { 0x201, "max" }, ++ { 0x202, "lt" }, ++ { 0x203, "ge" }, + { 0x204, "add" }, + { 0x205, "mul" }, + { 0x206, "atan2" }, +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index 0a91024a8d1..214632c00eb 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -561,10 +561,12 @@ static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3 + + static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) + { ++ const char *name = vsir_opcode_get_name(ins->opcode, ""); ++ + shader_glsl_print_indent(gen->buffer, gen->indent); +- vkd3d_string_buffer_printf(gen->buffer, "/* */\n", ins->opcode); ++ vkd3d_string_buffer_printf(gen->buffer, "/* */\n", name, ins->opcode); + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled instruction %#x.", ins->opcode); ++ "Internal compiler error: Unhandled instruction \"%s\" (%#x).", name, ins->opcode); + } + + static void shader_glsl_binop(struct vkd3d_glsl_generator *gen, +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 4abf6a65dbb..1925e20c685 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -29,6 +29,344 @@ struct vsir_transformation_context + struct vkd3d_shader_message_context *message_context; + }; + ++const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) ++{ ++ static const char * const names[] = ++ { ++ [VKD3DSIH_ABS ] = "abs", ++ [VKD3DSIH_ACOS ] = "acos", ++ [VKD3DSIH_ADD ] = "add", ++ [VKD3DSIH_AND ] = "and", ++ [VKD3DSIH_ASIN ] = "asin", ++ [VKD3DSIH_ATAN ] = "atan", ++ [VKD3DSIH_ATOMIC_AND ] = "atomic_and", ++ [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", ++ [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", ++ [VKD3DSIH_ATOMIC_IMAX ] = "atomic_imax", ++ [VKD3DSIH_ATOMIC_IMIN ] = "atomic_imin", ++ [VKD3DSIH_ATOMIC_OR ] = "atomic_or", ++ [VKD3DSIH_ATOMIC_UMAX ] = "atomic_umax", ++ [VKD3DSIH_ATOMIC_UMIN ] = "atomic_umin", ++ [VKD3DSIH_ATOMIC_XOR ] = "atomic_xor", ++ [VKD3DSIH_BEM ] = "bem", ++ [VKD3DSIH_BFI ] = "bfi", ++ [VKD3DSIH_BFREV ] = "bfrev", ++ [VKD3DSIH_BRANCH ] = "branch", ++ [VKD3DSIH_BREAK ] = "break", ++ [VKD3DSIH_BREAKC ] = "break", ++ [VKD3DSIH_BREAKP ] = "breakp", ++ [VKD3DSIH_BUFINFO ] = "bufinfo", ++ [VKD3DSIH_CALL ] = "call", ++ [VKD3DSIH_CALLNZ ] = "callnz", ++ [VKD3DSIH_CASE ] = "case", ++ [VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped", ++ [VKD3DSIH_CMP ] = "cmp", ++ [VKD3DSIH_CND ] = "cnd", ++ [VKD3DSIH_CONTINUE ] = "continue", ++ [VKD3DSIH_CONTINUEP ] = "continuec", ++ [VKD3DSIH_COUNTBITS ] = "countbits", ++ [VKD3DSIH_CRS ] = "crs", ++ [VKD3DSIH_CUT ] = "cut", ++ [VKD3DSIH_CUT_STREAM ] = "cut_stream", ++ [VKD3DSIH_DADD ] = "dadd", ++ [VKD3DSIH_DCL ] = "dcl", ++ [VKD3DSIH_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer", ++ [VKD3DSIH_DCL_FUNCTION_BODY ] = "dcl_function_body", ++ [VKD3DSIH_DCL_FUNCTION_TABLE ] = "dcl_function_table", ++ [VKD3DSIH_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags", ++ [VKD3DSIH_DCL_GS_INSTANCES ] = "dcl_gs_instances", ++ [VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count", ++ [VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count", ++ [VKD3DSIH_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor", ++ [VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer", ++ [VKD3DSIH_DCL_INDEX_RANGE ] = "dcl_index_range", ++ [VKD3DSIH_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp", ++ [VKD3DSIH_DCL_INPUT ] = "dcl_input", ++ [VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count", ++ [VKD3DSIH_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive", ++ [VKD3DSIH_DCL_INPUT_PS ] = "dcl_input_ps", ++ [VKD3DSIH_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv", ++ [VKD3DSIH_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv", ++ [VKD3DSIH_DCL_INPUT_SGV ] = "dcl_input_sgv", ++ [VKD3DSIH_DCL_INPUT_SIV ] = "dcl_input_siv", ++ [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface", ++ [VKD3DSIH_DCL_OUTPUT ] = "dcl_output", ++ [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", ++ [VKD3DSIH_DCL_OUTPUT_SGV ] = "dcl_output_sgv", ++ [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv", ++ [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", ++ [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw", ++ [VKD3DSIH_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured", ++ [VKD3DSIH_DCL_SAMPLER ] = "dcl_sampler", ++ [VKD3DSIH_DCL_STREAM ] = "dcl_stream", ++ [VKD3DSIH_DCL_TEMPS ] = "dcl_temps", ++ [VKD3DSIH_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain", ++ [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive", ++ [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning", ++ [VKD3DSIH_DCL_TGSM_RAW ] = "dcl_tgsm_raw", ++ [VKD3DSIH_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured", ++ [VKD3DSIH_DCL_THREAD_GROUP ] = "dcl_thread_group", ++ [VKD3DSIH_DCL_UAV_RAW ] = "dcl_uav_raw", ++ [VKD3DSIH_DCL_UAV_STRUCTURED ] = "dcl_uav_structured", ++ [VKD3DSIH_DCL_UAV_TYPED ] = "dcl_uav_typed", ++ [VKD3DSIH_DCL_VERTICES_OUT ] = "dcl_maxout", ++ [VKD3DSIH_DDIV ] = "ddiv", ++ [VKD3DSIH_DEF ] = "def", ++ [VKD3DSIH_DEFAULT ] = "default", ++ [VKD3DSIH_DEFB ] = "defb", ++ [VKD3DSIH_DEFI ] = "defi", ++ [VKD3DSIH_DEQO ] = "deq", ++ [VKD3DSIH_DFMA ] = "dfma", ++ [VKD3DSIH_DGEO ] = "dge", ++ [VKD3DSIH_DISCARD ] = "discard", ++ [VKD3DSIH_DIV ] = "div", ++ [VKD3DSIH_DLT ] = "dlt", ++ [VKD3DSIH_DMAX ] = "dmax", ++ [VKD3DSIH_DMIN ] = "dmin", ++ [VKD3DSIH_DMOV ] = "dmov", ++ [VKD3DSIH_DMOVC ] = "dmovc", ++ [VKD3DSIH_DMUL ] = "dmul", ++ [VKD3DSIH_DNE ] = "dne", ++ [VKD3DSIH_DP2 ] = "dp2", ++ [VKD3DSIH_DP2ADD ] = "dp2add", ++ [VKD3DSIH_DP3 ] = "dp3", ++ [VKD3DSIH_DP4 ] = "dp4", ++ [VKD3DSIH_DRCP ] = "drcp", ++ [VKD3DSIH_DST ] = "dst", ++ [VKD3DSIH_DSX ] = "dsx", ++ [VKD3DSIH_DSX_COARSE ] = "deriv_rtx_coarse", ++ [VKD3DSIH_DSX_FINE ] = "deriv_rtx_fine", ++ [VKD3DSIH_DSY ] = "dsy", ++ [VKD3DSIH_DSY_COARSE ] = "deriv_rty_coarse", ++ [VKD3DSIH_DSY_FINE ] = "deriv_rty_fine", ++ [VKD3DSIH_DTOF ] = "dtof", ++ [VKD3DSIH_DTOI ] = "dtoi", ++ [VKD3DSIH_DTOU ] = "dtou", ++ [VKD3DSIH_ELSE ] = "else", ++ [VKD3DSIH_EMIT ] = "emit", ++ [VKD3DSIH_EMIT_STREAM ] = "emit_stream", ++ [VKD3DSIH_ENDIF ] = "endif", ++ [VKD3DSIH_ENDLOOP ] = "endloop", ++ [VKD3DSIH_ENDREP ] = "endrep", ++ [VKD3DSIH_ENDSWITCH ] = "endswitch", ++ [VKD3DSIH_EQO ] = "eq", ++ [VKD3DSIH_EQU ] = "eq_unord", ++ [VKD3DSIH_EVAL_CENTROID ] = "eval_centroid", ++ [VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index", ++ [VKD3DSIH_EXP ] = "exp", ++ [VKD3DSIH_EXPP ] = "expp", ++ [VKD3DSIH_F16TOF32 ] = "f16tof32", ++ [VKD3DSIH_F32TOF16 ] = "f32tof16", ++ [VKD3DSIH_FCALL ] = "fcall", ++ [VKD3DSIH_FIRSTBIT_HI ] = "firstbit_hi", ++ [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo", ++ [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi", ++ [VKD3DSIH_FRC ] = "frc", ++ [VKD3DSIH_FREM ] = "frem", ++ [VKD3DSIH_FTOD ] = "ftod", ++ [VKD3DSIH_FTOI ] = "ftoi", ++ [VKD3DSIH_FTOU ] = "ftou", ++ [VKD3DSIH_GATHER4 ] = "gather4", ++ [VKD3DSIH_GATHER4_C ] = "gather4_c", ++ [VKD3DSIH_GATHER4_C_S ] = "gather4_c_s", ++ [VKD3DSIH_GATHER4_PO ] = "gather4_po", ++ [VKD3DSIH_GATHER4_PO_C ] = "gather4_po_c", ++ [VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s", ++ [VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s", ++ [VKD3DSIH_GATHER4_S ] = "gather4_s", ++ [VKD3DSIH_GEO ] = "ge", ++ [VKD3DSIH_GEU ] = "ge_unord", ++ [VKD3DSIH_HCOS ] = "hcos", ++ [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", ++ [VKD3DSIH_HS_DECLS ] = "hs_decls", ++ [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", ++ [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", ++ [VKD3DSIH_HSIN ] = "hsin", ++ [VKD3DSIH_HTAN ] = "htan", ++ [VKD3DSIH_IADD ] = "iadd", ++ [VKD3DSIH_IBFE ] = "ibfe", ++ [VKD3DSIH_IDIV ] = "idiv", ++ [VKD3DSIH_IEQ ] = "ieq", ++ [VKD3DSIH_IF ] = "if", ++ [VKD3DSIH_IFC ] = "if", ++ [VKD3DSIH_IGE ] = "ige", ++ [VKD3DSIH_ILT ] = "ilt", ++ [VKD3DSIH_IMAD ] = "imad", ++ [VKD3DSIH_IMAX ] = "imax", ++ [VKD3DSIH_IMIN ] = "imin", ++ [VKD3DSIH_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc", ++ [VKD3DSIH_IMM_ATOMIC_AND ] = "imm_atomic_and", ++ [VKD3DSIH_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch", ++ [VKD3DSIH_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume", ++ [VKD3DSIH_IMM_ATOMIC_EXCH ] = "imm_atomic_exch", ++ [VKD3DSIH_IMM_ATOMIC_IADD ] = "imm_atomic_iadd", ++ [VKD3DSIH_IMM_ATOMIC_IMAX ] = "imm_atomic_imax", ++ [VKD3DSIH_IMM_ATOMIC_IMIN ] = "imm_atomic_imin", ++ [VKD3DSIH_IMM_ATOMIC_OR ] = "imm_atomic_or", ++ [VKD3DSIH_IMM_ATOMIC_UMAX ] = "imm_atomic_umax", ++ [VKD3DSIH_IMM_ATOMIC_UMIN ] = "imm_atomic_umin", ++ [VKD3DSIH_IMM_ATOMIC_XOR ] = "imm_atomic_xor", ++ [VKD3DSIH_IMUL ] = "imul", ++ [VKD3DSIH_INE ] = "ine", ++ [VKD3DSIH_INEG ] = "ineg", ++ [VKD3DSIH_ISFINITE ] = "isfinite", ++ [VKD3DSIH_ISHL ] = "ishl", ++ [VKD3DSIH_ISHR ] = "ishr", ++ [VKD3DSIH_ISINF ] = "isinf", ++ [VKD3DSIH_ISNAN ] = "isnan", ++ [VKD3DSIH_ITOD ] = "itod", ++ [VKD3DSIH_ITOF ] = "itof", ++ [VKD3DSIH_ITOI ] = "itoi", ++ [VKD3DSIH_LABEL ] = "label", ++ [VKD3DSIH_LD ] = "ld", ++ [VKD3DSIH_LD2DMS ] = "ld2dms", ++ [VKD3DSIH_LD2DMS_S ] = "ld2dms_s", ++ [VKD3DSIH_LD_RAW ] = "ld_raw", ++ [VKD3DSIH_LD_RAW_S ] = "ld_raw_s", ++ [VKD3DSIH_LD_S ] = "ld_s", ++ [VKD3DSIH_LD_STRUCTURED ] = "ld_structured", ++ [VKD3DSIH_LD_STRUCTURED_S ] = "ld_structured_s", ++ [VKD3DSIH_LD_UAV_TYPED ] = "ld_uav_typed", ++ [VKD3DSIH_LD_UAV_TYPED_S ] = "ld_uav_typed_s", ++ [VKD3DSIH_LIT ] = "lit", ++ [VKD3DSIH_LOD ] = "lod", ++ [VKD3DSIH_LOG ] = "log", ++ [VKD3DSIH_LOGP ] = "logp", ++ [VKD3DSIH_LOOP ] = "loop", ++ [VKD3DSIH_LRP ] = "lrp", ++ [VKD3DSIH_LTO ] = "lt", ++ [VKD3DSIH_LTU ] = "lt_unord", ++ [VKD3DSIH_M3x2 ] = "m3x2", ++ [VKD3DSIH_M3x3 ] = "m3x3", ++ [VKD3DSIH_M3x4 ] = "m3x4", ++ [VKD3DSIH_M4x3 ] = "m4x3", ++ [VKD3DSIH_M4x4 ] = "m4x4", ++ [VKD3DSIH_MAD ] = "mad", ++ [VKD3DSIH_MAX ] = "max", ++ [VKD3DSIH_MIN ] = "min", ++ [VKD3DSIH_MOV ] = "mov", ++ [VKD3DSIH_MOVA ] = "mova", ++ [VKD3DSIH_MOVC ] = "movc", ++ [VKD3DSIH_MSAD ] = "msad", ++ [VKD3DSIH_MUL ] = "mul", ++ [VKD3DSIH_NEO ] = "ne_ord", ++ [VKD3DSIH_NEU ] = "ne", ++ [VKD3DSIH_NOP ] = "nop", ++ [VKD3DSIH_NOT ] = "not", ++ [VKD3DSIH_NRM ] = "nrm", ++ [VKD3DSIH_OR ] = "or", ++ [VKD3DSIH_ORD ] = "ord", ++ [VKD3DSIH_PHASE ] = "phase", ++ [VKD3DSIH_PHI ] = "phi", ++ [VKD3DSIH_POW ] = "pow", ++ [VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d", ++ [VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x", ++ [VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", ++ [VKD3DSIH_QUAD_READ_LANE_AT ] = "quad_read_lane_at", ++ [VKD3DSIH_RCP ] = "rcp", ++ [VKD3DSIH_REP ] = "rep", ++ [VKD3DSIH_RESINFO ] = "resinfo", ++ [VKD3DSIH_RET ] = "ret", ++ [VKD3DSIH_RETP ] = "retp", ++ [VKD3DSIH_ROUND_NE ] = "round_ne", ++ [VKD3DSIH_ROUND_NI ] = "round_ni", ++ [VKD3DSIH_ROUND_PI ] = "round_pi", ++ [VKD3DSIH_ROUND_Z ] = "round_z", ++ [VKD3DSIH_RSQ ] = "rsq", ++ [VKD3DSIH_SAMPLE ] = "sample", ++ [VKD3DSIH_SAMPLE_B ] = "sample_b", ++ [VKD3DSIH_SAMPLE_B_CL_S ] = "sample_b_cl_s", ++ [VKD3DSIH_SAMPLE_C ] = "sample_c", ++ [VKD3DSIH_SAMPLE_C_CL_S ] = "sample_c_cl_s", ++ [VKD3DSIH_SAMPLE_C_LZ ] = "sample_c_lz", ++ [VKD3DSIH_SAMPLE_C_LZ_S ] = "sample_c_lz_s", ++ [VKD3DSIH_SAMPLE_CL_S ] = "sample_cl_s", ++ [VKD3DSIH_SAMPLE_GRAD ] = "sample_d", ++ [VKD3DSIH_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s", ++ [VKD3DSIH_SAMPLE_INFO ] = "sample_info", ++ [VKD3DSIH_SAMPLE_LOD ] = "sample_l", ++ [VKD3DSIH_SAMPLE_LOD_S ] = "sample_l_s", ++ [VKD3DSIH_SAMPLE_POS ] = "sample_pos", ++ [VKD3DSIH_SETP ] = "setp", ++ [VKD3DSIH_SGE ] = "sge", ++ [VKD3DSIH_SGN ] = "sgn", ++ [VKD3DSIH_SINCOS ] = "sincos", ++ [VKD3DSIH_SLT ] = "slt", ++ [VKD3DSIH_SQRT ] = "sqrt", ++ [VKD3DSIH_STORE_RAW ] = "store_raw", ++ [VKD3DSIH_STORE_STRUCTURED ] = "store_structured", ++ [VKD3DSIH_STORE_UAV_TYPED ] = "store_uav_typed", ++ [VKD3DSIH_SUB ] = "sub", ++ [VKD3DSIH_SWAPC ] = "swapc", ++ [VKD3DSIH_SWITCH ] = "switch", ++ [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch", ++ [VKD3DSIH_SYNC ] = "sync", ++ [VKD3DSIH_TAN ] = "tan", ++ [VKD3DSIH_TEX ] = "tex", ++ [VKD3DSIH_TEXBEM ] = "texbem", ++ [VKD3DSIH_TEXBEML ] = "texbeml", ++ [VKD3DSIH_TEXCOORD ] = "texcoord", ++ [VKD3DSIH_TEXCRD ] = "texcrd", ++ [VKD3DSIH_TEXDEPTH ] = "texdepth", ++ [VKD3DSIH_TEXDP3 ] = "texdp3", ++ [VKD3DSIH_TEXDP3TEX ] = "texdp3tex", ++ [VKD3DSIH_TEXKILL ] = "texkill", ++ [VKD3DSIH_TEXLD ] = "texld", ++ [VKD3DSIH_TEXLDD ] = "texldd", ++ [VKD3DSIH_TEXLDL ] = "texldl", ++ [VKD3DSIH_TEXM3x2DEPTH ] = "texm3x2depth", ++ [VKD3DSIH_TEXM3x2PAD ] = "texm3x2pad", ++ [VKD3DSIH_TEXM3x2TEX ] = "texm3x2tex", ++ [VKD3DSIH_TEXM3x3 ] = "texm3x3", ++ [VKD3DSIH_TEXM3x3DIFF ] = "texm3x3diff", ++ [VKD3DSIH_TEXM3x3PAD ] = "texm3x3pad", ++ [VKD3DSIH_TEXM3x3SPEC ] = "texm3x3spec", ++ [VKD3DSIH_TEXM3x3TEX ] = "texm3x3tex", ++ [VKD3DSIH_TEXM3x3VSPEC ] = "texm3x3vspec", ++ [VKD3DSIH_TEXREG2AR ] = "texreg2ar", ++ [VKD3DSIH_TEXREG2GB ] = "texreg2gb", ++ [VKD3DSIH_TEXREG2RGB ] = "texreg2rgb", ++ [VKD3DSIH_UBFE ] = "ubfe", ++ [VKD3DSIH_UDIV ] = "udiv", ++ [VKD3DSIH_UGE ] = "uge", ++ [VKD3DSIH_ULT ] = "ult", ++ [VKD3DSIH_UMAX ] = "umax", ++ [VKD3DSIH_UMIN ] = "umin", ++ [VKD3DSIH_UMUL ] = "umul", ++ [VKD3DSIH_UNO ] = "uno", ++ [VKD3DSIH_USHR ] = "ushr", ++ [VKD3DSIH_UTOD ] = "utod", ++ [VKD3DSIH_UTOF ] = "utof", ++ [VKD3DSIH_UTOU ] = "utou", ++ [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", ++ [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", ++ [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", ++ [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", ++ [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", ++ [VKD3DSIH_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count", ++ [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true", ++ [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true", ++ [VKD3DSIH_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane", ++ [VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add", ++ [VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax", ++ [VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin", ++ [VKD3DSIH_WAVE_OP_MAX ] = "wave_op_max", ++ [VKD3DSIH_WAVE_OP_MIN ] = "wave_op_min", ++ [VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul", ++ [VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax", ++ [VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin", ++ [VKD3DSIH_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count", ++ [VKD3DSIH_WAVE_READ_LANE_AT ] = "wave_read_lane_at", ++ [VKD3DSIH_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first", ++ [VKD3DSIH_XOR ] = "xor", ++ }; ++ ++ if ((uint32_t)op < ARRAY_SIZE(names)) ++ return names[op] ? names[op] : error; ++ ++ return error; ++} ++ + static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, + unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) + { +@@ -1078,8 +1416,8 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + case VKD3DSIH_TEXREG2GB: + case VKD3DSIH_TEXREG2RGB: + vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, +- "Aborting due to unimplemented feature: Combined sampler instruction %#x.", +- ins->opcode); ++ "Aborting due to unimplemented feature: Combined sampler instruction \"%s\" (%#x).", ++ vsir_opcode_get_name(ins->opcode, ""), ins->opcode); + return VKD3D_ERROR_NOT_IMPLEMENTED; + + default: +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index b3e251eff28..47ea6ce1f4b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/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); + } + +@@ -761,6 +778,50 @@ static void msl_else(struct msl_generator *gen) + msl_begin_block(gen); + } + ++static void msl_loop(struct msl_generator *gen) ++{ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "for (;;)\n"); ++ msl_begin_block(gen); ++} ++ ++static void msl_break(struct msl_generator *gen) ++{ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "break;\n"); ++} ++ ++static void msl_switch(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ struct msl_src src; ++ ++ msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); ++ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "switch (%s)\n", src.str->buffer); ++ msl_begin_block(gen); ++ ++ msl_src_cleanup(&src, &gen->string_buffers); ++} ++ ++static void msl_case(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ struct msl_src src; ++ ++ msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); ++ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "case %s:\n", src.str->buffer); ++ ++ msl_src_cleanup(&src, &gen->string_buffers); ++} ++ ++static void msl_default(struct msl_generator *gen) ++{ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "default:\n"); ++} ++ + static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + const struct msl_resource_type_info *resource_type_info; +@@ -908,6 +969,37 @@ static void msl_movc(struct msl_generator *gen, const struct vkd3d_shader_instru + msl_dst_cleanup(&dst, &gen->string_buffers); + } + ++static void msl_mul64(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ struct msl_src src[2]; ++ struct msl_dst dst; ++ uint32_t mask; ++ ++ if (ins->dst[0].reg.type != VKD3DSPR_NULL) ++ { ++ /* TODO: mulhi(). */ ++ mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); ++ msl_print_assignment(gen, &dst, ""); ++ msl_dst_cleanup(&dst, &gen->string_buffers); ++ ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled 64-bit integer multiplication."); ++ } ++ ++ if (ins->dst[1].reg.type != VKD3DSPR_NULL) ++ { ++ mask = msl_dst_init(&dst, gen, ins, &ins->dst[1]); ++ msl_src_init(&src[0], gen, &ins->src[0], mask); ++ msl_src_init(&src[1], gen, &ins->src[1], mask); ++ ++ msl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer); ++ ++ msl_src_cleanup(&src[1], &gen->string_buffers); ++ msl_src_cleanup(&src[0], &gen->string_buffers); ++ msl_dst_cleanup(&dst, &gen->string_buffers); ++ } ++} ++ + static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + msl_print_indent(gen->buffer, gen->indent); +@@ -935,11 +1027,23 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_AND: + msl_binop(gen, ins, "&"); + break; ++ case VKD3DSIH_BREAK: ++ msl_break(gen); ++ break; ++ case VKD3DSIH_CASE: ++ msl_case(gen, ins); ++ break; + case VKD3DSIH_DCL_INDEXABLE_TEMP: + msl_dcl_indexable_temp(gen, ins); + break; + case VKD3DSIH_NOP: + break; ++ case VKD3DSIH_DEFAULT: ++ msl_default(gen); ++ break; ++ case VKD3DSIH_DISCARD: ++ msl_discard(gen, ins); ++ break; + case VKD3DSIH_DIV: + msl_binop(gen, ins, "/"); + break; +@@ -956,6 +1060,8 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + msl_else(gen); + break; + case VKD3DSIH_ENDIF: ++ case VKD3DSIH_ENDLOOP: ++ case VKD3DSIH_ENDSWITCH: + msl_end_block(gen); + break; + case VKD3DSIH_EQO: +@@ -988,6 +1094,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_USHR: + msl_binop(gen, ins, ">>"); + break; ++ case VKD3DSIH_ILT: + case VKD3DSIH_LTO: + msl_relop(gen, ins, "<"); + break; +@@ -1000,6 +1107,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_MIN: + msl_intrinsic(gen, ins, "min"); + break; ++ case VKD3DSIH_IMUL: ++ msl_mul64(gen, ins); ++ break; + case VKD3DSIH_INE: + case VKD3DSIH_NEU: + msl_relop(gen, ins, "!="); +@@ -1014,6 +1124,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_LOG: + msl_intrinsic(gen, ins, "log2"); + break; ++ case VKD3DSIH_LOOP: ++ msl_loop(gen); ++ break; + case VKD3DSIH_MOV: + msl_mov(gen, ins); + break; +@@ -1050,6 +1163,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_SQRT: + msl_intrinsic(gen, ins, "sqrt"); + break; ++ case VKD3DSIH_SWITCH: ++ msl_switch(gen, ins); ++ break; + default: + msl_unhandled(gen, ins); + break; +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 5dd00f00fe8..a5d1b8f4e05 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -223,6 +223,7 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES = 8017, + VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES = 8018, + VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE = 8019, ++ VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT = 8020, + + VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, + VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, +@@ -611,6 +612,8 @@ enum vkd3d_shader_opcode + VKD3DSIH_COUNT, + }; + ++const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error); ++ + enum vkd3d_shader_register_type + { + VKD3DSPR_TEMP, +@@ -1336,12 +1339,6 @@ static inline bool register_is_constant_or_undef(const struct vkd3d_shader_regis + return register_is_constant(reg) || register_is_undef(reg); + } + +-static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg) +-{ +- return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR +- && (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_u64[0] : !reg->u.immconst_u32[0]); +-} +- + static inline bool register_is_numeric_array(const struct vkd3d_shader_register *reg) + { + return (reg->type == VKD3DSPR_IMMCONSTBUFFER || reg->type == VKD3DSPR_IDXTEMP +-- +2.47.2 +