diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch similarity index 66% rename from patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch rename to patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch index cc254a5b..48324079 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch @@ -1,37 +1,56 @@ -From f15f38b33653aef51f701503eeebb305fc966706 Mon Sep 17 00:00:00 2001 +From 900a91b2b7e2260fe4eefb78e1db3dffa2360d23 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 3163e589bc41b674c46750bef9a3cbbaa90fc560. +Subject: [PATCH] Updated vkd3d to 44fffee5e1331e1c7e10489d84723c3b9dad7e17. --- + dlls/msado15/tests/msado15.c | 2 +- libs/vkd3d/include/private/vkd3d_common.h | 3 +- + .../include/private/vkd3d_shader_utils.h | 4 - libs/vkd3d/include/private/vkd3d_version.h | 2 +- - libs/vkd3d/include/vkd3d_shader.h | 6 + + libs/vkd3d/include/vkd3d_shader.h | 7 + libs/vkd3d/libs/vkd3d-common/blob.c | 1 + - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 517 +-- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 407 +-- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 626 +-- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 459 +- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 10 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 1547 +++++---- - libs/vkd3d/libs/vkd3d-shader/fx.c | 1347 +++++--- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 207 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 25 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 11 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 41 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 867 +++-- - libs/vkd3d/libs/vkd3d-shader/ir.c | 2854 ++++++++++++++--- - libs/vkd3d/libs/vkd3d-shader/msl.c | 956 +++++- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 1752 ++++---- + libs/vkd3d/libs/vkd3d-shader/fx.c | 1381 ++++-- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 320 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 289 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 47 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 + + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 128 +- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1917 +++++--- + libs/vkd3d/libs/vkd3d-shader/ir.c | 4000 +++++++++++++---- + libs/vkd3d/libs/vkd3d-shader/msl.c | 1064 ++++- libs/vkd3d/libs/vkd3d-shader/preproc.h | 2 +- libs/vkd3d/libs/vkd3d-shader/preproc.l | 39 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 1179 +++---- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 865 ++--- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 194 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 700 ++-- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 1477 +++--- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 1045 +++-- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 462 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 964 ++-- .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 2 + + libs/vkd3d/libs/vkd3d/command.c | 21 +- + libs/vkd3d/libs/vkd3d/device.c | 7 +- libs/vkd3d/libs/vkd3d/resource.c | 73 +- - libs/vkd3d/libs/vkd3d/state.c | 12 + + libs/vkd3d/libs/vkd3d/state.c | 36 +- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 13 +- - 26 files changed, 7383 insertions(+), 4497 deletions(-) + 31 files changed, 10162 insertions(+), 5992 deletions(-) +diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c +index 03eaab92b39..3f4b55d2916 100644 +--- a/dlls/msado15/tests/msado15.c ++++ b/dlls/msado15/tests/msado15.c +@@ -2023,8 +2023,8 @@ START_TEST(msado15) + setup_database(); + + test_Connection(); +- test_Connection_Open(); + test_ConnectionPoint(); ++ test_Connection_Open(); + test_ADORecordsetConstruction(FALSE); + test_ADORecordsetConstruction(TRUE); + test_Fields(); diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h index beb23257fb7..0501e6a06c2 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h @@ -53,6 +72,21 @@ index beb23257fb7..0501e6a06c2 100644 return __builtin_popcount(v); #else v -= (v >> 1) & 0x55555555; +diff --git a/libs/vkd3d/include/private/vkd3d_shader_utils.h b/libs/vkd3d/include/private/vkd3d_shader_utils.h +index 00052a89988..465734dfbff 100644 +--- a/libs/vkd3d/include/private/vkd3d_shader_utils.h ++++ b/libs/vkd3d/include/private/vkd3d_shader_utils.h +@@ -21,10 +21,6 @@ + + #include "vkd3d_shader.h" + +-#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') +-#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R') +-#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X') +- + static inline enum vkd3d_result vkd3d_shader_parse_dxbc_source_type(const struct vkd3d_shader_code *dxbc, + enum vkd3d_shader_source_type *type, char **messages) + { diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h index 0edc4428022..687751d6a5f 100644 --- a/libs/vkd3d/include/private/vkd3d_version.h @@ -61,7 +95,7 @@ index 0edc4428022..687751d6a5f 100644 -#define VKD3D_VCS_ID " (Wine bundled)" +#define VKD3D_VCS_ID " (git a8ca1f95)" diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index 30b6a070018..b50271ce9bb 100644 +index 30b6a070018..0fd3c67b7e0 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -1431,6 +1431,11 @@ enum vkd3d_shader_source_type @@ -84,6 +118,14 @@ index 30b6a070018..b50271ce9bb 100644 * * Supported transformations can also be detected at runtime with the functions * vkd3d_shader_get_supported_source_types() and +@@ -2960,6 +2966,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver + * - VKD3D_SHADER_SOURCE_DXBC_DXIL + * - VKD3D_SHADER_SOURCE_DXBC_TPF + * - VKD3D_SHADER_SOURCE_D3D_BYTECODE ++ * - VKD3D_SHADER_SOURCE_HLSL + * + * \param compile_info A chained structure containing scan parameters. + * \n diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c index f60ef7db769..c2c6ad67804 100644 --- a/libs/vkd3d/libs/vkd3d-common/blob.c @@ -97,7 +139,7 @@ index f60ef7db769..c2c6ad67804 100644 #include "vkd3d.h" #include "vkd3d_blob.h" diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 4521bfabd8e..ae9278f68b1 100644 +index 4521bfabd8e..6425a8f62d2 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -27,333 +27,6 @@ @@ -434,7 +476,76 @@ index 4521bfabd8e..ae9278f68b1 100644 static const char * const shader_register_names[] = { [VKD3DSPR_ADDR ] = "a", -@@ -917,9 +590,10 @@ static void shader_print_double_literal(struct vkd3d_d3d_asm_compiler *compiler, +@@ -483,6 +156,8 @@ static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, + atomic_flags &= ~VKD3DARF_VOLATILE; + } + ++ atomic_flags &= ~VKD3DSI_PRECISE_XYZW; ++ + if (atomic_flags) + vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", atomic_flags); + } +@@ -510,6 +185,8 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint + sync_flags &= ~VKD3DSSF_THREAD_GROUP; + } + ++ sync_flags &= ~VKD3DSI_PRECISE_XYZW; ++ + if (sync_flags) + vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", sync_flags); + } +@@ -711,25 +388,25 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, + compiler->colours.error, type, compiler->colours.reset); + } + +-static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) ++static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_data_type type) + { + static const char *const data_type_names[] = + { +- [VKD3D_DATA_FLOAT ] = "float", +- [VKD3D_DATA_INT ] = "int", +- [VKD3D_DATA_UINT ] = "uint", +- [VKD3D_DATA_UNORM ] = "unorm", +- [VKD3D_DATA_SNORM ] = "snorm", +- [VKD3D_DATA_OPAQUE ] = "opaque", +- [VKD3D_DATA_MIXED ] = "mixed", +- [VKD3D_DATA_DOUBLE ] = "double", +- [VKD3D_DATA_CONTINUED] = "", +- [VKD3D_DATA_UNUSED ] = "", +- [VKD3D_DATA_UINT8 ] = "uint8", +- [VKD3D_DATA_UINT64 ] = "uint64", +- [VKD3D_DATA_BOOL ] = "bool", +- [VKD3D_DATA_UINT16 ] = "uint16", +- [VKD3D_DATA_HALF ] = "half", ++ [VSIR_DATA_BOOL ] = "bool", ++ [VSIR_DATA_F16 ] = "half", ++ [VSIR_DATA_F32 ] = "float", ++ [VSIR_DATA_F64 ] = "double", ++ [VSIR_DATA_I32 ] = "int", ++ [VSIR_DATA_U8 ] = "uint8", ++ [VSIR_DATA_U16 ] = "uint16", ++ [VSIR_DATA_U32 ] = "uint", ++ [VSIR_DATA_U64 ] = "uint64", ++ [VSIR_DATA_SNORM ] = "snorm", ++ [VSIR_DATA_UNORM ] = "unorm", ++ [VSIR_DATA_OPAQUE ] = "opaque", ++ [VSIR_DATA_MIXED ] = "mixed", ++ [VSIR_DATA_CONTINUED] = "", ++ [VSIR_DATA_UNUSED ] = "", + }; + + if (type < ARRAY_SIZE(data_type_names)) +@@ -739,7 +416,7 @@ static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum + compiler->colours.error, type, compiler->colours.reset); + } + +-static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type) ++static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vsir_data_type *type) + { + int i; + +@@ -917,9 +594,10 @@ static void shader_print_double_literal(struct vkd3d_d3d_asm_compiler *compiler, static void shader_print_int_literal(struct vkd3d_d3d_asm_compiler *compiler, const char *prefix, int i, const char *suffix) { @@ -447,7 +558,7 @@ index 4521bfabd8e..ae9278f68b1 100644 else vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%d%s%s", prefix, compiler->colours.literal, i, compiler->colours.reset, suffix); -@@ -1041,8 +715,8 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -1041,8 +719,8 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const switch (compiler->current->opcode) { @@ -458,7 +569,77 @@ index 4521bfabd8e..ae9278f68b1 100644 untyped = true; break; -@@ -1610,11 +1284,11 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile +@@ -1056,16 +734,16 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const + case VSIR_DIMENSION_SCALAR: + switch (reg->data_type) + { +- case VKD3D_DATA_FLOAT: ++ case VSIR_DATA_F32: + if (untyped) + shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], ""); + else + shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], ""); + break; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], ""); + break; +- case VKD3D_DATA_UINT: ++ case VSIR_DATA_U32: + shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], ""); + break; + default: +@@ -1078,7 +756,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const + case VSIR_DIMENSION_VEC4: + switch (reg->data_type) + { +- case VKD3D_DATA_FLOAT: ++ case VSIR_DATA_F32: + if (untyped) + { + shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], ""); +@@ -1094,13 +772,13 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const + shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], ""); + } + break; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], ""); + shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[1], ""); + shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[2], ""); + shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[3], ""); + break; +- case VKD3D_DATA_UINT: ++ case VSIR_DATA_U32: + shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], ""); + shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[1], ""); + shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[2], ""); +@@ -1126,13 +804,13 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const + /* A double2 vector is treated as a float4 vector in enum vsir_dimension. */ + if (reg->dimension == VSIR_DIMENSION_SCALAR || reg->dimension == VSIR_DIMENSION_VEC4) + { +- if (reg->data_type == VKD3D_DATA_DOUBLE) ++ if (reg->data_type == VSIR_DATA_F64) + { + shader_print_double_literal(compiler, "", reg->u.immconst_f64[0], ""); + if (reg->dimension == VSIR_DIMENSION_VEC4) + shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], ""); + } +- else if (reg->data_type == VKD3D_DATA_UINT64) ++ else if (reg->data_type == VSIR_DATA_U64) + { + shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[0], ""); + if (reg->dimension == VSIR_DIMENSION_VEC4) +@@ -1283,7 +961,7 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, + return; + } + +- if (reg->data_type == VKD3D_DATA_UNUSED) ++ if (reg->data_type == VSIR_DATA_UNUSED) + return; + + if (reg->dimension < ARRAY_SIZE(dimensions)) +@@ -1610,11 +1288,11 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile switch (ins->opcode) { @@ -475,7 +656,7 @@ index 4521bfabd8e..ae9278f68b1 100644 switch (ins->flags) { case VKD3D_SHADER_CONDITIONAL_OP_NZ: -@@ -1629,8 +1303,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile +@@ -1629,8 +1307,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break; @@ -486,25 +667,29 @@ index 4521bfabd8e..ae9278f68b1 100644 switch (ins->flags) { case VKD3D_SHADER_REL_OP_GT: -@@ -1657,7 +1331,7 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile +@@ -1657,8 +1335,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break; - case VKD3DSIH_RESINFO: +- switch (ins->flags) + case VSIR_OP_RESINFO: - switch (ins->flags) ++ switch (ins->flags & ~VKD3DSI_PRECISE_XYZW) { case VKD3DSI_NONE: -@@ -1674,7 +1348,7 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile + break; +@@ -1674,8 +1352,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break; - case VKD3DSIH_SAMPLE_INFO: +- switch (ins->flags) + case VSIR_OP_SAMPLE_INFO: - switch (ins->flags) ++ switch (ins->flags & ~VKD3DSI_PRECISE_XYZW) { case VKD3DSI_NONE: -@@ -1688,24 +1362,24 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile + break; +@@ -1688,24 +1366,24 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break; @@ -541,7 +726,7 @@ index 4521bfabd8e..ae9278f68b1 100644 if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0)) { if (ins->flags & VKD3DSI_TEXLD_PROJECT) -@@ -1715,20 +1389,20 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile +@@ -1715,25 +1393,25 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break; @@ -572,8 +757,15 @@ index 4521bfabd8e..ae9278f68b1 100644 + case VSIR_OP_USHR: if (ins->flags & VKD3DSI_SHIFT_UNMASKED) vkd3d_string_buffer_printf(buffer, "_unmasked"); - /* fall through */ -@@ -1747,7 +1421,7 @@ static void shader_dump_register_space(struct vkd3d_d3d_asm_compiler *compiler, +- /* fall through */ ++ break; ++ + default: +- shader_dump_precise_flags(compiler, ins->flags); + break; + } + } +@@ -1747,7 +1425,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, @@ -582,7 +774,7 @@ index 4521bfabd8e..ae9278f68b1 100644 } static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler, -@@ -1799,8 +1473,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1799,8 +1477,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, switch (ins->opcode) { @@ -593,7 +785,7 @@ index 4521bfabd8e..ae9278f68b1 100644 vkd3d_string_buffer_printf(buffer, "%s", compiler->colours.opcode); shader_print_dcl_usage(compiler, "_", &ins->declaration.semantic, ins->flags, ""); shader_dump_ins_modifiers(compiler, &ins->declaration.semantic.resource.reg); -@@ -1809,7 +1483,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1809,7 +1487,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_dump_register_space(compiler, ins->declaration.semantic.resource.range.space); break; @@ -602,7 +794,7 @@ index 4521bfabd8e..ae9278f68b1 100644 shader_print_register(compiler, " ", &ins->declaration.cb.src.reg, true, ""); if (vkd3d_shader_ver_ge(&compiler->shader_version, 6, 0)) shader_print_subscript(compiler, ins->declaration.cb.size, NULL); -@@ -1820,33 +1494,33 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1820,33 +1498,33 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_dump_register_space(compiler, ins->declaration.cb.range.space); break; @@ -643,7 +835,7 @@ index 4521bfabd8e..ae9278f68b1 100644 vkd3d_string_buffer_printf(buffer, " %sx%u%s", compiler->colours.reg, ins->declaration.indexable_temp.register_idx, compiler->colours.reset); shader_print_subscript(compiler, ins->declaration.indexable_temp.register_size, NULL); -@@ -1857,112 +1531,113 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1857,112 +1535,113 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_dump_icb(compiler, ins->declaration.indexable_temp.initialiser); break; @@ -787,7 +979,7 @@ index 4521bfabd8e..ae9278f68b1 100644 vkd3d_string_buffer_printf(buffer, " %sc%u%s", compiler->colours.reg, ins->dst[0].reg.idx[0].offset, compiler->colours.reset); shader_print_float_literal(compiler, " = ", ins->src[0].reg.u.immconst_f32[0], ""); -@@ -1971,7 +1646,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1971,7 +1650,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[3], ""); break; @@ -796,7 +988,7 @@ index 4521bfabd8e..ae9278f68b1 100644 vkd3d_string_buffer_printf(buffer, " %si%u%s", compiler->colours.reg, ins->dst[0].reg.idx[0].offset, compiler->colours.reset); shader_print_int_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], ""); -@@ -1980,7 +1655,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1980,7 +1659,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[3], ""); break; @@ -805,8 +997,86 @@ index 4521bfabd8e..ae9278f68b1 100644 vkd3d_string_buffer_printf(buffer, " %sb%u%s", compiler->colours.reg, ins->dst[0].reg.idx[0].offset, compiler->colours.reset); shader_print_bool_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], ""); -@@ -2373,19 +2048,19 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, +@@ -1989,9 +1668,14 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, + default: + shader_dump_instruction_flags(compiler, ins); ++ if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE) ++ vkd3d_string_buffer_printf(buffer, "_indexable"); ++ ++ shader_dump_precise_flags(compiler, ins->flags); ++ + if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE) + { +- vkd3d_string_buffer_printf(buffer, "_indexable("); ++ vkd3d_string_buffer_printf(buffer, "("); + if (ins->raw) + vkd3d_string_buffer_printf(buffer, "raw_"); + if (ins->structured) +@@ -2009,10 +1693,10 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, + shader_print_int_literal(compiler, ",", ins->texel_offset.w, ")"); + } + +- if (ins->resource_data_type[0] != VKD3D_DATA_FLOAT +- || ins->resource_data_type[1] != VKD3D_DATA_FLOAT +- || ins->resource_data_type[2] != VKD3D_DATA_FLOAT +- || ins->resource_data_type[3] != VKD3D_DATA_FLOAT) ++ if (ins->resource_data_type[0] != VSIR_DATA_F32 ++ || ins->resource_data_type[1] != VSIR_DATA_F32 ++ || ins->resource_data_type[2] != VSIR_DATA_F32 ++ || ins->resource_data_type[3] != VSIR_DATA_F32) + shader_dump_resource_data_type(compiler, ins->resource_data_type); + + for (i = 0; i < ins->dst_count; ++i) +@@ -2276,9 +1960,8 @@ static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler, + } + } + +-enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, +- const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_code *out, enum vsir_asm_flags flags) ++enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_code *out, enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context) + { + const struct vkd3d_shader_version *shader_version = &program->shader_version; + enum vkd3d_shader_compile_option_formatting_flags formatting; +@@ -2286,8 +1969,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, + { + .flags = flags, + }; ++ struct vkd3d_shader_instruction *ins; + enum vkd3d_result result = VKD3D_OK; + struct vkd3d_string_buffer *buffer; ++ struct vsir_program_iterator it; + unsigned int indent, i, j; + const char *indent_str; + +@@ -2344,6 +2029,14 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, + if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) + compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES; + ++ if (compiler.flags & VSIR_ASM_FLAG_ALLOCATE_TEMPS) ++ { ++ if ((result = vsir_allocate_temp_registers(program, message_context)) < 0) ++ return result; ++ if ((result = vsir_update_dcl_temps(program, message_context))) ++ return result; ++ } ++ + buffer = &compiler.buffer; + vkd3d_string_buffer_init(buffer); + +@@ -2367,25 +2060,25 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, + vkd3d_string_buffer_printf(buffer, "%s.text%s\n", compiler.colours.opcode, compiler.colours.reset); + + indent = 0; +- for (i = 0; i < program->instructions.count; ++i) +- { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + ++ it = vsir_program_iterator(&program->instructions); ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { switch (ins->opcode) { - case VKD3DSIH_ELSE: @@ -834,7 +1104,7 @@ index 4521bfabd8e..ae9278f68b1 100644 indent = 0; break; -@@ -2402,12 +2077,12 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, +@@ -2402,12 +2095,12 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, switch (ins->opcode) { @@ -853,8 +1123,37 @@ index 4521bfabd8e..ae9278f68b1 100644 ++indent; break; +@@ -2561,21 +2254,26 @@ static void trace_io_declarations(const struct vsir_program *program) + vkd3d_string_buffer_cleanup(&buffer); + } + +-void vsir_program_trace(const struct vsir_program *program) ++void vsir_program_trace(struct vsir_program *program) + { + const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES + | VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS; ++ struct vkd3d_shader_message_context message_context; + struct vkd3d_shader_code code; + const char *p, *q, *end; + ++ vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_NONE); ++ + trace_signature(&program->input_signature, "Input"); + trace_signature(&program->output_signature, "Output"); + trace_signature(&program->patch_constant_signature, "Patch-constant"); + trace_io_declarations(program); + +- if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK) ++ if (d3d_asm_compile(program, NULL, &code, flags, &message_context) != VKD3D_OK) + return; + ++ vkd3d_shader_message_context_cleanup(&message_context); ++ + end = (const char *)code.code + code.size; + for (p = code.code; p < end; p = q) + { diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 57d874efe37..eeb4deff61f 100644 +index 57d874efe37..751e5578276 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -259,159 +259,159 @@ struct vkd3d_shader_sm1_parser @@ -1165,6 +1464,15 @@ index 57d874efe37..eeb4deff61f 100644 return NULL; if (opcode == info->sm1_opcode +@@ -563,7 +563,7 @@ static void d3dbc_parse_register(struct vkd3d_shader_sm1_parser *d3dbc, + + reg_type = parse_register_type(d3dbc, param, &index_offset); + idx_count = idx_count_from_reg_type(reg_type); +- vsir_register_init(reg, reg_type, VKD3D_DATA_FLOAT, idx_count); ++ vsir_register_init(reg, reg_type, VSIR_DATA_F32, idx_count); + reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; + reg->non_uniform = false; + if (idx_count == 1) @@ -994,7 +994,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co /* DCL instructions do not have sources or destinations, but they * read two tokens to a semantic. See @@ -1183,6 +1491,30 @@ index 57d874efe37..eeb4deff61f 100644 { *ptr += 3; } +@@ -1088,10 +1088,10 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, + { + semantic->resource_type = resource_type_table[resource_type]; + } +- semantic->resource_data_type[0] = VKD3D_DATA_FLOAT; +- semantic->resource_data_type[1] = VKD3D_DATA_FLOAT; +- semantic->resource_data_type[2] = VKD3D_DATA_FLOAT; +- semantic->resource_data_type[3] = VKD3D_DATA_FLOAT; ++ semantic->resource_data_type[0] = VSIR_DATA_F32; ++ semantic->resource_data_type[1] = VSIR_DATA_F32; ++ semantic->resource_data_type[2] = VSIR_DATA_F32; ++ semantic->resource_data_type[3] = VSIR_DATA_F32; + shader_sm1_parse_dst_param(sm1, dst_token, NULL, &semantic->resource.reg); + range = &semantic->resource.range; + range->space = 0; +@@ -1101,7 +1101,7 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, + } + + static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, +- struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vkd3d_data_type data_type) ++ struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vsir_data_type data_type) + { + unsigned int count = dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; + @@ -1194,7 +1194,7 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1) static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins) @@ -1201,6 +1533,21 @@ index 57d874efe37..eeb4deff61f 100644 { vsir_src_count = 1; vsir_dst_count = 0; +@@ -1272,10 +1272,10 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + + ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; + ins->resource_stride = 0; +- ins->resource_data_type[0] = VKD3D_DATA_FLOAT; +- ins->resource_data_type[1] = VKD3D_DATA_FLOAT; +- ins->resource_data_type[2] = VKD3D_DATA_FLOAT; +- ins->resource_data_type[3] = VKD3D_DATA_FLOAT; ++ ins->resource_data_type[0] = VSIR_DATA_F32; ++ ins->resource_data_type[1] = VSIR_DATA_F32; ++ ins->resource_data_type[2] = VSIR_DATA_F32; ++ ins->resource_data_type[3] = VSIR_DATA_F32; + memset(&ins->texel_offset, 0, sizeof(ins->texel_offset)); + + p = *ptr; @@ -1288,29 +1288,29 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str goto fail; } @@ -1214,21 +1561,24 @@ index 57d874efe37..eeb4deff61f 100644 + else if (ins->opcode == VSIR_OP_DEF) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_FLOAT); +- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_FLOAT); ++ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VSIR_DATA_F32); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } - else if (ins->opcode == VKD3DSIH_DEFB) + else if (ins->opcode == VSIR_OP_DEFB) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VKD3D_DATA_UINT); +- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VKD3D_DATA_UINT); ++ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VSIR_DATA_U32); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } - else if (ins->opcode == VKD3DSIH_DEFI) + else if (ins->opcode == VSIR_OP_DEFI) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT); +- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT); ++ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VSIR_DATA_I32); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } - else if (ins->opcode == VKD3DSIH_TEXKILL) @@ -1245,8 +1595,30 @@ index 57d874efe37..eeb4deff61f 100644 *ptr = sm1->end; } -@@ -1497,7 +1497,7 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c - ins = &instructions->elements[instructions->count]; +@@ -1472,7 +1472,6 @@ static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1, + int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, + struct vkd3d_shader_message_context *message_context, struct vsir_program *program) + { +- struct vkd3d_shader_instruction_array *instructions; + struct vkd3d_shader_sm1_parser sm1 = {0}; + struct vkd3d_shader_instruction *ins; + unsigned int i; +@@ -1484,26 +1483,22 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c + return ret; + } + +- instructions = &program->instructions; + while (!shader_sm1_is_end(&sm1)) + { +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) ++ if (!(ins = vsir_program_append(program))) + { +- ERR("Failed to allocate instructions.\n"); + vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); + vsir_program_cleanup(program); + return VKD3D_ERROR_OUT_OF_MEMORY; + } +- ins = &instructions->elements[instructions->count]; shader_sm1_read_instruction(&sm1, ins); - if (ins->opcode == VKD3DSIH_INVALID) @@ -1254,7 +1626,25 @@ index 57d874efe37..eeb4deff61f 100644 { WARN("Encountered unrecognized or invalid instruction.\n"); vsir_program_cleanup(program); -@@ -1662,7 +1662,7 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir( + return VKD3D_ERROR_INVALID_SHADER; + } +- ++instructions->count; + } + + for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) +@@ -1518,7 +1513,10 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c + return ret; + } + +- return VKD3D_OK; ++ if (program->normalisation_level >= VSIR_NORMALISED_SM4) ++ ret = vsir_program_lower_d3dbc(program, config_flags, compile_info, message_context); ++ ++ return ret; + } + + bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, +@@ -1662,7 +1660,7 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir( for (;;) { info = &d3dbc->opcode_table[i++]; @@ -1263,7 +1653,7 @@ index 57d874efe37..eeb4deff61f 100644 return NULL; if (vkd3d_opcode == info->vkd3d_opcode -@@ -1681,7 +1681,8 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ +@@ -1681,7 +1679,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, @@ -1273,13 +1663,13 @@ index 57d874efe37..eeb4deff61f 100644 d3dbc->failed = true; return NULL; } -@@ -1689,16 +1690,16 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ +@@ -1689,16 +1688,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.", ++ "Invalid destination parameter count %zu 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; @@ -1289,12 +1679,12 @@ index 57d874efe37..eeb4deff61f 100644 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.", ++ "Invalid source parameter count %zu 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; } -@@ -1772,7 +1773,7 @@ static bool is_inconsequential_instr(const struct vkd3d_shader_instruction *ins) +@@ -1772,7 +1771,7 @@ static bool is_inconsequential_instr(const struct vkd3d_shader_instruction *ins) const struct vkd3d_shader_src_param *src = &ins->src[0]; unsigned int i; @@ -1303,7 +1693,7 @@ index 57d874efe37..eeb4deff61f 100644 return false; if (dst->modifiers != VKD3DSPDM_NONE) return false; -@@ -1829,6 +1830,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v +@@ -1829,6 +1828,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v struct vkd3d_bytecode_buffer *buffer = &d3dbc->buffer; const struct vkd3d_shader_src_param *src; const struct vkd3d_sm1_opcode_info *info; @@ -1311,7 +1701,7 @@ index 57d874efe37..eeb4deff61f 100644 unsigned int i; uint32_t token; -@@ -1841,9 +1843,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v +@@ -1841,9 +1841,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v token = info->sm1_opcode; token |= VKD3D_SM1_INSTRUCTION_FLAGS_MASK & (ins->flags << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT); @@ -1322,7 +1712,7 @@ index 57d874efe37..eeb4deff61f 100644 for (i = 0; i < ins->dst_count; ++i) { -@@ -1863,6 +1863,14 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v +@@ -1863,6 +1861,14 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v if (src->reg.idx_count && src->reg.idx[0].rel_addr) write_sm1_src_register(buffer, src->reg.idx[0].rel_addr); } @@ -1337,7 +1727,7 @@ index 57d874efe37..eeb4deff61f 100644 }; static void d3dbc_write_texkill(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) -@@ -1982,55 +1990,55 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str +@@ -1982,55 +1988,56 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str switch (ins->opcode) { @@ -1399,6 +1789,7 @@ index 57d874efe37..eeb4deff61f 100644 + case VSIR_OP_SINCOS: + case VSIR_OP_SLT: + case VSIR_OP_TEXLD: ++ case VSIR_OP_TEXLDL: + case VSIR_OP_TEXLDD: d3dbc_write_instruction(d3dbc, ins); break; @@ -1424,7 +1815,7 @@ index 57d874efe37..eeb4deff61f 100644 d3dbc->failed = true; } d3dbc_write_instruction(d3dbc, ins); -@@ -2038,7 +2046,8 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str +@@ -2038,7 +2045,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, @@ -1434,7 +1825,7 @@ index 57d874efe37..eeb4deff61f 100644 d3dbc->failed = true; break; } -@@ -2067,6 +2076,13 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, +@@ -2067,6 +2075,13 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, VKD3D_ASSERT(ret); reg.reg.type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT; reg.reg.idx[0].offset = element->register_index; @@ -1448,17 +1839,38 @@ index 57d874efe37..eeb4deff61f 100644 } token = VKD3D_SM1_OP_DCL; -@@ -2128,6 +2144,9 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, +@@ -2112,11 +2127,13 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc) + + static void d3dbc_write_program_instructions(struct d3dbc_compiler *d3dbc) + { +- struct vsir_program *program = d3dbc->program; +- unsigned int i; ++ struct vsir_program_iterator it = vsir_program_iterator(&d3dbc->program->instructions); ++ struct vkd3d_shader_instruction *ins; + +- for (i = 0; i < program->instructions.count; ++i) +- d3dbc_write_vsir_instruction(d3dbc, &program->instructions.elements[i]); ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ d3dbc_write_vsir_instruction(d3dbc, ins); ++ } + } + + int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, +@@ -2128,6 +2145,12 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, struct vkd3d_bytecode_buffer *buffer = &d3dbc.buffer; int result; + if ((result = vsir_allocate_temp_registers(program, message_context))) + return result; ++ ++ if ((result = vsir_update_dcl_temps(program, message_context))) ++ return result; + d3dbc.program = program; d3dbc.message_context = message_context; switch (version->type) -@@ -2147,7 +2166,7 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, +@@ -2147,7 +2170,7 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, } put_u32(buffer, sm1_version(version->type, version->major, version->minor)); @@ -1517,7 +1929,7 @@ index 9e3a57132a1..45a45c3ad4a 100644 } flags = read_u64(&ptr); diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index ca79939a39b..db74a7bfbcc 100644 +index ca79939a39b..c448e000cf9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -643,16 +643,22 @@ struct sm6_type @@ -1597,6 +2009,18 @@ index ca79939a39b..db74a7bfbcc 100644 struct incoming_value *incoming; size_t incoming_capacity; size_t incoming_count; +@@ -867,9 +882,9 @@ struct sm6_descriptor_info + struct vkd3d_shader_register_range range; + enum vkd3d_shader_resource_type resource_type; + enum dxil_resource_kind kind; +- enum vkd3d_data_type resource_data_type; ++ enum vsir_data_type resource_data_type; + enum vkd3d_shader_register_type reg_type; +- enum vkd3d_data_type reg_data_type; ++ enum vsir_data_type reg_data_type; + }; + + struct sm6_parser @@ -2010,11 +2025,6 @@ static inline bool sm6_type_is_handle(const struct sm6_type *type) return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Handle"); } @@ -1816,8 +2240,68 @@ index ca79939a39b..db74a7bfbcc 100644 } static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) -@@ -2433,33 +2514,123 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type - return VKD3D_DATA_UINT; +@@ -2386,31 +2467,31 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ + } + + static void register_init_with_id(struct vkd3d_shader_register *reg, +- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id) ++ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int id) + { + vsir_register_init(reg, reg_type, data_type, 1); + reg->idx[0].offset = id; + } + +-static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type *type) ++static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) + { + if (type->class == TYPE_CLASS_INTEGER) + { + switch (type->u.width) + { + case 1: +- return VKD3D_DATA_BOOL; ++ return VSIR_DATA_BOOL; + case 8: +- return VKD3D_DATA_UINT8; ++ return VSIR_DATA_U8; + case 16: +- return VKD3D_DATA_UINT16; ++ return VSIR_DATA_U16; + case 32: +- return VKD3D_DATA_UINT; ++ return VSIR_DATA_U32; + case 64: +- return VKD3D_DATA_UINT64; ++ return VSIR_DATA_U64; + default: + FIXME("Unhandled width %u.\n", type->u.width); +- return VKD3D_DATA_UINT; ++ return VSIR_DATA_U32; + } + } + else if (type->class == TYPE_CLASS_FLOAT) +@@ -2418,48 +2499,138 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type + switch (type->u.width) + { + case 16: +- return VKD3D_DATA_HALF; ++ return VSIR_DATA_F16; + case 32: +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + case 64: +- return VKD3D_DATA_DOUBLE; ++ return VSIR_DATA_F64; + default: + FIXME("Unhandled width %u.\n", type->u.width); +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + } + } + + FIXME("Unhandled type %u.\n", type->class); +- return VKD3D_DATA_UINT; ++ return VSIR_DATA_U32; } -static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value) @@ -1852,7 +2336,9 @@ index ca79939a39b..db74a7bfbcc 100644 + } + } + else if (e == 31u) -+ { + { +- case VALUE_TYPE_REG: +- *reg = value->reg; + /* Positive or negative infinity for zero 'm'. + * Nan for non-zero 'm' -- preserve sign and significand bits */ + return s | 0x7f800000u | (m << 13); @@ -1871,11 +2357,9 @@ index ca79939a39b..db74a7bfbcc 100644 + unsigned int i; + + switch (reg->data_type) - { -- case VALUE_TYPE_REG: -- *reg = value->reg; -+ case VKD3D_DATA_HALF: -+ reg->data_type = VKD3D_DATA_FLOAT; ++ { ++ case VSIR_DATA_F16: ++ reg->data_type = VSIR_DATA_F32; + reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16; + if (reg->type == VKD3DSPR_IMMCONST) + { @@ -1884,32 +2368,32 @@ index ca79939a39b..db74a7bfbcc 100644 + } + break; + -+ case VKD3D_DATA_UINT16: -+ reg->data_type = VKD3D_DATA_UINT; ++ case VSIR_DATA_U16: ++ reg->data_type = VSIR_DATA_U32; + reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16; + if (reg->type == VKD3DSPR_IMMCONST) + { + for (i = 0; i < VSIR_DIMENSION_VEC4; ++i) + reg->u.immconst_u32[i] = (int16_t)reg->u.immconst_u32[i]; + } - break; - -+ default: + break; ++ ++ default: + break; + } +} + +static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, + struct sm6_parser *sm6); -+ + +static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value, + struct sm6_parser *sm6) +{ + const struct sm6_type *scalar_type; -+ enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + + scalar_type = sm6_type_get_scalar_type(value->type, 0); -+ data_type = vkd3d_data_type_from_sm6_type(scalar_type); ++ data_type = vsir_data_type_from_dxil(scalar_type); + + switch (value->value_type) + { @@ -1970,7 +2454,7 @@ index ca79939a39b..db74a7bfbcc 100644 TRACE("Using forward-allocated id %u.\n", id); } else -@@ -2490,7 +2664,6 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value * +@@ -2490,12 +2664,11 @@ 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; @@ -1978,6 +2462,12 @@ index ca79939a39b..db74a7bfbcc 100644 } static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value) + { +- vsir_register_init(reg, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); ++ vsir_register_init(reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); + reg->u.immconst_u32[0] = value; + } + @@ -2547,10 +2720,11 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned param->modifiers = VKD3DSPSM_NONE; } @@ -2044,7 +2534,7 @@ index ca79939a39b..db74a7bfbcc 100644 return false; - vsir_dst_param_init(param, VKD3DSPR_TEMP, vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(dst->type, 0)), 1); -+ vsir_dst_param_init(param, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_dst_param_init(param, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); param->write_mask = VKD3DSP_WRITEMASK_ALL; param->reg.idx[0].offset = 0; param->reg.dimension = VSIR_DIMENSION_VEC4; @@ -2115,6 +2605,15 @@ index ca79939a39b..db74a7bfbcc 100644 elem_type = type->u.array.elem_type; /* Multidimensional arrays are emitted in flattened form. */ +@@ -3106,7 +3237,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co + dst->u.data = icb; + + icb->register_idx = sm6->icb_count++; +- icb->data_type = vkd3d_data_type_from_sm6_type(elem_type); ++ icb->data_type = vsir_data_type_from_dxil(elem_type); + icb->element_count = type->u.array.count; + icb->component_count = 1; + icb->is_null = !operands; @@ -3115,28 +3246,70 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co return VKD3D_OK; @@ -2130,26 +2629,26 @@ index ca79939a39b..db74a7bfbcc 100644 - { - for (i = 0; i < count; ++i) - icb->data[i] = operands[i]; -+ case VKD3D_DATA_HALF: ++ case VSIR_DATA_F16: + for (i = 0; i < count; ++i) + icb->data[i] = half_to_float(operands[i]); -+ icb->data_type = VKD3D_DATA_FLOAT; ++ icb->data_type = VSIR_DATA_F32; + break; + -+ case VKD3D_DATA_UINT16: ++ case VSIR_DATA_U16: + for (i = 0; i < count; ++i) + icb->data[i] = (int16_t)operands[i]; -+ icb->data_type = VKD3D_DATA_UINT; ++ icb->data_type = VSIR_DATA_U32; + break; + -+ case VKD3D_DATA_FLOAT: -+ case VKD3D_DATA_UINT: ++ case VSIR_DATA_F32: ++ case VSIR_DATA_U32: + for (i = 0; i < count; ++i) + icb->data[i] = operands[i]; + break; + -+ case VKD3D_DATA_DOUBLE: -+ case VKD3D_DATA_UINT64: ++ case VSIR_DATA_F64: ++ case VSIR_DATA_U64: + data64 = (uint64_t *)icb->data; + for (i = 0; i < count; ++i) + data64[i] = operands[i]; @@ -2468,8 +2967,12 @@ index ca79939a39b..db74a7bfbcc 100644 /* The icb value index will be resolved later so forward references can be handled. */ ins->declaration.icb = (void *)(intptr_t)init; dst->value_type = VALUE_TYPE_ICB; -@@ -3523,9 +3693,9 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru - enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); +@@ -3520,12 +3690,12 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru + unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst) + { +- enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); ++ enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type); if (ins) - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_INDEXABLE_TEMP); @@ -2538,10 +3041,22 @@ index ca79939a39b..db74a7bfbcc 100644 dst->is_back_ref = true; if (is_constant && !init) -@@ -3859,21 +4031,21 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) - for (i = 0; i < sm6->p.program->instructions.count; ++i) +@@ -3797,6 +3969,7 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm + + static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&sm6->p.program->instructions); + size_t i, count, base_value_idx = sm6->value_count; + const struct dxil_block *block = &sm6->root_block; + struct vkd3d_shader_instruction *ins; +@@ -3856,24 +4029,23 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + } + + /* Resolve initialiser forward references. */ +- for (i = 0; i < sm6->p.program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - ins = &sm6->p.program->instructions.elements[i]; +- ins = &sm6->p.program->instructions.elements[i]; - if (ins->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser) + if (ins->opcode == VSIR_OP_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser) { @@ -2564,7 +3079,7 @@ index ca79939a39b..db74a7bfbcc 100644 { ins->declaration.tgsm_structured.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6); ins->flags = 0; -@@ -3891,7 +4063,6 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) +@@ -3891,14 +4063,13 @@ 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; @@ -2572,7 +3087,23 @@ index ca79939a39b..db74a7bfbcc 100644 } return VKD3D_OK; -@@ -3912,12 +4083,12 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, + } + +-static void dst_param_io_init(struct vkd3d_shader_dst_param *param, +- const struct signature_element *e, enum vkd3d_shader_register_type reg_type) ++static void dst_param_io_init(struct vkd3d_shader_dst_param *param, const struct signature_element *e, ++ enum vkd3d_shader_register_type reg_type, enum vsir_dimension dimension) + { + enum vkd3d_shader_component_type component_type; + +@@ -3907,36 +4078,44 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, + param->shift = 0; + /* DXIL types do not have signedness. Load signed elements as unsigned. */ + component_type = e->component_type == VKD3D_SHADER_COMPONENT_INT ? VKD3D_SHADER_COMPONENT_UINT : e->component_type; +- vsir_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(component_type), 0); +- param->reg.dimension = VSIR_DIMENSION_VEC4; ++ vsir_register_init(¶m->reg, reg_type, vsir_data_type_from_component_type(component_type), 0); ++ param->reg.dimension = dimension; } static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params, @@ -2587,7 +3118,60 @@ index ca79939a39b..db74a7bfbcc 100644 } static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( -@@ -4163,7 +4334,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec +- enum vkd3d_shader_sysval_semantic sysval_semantic, bool is_input) ++ enum vkd3d_shader_sysval_semantic sysval_semantic, bool is_input, enum vsir_dimension *dimension) + { ++ *dimension = VSIR_DIMENSION_VEC4; ++ + switch (sysval_semantic) + { ++ case VKD3D_SHADER_SV_PRIMITIVE_ID: ++ return VKD3DSPR_PRIMID; + /* VSIR does not use an I/O register for SV_SampleIndex, but its + * signature element has a register index of UINT_MAX and it is + * convenient to return a valid register type here to handle it. */ + case VKD3D_SHADER_SV_SAMPLE_INDEX: + return VKD3DSPR_NULL; + case VKD3D_SHADER_SV_COVERAGE: ++ *dimension = is_input ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; + return is_input ? VKD3DSPR_COVERAGE : VKD3DSPR_SAMPLEMASK; + case VKD3D_SHADER_SV_DEPTH: ++ *dimension = VSIR_DIMENSION_SCALAR; + return VKD3DSPR_DEPTHOUT; + case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: ++ *dimension = VSIR_DIMENSION_SCALAR; + return VKD3DSPR_DEPTHOUTGE; + case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: ++ *dimension = VSIR_DIMENSION_SCALAR; + return VKD3DSPR_DEPTHOUTLE; + default: + return VKD3DSPR_INVALID; +@@ -3976,18 +4155,21 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade + + for (i = 0; i < s->element_count; ++i) + { ++ enum vsir_dimension dimension; ++ + e = &s->elements[i]; + + param = ¶ms[i]; + + if (e->register_index == UINT_MAX +- && (io_reg_type = register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input)) != VKD3DSPR_NULL) ++ && (io_reg_type = register_type_from_dxil_semantic_kind( ++ e->sysval_semantic, is_input, &dimension)) != VKD3DSPR_NULL) + { +- dst_param_io_init(param, e, io_reg_type); ++ dst_param_io_init(param, e, io_reg_type, dimension); + continue; + } + +- dst_param_io_init(param, e, reg_type); ++ dst_param_io_init(param, e, reg_type, VSIR_DIMENSION_VEC4); + count = 0; + + if (is_control_point) +@@ -4163,7 +4345,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. */ @@ -2596,7 +3180,7 @@ index ca79939a39b..db74a7bfbcc 100644 { FIXME("Allocation size is not 1.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -4186,26 +4357,26 @@ static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code) +@@ -4186,26 +4368,26 @@ static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code) switch (code) { case RMW_ADD: @@ -2633,7 +3217,7 @@ index ca79939a39b..db74a7bfbcc 100644 } } -@@ -4228,7 +4399,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ +@@ -4228,7 +4410,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ || !sm6_value_validate_is_backward_ref(ptr, sm6)) return; @@ -2642,7 +3226,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (reg.type != VKD3DSPR_GROUPSHAREDMEM) { -@@ -4246,7 +4417,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ +@@ -4246,7 +4428,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ if (!dxil_record_validate_operand_count(record, i + 4, i + 4, sm6)) return; @@ -2651,7 +3235,7 @@ index ca79939a39b..db74a7bfbcc 100644 { FIXME("Unhandled atomicrmw op %"PRIu64".\n", code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -4284,12 +4455,12 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ +@@ -4284,16 +4466,16 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ src_param_init_vector_from_reg(&src_params[0], &coord); else src_param_make_constant_uint(&src_params[0], 0); @@ -2666,7 +3250,12 @@ index ca79939a39b..db74a7bfbcc 100644 dst_param_init(&dst_params[0]); dst_params[1].reg = reg; -@@ -4314,7 +4485,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty +- dst_params[1].reg.data_type = VKD3D_DATA_UNUSED; ++ dst_params[1].reg.data_type = VSIR_DATA_UNUSED; + dst_params[1].reg.idx[1].rel_addr = NULL; + dst_params[1].reg.idx[1].offset = ~0u; + dst_params[1].reg.idx_count = 1; +@@ -4314,7 +4496,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty WARN("Argument type %u is not bool, int16/32/64 or floating point.\n", type_a->class); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "An argument to a binary operation is not bool, int16/32/64 or floating point."); @@ -2675,7 +3264,7 @@ index ca79939a39b..db74a7bfbcc 100644 } if (type_a != type_b) { -@@ -4329,55 +4500,58 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty +@@ -4329,55 +4511,58 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty case BINOP_ADD: case BINOP_SUB: /* NEG is applied later for subtraction. */ @@ -2746,7 +3335,7 @@ index ca79939a39b..db74a7bfbcc 100644 } if (!is_valid) -@@ -4411,7 +4585,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco +@@ -4411,7 +4596,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco return; code = record->operands[i++]; @@ -2755,7 +3344,7 @@ index ca79939a39b..db74a7bfbcc 100644 return; vsir_instruction_init(ins, &sm6->p.location, handler_idx); -@@ -4421,25 +4595,27 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco +@@ -4421,25 +4606,27 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco switch (handler_idx) { @@ -2794,7 +3383,7 @@ index ca79939a39b..db74a7bfbcc 100644 silence_warning = !(flags & ~PEB_EXACT); break; default: -@@ -4459,34 +4635,21 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco +@@ -4459,34 +4646,21 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; @@ -2808,7 +3397,8 @@ index ca79939a39b..db74a7bfbcc 100644 dst->type = a->type; - if (handler_idx == VKD3DSIH_UMUL || handler_idx == VKD3DSIH_UDIV || handler_idx == VKD3DSIH_IDIV) -- { ++ if (handler_idx == VSIR_OP_ISHL || handler_idx == VSIR_OP_ISHR || handler_idx == VSIR_OP_USHR) + { - struct vkd3d_shader_dst_param *dst_params = instruction_dst_params_alloc(ins, 2, sm6); - unsigned int index = code != BINOP_UDIV && code != BINOP_SDIV; - @@ -2819,8 +3409,7 @@ index ca79939a39b..db74a7bfbcc 100644 - vsir_dst_param_init_null(&dst_params[index ^ 1]); - } - else -+ if (handler_idx == VSIR_OP_ISHL || handler_idx == VSIR_OP_ISHR || handler_idx == VSIR_OP_USHR) - { +- { - if (handler_idx == VKD3DSIH_ISHL || handler_idx == VKD3DSIH_ISHR || handler_idx == VKD3DSIH_USHR) - { - /* DXC emits AND instructions where necessary to mask shift counts. Shift binops @@ -2837,7 +3426,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index, -@@ -4536,12 +4699,12 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record +@@ -4536,12 +4710,12 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record dxil_record_validate_operand_max_count(record, i, sm6); code_block->terminator.type = TERMINATOR_COND_BR; @@ -2852,7 +3441,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, -@@ -4579,7 +4742,7 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, +@@ -4579,7 +4753,7 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, for (i = 0; i < component_count; ++i, ++ins) { @@ -2861,7 +3450,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return false; -@@ -4607,7 +4770,7 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st +@@ -4607,7 +4781,7 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st unsigned int i; for (i = 0; i < component_count; ++i) @@ -2870,7 +3459,7 @@ index ca79939a39b..db74a7bfbcc 100644 return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); } -@@ -4623,11 +4786,11 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s +@@ -4623,11 +4797,11 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s { if (!z_operand && operands[component_count]->value_type == VALUE_TYPE_UNDEFINED) break; @@ -2884,7 +3473,7 @@ index ca79939a39b..db74a7bfbcc 100644 return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); } -@@ -4637,7 +4800,7 @@ static enum vkd3d_shader_opcode sm6_dx_map_void_op(enum dx_intrinsic_opcode op) +@@ -4637,7 +4811,7 @@ static enum vkd3d_shader_opcode sm6_dx_map_void_op(enum dx_intrinsic_opcode op) switch (op) { case DX_WAVE_IS_FIRST_LANE: @@ -2893,7 +3482,7 @@ index ca79939a39b..db74a7bfbcc 100644 default: vkd3d_unreachable(); } -@@ -4656,77 +4819,81 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) +@@ -4656,77 +4830,81 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) switch (op) { case DX_ISNAN: @@ -3011,7 +3600,7 @@ index ca79939a39b..db74a7bfbcc 100644 default: vkd3d_unreachable(); } -@@ -4741,7 +4908,7 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o +@@ -4741,7 +4919,7 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op)); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -3020,7 +3609,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -4751,21 +4918,21 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co +@@ -4751,21 +4929,21 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co switch (op) { case DX_FMAX: @@ -3050,7 +3639,7 @@ index ca79939a39b..db74a7bfbcc 100644 default: vkd3d_unreachable(); } -@@ -4780,42 +4947,42 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -4780,42 +4958,42 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type)); if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; @@ -3106,7 +3695,7 @@ index ca79939a39b..db74a7bfbcc 100644 } } -@@ -4838,8 +5005,8 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr +@@ -4838,8 +5016,8 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr return; if (is_cmp_xchg) @@ -3117,7 +3706,7 @@ index ca79939a39b..db74a7bfbcc 100644 return; coord_idx = 2 - is_cmp_xchg; -@@ -4852,7 +5019,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr +@@ -4852,7 +5030,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr } else { @@ -3126,7 +3715,7 @@ index ca79939a39b..db74a7bfbcc 100644 } for (i = coord_idx + coord_count; i < coord_idx + 3; ++i) -@@ -4873,14 +5040,14 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr +@@ -4873,14 +5051,14 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr return; src_param_init_vector_from_reg(&src_params[0], ®); if (is_cmp_xchg) @@ -3144,7 +3733,7 @@ index ca79939a39b..db74a7bfbcc 100644 dst_param_init(&dst_params[1]); sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); } -@@ -4891,8 +5058,8 @@ static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic +@@ -4891,8 +5069,8 @@ static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic struct vkd3d_shader_instruction *ins = state->ins; enum dxil_sync_flags flags; @@ -3155,7 +3744,7 @@ index ca79939a39b..db74a7bfbcc 100644 ins->flags = flags & (SYNC_THREAD_GROUP | SYNC_THREAD_GROUP_UAV); if (flags & SYNC_GLOBAL_UAV) ins->flags |= VKD3DSSF_GLOBAL_UAV; -@@ -4926,7 +5093,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu +@@ -4926,7 +5104,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; } @@ -3164,7 +3753,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (i != 1 && i != 255) { WARN("Unexpected update value %#x.\n", i); -@@ -4935,7 +5102,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu +@@ -4935,7 +5113,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu } inc = i; @@ -3173,7 +3762,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); -@@ -4963,10 +5130,10 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int +@@ -4963,10 +5141,10 @@ 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; @@ -3186,7 +3775,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; src_param_init_vector_from_reg(&src_params[0], &coord); -@@ -4990,7 +5157,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr +@@ -4990,7 +5168,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr if (!sm6_value_validate_is_handle(buffer, sm6)) return; @@ -3195,8 +3784,12 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; -@@ -5005,6 +5172,8 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr - src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type); +@@ -5002,15 +5180,17 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr + + type = sm6_type_get_scalar_type(dst->type, 0); + VKD3D_ASSERT(type); +- src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type); ++ src_param->reg.data_type = vsir_data_type_from_dxil(type); if (data_type_is_64_bit(src_param->reg.data_type)) src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); + else @@ -3204,7 +3797,21 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6); } -@@ -5030,11 +5199,11 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, + + static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, +- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int component_count) ++ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int component_count) + { + struct vkd3d_shader_dst_param *dst_param; + struct vkd3d_shader_instruction *ins; +@@ -5025,17 +5205,19 @@ static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_s + } + } + +-static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, +- struct vkd3d_shader_instruction *ins, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type) ++static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, ++ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, bool scalar) { struct vkd3d_shader_src_param *src_param; @@ -3216,9 +3823,21 @@ index ca79939a39b..db74a7bfbcc 100644 - sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, reg_type, data_type, 1); + sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, data_type, 1); vsir_register_init(&src_param->reg, reg_type, data_type, 0); ++ if (!scalar) ++ src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param_init(src_param); -@@ -5064,7 +5233,7 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa + instruction_dst_param_init_ssa_scalar(ins, sm6); +@@ -5044,7 +5226,7 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, + static void sm6_parser_emit_dx_coverage(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) + { +- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VKD3D_DATA_UINT); ++ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VSIR_DATA_U32, false); + } + + static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6, +@@ -5064,7 +5246,7 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa if (!sm6_value_is_constant(address)) return d; @@ -3227,7 +3846,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (register_index >= d->range.first && register_index <= d->range.last) return d; } -@@ -5081,8 +5250,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int +@@ -5081,8 +5263,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int struct sm6_value *dst; unsigned int id; @@ -3238,7 +3857,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2]))) { WARN("Failed to find resource type %#x, id %#x.\n", type, id); -@@ -5095,10 +5264,10 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int +@@ -5095,10 +5277,10 @@ 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]; @@ -3251,7 +3870,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5108,12 +5277,12 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -5108,12 +5290,12 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ struct vkd3d_shader_src_param *src_param; unsigned int i; @@ -3266,7 +3885,17 @@ index ca79939a39b..db74a7bfbcc 100644 if (i >= MAX_GS_OUTPUT_STREAMS) { WARN("Invalid stream index %u.\n", i); -@@ -5139,10 +5308,10 @@ static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic +@@ -5121,8 +5303,7 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ + "Output stream index %u is invalid.", i); + } + +- /* VKD3D_DATA_UNUSED would be more reasonable, but TPF uses data type 0 here. */ +- register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, 0, i); ++ register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, VSIR_DATA_UNUSED, i); + src_param_init(src_param); + + if (op == DX_EMIT_THEN_CUT_STREAM) +@@ -5139,10 +5320,10 @@ static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; @@ -3279,7 +3908,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5152,9 +5321,9 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i +@@ -5152,9 +5333,9 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i struct vkd3d_shader_src_param *src_param; unsigned int component_idx; @@ -3291,16 +3920,18 @@ index ca79939a39b..db74a7bfbcc 100644 { WARN("Invalid component index %u.\n", component_idx); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -5164,7 +5333,7 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i +@@ -5164,8 +5345,8 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 3); -+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 3); - vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 0); +- vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 0); ++ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, VKD3DSPR_TESSCOORD, VSIR_DATA_F32, 3); ++ vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VSIR_DATA_F32, 0); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param_init_scalar(src_param, component_idx); -@@ -5184,15 +5353,15 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc + +@@ -5184,15 +5365,15 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc switch (op) { case DX_DOT2: @@ -3319,7 +3950,7 @@ index ca79939a39b..db74a7bfbcc 100644 component_count = 4; break; default: -@@ -5223,8 +5392,8 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri +@@ -5223,8 +5404,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; @@ -3330,7 +3961,7 @@ index ca79939a39b..db74a7bfbcc 100644 signature = &sm6->p.program->input_signature; if (row_index >= signature->element_count) -@@ -5245,7 +5414,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri +@@ -5245,7 +5426,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri } vsir_instruction_init(ins, &sm6->p.location, (op == DX_EVAL_CENTROID) @@ -3339,7 +3970,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 1 + (op == DX_EVAL_SAMPLE_INDEX), sm6))) return; -@@ -5256,7 +5425,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri +@@ -5256,7 +5437,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri register_index_address_init(&src_params[0].reg.idx[0], operands[1], sm6); if (op == DX_EVAL_SAMPLE_INDEX) @@ -3348,7 +3979,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -5267,10 +5436,10 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op +@@ -5267,10 +5448,10 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; @@ -3361,26 +3992,29 @@ index ca79939a39b..db74a7bfbcc 100644 src_param->modifiers = VKD3DSPSM_ABS; instruction_dst_param_init_ssa_scalar(ins, sm6); -@@ -5303,15 +5472,15 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i +@@ -5303,16 +5484,14 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i vkd3d_unreachable(); } - sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, reg_type, VKD3D_DATA_UINT, component_count); - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, VKD3D_DATA_UINT, component_count); ++ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, VSIR_DATA_U32, component_count); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - vsir_register_init(&src_param->reg, reg_type, VKD3D_DATA_UINT, 0); +- vsir_register_init(&src_param->reg, reg_type, VKD3D_DATA_UINT, 0); ++ vsir_register_init(&src_param->reg, reg_type, VSIR_DATA_U32, 0); ++ src_param->reg.dimension = VSIR_DIMENSION_VEC4; if (component_count > 1) - { - src_param->reg.dimension = VSIR_DIMENSION_VEC4; +- { +- 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); -@@ -5323,12 +5492,12 @@ static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, co + instruction_dst_param_init_ssa_scalar(ins, sm6); +@@ -5323,12 +5502,12 @@ static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, co switch (op) { case DX_FMA: @@ -3396,7 +4030,7 @@ index ca79939a39b..db74a7bfbcc 100644 default: vkd3d_unreachable(); } -@@ -5345,7 +5514,7 @@ static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opco +@@ -5345,7 +5524,7 @@ static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opco if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; for (i = 0; i < 3; ++i) @@ -3405,7 +4039,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -5366,7 +5535,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in +@@ -5366,7 +5545,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in is_texture = resource->u.handle.d->resource_type != VKD3D_SHADER_RESOURCE_BUFFER; resource_kind = resource->u.handle.d->kind; @@ -3414,7 +4048,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 1 + is_texture, sm6))) return; -@@ -5375,17 +5544,17 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in +@@ -5375,17 +5554,17 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in if (is_texture) { ins->flags = VKD3DSI_RESINFO_UINT; @@ -3435,7 +4069,7 @@ index ca79939a39b..db74a7bfbcc 100644 ins->flags = VKD3DSI_SAMPLE_INFO_UINT; if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) -@@ -5393,7 +5562,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in +@@ -5393,7 +5572,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); src_params[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); @@ -3444,7 +4078,7 @@ index ca79939a39b..db74a7bfbcc 100644 return; dst = ins->dst; dst->write_mask = VKD3DSP_WRITEMASK_3; -@@ -5401,7 +5570,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in +@@ -5401,7 +5580,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in /* Move the result to an SSA in case another instruction overwrites r0 before * the components are extracted for use. */ ++ins; @@ -3453,7 +4087,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; src_param_init_vector_from_reg(&src_params[0], &dst->reg); -@@ -5429,9 +5598,9 @@ static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode +@@ -5429,9 +5608,9 @@ static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode switch (op) { case DX_IBFE: @@ -3465,7 +4099,7 @@ index ca79939a39b..db74a7bfbcc 100644 default: vkd3d_unreachable(); } -@@ -5448,7 +5617,7 @@ static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsi +@@ -5448,7 +5627,7 @@ static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsi if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; for (i = 0; i < 3; ++i) @@ -3474,7 +4108,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -5466,8 +5635,8 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin +@@ -5466,8 +5645,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; @@ -3485,7 +4119,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (is_control_point && operands[3]->value_type == VALUE_TYPE_UNDEFINED) { -@@ -5477,7 +5646,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin +@@ -5477,7 +5656,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin "The index for a control point load is undefined."); } @@ -3494,7 +4128,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (is_patch_constant) { -@@ -5532,7 +5701,7 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri +@@ -5532,7 +5711,7 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri return; ins = state->ins; @@ -3503,7 +4137,23 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; src_params[0].reg = reg; -@@ -5558,13 +5727,13 @@ static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op) +@@ -5544,13 +5723,13 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri + static void sm6_parser_emit_dx_output_control_point_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) + { +- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT); ++ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, true); + } + + static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) + { +- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VKD3D_DATA_UINT); ++ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VSIR_DATA_U32, true); + } + + static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op) +@@ -5558,13 +5737,13 @@ static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op) switch (op) { case QUAD_READ_ACROSS_X: @@ -3521,7 +4171,7 @@ index ca79939a39b..db74a7bfbcc 100644 } } -@@ -5576,8 +5745,8 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic +@@ -5576,8 +5755,8 @@ 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; @@ -3532,7 +4182,7 @@ index ca79939a39b..db74a7bfbcc 100644 { FIXME("Unhandled quad op kind %u.\n", quad_op); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, -@@ -5589,7 +5758,7 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic +@@ -5589,7 +5768,7 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -3541,7 +4191,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -5610,7 +5779,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i +@@ -5610,7 +5789,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i if (op == DX_RAW_BUFFER_LOAD) { @@ -3550,7 +4200,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); -@@ -5627,11 +5796,11 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i +@@ -5627,11 +5806,11 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i component_count = vsir_write_mask_component_count(write_mask); } @@ -3564,7 +4214,7 @@ index ca79939a39b..db74a7bfbcc 100644 src_param_init_vector_from_handle(sm6, &src_params[operand_count - 1], &resource->u.handle); instruction_dst_param_init_ssa_vector(ins, component_count, sm6); -@@ -5653,7 +5822,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ +@@ -5653,7 +5832,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; @@ -3573,7 +4223,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); -@@ -5679,7 +5848,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ +@@ -5679,7 +5858,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."); } @@ -3582,7 +4232,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (alignment & (alignment - 1)) { FIXME("Invalid alignment %#x.\n", alignment); -@@ -5692,12 +5861,12 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ +@@ -5692,13 +5871,13 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ return; ins = state->ins; @@ -3593,11 +4243,13 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) return; - src_params_init_from_operands(src_params, &operands[1], operand_count - 1); +- data.data_type = VKD3D_DATA_UINT; + src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6); - data.data_type = VKD3D_DATA_UINT; ++ data.data_type = VSIR_DATA_U32; src_param_init_vector_from_reg(&src_params[operand_count - 1], &data); -@@ -5732,11 +5901,11 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri + dst_param = instruction_dst_params_alloc(ins, 1, sm6); +@@ -5732,11 +5911,11 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri } instruction_init_with_resource(ins, (resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) @@ -3611,7 +4263,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!sm6_value_is_undef(operands[2])) { /* Constant zero would be ok, but is not worth checking for unless it shows up. */ -@@ -5776,7 +5945,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr +@@ -5776,7 +5955,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."); } @@ -3620,7 +4272,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); -@@ -5797,11 +5966,11 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr +@@ -5797,11 +5976,11 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr return; ins = state->ins; @@ -3634,7 +4286,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!sm6_value_is_undef(operands[2])) { /* Constant zero would have no effect, but is not worth checking for unless it shows up. */ -@@ -5822,7 +5991,7 @@ static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_ +@@ -5822,17 +6001,17 @@ static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_ struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; @@ -3643,7 +4295,19 @@ index ca79939a39b..db74a7bfbcc 100644 ins->flags = VKD3DSI_SAMPLE_INFO_UINT; if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) -@@ -5849,37 +6018,37 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in + return; +- vsir_register_init(&src_param->reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&src_param->reg, VKD3DSPR_RASTERIZER, VSIR_DATA_F32, 0); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; + src_param_init(src_param); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +- ins->dst->reg.data_type = VKD3D_DATA_FLOAT; ++ ins->dst->reg.data_type = VSIR_DATA_U32; + } + + static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -5849,37 +6028,37 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in return; } @@ -3661,7 +4325,8 @@ index ca79939a39b..db74a7bfbcc 100644 else { src_param_init_vector(&src_params[0], 2); - vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0); +- vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VSIR_DATA_F32, 0); src_params[0].reg.dimension = VSIR_DIMENSION_VEC4; - src_param_init_from_value(&src_params[1], operands[0]); + src_param_init_from_value(&src_params[1], operands[0], sm6); @@ -3689,7 +4354,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5914,7 +6083,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -5914,7 +6093,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ switch (op) { case DX_SAMPLE: @@ -3698,7 +4363,7 @@ index ca79939a39b..db74a7bfbcc 100644 src_params = instruction_src_params_alloc(ins, 3, sm6); clamp_idx = 9; break; -@@ -5922,23 +6091,23 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -5922,23 +6101,23 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ clamp_idx = 10; /* fall through */ case DX_SAMPLE_LOD: @@ -3727,7 +4392,7 @@ index ca79939a39b..db74a7bfbcc 100644 src_params = instruction_src_params_alloc(ins, 5, sm6); src_param_init_vector_from_reg(&src_params[3], &ddx); src_param_init_vector_from_reg(&src_params[4], &ddy); -@@ -5974,7 +6143,7 @@ static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intr +@@ -5974,7 +6153,7 @@ static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intr struct vkd3d_shader_src_param *src_param; unsigned int element_idx; @@ -3736,7 +4401,7 @@ index ca79939a39b..db74a7bfbcc 100644 /* SV_SampleIndex is identified in VSIR by its signature element index, * but the index is not supplied as a parameter to the DXIL intrinsic. */ -@@ -6000,49 +6169,25 @@ static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsi +@@ -6000,49 +6179,25 @@ static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsi struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; @@ -3790,7 +4455,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_vector(ins, 2, sm6); } -@@ -6060,8 +6205,8 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr +@@ -6060,8 +6215,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; @@ -3801,7 +4466,7 @@ index ca79939a39b..db74a7bfbcc 100644 signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature; if (row_index >= signature->element_count) -@@ -6092,7 +6237,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr +@@ -6092,7 +6247,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr return; } @@ -3810,7 +4475,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) return; -@@ -6103,12 +6248,12 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr +@@ -6103,12 +6258,12 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr if (e->register_index == UINT_MAX) { @@ -3825,7 +4490,14 @@ index ca79939a39b..db74a7bfbcc 100644 } static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -6141,16 +6286,16 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in +@@ -6138,19 +6293,23 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in + return; + } + ++ /* DXIL doesn't know about signedness, but vsir expects the offset to be signed. */ ++ if (extended_offset) ++ offset.data_type = VSIR_DATA_I32; ++ ins = state->ins; if (op == DX_TEXTURE_GATHER) { @@ -3845,7 +4517,7 @@ index ca79939a39b..db74a7bfbcc 100644 } src_param_init_vector_from_reg(&src_params[0], &coord); -@@ -6161,7 +6306,7 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in +@@ -6161,7 +6320,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. */ @@ -3854,7 +4526,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (swizzle >= VKD3D_VEC4_SIZE) { WARN("Invalid swizzle %#x.\n", swizzle); -@@ -6201,8 +6346,8 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr +@@ -6201,8 +6360,8 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr } ins = state->ins; @@ -3865,7 +4537,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_set_texel_offset(ins, &operands[5], sm6); for (i = 0; i < VKD3D_VEC4_SIZE; ++i) -@@ -6213,7 +6358,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr +@@ -6213,7 +6372,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr src_param_init_vector_from_reg(&src_params[0], &coord); src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); if (is_multisample) @@ -3874,7 +4546,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); } -@@ -6235,7 +6380,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int +@@ -6235,7 +6394,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; @@ -3883,7 +4555,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); -@@ -6256,7 +6401,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int +@@ -6256,7 +6415,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int return; ins = state->ins; @@ -3892,7 +4564,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; -@@ -6274,10 +6419,10 @@ static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum d +@@ -6274,10 +6433,10 @@ static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum d struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; @@ -3905,7 +4577,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); } -@@ -6288,16 +6433,16 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_bit_op(enum dxil_wave_bit_op_kin +@@ -6288,16 +6447,16 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_bit_op(enum dxil_wave_bit_op_kin switch (op) { case WAVE_BIT_OP_AND: @@ -3927,7 +4599,7 @@ index ca79939a39b..db74a7bfbcc 100644 } } -@@ -6309,15 +6454,15 @@ static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_i +@@ -6309,15 +6468,15 @@ 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; @@ -3946,7 +4618,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -6328,22 +6473,22 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_op(enum dxil_wave_op_kind op, bo +@@ -6328,22 +6487,22 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_op(enum dxil_wave_op_kind op, bo switch (op) { case WAVE_OP_ADD: @@ -3977,7 +4649,7 @@ index ca79939a39b..db74a7bfbcc 100644 } } -@@ -6356,11 +6501,11 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic +@@ -6356,11 +6515,11 @@ 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; @@ -3992,7 +4664,7 @@ index ca79939a39b..db74a7bfbcc 100644 return; vsir_instruction_init(ins, &sm6->p.location, opcode); -@@ -6368,7 +6513,7 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic +@@ -6368,7 +6527,7 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -4001,7 +4673,16 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -6436,7 +6581,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = +@@ -6390,7 +6549,7 @@ static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intr + vkd3d_unreachable(); + } + +- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VKD3D_DATA_UINT); ++ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VSIR_DATA_U32, true); + } + + struct sm6_dx_opcode_info +@@ -6436,7 +6595,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_BUFFER_UPDATE_COUNTER ] = {"i", "H8", sm6_parser_emit_dx_buffer_update_counter}, [DX_CALCULATE_LOD ] = {"f", "HHfffb", sm6_parser_emit_dx_calculate_lod}, [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load}, @@ -4010,7 +4691,7 @@ index ca79939a39b..db74a7bfbcc 100644 [DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary}, [DX_COVERAGE ] = {"i", "", sm6_parser_emit_dx_coverage}, [DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle}, -@@ -6505,7 +6650,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = +@@ -6505,7 +6664,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_SAMPLE_INDEX ] = {"i", "", sm6_parser_emit_dx_sample_index}, [DX_SAMPLE_LOD ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample}, [DX_SATURATE ] = {"g", "R", sm6_parser_emit_dx_saturate}, @@ -4019,7 +4700,7 @@ index ca79939a39b..db74a7bfbcc 100644 [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, -@@ -6539,11 +6684,13 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = +@@ -6539,11 +6698,13 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = }; static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type, @@ -4035,7 +4716,7 @@ index ca79939a39b..db74a7bfbcc 100644 return false; switch (info_type) -@@ -6578,7 +6725,7 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc +@@ -6578,7 +6739,7 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc case 'g': return sm6_type_is_floating_point(type); case 'H': @@ -4044,7 +4725,7 @@ index ca79939a39b..db74a7bfbcc 100644 case 'D': return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Dimensions"); case 'S': -@@ -6586,7 +6733,7 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc +@@ -6586,7 +6747,7 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc case 'V': return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.fouri32"); case 'v': @@ -4053,7 +4734,7 @@ index ca79939a39b..db74a7bfbcc 100644 case 'o': /* TODO: some type checking may be possible */ return true; -@@ -6606,18 +6753,10 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -6606,18 +6767,10 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ info = &sm6_dx_op_table[op]; @@ -4073,7 +4754,7 @@ index ca79939a39b..db74a7bfbcc 100644 { WARN("Failed to validate operand %u for dx intrinsic id %u, '%s'.\n", i + 1, op, name); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -6639,13 +6778,12 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -6639,13 +6792,12 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { @@ -4088,7 +4769,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -6661,10 +6799,22 @@ static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_op +@@ -6661,10 +6813,22 @@ static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_op return; } @@ -4114,7 +4795,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -6750,15 +6900,16 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor +@@ -6750,15 +6914,16 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor "Expected a constant integer dx intrinsic function id."); return; } @@ -4133,7 +4814,7 @@ index ca79939a39b..db74a7bfbcc 100644 bool is_valid = false; from_int = sm6_type_is_integer(from); -@@ -6772,92 +6923,98 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ +@@ -6772,92 +6937,98 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ FIXME("Unhandled cast of type class %u to type class %u.\n", from->class, to->class); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Cast of type class %u to type class %u is not implemented.", from->class, to->class); @@ -4271,7 +4952,7 @@ index ca79939a39b..db74a7bfbcc 100644 return op; } -@@ -6885,33 +7042,33 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor +@@ -6885,33 +7056,33 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor { *dst = *value; dst->type = type; @@ -4316,7 +4997,7 @@ index ca79939a39b..db74a7bfbcc 100644 } struct sm6_cmp_info -@@ -6924,33 +7081,33 @@ static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) +@@ -6924,33 +7095,33 @@ static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) { static const struct sm6_cmp_info cmp_op_table[] = { @@ -4377,7 +5058,7 @@ index ca79939a39b..db74a7bfbcc 100644 }; return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL; -@@ -6996,7 +7153,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor +@@ -6996,7 +7167,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor * do not otherwise occur, so deleting these avoids the need for backend support. */ if (sm6_type_is_bool(type_a) && code == ICMP_NE && sm6_value_is_constant_zero(b)) { @@ -4386,7 +5067,7 @@ index ca79939a39b..db74a7bfbcc 100644 *dst = *a; return; } -@@ -7017,7 +7174,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor +@@ -7017,7 +7188,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor "Type mismatch in comparison operation arguments."); } @@ -4395,7 +5076,7 @@ index ca79939a39b..db74a7bfbcc 100644 { FIXME("Unhandled operation %"PRIu64".\n", code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -7051,8 +7208,8 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor +@@ -7051,8 +7222,8 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; @@ -4406,7 +5087,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -7074,7 +7231,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re +@@ -7074,7 +7245,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re || !sm6_value_validate_is_backward_ref(ptr, sm6)) return; @@ -4415,7 +5096,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (reg.type != VKD3DSPR_GROUPSHAREDMEM) { -@@ -7123,20 +7280,20 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re +@@ -7123,20 +7294,20 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re if (record->operand_count > i && record->operands[i]) FIXME("Ignoring weak cmpxchg.\n"); @@ -4440,7 +5121,7 @@ index ca79939a39b..db74a7bfbcc 100644 dst_param_init(&dst_params[0]); dst_params[1].reg = reg; dst_param_init(&dst_params[1]); -@@ -7191,11 +7348,11 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil +@@ -7191,11 +7362,11 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil } dst->type = type; @@ -4454,7 +5135,7 @@ index ca79939a39b..db74a7bfbcc 100644 src_param_init_scalar(src_param, elem_idx); instruction_dst_param_init_ssa_scalar(ins, sm6); -@@ -7208,9 +7365,8 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record +@@ -7208,9 +7379,8 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record unsigned int elem_idx, operand_idx = 2; enum bitcode_address_space addr_space; const struct sm6_value *elem_value; @@ -4465,7 +5146,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!dxil_record_validate_operand_min_count(record, 5, sm6) || !(type = sm6_parser_get_type(sm6, record->operands[1])) -@@ -7222,9 +7378,13 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record +@@ -7222,9 +7392,13 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; } @@ -4481,7 +5162,7 @@ index ca79939a39b..db74a7bfbcc 100644 { WARN("Unsupported stacked GEP.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -7232,8 +7392,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record +@@ -7232,8 +7406,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; } @@ -4490,7 +5171,7 @@ index ca79939a39b..db74a7bfbcc 100644 if ((pointee_type = src->type->u.pointer.type) != type) { WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type->class, -@@ -7247,7 +7405,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record +@@ -7247,7 +7419,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. */ @@ -4499,7 +5180,7 @@ index ca79939a39b..db74a7bfbcc 100644 { WARN("Expected constant zero.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -7267,7 +7425,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record +@@ -7267,7 +7439,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. */ @@ -4508,7 +5189,7 @@ index ca79939a39b..db74a7bfbcc 100644 type = sm6_type_get_element_type_at_index(pointee_type, elem_idx); if (!type) { -@@ -7293,15 +7451,10 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record +@@ -7293,15 +7465,10 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; } @@ -4516,18 +5197,18 @@ index ca79939a39b..db74a7bfbcc 100644 - register_index_address_init(®.idx[1], elem_value, sm6); - reg.idx[1].is_in_bounds = is_in_bounds; - reg.idx_count = 2; +- +- dst->reg = reg; +- dst->structure_stride = src->structure_stride; + index->index = elem_value; + index->is_in_bounds = record->operands[0]; -- dst->reg = reg; -- dst->structure_stride = src->structure_stride; -- - ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; } static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -7348,12 +7501,12 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor +@@ -7348,12 +7515,12 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor if (record->operands[i]) WARN("Ignoring volatile modifier.\n"); @@ -4542,7 +5223,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; -@@ -7363,7 +7516,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor +@@ -7363,7 +7530,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); /* Struct offset is always zero as there is no struct, just an array. */ src_param_make_constant_uint(&src_params[1], 0); @@ -4551,7 +5232,7 @@ index ca79939a39b..db74a7bfbcc 100644 src_params[2].reg.alignment = alignment; /* The offset is already in src_params[0]. */ src_params[2].reg.idx_count = 1; -@@ -7371,13 +7524,13 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor +@@ -7371,13 +7538,13 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor else { operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM); @@ -4567,7 +5248,7 @@ index ca79939a39b..db74a7bfbcc 100644 src_params[operand_count - 1].reg.alignment = alignment; } -@@ -7425,7 +7578,6 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record +@@ -7425,7 +7592,6 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record if (!(phi = sm6_block_phi_require_space(code_block, sm6))) return; @@ -4575,7 +5256,7 @@ index ca79939a39b..db74a7bfbcc 100644 phi->incoming_count = record->operand_count / 2u; if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count, -@@ -7456,7 +7608,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record +@@ -7456,7 +7622,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record incoming[j].block = sm6_function_get_block(function, record->operands[i + 1], sm6); } @@ -4584,7 +5265,7 @@ index ca79939a39b..db74a7bfbcc 100644 qsort(incoming, phi->incoming_count, sizeof(*incoming), phi_incoming_compare); -@@ -7491,7 +7643,7 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record +@@ -7491,7 +7657,7 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record code_block->terminator.type = TERMINATOR_RET; @@ -4593,7 +5274,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -7536,12 +7688,12 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco +@@ -7536,12 +7702,12 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco if (record->operands[i]) WARN("Ignoring volatile modifier.\n"); @@ -4608,7 +5289,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; -@@ -7551,18 +7703,18 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco +@@ -7551,18 +7717,18 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); /* Struct offset is always zero as there is no struct, just an array. */ src_param_make_constant_uint(&src_params[1], 0); @@ -4630,7 +5311,7 @@ index ca79939a39b..db74a7bfbcc 100644 } dst_param = instruction_dst_params_alloc(ins, 1, sm6); -@@ -7612,7 +7764,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec +@@ -7612,7 +7778,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec return; } @@ -4639,7 +5320,7 @@ index ca79939a39b..db74a7bfbcc 100644 terminator->type = TERMINATOR_SWITCH; terminator->case_count = record->operand_count / 2u; -@@ -7651,10 +7803,10 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec +@@ -7651,10 +7817,10 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec "A switch case value is not a constant."); } @@ -4652,7 +5333,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -7683,12 +7835,12 @@ static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_re +@@ -7683,12 +7849,12 @@ static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_re if (!sm6_value_validate_is_bool(src[0], sm6)) return; @@ -4667,7 +5348,7 @@ index ca79939a39b..db74a7bfbcc 100644 instruction_dst_param_init_ssa_scalar(ins, sm6); } -@@ -7714,7 +7866,7 @@ static bool sm6_metadata_value_is_zero_or_undef(const struct sm6_metadata_value +@@ -7714,7 +7880,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)); } @@ -4676,7 +5357,7 @@ index ca79939a39b..db74a7bfbcc 100644 const struct sm6_metadata_value *m, unsigned int *u) { const struct sm6_value *value; -@@ -7728,12 +7880,12 @@ static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, +@@ -7728,12 +7894,12 @@ static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, if (!sm6_type_is_integer(value->type)) return false; @@ -4691,7 +5372,7 @@ index ca79939a39b..db74a7bfbcc 100644 const struct sm6_metadata_value *m, uint64_t *u) { const struct sm6_value *value; -@@ -7747,12 +7899,12 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, +@@ -7747,12 +7913,12 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, if (!sm6_type_is_integer(value->type)) return false; @@ -4706,7 +5387,7 @@ index ca79939a39b..db74a7bfbcc 100644 const struct sm6_metadata_value *m, float *f) { const struct sm6_value *value; -@@ -7766,7 +7918,7 @@ static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, +@@ -7766,7 +7932,7 @@ static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, if (!sm6_type_is_floating_point(value->type)) return false; @@ -4715,7 +5396,7 @@ index ca79939a39b..db74a7bfbcc 100644 return true; } -@@ -7951,7 +8103,7 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e +@@ -7951,7 +8117,7 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e } else if (metadata_node_get_unary_uint(node, &operand, sm6)) { @@ -4724,7 +5405,7 @@ index ca79939a39b..db74a7bfbcc 100644 } } else -@@ -8023,13 +8175,13 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun +@@ -8023,13 +8189,13 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun "A PHI incoming value is not a constant or SSA register."); return VKD3D_ERROR_INVALID_SHADER; } @@ -4740,7 +5421,7 @@ index ca79939a39b..db74a7bfbcc 100644 } } } -@@ -8113,12 +8265,11 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const +@@ -8113,12 +8279,11 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const } ins = &code_block->instructions[code_block->instruction_count]; @@ -4754,7 +5435,7 @@ index ca79939a39b..db74a7bfbcc 100644 dst->is_back_ref = true; is_terminator = false; -@@ -8196,13 +8347,17 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const +@@ -8196,13 +8361,17 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const if (record->attachment) metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6); @@ -4773,7 +5454,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (dst->type && fwd_type && dst->type != fwd_type) { -@@ -8234,7 +8389,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ +@@ -8234,7 +8403,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ case TERMINATOR_UNCOND_BR: if (!block->terminator.true_block) return; @@ -4782,7 +5463,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; vsir_src_param_init_label(&src_params[0], block->terminator.true_block->id); -@@ -8243,7 +8398,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ +@@ -8243,7 +8412,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ case TERMINATOR_COND_BR: if (!block->terminator.true_block || !block->terminator.false_block) return; @@ -4791,7 +5472,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; src_param_init(&src_params[0]); -@@ -8253,7 +8408,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ +@@ -8253,7 +8422,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ break; case TERMINATOR_SWITCH: @@ -4800,7 +5481,28 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, block->terminator.case_count * 2u + 1, sm6))) return; src_param_init(&src_params[0]); -@@ -8300,7 +8455,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ +@@ -8278,9 +8447,9 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ + continue; + } + +- if (src_params[0].reg.data_type == VKD3D_DATA_UINT64) ++ if (src_params[0].reg.data_type == VSIR_DATA_U64) + { +- vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VKD3D_DATA_UINT64, 0); ++ vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VSIR_DATA_U64, 0); + src_params[count++].reg.u.immconst_u64[0] = switch_case->value; + } + else +@@ -8291,7 +8460,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "Truncating 64-bit switch case value %"PRIx64" to 32 bits.", switch_case->value); + } +- vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); ++ vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); + src_params[count++].reg.u.immconst_u32[0] = switch_case->value; + } + vsir_src_param_init_label(&src_params[count++], case_block->id); +@@ -8300,7 +8469,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ break; case TERMINATOR_RET: @@ -4809,7 +5511,7 @@ index ca79939a39b..db74a7bfbcc 100644 break; default: -@@ -8322,7 +8477,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser +@@ -8322,7 +8491,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser src_phi = &block->phi[i]; incoming_count = src_phi->incoming_count; @@ -4818,7 +5520,7 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_params = instruction_src_params_alloc(ins, incoming_count * 2u, sm6))) return; if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) -@@ -8342,7 +8497,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser +@@ -8342,7 +8511,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser } dst_param_init(dst_param); @@ -4827,7 +5529,7 @@ index ca79939a39b..db74a7bfbcc 100644 } } -@@ -8408,7 +8563,7 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) +@@ -8408,7 +8577,7 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; @@ -4836,7 +5538,108 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; -@@ -9018,7 +9173,7 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc +@@ -8738,6 +8907,7 @@ static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] = + [SEMANTIC_KIND_INSTANCEID] = VKD3D_SHADER_SV_INSTANCE_ID, + [SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION, + [SEMANTIC_KIND_RTARRAYINDEX] = VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX, ++ [SEMANTIC_KIND_VIEWPORTARRAYINDEX] = VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX, + [SEMANTIC_KIND_CLIPDISTANCE] = VKD3D_SHADER_SV_CLIP_DISTANCE, + [SEMANTIC_KIND_CULLDISTANCE] = VKD3D_SHADER_SV_CULL_DISTANCE, + [SEMANTIC_KIND_PRIMITIVEID] = VKD3D_SHADER_SV_PRIMITIVE_ID, +@@ -8876,40 +9046,39 @@ static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_k + } + } + +-static const enum vkd3d_data_type data_type_table[] = +-{ +- [COMPONENT_TYPE_INVALID] = VKD3D_DATA_UNUSED, +- [COMPONENT_TYPE_I1] = VKD3D_DATA_UNUSED, +- [COMPONENT_TYPE_I16] = VKD3D_DATA_INT, +- [COMPONENT_TYPE_U16] = VKD3D_DATA_UINT, +- [COMPONENT_TYPE_I32] = VKD3D_DATA_INT, +- [COMPONENT_TYPE_U32] = VKD3D_DATA_UINT, +- [COMPONENT_TYPE_I64] = VKD3D_DATA_UNUSED, +- [COMPONENT_TYPE_U64] = VKD3D_DATA_UNUSED, +- [COMPONENT_TYPE_F16] = VKD3D_DATA_FLOAT, +- [COMPONENT_TYPE_F32] = VKD3D_DATA_FLOAT, +- [COMPONENT_TYPE_F64] = VKD3D_DATA_DOUBLE, +- [COMPONENT_TYPE_SNORMF16] = VKD3D_DATA_SNORM, +- [COMPONENT_TYPE_UNORMF16] = VKD3D_DATA_UNORM, +- [COMPONENT_TYPE_SNORMF32] = VKD3D_DATA_SNORM, +- [COMPONENT_TYPE_UNORMF32] = VKD3D_DATA_UNORM, +- [COMPONENT_TYPE_SNORMF64] = VKD3D_DATA_DOUBLE, +- [COMPONENT_TYPE_UNORMF64] = VKD3D_DATA_DOUBLE, +- [COMPONENT_TYPE_PACKEDS8X32] = VKD3D_DATA_UNUSED, +- [COMPONENT_TYPE_PACKEDU8X32] = VKD3D_DATA_UNUSED, ++static const enum vsir_data_type data_type_table[] = ++{ ++ [COMPONENT_TYPE_INVALID] = VSIR_DATA_UNUSED, ++ [COMPONENT_TYPE_I1] = VSIR_DATA_UNUSED, ++ [COMPONENT_TYPE_I16] = VSIR_DATA_I32, ++ [COMPONENT_TYPE_U16] = VSIR_DATA_U32, ++ [COMPONENT_TYPE_I32] = VSIR_DATA_I32, ++ [COMPONENT_TYPE_U32] = VSIR_DATA_U32, ++ [COMPONENT_TYPE_I64] = VSIR_DATA_UNUSED, ++ [COMPONENT_TYPE_U64] = VSIR_DATA_UNUSED, ++ [COMPONENT_TYPE_F16] = VSIR_DATA_F32, ++ [COMPONENT_TYPE_F32] = VSIR_DATA_F32, ++ [COMPONENT_TYPE_F64] = VSIR_DATA_F64, ++ [COMPONENT_TYPE_SNORMF16] = VSIR_DATA_SNORM, ++ [COMPONENT_TYPE_UNORMF16] = VSIR_DATA_UNORM, ++ [COMPONENT_TYPE_SNORMF32] = VSIR_DATA_SNORM, ++ [COMPONENT_TYPE_UNORMF32] = VSIR_DATA_UNORM, ++ [COMPONENT_TYPE_SNORMF64] = VSIR_DATA_F64, ++ [COMPONENT_TYPE_UNORMF64] = VSIR_DATA_F64, ++ [COMPONENT_TYPE_PACKEDS8X32] = VSIR_DATA_UNUSED, ++ [COMPONENT_TYPE_PACKEDU8X32] = VSIR_DATA_UNUSED, + }; + +-static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_component_type type, ++static enum vsir_data_type vsir_data_type_from_dxil_component_type(enum dxil_component_type type, + struct sm6_parser *sm6) + { +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + +- if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VKD3D_DATA_UNUSED) ++ if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VSIR_DATA_UNUSED) + { +- FIXME("Unhandled component type %u.\n", type); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Resource descriptor component type %u is unhandled.", type); +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + } + + return data_type; +@@ -8917,7 +9086,7 @@ static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_c + + struct resource_additional_values + { +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + unsigned int byte_stride; + }; + +@@ -8926,7 +9095,7 @@ static bool resources_load_additional_values(struct resource_additional_values * + { + unsigned int i, operand_count, tag, value; + +- info->data_type = VKD3D_DATA_UNUSED; ++ info->data_type = VSIR_DATA_UNUSED; + info->byte_stride = 0; + + if (node->operand_count & 1) +@@ -8958,7 +9127,7 @@ static bool resources_load_additional_values(struct resource_additional_values * + "An untyped resource has type %u.", value); + return false; + } +- info->data_type = vkd3d_data_type_from_dxil_component_type(value, sm6); ++ info->data_type = vsir_data_type_from_dxil_component_type(value, sm6); + break; + + case RESOURCE_TAG_ELEMENT_STRIDE: +@@ -9018,7 +9187,7 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc if (!m) { @@ -4845,7 +5648,15 @@ index ca79939a39b..db74a7bfbcc 100644 ins->declaration.raw_resource.resource.reg.write_mask = 0; return &ins->declaration.raw_resource.resource; } -@@ -9043,7 +9198,7 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc +@@ -9036,14 +9205,13 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc + + if (kind == RESOURCE_KIND_TYPEDBUFFER || resource_kind_is_texture(kind)) + { +- if (resource_values.data_type == VKD3D_DATA_UNUSED) ++ if (resource_values.data_type == VSIR_DATA_UNUSED) + { +- WARN("No data type defined.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, "A typed resource has no data type."); } @@ -4854,7 +5665,7 @@ index ca79939a39b..db74a7bfbcc 100644 for (i = 0; i < VKD3D_VEC4_SIZE; ++i) ins->declaration.semantic.resource_data_type[i] = resource_values.data_type; ins->declaration.semantic.resource_type = resource_type; -@@ -9053,14 +9208,14 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc +@@ -9053,14 +9221,14 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc } else if (kind == RESOURCE_KIND_RAWBUFFER) { @@ -4871,7 +5682,18 @@ index ca79939a39b..db74a7bfbcc 100644 ins->declaration.structured_resource.byte_stride = resource_values.byte_stride; ins->declaration.structured_resource.resource.reg.write_mask = 0; -@@ -9129,7 +9284,7 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, +@@ -9086,8 +9254,8 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc + } + + static void init_resource_declaration(struct vkd3d_shader_resource *resource, +- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id, +- const struct vkd3d_shader_register_range *range) ++ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, ++ unsigned int id, const struct vkd3d_shader_register_range *range) + { + struct vkd3d_shader_dst_param *param = &resource->reg; + +@@ -9129,7 +9297,7 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; } @@ -4880,16 +5702,20 @@ index ca79939a39b..db74a7bfbcc 100644 if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], false, kind, node->operands[8], ins))) -@@ -9141,7 +9296,7 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, +@@ -9140,9 +9308,9 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, + d->resource_type = ins->resource_type; d->kind = kind; d->reg_type = VKD3DSPR_RESOURCE; - d->reg_data_type = VKD3D_DATA_UNUSED; +- d->reg_data_type = VKD3D_DATA_UNUSED; - d->resource_data_type = (ins->opcode == VKD3DSIH_DCL) +- ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; ++ d->reg_data_type = VSIR_DATA_UNUSED; + d->resource_data_type = (ins->opcode == VSIR_OP_DCL) - ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; ++ ? ins->declaration.semantic.resource_data_type[0] : VSIR_DATA_UNUSED; init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range); -@@ -9197,7 +9352,7 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, + +@@ -9197,7 +9365,7 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, } } @@ -4898,16 +5724,20 @@ index ca79939a39b..db74a7bfbcc 100644 if (values[1]) ins->flags = VKD3DSUF_GLOBALLY_COHERENT; if (values[2]) -@@ -9215,7 +9370,7 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, +@@ -9214,9 +9382,9 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, + d->resource_type = ins->resource_type; d->kind = values[0]; d->reg_type = VKD3DSPR_UAV; - d->reg_data_type = VKD3D_DATA_UNUSED; +- d->reg_data_type = VKD3D_DATA_UNUSED; - d->resource_data_type = (ins->opcode == VKD3DSIH_DCL_UAV_TYPED) +- ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; ++ d->reg_data_type = VSIR_DATA_UNUSED; + d->resource_data_type = (ins->opcode == VSIR_OP_DCL_UAV_TYPED) - ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; ++ ? ins->declaration.semantic.resource_data_type[0] : VSIR_DATA_UNUSED; init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range); -@@ -9251,7 +9406,7 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, + +@@ -9251,14 +9419,14 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; } @@ -4916,7 +5746,26 @@ index ca79939a39b..db74a7bfbcc 100644 ins->resource_type = VKD3D_SHADER_RESOURCE_BUFFER; ins->declaration.cb.size = buffer_size; ins->declaration.cb.src.swizzle = VKD3D_SHADER_NO_SWIZZLE; -@@ -9292,7 +9447,7 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm + ins->declaration.cb.src.modifiers = VKD3DSPSM_NONE; + + reg = &ins->declaration.cb.src.reg; +- vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); ++ vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 3); + reg->idx[0].offset = d->id; + reg->idx[1].offset = d->range.first; + reg->idx[2].offset = d->range.last; +@@ -9266,8 +9434,8 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, + ins->declaration.cb.range = d->range; + + d->reg_type = VKD3DSPR_CONSTBUFFER; +- d->reg_data_type = VKD3D_DATA_FLOAT; +- d->resource_data_type = VKD3D_DATA_FLOAT; ++ d->reg_data_type = VSIR_DATA_F32; ++ d->resource_data_type = VSIR_DATA_F32; + + return VKD3D_OK; + } +@@ -9292,7 +9460,7 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm "Ignoring %u extra operands for a sampler descriptor.", node->operand_count - 7); } @@ -4925,7 +5774,38 @@ index ca79939a39b..db74a7bfbcc 100644 ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind)) -@@ -9813,7 +9968,7 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm +@@ -9320,7 +9488,7 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm + ins->declaration.sampler.src.modifiers = VKD3DSPSM_NONE; + + reg = &ins->declaration.sampler.src.reg; +- vsir_register_init(reg, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 3); ++ vsir_register_init(reg, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 3); + reg->idx[0].offset = d->id; + reg->idx[1].offset = d->range.first; + reg->idx[2].offset = d->range.last; +@@ -9330,8 +9498,8 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm + d->resource_type = ins->resource_type; + d->kind = RESOURCE_KIND_SAMPLER; + d->reg_type = VKD3DSPR_SAMPLER; +- d->reg_data_type = VKD3D_DATA_UNUSED; +- d->resource_data_type = VKD3D_DATA_UNUSED; ++ d->reg_data_type = VSIR_DATA_UNUSED; ++ d->resource_data_type = VSIR_DATA_UNUSED; + + return VKD3D_OK; + } +@@ -9660,7 +9828,9 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const + + if ((is_register = e->register_index == UINT_MAX)) + { +- if (register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input) == VKD3DSPR_INVALID) ++ enum vsir_dimension dimension; ++ ++ if (register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input, &dimension) == VKD3DSPR_INVALID) + { + WARN("Unhandled I/O register semantic kind %u.\n", j); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE, +@@ -9813,7 +9983,7 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm rotated_flags = (rotated_flags >> 1) | ((rotated_flags & 1) << 4); global_flags = (global_flags & ~mask) | rotated_flags; @@ -4934,7 +5814,7 @@ index ca79939a39b..db74a7bfbcc 100644 ins->declaration.global_flags = global_flags; sm6->p.program->global_flags = global_flags; } -@@ -9870,7 +10025,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co +@@ -9870,7 +10040,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co } } @@ -4943,7 +5823,7 @@ index ca79939a39b..db74a7bfbcc 100644 ins->declaration.thread_group_size.x = group_sizes[0]; ins->declaration.thread_group_size.y = group_sizes[1]; ins->declaration.thread_group_size.z = group_sizes[2]; -@@ -9910,7 +10065,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, +@@ -9910,7 +10080,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, "Domain shader tessellator domain %u is unhandled.", tessellator_domain); } @@ -4952,7 +5832,7 @@ index ca79939a39b..db74a7bfbcc 100644 ins->declaration.tessellator_domain = tessellator_domain; sm6->p.program->tess_domain = tessellator_domain; } -@@ -9938,7 +10093,7 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, +@@ -9938,7 +10108,7 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, "Hull shader tessellator partitioning %u is unhandled.", tessellator_partitioning); } @@ -4961,7 +5841,7 @@ index ca79939a39b..db74a7bfbcc 100644 ins->declaration.tessellator_partitioning = tessellator_partitioning; sm6->p.program->tess_partitioning = tessellator_partitioning; -@@ -9956,7 +10111,7 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * +@@ -9956,7 +10126,7 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * "Hull shader tessellator output primitive %u is unhandled.", primitive); } @@ -4970,7 +5850,7 @@ index ca79939a39b..db74a7bfbcc 100644 ins->declaration.tessellator_output_primitive = primitive; sm6->p.program->tess_output_primitive = primitive; -@@ -9983,7 +10138,7 @@ static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, +@@ -9983,7 +10153,7 @@ static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, "Hull shader max tessellation factor %f is invalid.", max_tessellation_factor); } @@ -4979,7 +5859,7 @@ index ca79939a39b..db74a7bfbcc 100644 ins->declaration.max_tessellation_factor = max_tessellation_factor; } -@@ -10070,7 +10225,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -10070,7 +10240,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s break; } @@ -4988,7 +5868,7 @@ index ca79939a39b..db74a7bfbcc 100644 sm6->p.program->input_primitive = input_primitive; sm6->p.program->input_control_point_count = input_control_point_count; -@@ -10082,7 +10237,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -10082,7 +10252,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Geometry shader output vertex count %u is invalid.", i); } @@ -4997,7 +5877,7 @@ index ca79939a39b..db74a7bfbcc 100644 sm6->p.program->vertices_out_count = i; if (operands[2] > 1) -@@ -10100,7 +10255,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -10100,7 +10270,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s "Geometry shader output primitive %u is unhandled.", output_primitive); output_primitive = VKD3D_PT_TRIANGLELIST; } @@ -5006,7 +5886,7 @@ index ca79939a39b..db74a7bfbcc 100644 sm6->p.program->output_topology = output_primitive; i = operands[4]; -@@ -10110,7 +10265,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -10110,7 +10280,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Geometry shader instance count %u is invalid.", i); } @@ -5015,7 +5895,7 @@ index ca79939a39b..db74a7bfbcc 100644 } static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6, -@@ -10217,7 +10372,7 @@ static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_pa +@@ -10217,7 +10387,7 @@ static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_pa sm6_parser_validate_control_point_count(sm6, operands[1], false, "Hull shader input"); program->input_control_point_count = operands[1]; sm6_parser_validate_control_point_count(sm6, operands[2], false, "Hull shader output"); @@ -5024,7 +5904,7 @@ index ca79939a39b..db74a7bfbcc 100644 program->output_control_point_count = operands[2]; sm6_parser_emit_dcl_tessellator_domain(sm6, operands[3]); sm6_parser_emit_dcl_tessellator_partitioning(sm6, operands[4]); -@@ -10742,7 +10897,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10742,7 +10912,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro if (version.type == VKD3D_SHADER_TYPE_HULL) { @@ -5033,7 +5913,7 @@ index ca79939a39b..db74a7bfbcc 100644 if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) goto fail; -@@ -10757,7 +10912,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10757,7 +10927,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro goto fail; } @@ -5043,10 +5923,19 @@ index ca79939a39b..db74a7bfbcc 100644 goto fail; diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c -index a4f1a371299..e5a792583b3 100644 +index a4f1a371299..5b776108c95 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c -@@ -54,6 +54,22 @@ enum state_property_component_type +@@ -20,6 +20,8 @@ + + #include "hlsl.h" + ++#define TAG_FX20 0x46580200 ++ + static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uint32_t value) + { + return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value)); +@@ -54,6 +56,22 @@ enum state_property_component_type FX_COMPONENT_TYPE_COUNT, }; @@ -5069,7 +5958,7 @@ index a4f1a371299..e5a792583b3 100644 struct rhs_named_value { const char *name; -@@ -237,6 +253,8 @@ struct fx_write_context_ops +@@ -237,6 +255,8 @@ struct fx_write_context_ops void (*write_technique)(struct hlsl_ir_var *var, struct fx_write_context *fx); void (*write_pass)(struct hlsl_ir_var *var, struct fx_write_context *fx); void (*write_annotation)(struct hlsl_ir_var *var, struct fx_write_context *fx); @@ -5078,7 +5967,7 @@ index a4f1a371299..e5a792583b3 100644 bool are_child_effects_supported; }; -@@ -289,15 +307,6 @@ static void set_status(struct fx_write_context *fx, int status) +@@ -289,15 +309,6 @@ static void set_status(struct fx_write_context *fx, int status) fx->status = status; } @@ -5094,7 +5983,7 @@ index a4f1a371299..e5a792583b3 100644 static uint32_t write_string(const char *string, struct fx_write_context *fx) { return fx->ops->write_string(string, fx); -@@ -308,6 +317,15 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) +@@ -308,6 +319,15 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) fx->ops->write_pass(var, fx); } @@ -5110,7 +5999,7 @@ index a4f1a371299..e5a792583b3 100644 static uint32_t write_annotations(struct hlsl_scope *scope, struct fx_write_context *fx) { struct hlsl_ctx *ctx = fx->ctx; -@@ -343,8 +361,6 @@ static void write_fx_4_annotations(struct hlsl_scope *scope, struct fx_write_con +@@ -343,8 +363,6 @@ static void write_fx_4_annotations(struct hlsl_scope *scope, struct fx_write_con static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx); static const char * get_fx_4_type_name(const struct hlsl_type *type); static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_context *fx); @@ -5119,7 +6008,7 @@ index a4f1a371299..e5a792583b3 100644 static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx) { -@@ -369,18 +385,23 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context +@@ -369,18 +387,23 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context name = get_fx_4_type_name(element_type); modifiers = element_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK; @@ -5151,7 +6040,7 @@ index a4f1a371299..e5a792583b3 100644 } if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry)))) -@@ -391,7 +412,8 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context +@@ -391,7 +414,8 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context type_entry->elements_count = elements_count; type_entry->modifiers = modifiers; @@ -5161,7 +6050,7 @@ index a4f1a371299..e5a792583b3 100644 return type_entry->offset; } -@@ -491,17 +513,22 @@ static uint32_t write_fx_4_string(const char *string, struct fx_write_context *f +@@ -491,17 +515,22 @@ static uint32_t write_fx_4_string(const char *string, struct fx_write_context *f return string_entry->offset; } @@ -5186,7 +6075,7 @@ index a4f1a371299..e5a792583b3 100644 } static void write_fx_2_annotations(struct hlsl_ir_var *var, uint32_t count_offset, struct fx_write_context *fx) -@@ -764,208 +791,227 @@ static const struct rhs_named_value fx_2_filter_values[] = +@@ -764,208 +793,227 @@ static const struct rhs_named_value fx_2_filter_values[] = { NULL } }; @@ -5608,7 +6497,7 @@ index a4f1a371299..e5a792583b3 100644 }; static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) -@@ -988,16 +1034,6 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx +@@ -988,16 +1036,6 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx fx->shader_count++; } @@ -5625,7 +6514,7 @@ index a4f1a371299..e5a792583b3 100644 enum fx_4_type_constants { /* Numeric types encoding */ -@@ -1015,6 +1051,9 @@ enum fx_4_type_constants +@@ -1015,6 +1053,9 @@ enum fx_4_type_constants FX_4_NUMERIC_COLUMNS_SHIFT = 11, FX_4_NUMERIC_COLUMN_MAJOR_MASK = 0x4000, @@ -5635,7 +6524,7 @@ index a4f1a371299..e5a792583b3 100644 /* Object types */ FX_4_OBJECT_TYPE_STRING = 0x1, FX_4_OBJECT_TYPE_BLEND_STATE = 0x2, -@@ -1071,17 +1110,6 @@ enum fx_4_type_constants +@@ -1071,17 +1112,6 @@ enum fx_4_type_constants FX_4_ASSIGNMENT_VALUE_EXPRESSION = 0x6, FX_4_ASSIGNMENT_INLINE_SHADER = 0x7, FX_5_ASSIGNMENT_INLINE_SHADER = 0x8, @@ -5653,7 +6542,7 @@ index a4f1a371299..e5a792583b3 100644 }; static const uint32_t fx_4_numeric_base_types[] = -@@ -1238,7 +1266,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co +@@ -1238,7 +1268,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co name = get_fx_4_type_name(element_type); @@ -5662,7 +6551,7 @@ index a4f1a371299..e5a792583b3 100644 if (element_type->class == HLSL_CLASS_STRUCT) { if (!(field_offsets = hlsl_calloc(ctx, element_type->e.record.field_count, sizeof(*field_offsets)))) -@@ -1541,12 +1569,33 @@ static uint32_t get_fx_2_type_class(const struct hlsl_type *type) +@@ -1541,12 +1571,33 @@ static uint32_t get_fx_2_type_class(const struct hlsl_type *type) return hlsl_sm1_class(type); } @@ -5701,7 +6590,7 @@ index a4f1a371299..e5a792583b3 100644 /* Resolve arrays to element type and number of elements. */ if (type->class == HLSL_CLASS_ARRAY) -@@ -1555,13 +1604,11 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n +@@ -1555,13 +1606,11 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n type = hlsl_get_multiarray_element_type(type); } @@ -5719,7 +6608,7 @@ index a4f1a371299..e5a792583b3 100644 put_u32(buffer, elements_count); switch (type->class) -@@ -1586,19 +1633,68 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n +@@ -1586,19 +1635,68 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n ; } @@ -5794,7 +6683,7 @@ index a4f1a371299..e5a792583b3 100644 } static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_context *fx) -@@ -1623,6 +1719,15 @@ static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_contex +@@ -1623,6 +1721,15 @@ static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_contex set_u32(buffer, pass_count_offset, count); } @@ -5810,7 +6699,7 @@ index a4f1a371299..e5a792583b3 100644 static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hlsl_default_value *value, struct fx_write_context *fx) { -@@ -1656,7 +1761,7 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl +@@ -1656,7 +1763,7 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl for (j = 0; j < comp_count; ++j) { @@ -5819,7 +6708,7 @@ index a4f1a371299..e5a792583b3 100644 value++; } break; -@@ -1673,8 +1778,8 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl +@@ -1673,8 +1780,8 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl for (j = 0; j < type->e.record.field_count; ++j) { @@ -5830,7 +6719,7 @@ index a4f1a371299..e5a792583b3 100644 } break; } -@@ -1861,7 +1966,7 @@ static void write_fx_2_parameters(struct fx_write_context *fx) +@@ -1861,7 +1968,7 @@ static void write_fx_2_parameters(struct fx_write_context *fx) if (!is_type_supported_fx_2(ctx, var->data_type, &var->loc)) continue; @@ -5839,7 +6728,7 @@ index a4f1a371299..e5a792583b3 100644 value_offset = write_fx_2_initial_value(var, fx); flags = 0; -@@ -1884,19 +1989,28 @@ static void write_fx_2_annotation(struct hlsl_ir_var *var, struct fx_write_conte +@@ -1884,19 +1991,28 @@ static void write_fx_2_annotation(struct hlsl_ir_var *var, struct fx_write_conte struct vkd3d_bytecode_buffer *buffer = &fx->structured; uint32_t desc_offset, value_offset; @@ -5869,7 +6758,7 @@ index a4f1a371299..e5a792583b3 100644 }; static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) -@@ -1959,12 +2073,16 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) +@@ -1959,12 +2075,16 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) return fx_write_context_cleanup(&fx); } @@ -5886,7 +6775,7 @@ index a4f1a371299..e5a792583b3 100644 .are_child_effects_supported = true, }; -@@ -2001,7 +2119,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl +@@ -2001,7 +2121,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl for (j = 0; j < comp_count; ++j) { @@ -5895,7 +6784,7 @@ index a4f1a371299..e5a792583b3 100644 value++; } break; -@@ -2018,8 +2136,8 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl +@@ -2018,8 +2138,8 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl for (j = 0; j < type->e.record.field_count; ++j) { @@ -5906,7 +6795,7 @@ index a4f1a371299..e5a792583b3 100644 } break; } -@@ -2057,13 +2175,9 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st +@@ -2057,13 +2177,9 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st struct vkd3d_bytecode_buffer *buffer = &fx->structured; uint32_t name_offset, type_offset, value_offset; uint32_t semantic_offset, flags = 0; @@ -5921,7 +6810,7 @@ index a4f1a371299..e5a792583b3 100644 type_offset = write_type(var->data_type, fx); name_offset = write_string(var->name, fx); -@@ -2163,7 +2277,7 @@ static uint32_t write_fx_4_state_numeric_value(struct hlsl_ir_constant *value, s +@@ -2163,7 +2279,7 @@ static uint32_t write_fx_4_state_numeric_value(struct hlsl_ir_constant *value, s } put_u32_unaligned(buffer, type); @@ -5930,7 +6819,7 @@ index a4f1a371299..e5a792583b3 100644 } return offset; -@@ -2576,18 +2690,7 @@ static const struct rhs_named_value null_values[] = +@@ -2576,18 +2692,7 @@ static const struct rhs_named_value null_values[] = { NULL } }; @@ -5950,7 +6839,7 @@ index a4f1a371299..e5a792583b3 100644 { { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, -@@ -2655,7 +2758,7 @@ fx_4_states[] = +@@ -2655,7 +2760,7 @@ fx_4_states[] = { "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 }, }; @@ -5959,7 +6848,7 @@ index a4f1a371299..e5a792583b3 100644 { { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, -@@ -2668,45 +2771,61 @@ static const struct fx_4_state fx_5_blend_states[] = +@@ -2668,45 +2773,61 @@ static const struct fx_4_state fx_5_blend_states[] = { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, }; @@ -6034,7 +6923,7 @@ index a4f1a371299..e5a792583b3 100644 for (i = 0; i < table.count; ++i) { -@@ -2992,21 +3111,34 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h +@@ -2992,21 +3113,34 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h return decompose_fx_4_state_block_expand_array(var, block, entry_index, fx); } @@ -6077,7 +6966,7 @@ index a4f1a371299..e5a792583b3 100644 for (i = 0; i < block->count; ++i) { -@@ -3017,27 +3149,29 @@ static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_i +@@ -3017,27 +3151,29 @@ static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_i continue; /* Resolve special constant names and property names. */ @@ -6113,7 +7002,7 @@ index a4f1a371299..e5a792583b3 100644 } } -@@ -3212,6 +3346,8 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx +@@ -3212,6 +3348,8 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx size = 0; LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { @@ -6122,7 +7011,7 @@ index a4f1a371299..e5a792583b3 100644 if (!is_numeric_fx_4_type(var->data_type)) continue; -@@ -3219,7 +3355,9 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx +@@ -3219,7 +3357,9 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx continue; write_fx_4_numeric_variable(var, shared, fx); @@ -6133,7 +7022,7 @@ index a4f1a371299..e5a792583b3 100644 ++count; } -@@ -3446,6 +3584,7 @@ int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) +@@ -3446,6 +3586,7 @@ int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) struct fx_parser { @@ -6141,7 +7030,7 @@ index a4f1a371299..e5a792583b3 100644 const uint8_t *ptr, *start, *end; struct vkd3d_shader_message_context *message_context; struct vkd3d_string_buffer buffer; -@@ -3572,20 +3711,43 @@ static void parse_fx_print_indent(struct fx_parser *parser) +@@ -3572,20 +3713,43 @@ static void parse_fx_print_indent(struct fx_parser *parser) vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); } @@ -6151,7 +7040,9 @@ index a4f1a371299..e5a792583b3 100644 { - const char *ptr; + uint32_t len; -+ + +- fx_parser_read_unstructured(parser, size, offset, sizeof(*size)); +- ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size); + if (s) + len = strnlen(s, max_len); + if (!s || len == max_len) @@ -6160,14 +7051,12 @@ index a4f1a371299..e5a792583b3 100644 + return; + } -- fx_parser_read_unstructured(parser, size, offset, sizeof(*size)); -- ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size); +- if (!ptr) + 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); +} - -- if (!ptr) ++ +static void fx_2_parse_string_literal(struct fx_parser *parser, uint32_t offset, + bool unstructured, const char *prefix, const char *suffix) +{ @@ -6193,7 +7082,7 @@ index a4f1a371299..e5a792583b3 100644 } static unsigned int fx_get_fx_2_type_size(struct fx_parser *parser, uint32_t *offset) -@@ -3742,15 +3904,12 @@ static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset) +@@ -3742,15 +3906,12 @@ static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset) uint32_t semantic; uint32_t element_count; } var; @@ -6210,7 +7099,7 @@ index a4f1a371299..e5a792583b3 100644 if (var.element_count) vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count); } -@@ -3764,7 +3923,8 @@ static bool is_fx_2_sampler(uint32_t type) +@@ -3764,7 +3925,8 @@ static bool is_fx_2_sampler(uint32_t type) || type == D3DXPT_SAMPLERCUBE; } @@ -6220,7 +7109,7 @@ index a4f1a371299..e5a792583b3 100644 static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, uint32_t offset) -@@ -3789,7 +3949,7 @@ static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, +@@ -3789,7 +3951,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); @@ -6229,7 +7118,7 @@ index a4f1a371299..e5a792583b3 100644 } parse_fx_end_indent(parser); parse_fx_print_indent(parser); -@@ -3867,15 +4027,25 @@ static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count) +@@ -3867,15 +4029,25 @@ static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count) vkd3d_string_buffer_printf(&parser->buffer, ">"); } @@ -6260,7 +7149,7 @@ index a4f1a371299..e5a792583b3 100644 vkd3d_string_buffer_printf(&parser->buffer, "%s", state->name); if (state->array_size > 1) vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry->lhs_index); -@@ -3886,7 +4056,7 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a +@@ -3886,7 +4058,7 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a } vkd3d_string_buffer_printf(&parser->buffer, " = "); @@ -6269,7 +7158,7 @@ index a4f1a371299..e5a792583b3 100644 { const struct rhs_named_value *ptr = state->values; uint32_t value; -@@ -3910,13 +4080,14 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a +@@ -3910,13 +4082,14 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a } else if (state) { @@ -6287,7 +7176,7 @@ index a4f1a371299..e5a792583b3 100644 } else if (state->type == FX_VERTEXSHADER || state->type == FX_PIXELSHADER) { -@@ -3951,18 +4122,14 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) +@@ -3951,18 +4124,14 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) uint32_t annotation_count; uint32_t assignment_count; } pass; @@ -6307,7 +7196,7 @@ index a4f1a371299..e5a792583b3 100644 fx_parse_fx_2_annotations(parser, technique.annotation_count); vkd3d_string_buffer_printf(&parser->buffer, "\n"); -@@ -3973,10 +4140,9 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) +@@ -3973,10 +4142,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)); @@ -6319,7 +7208,7 @@ index a4f1a371299..e5a792583b3 100644 fx_parse_fx_2_annotations(parser, pass.annotation_count); vkd3d_string_buffer_printf(&parser->buffer, "\n"); -@@ -3990,7 +4156,7 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) +@@ -3990,7 +4158,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)); @@ -6328,7 +7217,7 @@ index a4f1a371299..e5a792583b3 100644 } parse_fx_end_indent(parser); -@@ -4112,8 +4278,7 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) +@@ -4112,8 +4280,7 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) { parse_fx_start_indent(parser); parse_fx_print_indent(parser); @@ -6338,7 +7227,7 @@ index a4f1a371299..e5a792583b3 100644 parse_fx_end_indent(parser); } else if (type == D3DXPT_PIXELSHADER || type == D3DXPT_VERTEXSHADER) -@@ -4135,38 +4300,18 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) +@@ -4135,38 +4302,18 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) fx_parser_skip(parser, align(size, 4)); } @@ -6346,7 +7235,8 @@ index a4f1a371299..e5a792583b3 100644 -{ - const uint32_t *data = blob; - unsigned int i, j, n; -- ++static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size); + - size /= sizeof(*data); - i = 0; - while (i < size) @@ -6359,8 +7249,7 @@ index a4f1a371299..e5a792583b3 100644 - vkd3d_string_buffer_printf(&parser->buffer, "\n"); - } -} -+static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size); - +- -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) { @@ -6384,7 +7273,7 @@ index a4f1a371299..e5a792583b3 100644 if (parser->ptr <= end) { -@@ -4180,16 +4325,11 @@ static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size +@@ -4180,17 +4327,38 @@ static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size "Malformed blob entry in the array selector."); } @@ -6399,10 +7288,37 @@ index a4f1a371299..e5a792583b3 100644 vkd3d_string_buffer_printf(&parser->buffer, "selector blob size %u\n", blob_size); - fx_dump_blob(parser, blob, blob_size); + fx_2_parse_fxlvm_expression(parser, blob, blob_size); ++ } ++} ++ ++static void fx_2_parse_code_blob(struct fx_parser *parser, const uint32_t *blob, uint32_t size) ++{ ++ uint32_t tag; ++ ++ if (size < sizeof(tag)) ++ return; ++ ++ tag = *blob; ++ ++ if (tag == TAG_FX20) ++ { ++ fx_2_parse_fxlvm_expression(parser, blob, size); ++ return; } ++ ++ tag >>= 16; ++ if (tag == 0xfffe || tag == 0xffff) ++ { ++ fx_parse_shader_blob(parser, VKD3D_SHADER_SOURCE_D3D_BYTECODE, blob, size); ++ vkd3d_string_buffer_printf(&parser->buffer, "\n"); ++ return; ++ } ++ ++ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Unrecognized code blob type, tag 0x%08x.", *blob); } -@@ -4203,7 +4343,7 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) + static void fx_parse_fx_2_complex_state(struct fx_parser *parser) +@@ -4203,7 +4371,7 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) uint32_t state; uint32_t assignment_type; } state; @@ -6411,7 +7327,7 @@ index a4f1a371299..e5a792583b3 100644 uint32_t size; fx_parser_read_u32s(parser, &state, sizeof(state)); -@@ -4219,28 +4359,29 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) +@@ -4219,28 +4387,29 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) state.technique, state.index, state.state); } @@ -6440,7 +7356,7 @@ index a4f1a371299..e5a792583b3 100644 data = fx_parser_get_ptr(parser, size); - fx_dump_blob(parser, data, size); + vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size); -+ fx_2_parse_fxlvm_expression(parser, data, size); ++ fx_2_parse_code_blob(parser, data, size); fx_parser_skip(parser, align(size, 4)); } + else @@ -6451,7 +7367,7 @@ index a4f1a371299..e5a792583b3 100644 } static void fx_2_parse(struct fx_parser *parser) -@@ -4457,6 +4598,11 @@ static void fx_parse_fx_4_numeric_variables(struct fx_parser *parser, uint32_t c +@@ -4457,6 +4626,11 @@ static void fx_parse_fx_4_numeric_variables(struct fx_parser *parser, uint32_t c semantic = fx_4_get_string(parser, var.semantic); vkd3d_string_buffer_printf(&parser->buffer, " : %s", semantic); } @@ -6463,7 +7379,7 @@ index a4f1a371299..e5a792583b3 100644 fx_parse_fx_4_annotations(parser); if (var.value) -@@ -4492,6 +4638,8 @@ static void fx_parse_buffers(struct fx_parser *parser) +@@ -4492,6 +4666,8 @@ static void fx_parse_buffers(struct fx_parser *parser) name = fx_4_get_string(parser, buffer.name); vkd3d_string_buffer_printf(&parser->buffer, "cbuffer %s", name); @@ -6472,7 +7388,7 @@ index a4f1a371299..e5a792583b3 100644 fx_parse_fx_4_annotations(parser); vkd3d_string_buffer_printf(&parser->buffer, "\n{\n"); -@@ -4598,7 +4746,7 @@ static bool fx_4_object_has_initializer(const struct fx_4_binary_type *type) +@@ -4598,7 +4774,7 @@ static bool fx_4_object_has_initializer(const struct fx_4_binary_type *type) static int fx_4_state_id_compare(const void *a, const void *b) { @@ -6481,7 +7397,7 @@ index a4f1a371299..e5a792583b3 100644 int id = *(int *)a; return id - state->id; -@@ -4609,7 +4757,7 @@ static const struct +@@ -4609,7 +4785,7 @@ static const struct uint32_t opcode; const char *name; } @@ -6490,7 +7406,7 @@ index a4f1a371299..e5a792583b3 100644 { { 0x100, "mov" }, { 0x101, "neg" }, -@@ -4634,6 +4782,8 @@ fx_4_fxlc_opcodes[] = +@@ -4634,6 +4810,8 @@ fx_4_fxlc_opcodes[] = { 0x13a, "ceil" }, { 0x200, "min" }, { 0x201, "max" }, @@ -6499,7 +7415,7 @@ index a4f1a371299..e5a792583b3 100644 { 0x204, "add" }, { 0x205, "mul" }, { 0x206, "atan2" }, -@@ -4659,29 +4809,24 @@ fx_4_fxlc_opcodes[] = +@@ -4659,29 +4837,24 @@ fx_4_fxlc_opcodes[] = { 0x236, "ushr" }, { 0x301, "movc" }, { 0x500, "dot" }, @@ -6535,7 +7451,7 @@ index a4f1a371299..e5a792583b3 100644 struct fx_4_ctab_entry { uint32_t name; -@@ -4693,10 +4838,29 @@ struct fx_4_ctab_entry +@@ -4693,10 +4866,29 @@ struct fx_4_ctab_entry uint32_t default_value; }; @@ -6567,7 +7483,7 @@ index a4f1a371299..e5a792583b3 100644 const struct fx_4_ctab_entry *constants; uint32_t ctab_offset; -@@ -4707,7 +4871,45 @@ struct fxlvm_code +@@ -4707,7 +4899,45 @@ struct fxlvm_code bool scalar; }; @@ -6614,7 +7530,7 @@ index a4f1a371299..e5a792583b3 100644 { unsigned int comp_count = code->scalar ? 1 : code->comp_count; static const char comp[] = "xyzw"; -@@ -4716,44 +4918,137 @@ static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlv +@@ -4716,44 +4946,137 @@ static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlv vkd3d_string_buffer_printf(&parser->buffer, ".%.*s", comp_count, &comp[addr % 4]); } @@ -6622,8 +7538,7 @@ index a4f1a371299..e5a792583b3 100644 - const struct fx_4_fxlc_argument *arg, const struct fxlvm_code *code) +static void fx_print_fxlc_register(struct fx_parser *parser, uint32_t reg_type, + uint32_t address, uint32_t index_type, uint32_t index_address, struct fxlvm_code *code) - { -- uint32_t i, offset, register_index = arg->address / 4; /* Address counts in components. */ ++{ + static const char *table_names[FX_FXLC_REG_MAX + 1] = + { + [FX_FXLC_REG_LITERAL] = "imm", @@ -6633,12 +7548,10 @@ index a4f1a371299..e5a792583b3 100644 + [FX_FXLC_REG_TEMP] = "r", + }; + uint32_t reg_index = address / 4; - -- for (i = 0; i < code->ctab_count; ++i) ++ + if (parser->source_type == VKD3D_SHADER_SOURCE_TX + && (reg_type == FX_FXLC_REG_INPUT || reg_type == FX_FXLC_REG_OUTPUT)) - { -- const struct fx_4_ctab_entry *c = &code->constants[i]; ++ { + if (reg_type == FX_FXLC_REG_INPUT) + { + if (reg_index == 0) @@ -6662,34 +7575,37 @@ index a4f1a371299..e5a792583b3 100644 + } + fx_parse_print_swizzle(parser, code, address); +} ++ ++static void fx_parse_fxlc_constant_argument(struct fx_parser *parser, ++ const struct fxlc_arg *arg, const struct fxlvm_code *code) + { +- uint32_t i, offset, register_index = arg->address / 4; /* Address counts in components. */ ++ uint32_t register_index = arg->address / 4; /* Address counts in components. */ + +- for (i = 0; i < code->ctab_count; ++i) ++ if (code->ctab_count) + { +- const struct fx_4_ctab_entry *c = &code->constants[i]; ++ uint32_t i, offset; - if (register_index < c->register_index || register_index - c->register_index >= c->register_count) - continue; -+static void fx_parse_fxlc_constant_argument(struct fx_parser *parser, -+ const struct fxlc_arg *arg, const struct fxlvm_code *code) -+{ -+ uint32_t register_index = arg->address / 4; /* Address counts in components. */ - -- vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); -+ if (code->ctab_count) -+ { -+ uint32_t i, offset; - -- /* Register offset within variable */ -- offset = arg->address - c->register_index * 4; + for (i = 0; i < code->ctab_count; ++i) + { + const struct fx_4_ctab_entry *c = &code->constants[i]; +- vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); ++ if (register_index < c->register_index || register_index - c->register_index >= c->register_count) ++ continue; + +- /* Register offset within variable */ +- offset = arg->address - c->register_index * 4; ++ vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); + - if (offset / 4) - vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4); - fx_4_parse_print_swizzle(parser, code, offset); - return; -+ if (register_index < c->register_index || register_index - c->register_index >= c->register_count) -+ continue; -+ -+ vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); -+ + /* Register offset within variable */ + offset = arg->address - c->register_index * 4; + @@ -6747,18 +7663,18 @@ index a4f1a371299..e5a792583b3 100644 + "Unexpected register type %u.", arg->reg_type); + return; + } -+ + +- switch (arg.reg_type) + if (arg->index.reg_type > FX_FXLC_REG_MAX) -+ { + { +- case FX_4_FXLC_REG_LITERAL: + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Unexpected index register type %u.", arg->index.reg_type); + return; + } - -- switch (arg.reg_type) ++ + if (arg->indexed) - { -- case FX_4_FXLC_REG_LITERAL: ++ { + fx_print_fxlc_register(parser, arg->reg_type, arg->address, arg->index.reg_type, + arg->index.address, code); + return; @@ -6773,7 +7689,7 @@ index a4f1a371299..e5a792583b3 100644 { vkd3d_string_buffer_printf(&parser->buffer, "()"); parser->failed = true; -@@ -4761,42 +5056,125 @@ static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, +@@ -4761,42 +5084,131 @@ static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, } vkd3d_string_buffer_printf(&parser->buffer, "("); @@ -6810,10 +7726,10 @@ index a4f1a371299..e5a792583b3 100644 default: - vkd3d_string_buffer_printf(&parser->buffer, "", arg.reg_type); + vkd3d_string_buffer_printf(&parser->buffer, "", arg->reg_type); -+ break; -+ } -+} -+ + break; + } + } + +static void fx_parse_fxlvm_expression(struct fx_parser *parser, struct fxlvm_code *code) +{ + struct fxlc_arg args[9]; @@ -6840,7 +7756,7 @@ index a4f1a371299..e5a792583b3 100644 + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Unexpected instruction source count %u.", src_count); - break; ++ break; + } + + /* Sources entries are followed by the destination, first read them all. @@ -6869,7 +7785,7 @@ index a4f1a371299..e5a792583b3 100644 + } + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); - } ++ } + + parse_fx_end_indent(parser); +} @@ -6897,9 +7813,15 @@ index a4f1a371299..e5a792583b3 100644 + code.ptr = find_d3dbc_section(blob, count, TAG_FXLC, &count); + code.end = code.ptr + count; + ++ if (!code.ptr) ++ { ++ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to locate expression code section."); ++ return; ++ } ++ + fx_parse_fxlvm_expression(parser, &code); - } - ++} ++ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offset) { struct vkd3d_shader_dxbc_section_desc *section, fxlc, cli4, ctab; @@ -6914,7 +7836,7 @@ index a4f1a371299..e5a792583b3 100644 offset = fx_parser_read_unstructured(parser, &size, offset, sizeof(size)); -@@ -4832,8 +5210,8 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse +@@ -4832,8 +5244,8 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse { uint32_t cli4_offset = offset + (size_t)cli4.data.code - (size_t)dxbc.code; @@ -6925,7 +7847,7 @@ index a4f1a371299..e5a792583b3 100644 } if (ctab.data.code) -@@ -4849,47 +5227,10 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse +@@ -4849,47 +5261,10 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse ctab_offset + consts_offset, code.ctab_count * sizeof(*code.constants)); } @@ -6933,7 +7855,9 @@ index a4f1a371299..e5a792583b3 100644 - offset = fx_parser_read_unstructured(parser, &ins_count, offset, sizeof(ins_count)); - - parse_fx_start_indent(parser); -- ++ code.ptr = fxlc.data.code; ++ code.end = (uint32_t *)((uint8_t *)fxlc.data.code + fxlc.data.size); + - for (i = 0; i < ins_count; ++i) - { - uint32_t instr, opcode, src_count; @@ -6968,15 +7892,13 @@ index a4f1a371299..e5a792583b3 100644 - - vkd3d_string_buffer_printf(&parser->buffer, "\n"); - } -+ code.ptr = fxlc.data.code; -+ code.end = (uint32_t *)((uint8_t *)fxlc.data.code + fxlc.data.size); - +- - parse_fx_end_indent(parser); + fx_parse_fxlvm_expression(parser, &code); } static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32_t count, -@@ -4919,12 +5260,12 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 +@@ -4919,12 +5294,12 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 }; const struct rhs_named_value *named_value; struct fx_5_shader shader = { 0 }; @@ -6992,7 +7914,7 @@ index a4f1a371299..e5a792583b3 100644 for (i = 0; i < count; ++i) { -@@ -4995,6 +5336,8 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 +@@ -4995,6 +5370,8 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 vkd3d_string_buffer_printf(&parser->buffer, "0x%.2x", value.u); else if (state->type == FX_UINT) vkd3d_string_buffer_printf(&parser->buffer, "%u", value.u); @@ -7001,7 +7923,7 @@ index a4f1a371299..e5a792583b3 100644 else if (state->type == FX_FLOAT) vkd3d_string_buffer_printf(&parser->buffer, "%g", value.f); -@@ -5374,6 +5717,7 @@ static void fx_parser_init(struct fx_parser *parser, const struct vkd3d_shader_c +@@ -5374,6 +5751,7 @@ static void fx_parser_init(struct fx_parser *parser, const struct vkd3d_shader_c struct vkd3d_shader_message_context *message_context) { memset(parser, 0, sizeof(*parser)); @@ -7009,7 +7931,7 @@ index a4f1a371299..e5a792583b3 100644 parser->start = compile_info->source.code; parser->ptr = compile_info->source.code; parser->end = (uint8_t *)compile_info->source.code + compile_info->source.size; -@@ -5434,3 +5778,38 @@ int fx_parse(const struct vkd3d_shader_compile_info *compile_info, +@@ -5434,3 +5812,38 @@ int fx_parse(const struct vkd3d_shader_compile_info *compile_info, return VKD3D_ERROR_INVALID_SHADER; return VKD3D_OK; } @@ -7049,9 +7971,89 @@ index a4f1a371299..e5a792583b3 100644 + return VKD3D_OK; +} diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index e4497b9ac5b..b3e3d10791d 100644 +index e4497b9ac5b..dfe0a40ddf0 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -328,12 +328,12 @@ static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_ca + } + + static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vkd3d_glsl_generator *gen, +- const char *src, enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type, unsigned int size) ++ const char *src, enum vsir_data_type dst_data_type, enum vsir_data_type src_data_type, unsigned int size) + { +- if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) +- dst_data_type = VKD3D_DATA_FLOAT; +- if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM) +- src_data_type = VKD3D_DATA_FLOAT; ++ if (dst_data_type == VSIR_DATA_UNORM || dst_data_type == VSIR_DATA_SNORM) ++ dst_data_type = VSIR_DATA_F32; ++ if (src_data_type == VSIR_DATA_UNORM || src_data_type == VSIR_DATA_SNORM) ++ src_data_type = VSIR_DATA_F32; + + if (dst_data_type == src_data_type) + { +@@ -341,14 +341,14 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk + return; + } + +- if (src_data_type == VKD3D_DATA_FLOAT) ++ if (src_data_type == VSIR_DATA_F32) + { + switch (dst_data_type) + { +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + vkd3d_string_buffer_printf(dst, "floatBitsToInt(%s)", src); + return; +- case VKD3D_DATA_UINT: ++ case VSIR_DATA_U32: + vkd3d_string_buffer_printf(dst, "floatBitsToUint(%s)", src); + return; + default: +@@ -356,14 +356,14 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk + } + } + +- if (src_data_type == VKD3D_DATA_UINT) ++ if (src_data_type == VSIR_DATA_U32) + { + switch (dst_data_type) + { +- case VKD3D_DATA_FLOAT: ++ case VSIR_DATA_F32: + vkd3d_string_buffer_printf(dst, "uintBitsToFloat(%s)", src); + return; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + if (size == 1) + vkd3d_string_buffer_printf(dst, "int(%s)", src); + else +@@ -381,11 +381,11 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk + } + + static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, +- const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) ++ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vsir_data_type data_type) + { + const struct vkd3d_shader_register *reg = &vsir_src->reg; + struct vkd3d_string_buffer *register_name, *str; +- enum vkd3d_data_type src_data_type; ++ enum vsir_data_type src_data_type; + unsigned int size; + + register_name = vkd3d_string_buffer_get(&gen->string_buffers); +@@ -395,9 +395,9 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd + "Internal compiler error: Unhandled 'non-uniform' modifier."); + + if (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_THREADID) +- src_data_type = VKD3D_DATA_UINT; ++ src_data_type = VSIR_DATA_U32; + else +- src_data_type = VKD3D_DATA_FLOAT; ++ src_data_type = VSIR_DATA_F32; + + shader_glsl_print_register_name(register_name, gen, reg); + @@ -421,6 +421,9 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd case VKD3DSPSM_ABS: vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); @@ -7062,7 +8064,14 @@ index e4497b9ac5b..b3e3d10791d 100644 default: vkd3d_string_buffer_printf(buffer, "(%s)", vsir_src->modifiers, str->buffer); -@@ -495,6 +498,9 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g +@@ -489,12 +492,15 @@ static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, stru + } + + static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_glsl_generator *gen, +- struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, va_list args) ++ struct glsl_dst *dst, enum vsir_data_type data_type, const char *format, va_list args) + { + struct vkd3d_string_buffer *buffer = gen->buffer; uint32_t modifiers = dst->vsir->modifiers; bool close = true; @@ -7072,6 +8081,32 @@ index e4497b9ac5b..b3e3d10791d 100644 if (dst->vsir->shift) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift); +@@ -513,13 +519,13 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled destination register data type %#x.", data_type); + /* fall through */ +- case VKD3D_DATA_FLOAT: ++ case VSIR_DATA_F32: + close = false; + break; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + vkd3d_string_buffer_printf(buffer, "intBitsToFloat("); + break; +- case VKD3D_DATA_UINT: ++ case VSIR_DATA_U32: + vkd3d_string_buffer_printf(buffer, "uintBitsToFloat("); + break; + } +@@ -544,7 +550,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( + } + + static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3d_glsl_generator *gen, +- struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, ...) ++ struct glsl_dst *dst, enum vsir_data_type data_type, const char *format, ...) + { + va_list args; + @@ -555,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) @@ -7087,6 +8122,24 @@ index e4497b9ac5b..b3e3d10791d 100644 } static void shader_glsl_binop(struct vkd3d_glsl_generator *gen, +@@ -789,7 +797,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_resource_type resource_type; + struct vkd3d_string_buffer *fetch; +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + struct glsl_src coord; + struct glsl_dst dst; + uint32_t coord_mask; +@@ -818,7 +826,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + sample_count = 1; +- data_type = VKD3D_DATA_FLOAT; ++ data_type = VSIR_DATA_F32; + } + + if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -843,7 +851,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) { @@ -7096,8 +8149,12 @@ index e4497b9ac5b..b3e3d10791d 100644 shader_glsl_print_src(fetch, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, ins->src[0].reg.data_type); else if (sample_count == 1) /* If the resource isn't a true multisample resource, this is the -@@ -907,14 +915,14 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk - enum vkd3d_data_type data_type; +@@ -904,17 +912,17 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk + enum vkd3d_shader_resource_type resource_type; + unsigned int component_idx, coord_size; + struct vkd3d_string_buffer *sample; +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; struct glsl_dst dst; - bias = ins->opcode == VKD3DSIH_SAMPLE_B; @@ -7118,6 +8175,78 @@ index e4497b9ac5b..b3e3d10791d 100644 resource = &ins->src[1 + dynamic_offset]; sampler = &ins->src[2 + dynamic_offset]; +@@ -938,7 +946,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk + "Internal compiler error: Undeclared resource descriptor %u.", resource_id); + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; +- data_type = VKD3D_DATA_FLOAT; ++ data_type = VSIR_DATA_F32; + } + + if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) +@@ -1053,7 +1061,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s + enum vkd3d_shader_resource_type resource_type; + unsigned int uav_id, uav_idx, uav_space; + struct vkd3d_string_buffer *load; +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + struct glsl_src coord; + struct glsl_dst dst; + uint32_t coord_mask; +@@ -1076,7 +1084,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s + "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); + uav_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; +- data_type = VKD3D_DATA_FLOAT; ++ data_type = VSIR_DATA_F32; + } + + if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) +@@ -1113,7 +1121,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const + enum vkd3d_shader_resource_type resource_type; + unsigned int uav_id, uav_idx, uav_space; + struct vkd3d_string_buffer *image_data; +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + struct glsl_src image_coord; + uint32_t coord_mask; + +@@ -1135,7 +1143,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const + "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); + uav_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; +- data_type = VKD3D_DATA_FLOAT; ++ data_type = VSIR_DATA_F32; + } + + if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) +@@ -1156,19 +1164,19 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const + { + switch (data_type) + { +- case VKD3D_DATA_UINT: +- vkd3d_string_buffer_printf(image_data, "uvec4("); +- break; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + vkd3d_string_buffer_printf(image_data, "ivec4("); + break; ++ case VSIR_DATA_U32: ++ vkd3d_string_buffer_printf(image_data, "uvec4("); ++ break; + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled data type %#x.", data_type); + /* fall through */ +- case VKD3D_DATA_FLOAT: +- case VKD3D_DATA_UNORM: +- case VKD3D_DATA_SNORM: ++ case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: + vkd3d_string_buffer_printf(image_data, "vec4("); + break; + } @@ -1242,37 +1250,6 @@ static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3 glsl_dst_cleanup(&dst, &gen->string_buffers); } @@ -7407,6 +8536,61 @@ index e4497b9ac5b..b3e3d10791d 100644 shader_glsl_binop(gen, ins, "^"); break; default: +@@ -1789,22 +1766,22 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge + + switch (uav->resource_data_type) + { +- case VKD3D_DATA_UINT: +- image_type_prefix = "u"; +- read_format = "r32ui"; +- break; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + image_type_prefix = "i"; + read_format = "r32i"; + break; ++ case VSIR_DATA_U32: ++ image_type_prefix = "u"; ++ read_format = "r32ui"; ++ break; + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled data type %#x for UAV %u.", + uav->resource_data_type, uav->register_id); + /* fall through */ +- case VKD3D_DATA_FLOAT: +- case VKD3D_DATA_UNORM: +- case VKD3D_DATA_SNORM: ++ case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: + image_type_prefix = ""; + read_format = "r32f"; + break; +@@ -2018,16 +1995,16 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator + + switch (srv->resource_data_type) + { +- case VKD3D_DATA_UINT: +- sampler_type_prefix = "u"; ++ case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: ++ sampler_type_prefix = ""; + break; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + sampler_type_prefix = "i"; + break; +- case VKD3D_DATA_FLOAT: +- case VKD3D_DATA_UNORM: +- case VKD3D_DATA_SNORM: +- sampler_type_prefix = ""; ++ case VSIR_DATA_U32: ++ sampler_type_prefix = "u"; + break; + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, @@ -2313,7 +2290,7 @@ static void shader_glsl_handle_global_flags(struct vkd3d_string_buffer *buffer, flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; } @@ -7416,11 +8600,184 @@ index e4497b9ac5b..b3e3d10791d 100644 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)flags); } +@@ -2348,9 +2325,9 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) + + static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struct vkd3d_shader_code *out) + { +- const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions; + struct vkd3d_string_buffer *buffer = gen->buffer; +- unsigned int i; ++ struct vkd3d_shader_instruction *ins; ++ struct vsir_program_iterator it; + void *code; + + MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); +@@ -2365,9 +2342,11 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc + + ++gen->indent; + shader_glsl_shader_prologue(gen); +- for (i = 0; i < instructions->count; ++i) ++ ++ it = vsir_program_iterator(&gen->program->instructions); ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- vkd3d_glsl_handle_instruction(gen, &instructions->elements[i]); ++ vkd3d_glsl_handle_instruction(gen, ins); + } + + vkd3d_string_buffer_printf(buffer, "}\n"); +@@ -2465,6 +2444,9 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, + if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) + return ret; + ++ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0) ++ return ret; ++ + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); + diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 653ddd2e8be..678ed324919 100644 +index 653ddd2e8be..62335086e20 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -3531,21 +3531,7 @@ static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_der +@@ -2062,7 +2062,7 @@ struct hlsl_ir_node *hlsl_block_add_load_component(struct hlsl_ctx *ctx, struct + return &load->node; + } + +-static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, ++static struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_resource_load *load; +@@ -2098,18 +2098,23 @@ static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, + load->sampling_dim = params->sampling_dim; + if (load->sampling_dim == HLSL_SAMPLER_DIM_GENERIC) + load->sampling_dim = hlsl_deref_get_type(ctx, &load->resource)->sampler_dim; +- return &load->node; ++ return load; + } + + struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) + { +- return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc)); ++ struct hlsl_ir_resource_load *load = hlsl_new_resource_load(ctx, params, loc); ++ ++ if (load && load->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ hlsl_src_from_node(&load->byte_offset, hlsl_block_add_uint_constant(ctx, block, 0, loc)); ++ ++ return append_new_instr(ctx, block, &load->node); + } + +-static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type, +- const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, +- const struct vkd3d_shader_location *loc) ++static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, ++ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, ++ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_resource_store *store; + +@@ -2117,6 +2122,7 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h + return NULL; + init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc); + store->store_type = type; ++ store->writemask = writemask; + + hlsl_copy_deref(ctx, &store->resource, resource); + hlsl_src_from_node(&store->coords, coords); +@@ -2126,9 +2132,9 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h + + void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, +- struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) ++ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) + { +- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc)); ++ append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc)); + } + + struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count, +@@ -2377,6 +2383,19 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index) + return false; + } + ++bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index) ++{ ++ if (index->val.node->type == HLSL_IR_LOAD) ++ { ++ struct hlsl_ir_load *load = hlsl_ir_load(index->val.node); ++ return load->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED; ++ } ++ ++ if (index->val.node->type == HLSL_IR_INDEX) ++ return hlsl_index_chain_has_tgsm_access(hlsl_ir_index(index->val.node)); ++ return false; ++} ++ + static struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) + { +@@ -2648,6 +2667,7 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, + vkd3d_free(dst); + return NULL; + } ++ clone_src(map, &dst->byte_offset, &src->byte_offset); + clone_src(map, &dst->coords, &src->coords); + clone_src(map, &dst->lod, &src->lod); + clone_src(map, &dst->ddx, &src->ddx); +@@ -2668,6 +2688,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, + return NULL; + init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc); + dst->store_type = src->store_type; ++ dst->writemask = src->writemask; + if (!clone_deref(ctx, map, &dst->resource, &src->resource)) + { + vkd3d_free(dst); +@@ -2985,6 +3006,17 @@ bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const + return ret; + } + ++struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) ++{ ++ struct clone_instr_map map = {0}; ++ struct hlsl_ir_node *ret; ++ ++ ret = clone_instr(ctx, &map, instr); ++ vkd3d_free(map.instrs); ++ ++ return ret; ++} ++ + struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, + struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, + const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) +@@ -2998,7 +3030,6 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, + decl->return_type = return_type; + decl->parameters = *parameters; + decl->loc = *loc; +- list_init(&decl->extern_vars); + + if (!hlsl_types_are_equal(return_type, ctx->builtin_types.Void)) + { +@@ -3220,12 +3251,14 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl + return; + } + +- VKD3D_ASSERT(hlsl_is_numeric_type(type->e.resource.format)); +- VKD3D_ASSERT(type->e.resource.format->e.numeric.type < ARRAY_SIZE(base_types)); + if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) + { + vkd3d_string_buffer_printf(buffer, "Buffer<"); + } ++ else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ { ++ vkd3d_string_buffer_printf(buffer, "StructuredBuffer<"); ++ } + else + { + VKD3D_ASSERT(type->sampler_dim < ARRAY_SIZE(dimensions)); +@@ -3531,21 +3564,7 @@ static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_der const char *debug_hlsl_writemask(unsigned int writemask) { @@ -7443,7 +8800,7 @@ index 653ddd2e8be..678ed324919 100644 } const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size) -@@ -3652,6 +3638,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) +@@ -3652,6 +3671,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_LOG2] = "log2", [HLSL_OP1_LOGIC_NOT] = "!", [HLSL_OP1_NEG] = "-", @@ -7451,7 +8808,38 @@ index 653ddd2e8be..678ed324919 100644 [HLSL_OP1_RCP] = "rcp", [HLSL_OP1_REINTERPRET] = "reinterpret", [HLSL_OP1_ROUND] = "round", -@@ -3844,11 +3831,11 @@ static void dump_ir_string(struct vkd3d_string_buffer *buffer, const struct hlsl +@@ -3776,6 +3796,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru + dump_deref(buffer, &load->resource); + vkd3d_string_buffer_printf(buffer, ", sampler = "); + dump_deref(buffer, &load->sampler); ++ if (load->byte_offset.node) ++ { ++ vkd3d_string_buffer_printf(buffer, ", byte_offset = "); ++ dump_src(buffer, &load->byte_offset); ++ } + if (load->coords.node) + { + vkd3d_string_buffer_printf(buffer, ", coords = "); +@@ -3814,7 +3839,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru + vkd3d_string_buffer_printf(buffer, ")"); + } + +-static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) ++static void dump_ir_resource_store(struct hlsl_ctx *ctx, ++ struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) + { + static const char *const type_names[] = + { +@@ -3826,6 +3852,8 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str + VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names)); + vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]); + dump_deref(buffer, &store->resource); ++ if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->resource))) ++ vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask)); + if (store->coords.node) + { + vkd3d_string_buffer_printf(buffer, ", coords = "); +@@ -3844,11 +3872,11 @@ static void dump_ir_string(struct vkd3d_string_buffer *buffer, const struct hlsl vkd3d_string_buffer_printf(buffer, "\"%s\"", debugstr_a(string->string)); } @@ -7465,7 +8853,16 @@ index 653ddd2e8be..678ed324919 100644 vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask)); vkd3d_string_buffer_printf(buffer, " "); dump_src(buffer, &store->rhs); -@@ -4046,7 +4033,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, +@@ -4038,7 +4066,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, + break; + + case HLSL_IR_RESOURCE_STORE: +- dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr)); ++ dump_ir_resource_store(ctx, buffer, hlsl_ir_resource_store(instr)); + break; + + case HLSL_IR_STRING_CONSTANT: +@@ -4046,7 +4074,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, break; case HLSL_IR_STORE: @@ -7474,7 +8871,34 @@ index 653ddd2e8be..678ed324919 100644 break; case HLSL_IR_SWITCH: -@@ -4137,7 +4124,7 @@ void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) +@@ -4079,20 +4107,23 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, + } + } + +-void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func) ++void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func, ++ const char *description, const struct hlsl_block *processed_block) + { + struct vkd3d_string_buffer buffer; + size_t i; + + vkd3d_string_buffer_init(&buffer); +- vkd3d_string_buffer_printf(&buffer, "Dumping function %s.\n", func->func->name); ++ vkd3d_string_buffer_printf(&buffer, "Dumping %s \"%s\".\n", description, func->func->name); + vkd3d_string_buffer_printf(&buffer, "Function parameters:\n"); + for (i = 0; i < func->parameters.count; ++i) + { + dump_ir_var(ctx, &buffer, func->parameters.vars[i]); + vkd3d_string_buffer_printf(&buffer, "\n"); + } +- if (func->has_body) ++ if (processed_block) ++ dump_block(ctx, &buffer, processed_block); ++ else if (func->has_body) + dump_block(ctx, &buffer, &func->body); + + vkd3d_string_buffer_trace(&buffer); +@@ -4137,7 +4168,7 @@ void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) const struct hlsl_type *old_type = old->data_type, *new_type = new->data_type; struct hlsl_src *src, *next; @@ -7483,8 +8907,283 @@ index 653ddd2e8be..678ed324919 100644 { VKD3D_ASSERT(hlsl_is_numeric_type(new_type)); VKD3D_ASSERT(old_type->e.numeric.dimx == new_type->e.numeric.dimx); +@@ -4241,6 +4272,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) + { + hlsl_cleanup_deref(&load->sampler); + hlsl_cleanup_deref(&load->resource); ++ hlsl_src_remove(&load->byte_offset); + hlsl_src_remove(&load->coords); + hlsl_src_remove(&load->lod); + hlsl_src_remove(&load->ddx); +@@ -4865,8 +4897,9 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) + hlsl_release_string_buffer(ctx, name); + } + +-static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, +- const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context) ++static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_files, ++ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, ++ struct vkd3d_shader_message_context *message_context) + { + unsigned int i; + +@@ -4876,15 +4909,12 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil + + ctx->message_context = message_context; + +- if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files)))) +- return false; +- if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : ""))) +- { +- vkd3d_free(ctx->source_files); ++ ctx->source_files = source_files; ++ if (!vkd3d_shader_source_list_append(source_files, ++ compile_info->source_name ? compile_info->source_name : "")) + return false; +- } +- ctx->source_files_count = 1; +- ctx->location.source_name = ctx->source_files[0]; ++ ++ ctx->location.source_name = source_files->sources[0]; + ctx->location.line = ctx->location.column = 1; + vkd3d_string_buffer_cache_init(&ctx->string_buffers); + +@@ -4892,8 +4922,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil + + if (!(ctx->dummy_scope = hlsl_new_scope(ctx, NULL))) + { +- vkd3d_free((void *)ctx->source_files[0]); +- vkd3d_free(ctx->source_files); ++ vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); + return false; + } + hlsl_push_scope(ctx); +@@ -4978,9 +5007,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) + struct hlsl_type *type, *next_type; + unsigned int i; + +- for (i = 0; i < ctx->source_files_count; ++i) +- vkd3d_free((void *)ctx->source_files[i]); +- vkd3d_free(ctx->source_files); + vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); + + rb_destroy(&ctx->functions, free_function_rb, NULL); +@@ -5022,31 +5048,13 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) + vkd3d_free(ctx->constant_defs.regs); + } + +-int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) ++static int hlsl_ctx_parse(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_list, ++ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, ++ struct vkd3d_shader_message_context *message_context) + { + enum vkd3d_shader_target_type target_type = compile_info->target_type; +- const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; +- struct hlsl_ir_function_decl *decl, *entry_func = NULL; +- const struct hlsl_profile_info *profile; +- struct hlsl_ir_function *func; +- const char *entry_point; +- struct hlsl_ctx ctx; + int ret; + +- if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) +- { +- ERR("No HLSL source info given.\n"); +- return VKD3D_ERROR_INVALID_ARGUMENT; +- } +- entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; +- +- if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) +- { +- FIXME("Unknown compilation target %s.\n", debugstr_a(hlsl_source_info->profile)); +- return VKD3D_ERROR_NOT_IMPLEMENTED; +- } +- + if (target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, +@@ -5072,37 +5080,115 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d + return VKD3D_ERROR_INVALID_ARGUMENT; + } + +- if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context)) ++ if (!hlsl_ctx_init(ctx, source_list, compile_info, profile, message_context)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- if ((ret = hlsl_lexer_compile(&ctx, hlsl)) == 2) ++ if ((ret = hlsl_lexer_compile(ctx, &compile_info->source)) == 2) + { +- hlsl_ctx_cleanup(&ctx); ++ hlsl_ctx_cleanup(ctx); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + +- if (ctx.result) ++ if (ctx->result) + { +- hlsl_ctx_cleanup(&ctx); +- return ctx.result; ++ hlsl_ctx_cleanup(ctx); ++ return ctx->result; + } + + /* If parsing failed without an error condition being recorded, we + * plausibly hit some unimplemented feature. */ + if (ret) + { +- hlsl_ctx_cleanup(&ctx); ++ hlsl_ctx_cleanup(ctx); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ return VKD3D_OK; ++} ++ ++int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) ++{ ++ const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; ++ struct vkd3d_shader_source_list source_list; ++ const struct hlsl_profile_info *profile; ++ struct hlsl_ctx ctx; ++ int ret; ++ ++ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) ++ { ++ WARN("No HLSL source info given.\n"); ++ return VKD3D_ERROR_INVALID_ARGUMENT; ++ } ++ ++ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) ++ { ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, ++ "Unknown target profile '%s'.", hlsl_source_info->profile); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + +- if (ctx.profile->type == VKD3D_SHADER_TYPE_EFFECT) ++ vkd3d_shader_source_list_init(&source_list); ++ if ((ret = hlsl_ctx_parse(&ctx, &source_list, compile_info, profile, message_context)) < 0) + { +- ret = hlsl_emit_effect_binary(&ctx, out); ++ vkd3d_shader_source_list_cleanup(&source_list); ++ return ret; ++ } + +- hlsl_ctx_cleanup(&ctx); ++ ret = hlsl_emit_effect_binary(&ctx, out); ++ hlsl_ctx_cleanup(&ctx); ++ vkd3d_shader_source_list_cleanup(&source_list); ++ ++ return ret; ++} ++ ++int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_message_context *message_context, ++ struct vsir_program *program, struct vkd3d_shader_code *reflection_data) ++{ ++ const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; ++ struct hlsl_ir_function_decl *decl, *entry_func = NULL; ++ enum vsir_normalisation_level normalisation_level; ++ const struct hlsl_profile_info *profile; ++ struct vkd3d_shader_version version; ++ struct hlsl_ir_function *func; ++ const char *entry_point; ++ struct hlsl_ctx ctx; ++ int ret; ++ ++ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) ++ { ++ WARN("No HLSL source info given.\n"); ++ return VKD3D_ERROR_INVALID_ARGUMENT; ++ } ++ ++ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) ++ { ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, ++ "Unknown target profile '%s'.", hlsl_source_info->profile); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ version = (struct vkd3d_shader_version) ++ { ++ .type = profile->type, ++ .major = profile->major_version, ++ .minor = profile->minor_version, ++ }; ++ normalisation_level = VSIR_NORMALISED_SM4; ++ if (version.major < 4 && (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM ++ || compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE)) ++ normalisation_level = VSIR_NORMALISED_SM1; ++ if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, normalisation_level)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ if ((ret = hlsl_ctx_parse(&ctx, &program->source_files, compile_info, profile, message_context)) < 0) ++ { ++ vsir_program_cleanup(program); + return ret; + } + ++ entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; + if ((func = hlsl_get_function(&ctx, entry_point))) + { + LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) +@@ -5126,46 +5212,17 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d + hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, + "Entry point \"%s\" is not defined.", entry_point); + hlsl_ctx_cleanup(&ctx); ++ vsir_program_cleanup(program); + return VKD3D_ERROR_INVALID_SHADER; + } + +- if (target_type == VKD3D_SHADER_TARGET_SPIRV_BINARY +- || target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT +- || target_type == VKD3D_SHADER_TARGET_GLSL +- || target_type == VKD3D_SHADER_TARGET_D3D_ASM) +- { +- uint64_t config_flags = vkd3d_shader_init_config_flags(); +- struct vkd3d_shader_compile_info info = *compile_info; +- struct vsir_program program; +- +- if (profile->major_version < 4) +- { +- if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0) +- goto done; +- info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE; +- ret = d3dbc_parse(&info, config_flags, message_context, &program); +- } +- else +- { +- if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0) +- goto done; +- info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; +- ret = tpf_parse(&info, config_flags, message_context, &program); +- } +- if (ret >= 0) +- { +- ret = vsir_program_compile(&program, config_flags, &info, out, message_context); +- vsir_program_cleanup(&program); +- } +- vkd3d_shader_free_shader_code(&info.source); +- } ++ ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, program, reflection_data); ++ hlsl_ctx_cleanup(&ctx); ++ if (ret < 0) ++ vsir_program_cleanup(program); + else +- { +- ret = hlsl_emit_bytecode(&ctx, entry_func, target_type, out); +- } ++ vsir_program_trace(program); + +-done: +- hlsl_ctx_cleanup(&ctx); + return ret; + } + diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 58f579cd9f9..0dce2831c3e 100644 +index 58f579cd9f9..d67f820fe8b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -59,8 +59,7 @@ static inline unsigned int hlsl_swizzle_get_component(uint32_t swizzle, unsigned @@ -7514,7 +9213,25 @@ index 58f579cd9f9..0dce2831c3e 100644 /* Name exactly as it appears in the sources. */ const char *raw_name; -@@ -308,6 +308,8 @@ struct hlsl_reg +@@ -278,11 +278,12 @@ struct hlsl_struct_field + size_t name_bytecode_offset; + }; + +-/* Information of the register(s) allocated for an instruction node or variable. +- * These values are initialized at the end of hlsl_emit_bytecode(), after the compilation passes, +- * just before writing the bytecode. +- * The type of register (register class) is implied from its use, so it is not stored in this +- * struct. */ ++/* Information about the register(s) allocated for an instruction node or ++ * variable. These values are initialised at the end of hlsl_emit_vsir(), ++ * after the compilation passes, as vsir starts being generated from HLSL IR. ++ * ++ * The type of register (register class) is implied by its usage, so it is not ++ * stored in this structure. */ + struct hlsl_reg + { + /* Register number of the first register allocated. */ +@@ -308,6 +309,8 @@ struct hlsl_reg unsigned int writemask; /* Whether the register has been allocated. */ bool allocated; @@ -7523,7 +9240,28 @@ index 58f579cd9f9..0dce2831c3e 100644 }; /* Types of instruction nodes for the IR. -@@ -733,6 +735,7 @@ enum hlsl_ir_expr_op +@@ -551,6 +554,7 @@ struct hlsl_ir_var + uint32_t is_param : 1; + uint32_t is_separated_resource : 1; + uint32_t is_synthetic : 1; ++ uint32_t is_tgsm : 1; + uint32_t has_explicit_bind_point : 1; + }; + +@@ -643,12 +647,6 @@ struct hlsl_ir_function_decl + * executed. Needed to deal with return statements in non-uniform control + * flow, since some backends can't handle them. */ + struct hlsl_ir_var *early_return_var; +- +- /* List of all the extern semantic variables; linked by the +- * hlsl_ir_var.extern_entry fields. This exists as a convenience because +- * it is often necessary to iterate all extern variables and these can be +- * declared in as function parameters, or as the function return value. */ +- struct list extern_vars; + }; + + struct hlsl_ir_call +@@ -733,6 +731,7 @@ enum hlsl_ir_expr_op HLSL_OP1_ISINF, HLSL_OP1_LOG2, HLSL_OP1_LOGIC_NOT, @@ -7531,7 +9269,34 @@ index 58f579cd9f9..0dce2831c3e 100644 HLSL_OP1_NEG, HLSL_OP1_RCP, HLSL_OP1_REINTERPRET, -@@ -1185,6 +1188,8 @@ struct hlsl_ctx +@@ -895,7 +894,7 @@ struct hlsl_ir_resource_load + struct hlsl_ir_node node; + enum hlsl_resource_load_type load_type; + struct hlsl_deref resource, sampler; +- struct hlsl_src coords, lod, ddx, ddy, cmp, sample_index, texel_offset; ++ struct hlsl_src byte_offset, coords, lod, ddx, ddy, cmp, sample_index, texel_offset; + enum hlsl_sampler_dim sampling_dim; + }; + +@@ -912,6 +911,7 @@ struct hlsl_ir_resource_store + enum hlsl_resource_store_type store_type; + struct hlsl_deref resource; + struct hlsl_src coords, value; ++ uint8_t writemask; + }; + + struct hlsl_ir_store +@@ -1093,8 +1093,7 @@ struct hlsl_ctx + { + const struct hlsl_profile_info *profile; + +- const char **source_files; +- unsigned int source_files_count; ++ struct vkd3d_shader_source_list *source_files; + /* Current location being read in the HLSL source, updated while parsing. */ + struct vkd3d_shader_location location; + /* Stores the logging messages and logging configuration. */ +@@ -1185,6 +1184,8 @@ struct hlsl_ctx } constant_defs; /* 'c' registers where the constants expected by SM2 sincos are stored. */ struct hlsl_reg d3dsincosconst1, d3dsincosconst2; @@ -7540,11 +9305,75 @@ index 58f579cd9f9..0dce2831c3e 100644 /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ +@@ -1586,7 +1587,7 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); + void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, +- struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); ++ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc); + void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -1609,8 +1610,10 @@ struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc); + void hlsl_block_cleanup(struct hlsl_block *block); + bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block); ++struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr); + +-void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func); ++void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func, ++ const char *description, const struct hlsl_block *processed_block); + void hlsl_dump_ir_function_decl(struct hlsl_ctx *ctx, + struct vkd3d_string_buffer *buffer, const struct hlsl_ir_function_decl *f); + void hlsl_dump_var_default_values(const struct hlsl_ir_var *var); +@@ -1625,9 +1628,10 @@ struct hlsl_state_block_entry *clone_stateblock_entry(struct hlsl_ctx *ctx, + + void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body); + void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body); +-int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, +- enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); + int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out); ++int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, ++ struct hlsl_ir_function_decl *entry_func, struct vsir_program *program, ++ struct vkd3d_shader_code *reflection_data); + + bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len); + bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain); +@@ -1707,6 +1711,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls + bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index); + bool hlsl_index_is_resource_access(struct hlsl_ir_index *index); + bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); ++bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index); + + struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, + const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +index d9fd43b5e78..0cdebb8a657 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +@@ -158,6 +158,7 @@ static {return KW_STATIC; } + string {return KW_STRING; } + String {return KW_STRING; } + struct {return KW_STRUCT; } ++StructuredBuffer {return KW_STRUCTUREDBUFFER; } + switch {return KW_SWITCH; } + tbuffer {return KW_TBUFFER; } + (?i:technique) {return KW_TECHNIQUE; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 5aee1e701cd..40353abd81b 100644 +index 5aee1e701cd..024d96c5663 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -2559,6 +2559,16 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2117,7 +2117,8 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc + VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); + VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count); + +- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, ++ &resource_deref, coords, rhs, writemask, &lhs->loc); + hlsl_cleanup_deref(&resource_deref); + } + else if (matrix_writemask) +@@ -2559,10 +2560,17 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Variable '%s' is declared as both \"uniform\" and \"static\".", var->name); @@ -7554,14 +9383,16 @@ index 5aee1e701cd..40353abd81b 100644 + hlsl_warning(ctx, &var->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER, + "Ignoring the 'groupshared' modifier in a non-compute shader."); + } -+ -+ if (modifiers & HLSL_STORAGE_GROUPSHARED) -+ hlsl_fixme(ctx, &var->loc, "Group shared variables."); + /* Mark it as uniform. We need to do this here since synthetic * variables also get put in the global scope, but shouldn't be * considered uniforms, and we have no way of telling otherwise. */ -@@ -4291,6 +4301,28 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +- if (!(modifiers & HLSL_STORAGE_STATIC)) ++ if (!(modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_GROUPSHARED))) + var->storage_modifiers |= HLSL_STORAGE_UNIFORM; + + if (stream_output) +@@ -4291,6 +4299,28 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, return true; } @@ -7590,7 +9421,35 @@ index 5aee1e701cd..40353abd81b 100644 static bool intrinsic_normalize(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -5119,10 +5151,10 @@ static bool intrinsic_InterlockedXor(struct hlsl_ctx *ctx, +@@ -5033,13 +5063,25 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op + + if (hlsl_deref_get_type(ctx, &dst_deref)->class != HLSL_CLASS_UAV) + { +- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements."); ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Interlocked targets must be UAV or groupshared elements."); + return false; + } + } ++ else if (lhs->type == HLSL_IR_INDEX && hlsl_index_chain_has_tgsm_access(hlsl_ir_index(lhs))) ++ { ++ hlsl_fixme(ctx, loc, "Interlocked operations on indexed groupshared elements."); ++ return false; ++ } ++ else if (lhs->type == HLSL_IR_LOAD && (hlsl_ir_load(lhs)->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED)) ++ { ++ hlsl_init_simple_deref_from_var(&dst_deref, hlsl_ir_load(lhs)->src.var); ++ coords = hlsl_block_add_uint_constant(ctx, params->instrs, 0, loc); ++ } + else + { +- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements."); ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Interlocked targets must be UAV or groupshared elements."); + return false; + } + +@@ -5119,10 +5161,10 @@ static bool intrinsic_InterlockedXor(struct hlsl_ctx *ctx, static void validate_group_barrier_profile(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) { @@ -7603,7 +9462,7 @@ index 5aee1e701cd..40353abd81b 100644 } } -@@ -5146,10 +5178,10 @@ static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx, +@@ -5146,10 +5188,10 @@ static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { if ((ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE && ctx->profile->type != VKD3D_SHADER_TYPE_PIXEL) @@ -7616,7 +9475,7 @@ index 5aee1e701cd..40353abd81b 100644 } return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV, loc); } -@@ -5255,6 +5287,7 @@ intrinsic_functions[] = +@@ -5255,6 +5297,7 @@ intrinsic_functions[] = {"min", 2, true, intrinsic_min}, {"modf", 2, true, intrinsic_modf}, {"mul", 2, true, intrinsic_mul}, @@ -7624,21 +9483,389 @@ index 5aee1e701cd..40353abd81b 100644 {"normalize", 1, true, intrinsic_normalize}, {"pow", 2, true, intrinsic_pow}, {"radians", 1, true, intrinsic_radians}, +@@ -5604,6 +5647,7 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) + case HLSL_SAMPLER_DIM_CUBEARRAY: + case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_RAW_BUFFER: ++ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + /* Offset parameters not supported for these types. */ + return 0; + default: +@@ -6269,6 +6313,7 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block + struct hlsl_ir_node *offset, *rhs; + struct hlsl_deref resource_deref; + unsigned int value_dim; ++ uint32_t writemask; + + if (params->args_count != 2) + { +@@ -6290,11 +6335,12 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); + rhs = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc); ++ writemask = vkd3d_write_mask_from_component_count(value_dim); + + if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) + return false; + +- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, writemask, loc); + hlsl_cleanup_deref(&resource_deref); + + return true; +@@ -6319,7 +6365,7 @@ static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *b + if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc))) + return false; + +- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, 0, loc); + hlsl_cleanup_deref(&so_deref); + + return true; +@@ -6340,7 +6386,7 @@ static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_bl + if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) + return false; + +- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, 0, loc); + hlsl_cleanup_deref(&so_deref); + + return true; +@@ -6521,19 +6567,25 @@ static bool add_object_property_access(struct hlsl_ctx *ctx, + return false; + } + +-static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, +- const struct vkd3d_shader_location *loc) ++static void validate_texture_format_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, ++ struct hlsl_type *format, const struct vkd3d_shader_location *loc) + { +- if (format->class > HLSL_CLASS_VECTOR) +- { +- struct vkd3d_string_buffer *string; ++ struct vkd3d_string_buffer *string; + +- string = hlsl_type_to_string(ctx, format); +- if (string) ++ if (!(string = hlsl_type_to_string(ctx, format))) ++ return; ++ ++ if (dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ { ++ if (!type_contains_only_numerics(format)) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, +- "Texture data type %s is not scalar or vector.", string->buffer); +- hlsl_release_string_buffer(ctx, string); ++ "SRV type %s is not numeric.", string->buffer); + } ++ else if (format->class > HLSL_CLASS_VECTOR) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Texture data type %s is not scalar or vector.", string->buffer); ++ ++ hlsl_release_string_buffer(ctx, string); + } + + static bool check_continue(struct hlsl_ctx *ctx, const struct hlsl_scope *scope, const struct vkd3d_shader_location *loc) +@@ -6801,6 +6853,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + %token KW_STATIC + %token KW_STRING + %token KW_STRUCT ++%token KW_STRUCTUREDBUFFER + %token KW_SWITCH + %token KW_TBUFFER + %token KW_TECHNIQUE +@@ -7137,23 +7190,19 @@ declaration_statement_list: + preproc_directive: + PRE_LINE STRING + { +- const char **new_array = NULL; +- +- ctx->location.line = $1; + if (strcmp($2, ctx->location.source_name)) +- new_array = hlsl_realloc(ctx, ctx->source_files, +- sizeof(*ctx->source_files) * (ctx->source_files_count + 1)); +- +- if (new_array) + { +- ctx->source_files = new_array; +- ctx->source_files[ctx->source_files_count++] = $2; +- ctx->location.source_name = $2; +- } +- else +- { +- vkd3d_free($2); ++ if (!vkd3d_shader_source_list_append(ctx->source_files, $2)) ++ { ++ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ else ++ { ++ ctx->location.line = $1; ++ ctx->location.source_name = ctx->source_files->sources[ctx->source_files->count - 1]; ++ } + } ++ vkd3d_free($2); + } + + struct_declaration_without_vars: +@@ -7888,6 +7937,10 @@ texture_type: + { + $$ = HLSL_SAMPLER_DIM_BUFFER; + } ++ | KW_STRUCTUREDBUFFER ++ { ++ $$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; ++ } + | KW_TEXTURE1D + { + $$ = HLSL_SAMPLER_DIM_1D; +@@ -8111,16 +8164,19 @@ type_no_void: + } + | texture_type + { ++ if ($1 == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Structured buffer type requires an explicit format."); + $$ = hlsl_new_texture_type(ctx, $1, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), 0); + } + | texture_type '<' resource_format '>' + { +- validate_texture_format_type(ctx, $3, &@3); ++ validate_texture_format_type(ctx, $1, $3, &@3); + $$ = hlsl_new_texture_type(ctx, $1, $3, 0); + } + | texture_ms_type '<' resource_format '>' + { +- validate_texture_format_type(ctx, $3, &@3); ++ validate_texture_format_type(ctx, $1, $3, &@3); + + $$ = hlsl_new_texture_type(ctx, $1, $3, 0); + } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 38d5c55c26b..afd6169514f 100644 +index 38d5c55c26b..0b3dee4d2ce 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -288,7 +288,8 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls +@@ -94,6 +94,134 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str + return base_offset; + } - static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, ++static unsigned int base_type_get_byte_size(enum hlsl_base_type t) ++{ ++ switch (t) ++ { ++ case HLSL_TYPE_HALF: ++ case HLSL_TYPE_MIN16UINT: ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_UINT: ++ case HLSL_TYPE_BOOL: ++ return 4; ++ ++ case HLSL_TYPE_DOUBLE: ++ return 8; ++ } ++ ++ return 0; ++} ++ ++static unsigned int hlsl_type_get_packed_alignment(const struct hlsl_type *type) ++{ ++ unsigned int max_align, i; ++ ++ switch (type->class) ++ { ++ case HLSL_CLASS_SCALAR: ++ case HLSL_CLASS_VECTOR: ++ case HLSL_CLASS_MATRIX: ++ return base_type_get_byte_size(type->e.numeric.type); ++ ++ case HLSL_CLASS_ARRAY: ++ return hlsl_type_get_packed_alignment(type->e.array.type); ++ ++ case HLSL_CLASS_STRUCT: ++ for (i = 0, max_align = 0; i < type->e.record.field_count; ++i) ++ { ++ struct hlsl_struct_field *field = &type->e.record.fields[i]; ++ ++ max_align = max(max_align, hlsl_type_get_packed_alignment(field->type)); ++ } ++ ++ return max_align; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++} ++ ++static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) ++{ ++ unsigned int size, i; ++ ++ switch (type->class) ++ { ++ case HLSL_CLASS_SCALAR: ++ case HLSL_CLASS_VECTOR: ++ return type->e.numeric.dimx * base_type_get_byte_size(type->e.numeric.type); ++ ++ case HLSL_CLASS_MATRIX: ++ return type->e.numeric.dimx * type->e.numeric.dimy * base_type_get_byte_size(type->e.numeric.type); ++ ++ case HLSL_CLASS_ARRAY: ++ return type->e.array.elements_count * hlsl_type_get_packed_size(type->e.array.type); ++ ++ case HLSL_CLASS_STRUCT: ++ for (i = 0, size = 0; i < type->e.record.field_count; ++i) ++ { ++ struct hlsl_struct_field *field = &type->e.record.fields[i]; ++ ++ size = align(size, hlsl_type_get_packed_alignment(field->type)) ++ + hlsl_type_get_packed_size(field->type); ++ } ++ size = align(size, hlsl_type_get_packed_alignment(type)); ++ ++ return size; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++} ++ ++static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hlsl_ctx *ctx, ++ struct hlsl_block *block, struct hlsl_ir_node *prev_offset, struct hlsl_ir_node *idx, ++ struct hlsl_type *type, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *idx_offset = NULL, *c; ++ unsigned int field_idx, offset, size, i; ++ ++ switch (type->class) ++ { ++ case HLSL_CLASS_VECTOR: ++ c = hlsl_block_add_uint_constant(ctx, block, base_type_get_byte_size(type->e.numeric.type), loc); ++ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); ++ break; ++ ++ case HLSL_CLASS_MATRIX: ++ size = base_type_get_byte_size(type->e.numeric.type) * hlsl_type_minor_size(type); ++ c = hlsl_block_add_uint_constant(ctx, block, size, loc); ++ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); ++ break; ++ ++ case HLSL_CLASS_ARRAY: ++ size = hlsl_type_get_packed_size(type->e.array.type); ++ c = hlsl_block_add_uint_constant(ctx, block, size, loc); ++ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); ++ break; ++ ++ case HLSL_CLASS_STRUCT: ++ field_idx = hlsl_ir_constant(idx)->value.u[0].u; ++ for (i = 0, offset = 0; i < field_idx; ++i) ++ { ++ struct hlsl_struct_field *field = &type->e.record.fields[i]; ++ ++ offset = align(offset, hlsl_type_get_packed_alignment(field->type)) ++ + hlsl_type_get_packed_size(field->type); ++ } ++ ++ offset = align(offset, hlsl_type_get_packed_alignment(type->e.record.fields[field_idx].type)); ++ idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); ++ break; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++ ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, idx_offset, prev_offset); ++} ++ + /* TODO: remove when no longer needed, only used for replace_deref_path_with_offset() */ + static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, unsigned int *offset_component, const struct vkd3d_shader_location *loc) +@@ -186,30 +314,34 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, + { + struct hlsl_ir_node *store; + struct hlsl_ir_load *load; +- struct hlsl_ir_var *temp; +- char *new_name; + + uniform->is_uniform = 1; + list_add_tail(&ctx->extern_vars, &uniform->extern_entry); + +- if (!(new_name = hlsl_sprintf_alloc(ctx, "", uniform->name))) +- return; +- +- if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type, +- &uniform->loc, NULL, uniform->storage_modifiers, NULL))) ++ if (!uniform->temp_copy) + { +- vkd3d_free(new_name); +- return; +- } +- list_add_before(&uniform->scope_entry, &temp->scope_entry); ++ struct hlsl_ir_var *temp; ++ char *new_name; + +- uniform->temp_copy = temp; ++ if (!(new_name = hlsl_sprintf_alloc(ctx, "", uniform->name))) ++ return; ++ ++ if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type, ++ &uniform->loc, NULL, uniform->storage_modifiers, NULL))) ++ { ++ vkd3d_free(new_name); ++ return; ++ } ++ list_add_tail(&ctx->dummy_scope->vars, &temp->scope_entry); ++ ++ uniform->temp_copy = temp; ++ } + + if (!(load = hlsl_new_var_load(ctx, uniform, &uniform->loc))) + return; + list_add_head(&block->instrs, &load->node.entry); + +- if (!(store = hlsl_new_simple_store(ctx, temp, &load->node))) ++ if (!(store = hlsl_new_simple_store(ctx, uniform->temp_copy, &load->node))) + return; + list_add_after(&load->node.entry, &store->entry); + } +@@ -233,6 +365,20 @@ static bool divert_written_uniform_derefs_to_temp(struct hlsl_ctx *ctx, struct h + return true; + } + ++static void warn_on_field_semantic(struct hlsl_ctx *ctx, ++ const struct hlsl_struct_field *field, const struct hlsl_semantic *outer) ++{ ++ if (!field->semantic.name) ++ return; ++ ++ if (!ascii_strcasecmp(field->semantic.name, outer->name) && field->semantic.index == outer->index) ++ return; ++ ++ hlsl_warning(ctx, &field->loc, VKD3D_SHADER_WARNING_HLSL_OVERRIDDEN_SEMANTIC, ++ "Field semantic %s%u is overridden by outer semantic %s%u.\n", ++ field->semantic.name, field->semantic.index, outer->name, outer->index); ++} ++ + static void validate_field_semantic(struct hlsl_ctx *ctx, struct hlsl_struct_field *field) + { + if (!field->semantic.name && hlsl_is_numeric_type(hlsl_get_multiarray_element_type(field->type)) +@@ -286,11 +432,12 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls + == base_type_get_semantic_equivalent(type2->e.numeric.type); + } + +-static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, +- struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, - uint32_t index, bool output, bool force_align, bool create, const struct vkd3d_shader_location *loc) -+ uint32_t index, uint32_t stream_index, bool output, bool force_align, bool create, -+ const struct vkd3d_shader_location *loc) ++static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_ir_var *var, ++ struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t stream_index, bool output, ++ bool force_align, bool create, const struct vkd3d_shader_location *loc) { struct hlsl_semantic new_semantic; ++ uint32_t index = semantic->index; struct hlsl_ir_var *ext_var; -@@ -300,7 +301,12 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir + const char *prefix; + char *new_name; +@@ -300,10 +447,15 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir else prefix = output ? "output" : "input"; @@ -7651,8 +9878,12 @@ index 38d5c55c26b..afd6169514f 100644 + if (!new_name) return NULL; - LIST_FOR_EACH_ENTRY(ext_var, &func->extern_vars, struct hlsl_ir_var, extern_entry) -@@ -353,6 +359,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir +- LIST_FOR_EACH_ENTRY(ext_var, &func->extern_vars, struct hlsl_ir_var, extern_entry) ++ LIST_FOR_EACH_ENTRY(ext_var, semantic_vars, struct hlsl_ir_var, extern_entry) + { + if (!ascii_strcasecmp(ext_var->name, new_name)) + { +@@ -353,6 +505,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir return NULL; } new_semantic.index = index; @@ -7660,86 +9891,510 @@ index 38d5c55c26b..afd6169514f 100644 if (!(ext_var = hlsl_new_var(ctx, new_name, type, loc, &new_semantic, modifiers, NULL))) { vkd3d_free(new_name); -@@ -435,7 +442,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec +@@ -366,7 +519,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir + ext_var->is_param = var->is_param; + ext_var->force_align = force_align; + list_add_before(&var->scope_entry, &ext_var->scope_entry); +- list_add_tail(&func->extern_vars, &ext_var->extern_entry); ++ list_add_tail(semantic_vars, &ext_var->extern_entry); + + return ext_var; + } +@@ -388,9 +541,9 @@ static uint32_t combine_field_storage_modifiers(uint32_t modifiers, uint32_t fie + return field_modifiers; + } + +-static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, ++static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *semantic_vars, + struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, +- uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) ++ uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align) + { + struct hlsl_type *type = lhs->node.data_type, *vector_type_src, *vector_type_dst; + struct vkd3d_shader_location *loc = &lhs->node.loc; +@@ -434,9 +587,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + return; prim_type_src->modifiers = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK; - if (!(input = add_semantic_var(ctx, func, var, prim_type_src, +- if (!(input = add_semantic_var(ctx, func, var, prim_type_src, - modifiers, semantic, semantic_index + i, false, force_align, true, loc))) -+ modifiers, semantic, semantic_index + i, 0, false, force_align, true, loc))) ++ if (!(input = add_semantic_var(ctx, semantic_vars, var, prim_type_src, ++ modifiers, semantic, 0, false, force_align, true, loc))) return; ++ ++semantic->index; hlsl_init_simple_deref_from_var(&prim_deref, input); -@@ -448,7 +455,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + idx = hlsl_block_add_uint_constant(ctx, block, prim_index, &var->loc); +@@ -447,9 +601,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + } else { - if (!(input = add_semantic_var(ctx, func, var, vector_type_src, +- if (!(input = add_semantic_var(ctx, func, var, vector_type_src, - modifiers, semantic, semantic_index + i, false, force_align, true, loc))) -+ modifiers, semantic, semantic_index + i, 0, false, force_align, true, loc))) ++ if (!(input = add_semantic_var(ctx, semantic_vars, var, vector_type_src, ++ modifiers, semantic, 0, false, force_align, true, loc))) return; ++ ++semantic->index; if (!(load = hlsl_new_var_load(ctx, input, &var->loc))) -@@ -558,7 +565,7 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function + return; +@@ -473,9 +628,9 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + } + } + +-static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, ++static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct list *semantic_vars, + struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, +- uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) ++ uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align) + { + struct vkd3d_shader_location *loc = &lhs->node.loc; + struct hlsl_type *type = lhs->node.data_type; +@@ -487,21 +642,31 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func + { + struct hlsl_ir_load *element_load; + struct hlsl_struct_field *field; +- uint32_t elem_semantic_index; + + for (i = 0; i < hlsl_type_element_count(type); ++i) + { + uint32_t element_modifiers; + ++ if (type->class == HLSL_CLASS_STRUCT) ++ loc = &type->e.record.fields[i].loc; ++ ++ c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); ++ ++ /* This redundant load is expected to be deleted later by DCE. */ ++ if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc))) ++ return; ++ hlsl_block_add_instr(block, &element_load->node); ++ + if (type->class == HLSL_CLASS_ARRAY) + { +- elem_semantic_index = semantic_index +- + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4; + element_modifiers = modifiers; + force_align = true; + + if (hlsl_type_is_primitive_array(type)) + prim_index = i; ++ ++ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, ++ element_load, element_modifiers, semantic, force_align); + } + else + { +@@ -511,35 +676,42 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func + hlsl_fixme(ctx, &field->loc, "Prepend uniform copies for resource components within structs."); + continue; + } +- validate_field_semantic(ctx, field); +- semantic = &field->semantic; +- elem_semantic_index = semantic->index; +- loc = &field->loc; + element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers); + force_align = (i == 0); +- } + +- c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); ++ if (semantic->name) ++ { ++ warn_on_field_semantic(ctx, field, semantic); ++ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, ++ element_load, element_modifiers, semantic, force_align); ++ } ++ else ++ { ++ struct hlsl_semantic semantic_copy; + +- /* This redundant load is expected to be deleted later by DCE. */ +- if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc))) +- return; +- hlsl_block_add_instr(block, &element_load->node); ++ validate_field_semantic(ctx, field); + +- prepend_input_copy_recurse(ctx, func, block, prim_index, element_load, +- element_modifiers, semantic, elem_semantic_index, force_align); ++ if (!(hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic))) ++ return; ++ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, ++ element_load, element_modifiers, &semantic_copy, force_align); ++ hlsl_cleanup_semantic(&semantic_copy); ++ } ++ } + } + } + else + { +- prepend_input_copy(ctx, func, block, prim_index, lhs, modifiers, semantic, semantic_index, force_align); ++ prepend_input_copy(ctx, semantic_vars, block, prim_index, lhs, modifiers, semantic, force_align); + } + } + + /* Split inputs into two variables representing the semantic and temp registers, + * and copy the former to the latter, so that writes to input variables work. */ +-static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var) ++static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *body, ++ struct list *semantic_vars, struct hlsl_ir_var *var) + { ++ struct hlsl_semantic semantic_copy; + struct hlsl_ir_load *load; + struct hlsl_block block; + +@@ -550,15 +722,20 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function + return; + hlsl_block_add_instr(&block, &load->node); + +- prepend_input_copy_recurse(ctx, func, &block, 0, load, var->storage_modifiers, +- &var->semantic, var->semantic.index, false); ++ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) ++ { ++ hlsl_block_cleanup(&block); ++ return; ++ } ++ prepend_input_copy_recurse(ctx, semantic_vars, &block, 0, load, var->storage_modifiers, &semantic_copy, false); ++ hlsl_cleanup_semantic(&semantic_copy); + +- list_move_head(&func->body.instrs, &block.instrs); ++ list_move_head(&body->instrs, &block.instrs); + } static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, +- struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, - struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) -+ struct hlsl_semantic *semantic, uint32_t semantic_index, uint32_t stream_index, bool force_align, bool create) ++ struct list *semantic_vars, struct hlsl_ir_load *rhs, uint32_t modifiers, ++ struct hlsl_semantic *semantic, uint32_t stream_index, bool force_align, bool create) { struct hlsl_type *type = rhs->node.data_type, *vector_type; struct vkd3d_shader_location *loc = &rhs->node.loc; -@@ -588,7 +595,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -587,9 +764,10 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_var *output; struct hlsl_ir_node *load; - if (!(output = add_semantic_var(ctx, func, var, vector_type, +- if (!(output = add_semantic_var(ctx, func, var, vector_type, - modifiers, semantic, semantic_index + i, true, force_align, create, loc))) -+ modifiers, semantic, semantic_index + i, stream_index, true, force_align, create, loc))) ++ if (!(output = add_semantic_var(ctx, semantic_vars, var, vector_type, modifiers, ++ semantic, stream_index, true, force_align, create, loc))) return; ++ ++semantic->index; if (type->class == HLSL_CLASS_MATRIX) -@@ -609,7 +616,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, + { +@@ -607,9 +785,9 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, + } + } - static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, +-static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, +- struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, - struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) -+ struct hlsl_semantic *semantic, uint32_t semantic_index, uint32_t stream_index, bool force_align, bool create) ++static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct list *semantic_vars, ++ const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, struct hlsl_semantic *semantic, ++ uint32_t stream_index, bool force_align, bool create) { struct vkd3d_shader_location *loc = &rhs->node.loc; struct hlsl_ir_var *var = rhs->src.var; -@@ -654,12 +661,13 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * - hlsl_block_add_instr(block, &element_load->node); +@@ -620,63 +798,84 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * + { + for (i = 0; i < hlsl_type_element_count(type); ++i) + { +- uint32_t element_modifiers, elem_semantic_index; + const struct hlsl_type *element_type; + struct hlsl_ir_load *element_load; + struct hlsl_struct_field *field; ++ uint32_t element_modifiers; ++ ++ if (type->class == HLSL_CLASS_STRUCT) ++ loc = &type->e.record.fields[i].loc; ++ ++ c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); ++ if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc))) ++ return; ++ hlsl_block_add_instr(block, &element_load->node); - append_output_copy_recurse(ctx, block, func, element_type, element_load, element_modifiers, semantic, + if (type->class == HLSL_CLASS_ARRAY) + { +- elem_semantic_index = semantic_index +- + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4; + element_type = type->e.array.type; + element_modifiers = modifiers; + force_align = true; ++ ++ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, ++ element_modifiers, semantic, stream_index, force_align, create); + } + else + { + field = &type->e.record.fields[i]; + if (hlsl_type_is_resource(field->type)) + continue; +- validate_field_semantic(ctx, field); +- semantic = &field->semantic; +- elem_semantic_index = semantic->index; +- loc = &field->loc; + element_type = field->type; + element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers); + force_align = (i == 0); +- } + +- c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); ++ if (semantic->name) ++ { ++ warn_on_field_semantic(ctx, field, semantic); + +- if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc))) +- return; +- hlsl_block_add_instr(block, &element_load->node); ++ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, ++ element_modifiers, semantic, stream_index, force_align, create); ++ } ++ else ++ { ++ struct hlsl_semantic semantic_copy; ++ ++ validate_field_semantic(ctx, field); + +- append_output_copy_recurse(ctx, block, func, element_type, element_load, element_modifiers, semantic, - elem_semantic_index, force_align, create); -+ elem_semantic_index, stream_index, force_align, create); ++ if (!hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic)) ++ continue; ++ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, ++ element_modifiers, &semantic_copy, stream_index, force_align, create); ++ hlsl_cleanup_semantic(&semantic_copy); ++ } ++ } } } else { - append_output_copy(ctx, block, func, rhs, modifiers, semantic, semantic_index, force_align, create); -+ append_output_copy(ctx, block, func, rhs, modifiers, semantic, -+ semantic_index, stream_index, force_align, create); ++ append_output_copy(ctx, block, semantic_vars, rhs, modifiers, semantic, stream_index, force_align, create); } } -@@ -676,7 +684,7 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function - hlsl_block_add_instr(&func->body, &load->node); + /* Split outputs into two variables representing the temp and semantic + * registers, and copy the former to the latter, so that reads from output + * variables work. */ +-static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var) ++static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *body, ++ struct list *semantic_vars, struct hlsl_ir_var *var) + { ++ struct hlsl_semantic semantic_copy; + struct hlsl_ir_load *load; - append_output_copy_recurse(ctx, &func->body, func, var->data_type, load, var->storage_modifiers, + /* This redundant load is expected to be deleted later by DCE. */ + if (!(load = hlsl_new_var_load(ctx, var, &var->loc))) + return; +- hlsl_block_add_instr(&func->body, &load->node); ++ hlsl_block_add_instr(body, &load->node); + +- append_output_copy_recurse(ctx, &func->body, func, var->data_type, load, var->storage_modifiers, - &var->semantic, var->semantic.index, false, true); -+ &var->semantic, var->semantic.index, 0, false, true); ++ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) ++ return; ++ append_output_copy_recurse(ctx, body, semantic_vars, var->data_type, ++ load, var->storage_modifiers, &semantic_copy, 0, false, true); ++ hlsl_cleanup_semantic(&semantic_copy); } bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), -@@ -3360,7 +3368,7 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -1237,6 +1436,73 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return true; + } + ++ if (val->type == HLSL_IR_RESOURCE_LOAD) ++ { ++ struct hlsl_ir_resource_load *parent = hlsl_ir_resource_load(index->val.node); ++ ++ if (parent->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ { ++ if (hlsl_index_is_noncontiguous(index)) ++ { ++ /* For column major matrices, since we have to output a row, ++ * we need to emit dimx loads. */ ++ struct hlsl_ir_node *mat = index->val.node; ++ struct hlsl_deref row_deref; ++ ++ if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) ++ return false; ++ hlsl_init_simple_deref_from_var(&row_deref, var); ++ ++ for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i) ++ { ++ struct hlsl_type *type = parent->node.data_type; ++ struct hlsl_ir_node *c, *c_offset, *idx_offset; ++ struct hlsl_ir_resource_load *column_load; ++ ++ c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc); ++ c_offset = hlsl_block_add_packed_index_offset_append(ctx, ++ block, parent->byte_offset.node, c, type, &instr->loc); ++ type = hlsl_get_element_type_from_path_index(ctx, type, c); ++ ++ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, ++ block, c_offset, index->idx.node, type, &instr->loc); ++ type = hlsl_get_element_type_from_path_index(ctx, type, c_offset); ++ ++ column_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node)); ++ ++ hlsl_src_remove(&column_load->byte_offset); ++ hlsl_src_from_node(&column_load->byte_offset, idx_offset); ++ column_load->node.data_type = type; ++ ++ hlsl_block_add_instr(block, &column_load->node); ++ ++ hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node); ++ } ++ ++ hlsl_block_add_simple_load(ctx, block, var, &instr->loc); ++ } ++ else ++ { ++ struct hlsl_type *type = parent->node.data_type; ++ struct hlsl_ir_resource_load *appended_load; ++ struct hlsl_ir_node *idx_offset; ++ ++ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, block, ++ parent->byte_offset.node, index->idx.node, type, &instr->loc); ++ appended_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node)); ++ type = hlsl_get_element_type_from_path_index(ctx, type, index->idx.node); ++ ++ hlsl_src_remove(&appended_load->byte_offset); ++ hlsl_src_from_node(&appended_load->byte_offset, idx_offset); ++ appended_load->node.data_type = type; ++ ++ hlsl_block_add_instr(block, &appended_load->node); ++ } ++ ++ return true; ++ } ++ } ++ + if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc))) + return false; + hlsl_init_simple_deref_from_var(&var_deref, var); +@@ -1315,6 +1581,67 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s + return false; + } + ++/* Lowers loads from TGSMs to resource loads. */ ++static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++{ ++ struct hlsl_resource_load_params params = {.type = HLSL_RESOURCE_LOAD}; ++ const struct vkd3d_shader_location *loc = &instr->loc; ++ struct hlsl_ir_load *load; ++ struct hlsl_deref *deref; ++ ++ if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type)) ++ return false; ++ load = hlsl_ir_load(instr); ++ deref = &load->src; ++ ++ if (!deref->var->is_tgsm) ++ return false; ++ ++ if (deref->path_len) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM."); ++ return false; ++ } ++ ++ params.resource = hlsl_block_add_simple_load(ctx, block, deref->var, loc); ++ params.format = instr->data_type; ++ params.coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); ++ hlsl_block_add_resource_load(ctx, block, ¶ms, loc); ++ ++ return true; ++} ++ ++/* Lowers stores to TGSMs to resource stores. */ ++static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++{ ++ struct hlsl_ir_store *store; ++ struct hlsl_ir_node *coords; ++ struct hlsl_deref res_deref; ++ struct hlsl_deref *deref; ++ ++ if (instr->type != HLSL_IR_STORE) ++ return false; ++ store = hlsl_ir_store(instr); ++ deref = &store->lhs; ++ ++ if (!deref->var->is_tgsm) ++ return false; ++ ++ if (deref->path_len) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM."); ++ return false; ++ } ++ ++ hlsl_init_simple_deref_from_var(&res_deref, deref->var); ++ coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); ++ ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref, ++ coords, store->rhs.node, store->writemask, &instr->loc); ++ ++ return true; ++} ++ + /* Allocate a unique, ordered index to each instruction, which will be used for + * copy propagation and computing liveness ranges. + * Index 0 means unused, so start at 1. */ +@@ -3146,10 +3473,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + { + struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); + +- if (!load->resource.var->is_uniform) ++ if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, +- "Loaded resource must have a single uniform source."); ++ "Loaded resource must have a single uniform or groupshared source."); + } + else if (validate_component_index_range_from_deref(ctx, &load->resource) == DEREF_VALIDATION_NOT_CONSTANT) + { +@@ -3180,10 +3507,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + { + struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr); + +- if (!store->resource.var->is_uniform) ++ if (!store->resource.var->is_uniform && !store->resource.var->is_tgsm) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, +- "Accessed resource must have a single uniform source."); ++ "Accessed resource must have a single uniform or groupshared source."); + } + else if (validate_component_index_range_from_deref(ctx, &store->resource) == DEREF_VALIDATION_NOT_CONSTANT) + { +@@ -3210,10 +3537,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + { + struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr); + +- if (!interlocked->dst.var->is_uniform) ++ if (!interlocked->dst.var->is_uniform && !interlocked->dst.var->is_tgsm) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, +- "Accessed resource must have a single uniform source."); ++ "Accessed resource must have a single uniform or groupshared source."); + } + else if (validate_component_index_range_from_deref(ctx, &interlocked->dst) == DEREF_VALIDATION_NOT_CONSTANT) + { +@@ -3359,18 +3686,20 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + struct stream_append_ctx { - struct hlsl_ir_function_decl *func; +- struct hlsl_ir_function_decl *func; - bool created; ++ struct list *semantic_vars; + bool created[VKD3D_MAX_STREAM_COUNT]; }; static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -3371,6 +3379,7 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + { + struct stream_append_ctx *append_ctx = context; + struct hlsl_ir_resource_store *store; ++ struct hlsl_semantic semantic_copy; + const struct hlsl_ir_node *rhs; const struct hlsl_type *type; struct hlsl_ir_var *var; struct hlsl_block block; @@ -7747,7 +10402,7 @@ index 38d5c55c26b..afd6169514f 100644 if (instr->type != HLSL_IR_RESOURCE_STORE) return false; -@@ -3390,18 +3399,17 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst +@@ -3390,24 +3719,49 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst } VKD3D_ASSERT(var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); @@ -7765,15 +10420,84 @@ index 38d5c55c26b..afd6169514f 100644 - append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), var->storage_modifiers, - &var->semantic, var->semantic.index, false, !append_ctx->created); - append_ctx->created = true; -+ append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), -+ var->storage_modifiers, &var->semantic, var->semantic.index, -+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, false, !append_ctx->created[stream_index]); ++ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) ++ return false; ++ append_output_copy_recurse(ctx, &block, append_ctx->semantic_vars, type->e.so.type, hlsl_ir_load(rhs), ++ var->storage_modifiers, &semantic_copy, var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, ++ false, !append_ctx->created[stream_index]); ++ hlsl_cleanup_semantic(&semantic_copy); + + append_ctx->created[stream_index] = true; list_move_before(&instr->entry, &block.instrs); hlsl_src_remove(&store->value); -@@ -3919,7 +3927,7 @@ static bool lower_separate_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + + return true; ++} ++ ++static void split_resource_load(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, ++ struct hlsl_ir_resource_load *load, const unsigned int idx, struct hlsl_type *type) ++{ ++ struct hlsl_ir_resource_load *vector_load; ++ struct hlsl_ir_node *c, *idx_offset; ++ struct hlsl_block block; ++ ++ hlsl_block_init(&block); + ++ c = hlsl_block_add_uint_constant(ctx, &block, idx, &store->node.loc); ++ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, &block, ++ load->byte_offset.node, c, load->node.data_type, &store->node.loc); ++ ++ vector_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &load->node)); ++ hlsl_src_remove(&vector_load->byte_offset); ++ hlsl_src_from_node(&vector_load->byte_offset, idx_offset); ++ vector_load->node.data_type = type; ++ hlsl_block_add_instr(&block, &vector_load->node); ++ ++ hlsl_block_add_store_index(ctx, &block, &store->lhs, c, &vector_load->node, 0, &store->node.loc); ++ ++ list_move_before(&store->node.entry, &block.instrs); + } + + static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -3428,16 +3782,32 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return false; + element_type = hlsl_get_vector_type(ctx, type->e.numeric.type, hlsl_type_minor_size(type)); + +- if (rhs->type != HLSL_IR_LOAD) ++ if (rhs->type != HLSL_IR_LOAD && rhs->type != HLSL_IR_RESOURCE_LOAD) + { + hlsl_fixme(ctx, &instr->loc, "Copying from unsupported node type."); + return false; + } + +- for (i = 0; i < hlsl_type_major_size(type); ++i) ++ if (rhs->type == HLSL_IR_RESOURCE_LOAD) + { +- if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) +- return false; ++ /* As we forbid non-scalar or vector types in non-structured resource ++ * loads, this is specific to structured buffer loads. */ ++ struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(rhs); ++ ++ VKD3D_ASSERT(hlsl_deref_get_type(ctx, &load->resource)->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER); ++ ++ for (i = 0; i < hlsl_type_major_size(type); ++i) ++ { ++ split_resource_load(ctx, store, load, i, element_type); ++ } ++ } ++ else ++ { ++ for (i = 0; i < hlsl_type_major_size(type); ++i) ++ { ++ if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) ++ return false; ++ } + } + + list_remove(&store->node.entry); +@@ -3919,7 +4289,7 @@ static bool lower_separate_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in if (load->texel_offset.node) { hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, @@ -7782,7 +10506,70 @@ index 38d5c55c26b..afd6169514f 100644 return false; } -@@ -5648,6 +5656,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a +@@ -5223,7 +5593,7 @@ static void dump_function(struct rb_entry *entry, void *context) + LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) + { + if (decl->has_body) +- hlsl_dump_function(ctx, decl); ++ hlsl_dump_function(ctx, decl, "function", NULL); + } + } + +@@ -5240,7 +5610,7 @@ static bool mark_indexable_var(struct hlsl_ctx *ctx, struct hlsl_deref *deref, + return true; + } + +-static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) ++static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_block *body) + { + struct hlsl_scope *scope; + struct hlsl_ir_var *var; +@@ -5251,7 +5621,7 @@ static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_de + var->indexable = false; + } + +- transform_derefs(ctx, mark_indexable_var, &entry_func->body); ++ transform_derefs(ctx, mark_indexable_var, body); + } + + static char get_regset_name(enum hlsl_regset regset) +@@ -5411,6 +5781,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop + deref_mark_last_read(&load->sampler, last_read); + } + ++ if (load->byte_offset.node) ++ load->byte_offset.node->last_read = last_read; + if (load->coords.node) + load->coords.node->last_read = last_read; + if (load->texel_offset.node) +@@ -5498,7 +5870,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop + } + } + +-static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) ++static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_block *body) + { + struct hlsl_scope *scope; + struct hlsl_ir_var *var; +@@ -5506,7 +5878,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl + if (ctx->result) + return; + +- index_instructions(&entry_func->body, 1); ++ index_instructions(body, 1); + + LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) + { +@@ -5514,7 +5886,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl + var->first_write = var->last_read = 0; + } + +- compute_liveness_recurse(&entry_func->body, 0, 0); ++ compute_liveness_recurse(body, 0, 0); + } + + static void mark_vars_usage(struct hlsl_ctx *ctx) +@@ -5648,6 +6020,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a unsigned int writemask = hlsl_combine_writemasks(available_writemask, vkd3d_write_mask_from_component_count(reg_size)); @@ -7790,7 +10577,7 @@ index 38d5c55c26b..afd6169514f 100644 ret.id = reg_idx; ret.writemask = hlsl_combine_writemasks(writemask, vkd3d_write_mask_from_component_count(component_count)); -@@ -5658,6 +5667,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a +@@ -5658,6 +6031,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a } } @@ -7798,7 +10585,7 @@ index 38d5c55c26b..afd6169514f 100644 ret.id = allocator->reg_count; ret.writemask = vkd3d_write_mask_from_component_count(component_count); record_allocation(ctx, allocator, allocator->reg_count, -@@ -5684,6 +5694,7 @@ static struct hlsl_reg allocate_register_with_masks(struct hlsl_ctx *ctx, +@@ -5684,6 +6058,7 @@ static struct hlsl_reg allocate_register_with_masks(struct hlsl_ctx *ctx, record_allocation(ctx, allocator, reg_idx, reg_writemask, first_write, last_read, mode, vip); @@ -7806,7 +10593,7 @@ index 38d5c55c26b..afd6169514f 100644 ret.id = reg_idx; ret.allocation_size = 1; ret.writemask = writemask; -@@ -5729,6 +5740,7 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo +@@ -5729,6 +6104,7 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo record_allocation(ctx, allocator, reg_idx + (reg_size / 4), (1u << (reg_size % 4)) - 1, first_write, last_read, mode, vip); @@ -7814,7 +10601,7 @@ index 38d5c55c26b..afd6169514f 100644 ret.id = reg_idx; ret.allocation_size = align(reg_size, 4) / 4; ret.allocated = true; -@@ -5749,20 +5761,30 @@ static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, +@@ -5749,20 +6125,30 @@ static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, return allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false); } @@ -7850,7 +10637,26 @@ index 38d5c55c26b..afd6169514f 100644 } static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -5902,11 +5924,12 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, +@@ -5778,6 +6164,9 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls + load = hlsl_ir_resource_load(instr); + var = load->resource.var; + ++ if (var->is_tgsm) ++ return false; ++ + regset = hlsl_deref_get_regset(ctx, &load->resource); + if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) + return false; +@@ -5846,7 +6235,7 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + { + struct hlsl_ir_load *load = hlsl_ir_load(instr); + +- if (!load->src.var->is_uniform) ++ if (!load->src.var->is_uniform && !load->src.var->is_tgsm) + return false; + + /* These will are handled by validate_static_object_references(). */ +@@ -5902,11 +6291,12 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct register_allocator *allocator) { unsigned int reg_writemask = 0, dst_writemask = 0; @@ -7864,7 +10670,7 @@ index 38d5c55c26b..afd6169514f 100644 { switch (hlsl_ir_expr(instr)->op) { -@@ -5920,20 +5943,42 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, +@@ -5920,20 +6310,42 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_1; break; @@ -7911,7 +10717,7 @@ index 38d5c55c26b..afd6169514f 100644 } static void allocate_variable_temp_register(struct hlsl_ctx *ctx, -@@ -5958,8 +6003,8 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, +@@ -5958,8 +6370,8 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator, var->first_write, var->last_read, var->data_type); @@ -7922,7 +10728,7 @@ index 38d5c55c26b..afd6169514f 100644 } } } -@@ -6043,6 +6088,7 @@ static bool find_constant(struct hlsl_ctx *ctx, const float *f, unsigned int cou +@@ -6043,6 +6455,7 @@ static bool find_constant(struct hlsl_ctx *ctx, const float *f, unsigned int cou if ((reg->allocated_mask & writemask) == writemask && !memcmp(f, ®->value.f[j], count * sizeof(float))) { @@ -7930,7 +10736,7 @@ index 38d5c55c26b..afd6169514f 100644 ret->id = reg->index; ret->allocation_size = 1; ret->writemask = writemask; -@@ -6136,12 +6182,13 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, +@@ -6136,12 +6549,13 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, if (find_constant(ctx, f, type->e.numeric.dimx, &constant->reg)) { TRACE("Reusing already allocated constant %s for @%u.\n", @@ -7946,7 +10752,7 @@ index 38d5c55c26b..afd6169514f 100644 for (unsigned int x = 0, i = 0; x < 4; ++x) { -@@ -6238,14 +6285,16 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -6238,14 +6652,16 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); @@ -7965,7 +10771,16 @@ index 38d5c55c26b..afd6169514f 100644 record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 0, -2.08333340e-02f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 1, -1.25000000e-01f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 2, 1.00000000e+00f, &instr->loc); -@@ -6293,12 +6342,13 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -6256,7 +6672,7 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl + } + } + +-static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) ++static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *body) + { + struct register_allocator allocator_used = {0}; + struct register_allocator allocator = {0}; +@@ -6293,12 +6709,13 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); } @@ -7980,7 +10795,7 @@ index 38d5c55c26b..afd6169514f 100644 } } -@@ -6314,8 +6364,9 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -6314,14 +6731,15 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi if (!var->regs[HLSL_REGSET_NUMERIC].allocated) { var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size, 0, false); @@ -7991,7 +10806,64 @@ index 38d5c55c26b..afd6169514f 100644 } } -@@ -6456,6 +6507,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +- allocate_const_registers_recurse(ctx, &entry_func->body, &allocator); ++ allocate_const_registers_recurse(ctx, body, &allocator); + +- allocate_sincos_const_registers(ctx, &entry_func->body, &allocator); ++ allocate_sincos_const_registers(ctx, body, &allocator); + + vkd3d_free(allocator.allocations); + } +@@ -6330,7 +6748,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi + * index to all (simultaneously live) variables or intermediate values. Agnostic + * as to how many registers are actually available for the current backend, and + * does not handle constants. */ +-static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) ++static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) + { + struct register_allocator allocator = {0}; + struct hlsl_scope *scope; +@@ -6341,7 +6759,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + { + LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) + { +- if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform)) ++ if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform || var->is_tgsm)) + memset(var->regs, 0, sizeof(var->regs)); + } + } +@@ -6349,7 +6767,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + /* ps_1_* outputs are special and go in temp register 0. */ + if (ctx->profile->major_version == 1 && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) + { +- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) ++ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_output_semantic) + { +@@ -6360,15 +6778,16 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + } + } + +- allocate_temp_registers_recurse(ctx, &entry_func->body, &allocator); ++ allocate_temp_registers_recurse(ctx, body, &allocator); + vkd3d_free(allocator.allocations); + + if (allocator.indexable_count) +- TRACE("Declaration of function \"%s\" required %u temp registers, and %u indexable temps.\n", +- entry_func->func->name, allocator.reg_count, allocator.indexable_count); ++ TRACE("Declaration of %s function required %u temp registers, and %u indexable temps.\n", ++ ctx->is_patch_constant_func ? "patch constant" : "main", ++ allocator.reg_count, allocator.indexable_count); + else +- TRACE("Declaration of function \"%s\" required %u temp registers.\n", +- entry_func->func->name, allocator.reg_count); ++ TRACE("Declaration of %s function required %u temp registers.\n", ++ ctx->is_patch_constant_func ? "patch constant" : "main", allocator.reg_count); + + return allocator.reg_count; + } +@@ -6456,6 +6875,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var if ((!output && !var->last_read) || (output && !var->first_write)) return; @@ -8000,7 +10872,7 @@ index 38d5c55c26b..afd6169514f 100644 } else { -@@ -6509,17 +6562,18 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -6509,17 +6930,17 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX, reg_size, component_count, mode, var->force_align, vip_allocation); @@ -8013,8 +10885,9 @@ index 38d5c55c26b..afd6169514f 100644 } } - static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - uint32_t *output_reg_count) +-static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, +- uint32_t *output_reg_count) ++static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *semantic_vars, uint32_t *output_reg_count) { + struct register_allocator input_allocator = {0}, output_allocators[VKD3D_MAX_STREAM_COUNT] = {{0}}; struct register_allocator in_prim_allocator = {0}, patch_constant_out_patch_allocator = {0}; @@ -8022,7 +10895,7 @@ index 38d5c55c26b..afd6169514f 100644 bool is_vertex_shader = ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX; bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; struct hlsl_ir_var *var; -@@ -6527,7 +6581,8 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun +@@ -6527,9 +6948,10 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun in_prim_allocator.prioritize_smaller_writemasks = true; patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; input_allocator.prioritize_smaller_writemasks = true; @@ -8030,9 +10903,12 @@ index 38d5c55c26b..afd6169514f 100644 + for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) + output_allocators[i].prioritize_smaller_writemasks = true; - LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) +- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) ++ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { -@@ -6550,15 +6605,22 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + if (var->is_input_semantic) + { +@@ -6550,15 +6972,22 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun } if (var->is_output_semantic) @@ -8058,7 +10934,62 @@ index 38d5c55c26b..afd6169514f 100644 } static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, -@@ -7715,8 +7777,6 @@ static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx) +@@ -6863,7 +7292,7 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum + return NULL; + } + +-static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, enum hlsl_regset regset) ++static void allocate_objects(struct hlsl_ctx *ctx, struct list *semantic_vars, enum hlsl_regset regset) + { + char regset_name = get_regset_name(regset); + uint32_t min_index = 0, id = 0; +@@ -6871,7 +7300,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl + + if (regset == HLSL_REGSET_UAVS && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) + { +- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) ++ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) + { + if (var->semantic.name && (!ascii_strcasecmp(var->semantic.name, "color") + || !ascii_strcasecmp(var->semantic.name, "sv_target"))) +@@ -6980,6 +7409,27 @@ static void allocate_stream_outputs(struct hlsl_ctx *ctx) + } + } + ++static void allocate_tgsms(struct hlsl_ctx *ctx) ++{ ++ struct hlsl_ir_var *var; ++ struct hlsl_reg *reg; ++ uint32_t index = 0; ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (!var->is_tgsm || !var->bind_count[HLSL_REGSET_NUMERIC]) ++ continue; ++ ++ reg = &var->regs[HLSL_REGSET_NUMERIC]; ++ reg->space = 0; ++ reg->index = index; ++ reg->id = index; ++ reg->allocated = true; ++ ++ ++index; ++ } ++} ++ + bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + unsigned int *start, unsigned int *count) + { +@@ -7420,6 +7870,8 @@ static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir + entry_func->early_depth_test = true; + else if (!strcmp(attr->name, "maxvertexcount") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + parse_maxvertexcount_attribute(ctx, attr); ++ else if (!strcmp(attr->name, "instance") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY) ++ hlsl_fixme(ctx, &entry_func->attrs[i]->loc, "Geometry shader instance count"); + else + hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, + "Ignoring unknown attribute \"%s\".", entry_func->attrs[i]->name); +@@ -7715,12 +8167,10 @@ static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx) reported_invalid_index = true; } } @@ -8066,8 +10997,32 @@ index 38d5c55c26b..afd6169514f 100644 - /* TODO: check that maxvertexcount * outputdatasize <= 1024. */ } - static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, -@@ -7960,8 +8020,19 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog +-static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, +- uint32_t output_reg_count) ++static void validate_max_output_size(struct hlsl_ctx *ctx, struct list *semantic_vars, ++ uint32_t output_reg_count, const struct vkd3d_shader_location *loc) + { + unsigned int max_output_size, comp_count = 0; + unsigned int *reg_comp_count; +@@ -7733,7 +8183,7 @@ static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_functi + if (!(reg_comp_count = hlsl_calloc(ctx, output_reg_count, sizeof(*reg_comp_count)))) + return; + +- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) ++ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->is_output_semantic) + continue; +@@ -7748,7 +8198,7 @@ static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_functi + + max_output_size = ctx->max_vertex_count * comp_count; + if (max_output_size > 1024) +- hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, + "Max vertex count (%u) * output data component count (%u) = %u, which is greater than 1024.", + ctx->max_vertex_count, comp_count, max_output_size); + +@@ -7960,8 +8410,19 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog if ((!output && !var->last_read) || (output && !var->first_write)) return; @@ -8088,7 +11043,7 @@ index 38d5c55c26b..afd6169514f 100644 { enum vkd3d_decl_usage usage; unsigned int usage_idx; -@@ -8018,6 +8089,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog +@@ -8018,6 +8479,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog return; } element->semantic_index = var->semantic.index; @@ -8096,34 +11051,200 @@ index 38d5c55c26b..afd6169514f 100644 element->sysval_semantic = sysval; element->component_type = component_type; element->register_index = register_index; -@@ -8120,7 +8192,7 @@ static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, +@@ -8050,15 +8512,15 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + } + } + +-static void generate_vsir_signature(struct hlsl_ctx *ctx, +- struct vsir_program *program, struct hlsl_ir_function_decl *func) ++static void generate_vsir_signature(struct hlsl_ctx *ctx, struct vsir_program *program, ++ struct hlsl_ir_function_decl *func, struct list *semantic_vars) + { + bool is_domain = program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; + struct hlsl_ir_var *var; + + ctx->is_patch_constant_func = func == ctx->patch_constant_func; + +- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) ++ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_input_semantic) + { +@@ -8092,38 +8554,38 @@ static void generate_vsir_signature(struct hlsl_ctx *ctx, + } + } + +-static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type) ++static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type) + { + if (hlsl_version_lt(ctx, 4, 0)) +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + + if (type->class == HLSL_CLASS_ARRAY) + return vsir_data_type_from_hlsl_type(ctx, type->e.array.type); + if (type->class == HLSL_CLASS_STRUCT) +- return VKD3D_DATA_MIXED; ++ return VSIR_DATA_MIXED; + if (type->class <= HLSL_CLASS_LAST_NUMERIC) + { + switch (type->e.numeric.type) + { + case HLSL_TYPE_DOUBLE: +- return VKD3D_DATA_DOUBLE; ++ return VSIR_DATA_F64; + case HLSL_TYPE_FLOAT: +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + case HLSL_TYPE_HALF: +- return VKD3D_DATA_HALF; ++ return VSIR_DATA_F16; + case HLSL_TYPE_INT: +- return VKD3D_DATA_INT; ++ return VSIR_DATA_I32; + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: +- return VKD3D_DATA_UINT; ++ return VSIR_DATA_U32; } } - vkd3d_unreachable(); -+ return VKD3D_DATA_UNUSED; ++ return VSIR_DATA_UNUSED; } - static enum vkd3d_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx, -@@ -8158,7 +8230,7 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr - } +-static enum vkd3d_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx, ++static enum vsir_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx, + const struct hlsl_ir_node *instr) + { + return vsir_data_type_from_hlsl_type(ctx, instr->data_type); +@@ -8141,7 +8603,6 @@ static uint32_t generate_vsir_get_src_swizzle(uint32_t src_writemask, uint32_t d + static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_program *program, + struct hlsl_block *block) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; + struct vkd3d_shader_dst_param *dst_param; + struct vkd3d_shader_src_param *src_param; + struct vkd3d_shader_instruction *ins; +@@ -8151,32 +8612,30 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr + { + const struct hlsl_constant_register *constant_reg = &ctx->constant_defs.regs[i]; - ins = &instructions->elements[instructions->count]; -- if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VKD3DSIH_DEF, 1, 1)) -+ if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VSIR_OP_DEF, 1, 1)) +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) ++ if (!(ins = vsir_program_append(program))) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; -@@ -8241,7 +8313,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, + } +- +- ins = &instructions->elements[instructions->count]; +- if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VKD3DSIH_DEF, 1, 1)) ++ if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VSIR_OP_DEF, 1, 1)) + { ++ vsir_instruction_init(ins, &constant_reg->loc, VSIR_OP_NOP); + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } +- ++instructions->count; + + dst_param = &ins->dst[0]; +- vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].reg.idx[0].offset = constant_reg->index; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; + + src_param = &ins->src[0]; +- vsir_register_init(&src_param->reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&src_param->reg, VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); + src_param->reg.type = VKD3DSPR_IMMCONST; + src_param->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; + src_param->reg.non_uniform = false; +- src_param->reg.data_type = VKD3D_DATA_FLOAT; ++ src_param->reg.data_type = VSIR_DATA_F32; + src_param->reg.dimension = VSIR_DIMENSION_VEC4; + for (x = 0; x < 4; ++x) + src_param->reg.u.immconst_f32[x] = constant_reg->value.f[x]; +@@ -8187,7 +8646,6 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr + static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, + struct vsir_program *program, struct hlsl_block *block) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; + enum vkd3d_shader_resource_type resource_type; + struct vkd3d_shader_register_range *range; + struct vkd3d_shader_dst_param *dst_param; +@@ -8234,25 +8692,18 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, + break; } - ins = &instructions->elements[instructions->count]; +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) +- { +- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; +- return; +- } +- +- ins = &instructions->elements[instructions->count]; - if (!vsir_instruction_init_with_params(program, ins, &var->loc, VKD3DSIH_DCL, 0, 0)) -+ if (!vsir_instruction_init_with_params(program, ins, &var->loc, VSIR_OP_DCL, 0, 0)) ++ if (!(ins = vsir_program_append(program))) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; -@@ -8357,7 +8429,7 @@ static void vsir_src_from_hlsl_node(struct vkd3d_shader_src_param *src, + } +- ++instructions->count; + ++ vsir_instruction_init(ins, &var->loc, VSIR_OP_DCL); + semantic = &ins->declaration.semantic; + semantic->resource_type = resource_type; + + dst_param = &semantic->resource.reg; +- vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1); + dst_param->reg.dimension = VSIR_DIMENSION_NONE; + dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index + i; + dst_param->write_mask = 0; +@@ -8297,32 +8748,31 @@ static enum vkd3d_shader_register_type sm4_get_semantic_register_type(enum vkd3d + return VKD3DSPR_INPUT; + } + +-static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction( +- struct hlsl_ctx *ctx, struct vsir_program *program, +- const struct vkd3d_shader_location *loc, enum vkd3d_shader_opcode opcode, +- unsigned int dst_count, unsigned int src_count) ++static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction(struct hlsl_ctx *ctx, ++ struct vsir_program *program, const struct vkd3d_shader_location *loc, ++ enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; + struct vkd3d_shader_instruction *ins; + +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) ++ if (!(ins = vsir_program_append(program))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return NULL; + } +- ins = &instructions->elements[instructions->count]; ++ + if (!vsir_instruction_init_with_params(program, ins, loc, opcode, dst_count, src_count)) + { ++ vsir_instruction_init(ins, loc, VSIR_OP_NOP); + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return NULL; + } +- ++instructions->count; ++ + return ins; + } + + static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src, + struct hlsl_ctx *ctx, const struct hlsl_constant_value *value, +- enum vkd3d_data_type type, unsigned int width, unsigned int map_writemask) ++ enum vsir_data_type type, unsigned int width, unsigned int map_writemask) + { + unsigned int i, j; + +@@ -8357,7 +8807,7 @@ static void vsir_src_from_hlsl_node(struct vkd3d_shader_src_param *src, } else { @@ -8132,7 +11253,7 @@ index 38d5c55c26b..afd6169514f 100644 src->reg.idx[0].offset = instr->reg.id; src->reg.dimension = VSIR_DIMENSION_VEC4; src->swizzle = generate_vsir_get_src_swizzle(instr->reg.writemask, map_writemask); -@@ -8424,6 +8496,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p +@@ -8424,6 +8874,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p const struct hlsl_type *data_type = hlsl_deref_get_type(ctx, deref); const struct hlsl_ir_var *var = deref->var; @@ -8141,7 +11262,7 @@ index 38d5c55c26b..afd6169514f 100644 if (var->is_uniform) { enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); -@@ -8432,18 +8506,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p +@@ -8432,18 +8884,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p { reg->type = VKD3DSPR_RESOURCE; reg->dimension = VSIR_DIMENSION_VEC4; @@ -8164,7 +11285,7 @@ index 38d5c55c26b..afd6169514f 100644 VKD3D_ASSERT(regset == HLSL_REGSET_TEXTURES); *writemask = VKD3DSP_WRITEMASK_ALL; } -@@ -8451,18 +8517,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p +@@ -8451,18 +8895,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p { reg->type = VKD3DSPR_UAV; reg->dimension = VSIR_DIMENSION_VEC4; @@ -8187,7 +11308,7 @@ index 38d5c55c26b..afd6169514f 100644 VKD3D_ASSERT(regset == HLSL_REGSET_UAVS); *writemask = VKD3DSP_WRITEMASK_ALL; } -@@ -8470,21 +8528,21 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p +@@ -8470,21 +8906,21 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p { reg->type = VKD3DSPR_SAMPLER; reg->dimension = VSIR_DIMENSION_NONE; @@ -8221,7 +11342,7 @@ index 38d5c55c26b..afd6169514f 100644 else { unsigned int offset = deref->const_offset + var->buffer_offset; -@@ -8492,19 +8550,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p +@@ -8492,19 +8928,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p VKD3D_ASSERT(data_type->class <= HLSL_CLASS_VECTOR); reg->type = VKD3DSPR_CONSTBUFFER; reg->dimension = VSIR_DIMENSION_VEC4; @@ -8245,7 +11366,23 @@ index 38d5c55c26b..afd6169514f 100644 if (deref->rel_offset.node) { -@@ -8630,7 +8679,7 @@ static void vsir_dst_from_hlsl_node(struct vkd3d_shader_dst_param *dst, +@@ -8594,6 +9021,15 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p + *writemask = hlsl_reg.writemask; + } + } ++ else if (var->is_tgsm) ++ { ++ VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated); ++ reg->type = VKD3DSPR_GROUPSHAREDMEM; ++ reg->dimension = VSIR_DIMENSION_VEC4; ++ reg->idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; ++ reg->idx_count = 1; ++ *writemask = (1u << data_type->e.numeric.dimx) - 1; ++ } + else + { + return sm4_generate_vsir_numeric_reg_from_deref(ctx, program, reg, writemask, deref); +@@ -8630,7 +9066,7 @@ static void vsir_dst_from_hlsl_node(struct vkd3d_shader_dst_param *dst, struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) { VKD3D_ASSERT(instr->reg.allocated); @@ -8254,7 +11391,7 @@ index 38d5c55c26b..afd6169514f 100644 dst->reg.idx[0].offset = instr->reg.id; dst->reg.dimension = VSIR_DIMENSION_VEC4; dst->write_mask = instr->reg.writemask; -@@ -8646,7 +8695,7 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, +@@ -8646,11 +9082,11 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, VKD3D_ASSERT(instr->reg.allocated); VKD3D_ASSERT(constant->reg.allocated); @@ -8263,7 +11400,12 @@ index 38d5c55c26b..afd6169514f 100644 return; src_param = &ins->src[0]; -@@ -8665,7 +8714,7 @@ static void sm4_generate_vsir_rasterizer_sample_count(struct hlsl_ctx *ctx, +- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; + src_param->reg.idx[0].offset = constant->reg.id; + src_param->swizzle = generate_vsir_get_src_swizzle(constant->reg.writemask, instr->reg.writemask); +@@ -8665,14 +9101,14 @@ static void sm4_generate_vsir_rasterizer_sample_count(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr = &expr->node; struct vkd3d_shader_instruction *ins; @@ -8272,23 +11414,31 @@ index 38d5c55c26b..afd6169514f 100644 return; ins->flags = VKD3DSI_SAMPLE_INFO_UINT; -@@ -8740,13 +8789,13 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); + + src_param = &ins->src[0]; +- vsir_src_param_init(src_param, VKD3DSPR_RASTERIZER, VKD3D_DATA_UNUSED, 0); ++ vsir_src_param_init(src_param, VKD3DSPR_RASTERIZER, VSIR_DATA_UNUSED, 0); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; + src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + } +@@ -8740,13 +9176,13 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx return; dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&dst_param->reg, instr->reg.type, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&dst_param->reg, instr->reg.type, VSIR_DATA_F32, 1); dst_param->reg.idx[0].offset = instr->reg.id; dst_param->reg.dimension = VSIR_DIMENSION_VEC4; dst_param->write_mask = 1u << i; src_param = &ins->src[0]; - vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&src_param->reg, operand->reg.type, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&src_param->reg, operand->reg.type, VSIR_DATA_F32, 1); src_param->reg.idx[0].offset = operand->reg.id; src_param->reg.dimension = VSIR_DIMENSION_VEC4; c = vsir_swizzle_get_component(src_swizzle, i); -@@ -8767,7 +8816,7 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi +@@ -8767,7 +9203,7 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi VKD3D_ASSERT(instr->reg.allocated); src_count = (ctx->profile->major_version < 3) ? 3 : 1; @@ -8297,7 +11447,23 @@ index 38d5c55c26b..afd6169514f 100644 return; vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); -@@ -8816,13 +8865,13 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -8776,13 +9212,13 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi + if (ctx->profile->major_version < 3) + { + src_param = &ins->src[1]; +- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; + src_param->reg.idx[0].offset = ctx->d3dsincosconst1.id; + src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; + + src_param = &ins->src[2]; +- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; + src_param->reg.idx[0].offset = ctx->d3dsincosconst2.id; + src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; +@@ -8816,13 +9252,13 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, /* Integrals are internally represented as floats, so no change is necessary.*/ case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -8313,7 +11479,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; } hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -@@ -8847,7 +8896,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -8847,7 +9283,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: @@ -8322,7 +11488,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; case HLSL_TYPE_DOUBLE: -@@ -8860,7 +8909,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -8860,7 +9296,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -8331,7 +11497,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; break; -@@ -8899,7 +8948,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8899,7 +9335,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr switch (expr->op) { case HLSL_OP1_ABS: @@ -8340,7 +11506,7 @@ index 38d5c55c26b..afd6169514f 100644 break; case HLSL_OP1_CAST: -@@ -8915,53 +8964,53 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8915,53 +9351,53 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr case HLSL_OP1_DSX: if (!hlsl_type_is_floating_point(type)) goto err; @@ -8403,7 +11569,7 @@ index 38d5c55c26b..afd6169514f 100644 break; case HLSL_OP1_SIN_REDUCED: -@@ -8974,7 +9023,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8974,7 +9410,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr case HLSL_OP2_ADD: if (type->e.numeric.type == HLSL_TYPE_BOOL) goto err; @@ -8412,7 +11578,7 @@ index 38d5c55c26b..afd6169514f 100644 break; case HLSL_OP2_DOT: -@@ -8983,11 +9032,11 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8983,11 +9419,11 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr switch (expr->operands[0].node->data_type->e.numeric.dimx) { case 3: @@ -8426,7 +11592,7 @@ index 38d5c55c26b..afd6169514f 100644 break; default: -@@ -8997,55 +9046,55 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8997,55 +9433,55 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break; case HLSL_OP2_MAX: @@ -8492,7 +11658,22 @@ index 38d5c55c26b..afd6169514f 100644 break; default: -@@ -9125,7 +9174,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, +@@ -9107,12 +9543,12 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, + + if (type == VKD3DSPR_DEPTHOUT) + { +- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 0); + dst_param->reg.dimension = VSIR_DIMENSION_SCALAR; + } + else + { +- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 1); + dst_param->reg.idx[0].offset = register_index; + dst_param->reg.dimension = VSIR_DIMENSION_VEC4; + } +@@ -9125,7 +9561,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, static void sm1_generate_vsir_instr_mova(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_node *instr) { @@ -8501,7 +11682,34 @@ index 38d5c55c26b..afd6169514f 100644 struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins; -@@ -9252,7 +9301,7 @@ static void sm1_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr +@@ -9135,7 +9571,7 @@ static void sm1_generate_vsir_instr_mova(struct hlsl_ctx *ctx, + return; + + dst_param = &ins->dst[0]; +- vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VSIR_DATA_F32, 0); + dst_param->write_mask = VKD3DSP_WRITEMASK_0; + + VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); +@@ -9155,7 +9591,7 @@ static struct vkd3d_shader_src_param *sm1_generate_vsir_new_address_src(struct h + } + + memset(idx_src, 0, sizeof(*idx_src)); +- vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VSIR_DATA_F32, 0); + idx_src->reg.dimension = VSIR_DIMENSION_VEC4; + idx_src->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + return idx_src; +@@ -9234,7 +9670,7 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, + writemask = reg.writemask; + } + +- vsir_register_init(&src_param->reg, type, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&src_param->reg, type, VSIR_DATA_F32, 1); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; + src_param->reg.idx[0].offset = register_index; + src_param->reg.idx[0].rel_addr = src_rel_addr; +@@ -9252,7 +9688,7 @@ static void sm1_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr if (load->src.rel_offset.node) sm1_generate_vsir_instr_mova(ctx, program, load->src.rel_offset.node); @@ -8510,7 +11718,7 @@ index 38d5c55c26b..afd6169514f 100644 return; vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); -@@ -9279,21 +9328,21 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, +@@ -9279,21 +9715,25 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, switch (load->load_type) { case HLSL_RESOURCE_SAMPLE: @@ -8524,6 +11732,10 @@ index 38d5c55c26b..afd6169514f 100644 flags |= VKD3DSI_TEXLD_PROJECT; break; ++ case HLSL_RESOURCE_SAMPLE_LOD: ++ opcode = VSIR_OP_TEXLDL; ++ break; ++ case HLSL_RESOURCE_SAMPLE_LOD_BIAS: - opcode = VKD3DSIH_TEX; + opcode = VSIR_OP_TEXLD; @@ -8536,7 +11748,7 @@ index 38d5c55c26b..afd6169514f 100644 src_count += 2; break; -@@ -9334,7 +9383,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, +@@ -9334,7 +9774,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, VKD3D_ASSERT(instr->reg.allocated); @@ -8545,7 +11757,7 @@ index 38d5c55c26b..afd6169514f 100644 return; vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); -@@ -9345,7 +9394,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, +@@ -9345,7 +9785,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, src_param = &ins->src[0]; VKD3D_ASSERT(val->type != HLSL_IR_CONSTANT); @@ -8554,7 +11766,7 @@ index 38d5c55c26b..afd6169514f 100644 src_param->reg.idx[0].offset = val->reg.id; src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->swizzle = swizzle; -@@ -9359,7 +9408,7 @@ static void sm1_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vsir_prog +@@ -9359,7 +9799,7 @@ static void sm1_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vsir_prog struct vkd3d_shader_instruction *ins; struct vkd3d_shader_src_param *src_param; @@ -8563,7 +11775,7 @@ index 38d5c55c26b..afd6169514f 100644 return; sm1_generate_vsir_init_dst_param_from_deref(ctx, &ins->dst[0], &store->lhs, &ins->location, store->writemask); -@@ -9377,7 +9426,7 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, +@@ -9377,7 +9817,7 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, if (jump->type == HLSL_IR_JUMP_DISCARD_NEG) { @@ -8572,7 +11784,7 @@ index 38d5c55c26b..afd6169514f 100644 return; vsir_src_from_hlsl_node(&ins->src[0], ctx, condition, VKD3DSP_WRITEMASK_ALL); -@@ -9404,7 +9453,7 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program +@@ -9404,7 +9844,7 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program } VKD3D_ASSERT(condition->data_type->e.numeric.dimx == 1 && condition->data_type->e.numeric.dimy == 1); @@ -8581,7 +11793,7 @@ index 38d5c55c26b..afd6169514f 100644 return; ins->flags = VKD3D_SHADER_REL_OP_NE; -@@ -9418,12 +9467,12 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program +@@ -9418,12 +9858,12 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program sm1_generate_vsir_block(ctx, &iff->then_block, program); @@ -8596,24 +11808,55 @@ index 38d5c55c26b..afd6169514f 100644 return; } -@@ -9501,6 +9550,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - return; +@@ -9486,33 +9926,30 @@ static void sm1_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo } + } +-static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, +- uint64_t config_flags, struct vsir_program *program) ++static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, ++ struct hlsl_ir_function_decl *func, struct list *semantic_vars, ++ struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) + { +- struct vkd3d_shader_version version = {0}; + struct hlsl_block block; + +- version.major = ctx->profile->major_version; +- version.minor = ctx->profile->minor_version; +- version.type = ctx->profile->type; +- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) +- { +- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; +- return; +- } +- +- program->temp_count = allocate_temp_registers(ctx, entry_func); + program->ssa_count = 0; - program->temp_count = allocate_temp_registers(ctx, entry_func); ++ program->temp_count = allocate_temp_registers(ctx, body, semantic_vars); if (ctx->result) return; -@@ -9513,6 +9563,8 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - list_move_head(&entry_func->body.instrs, &block.instrs); - sm1_generate_vsir_block(ctx, &entry_func->body, program); +- generate_vsir_signature(ctx, program, entry_func); +- + hlsl_block_init(&block); + sm1_generate_vsir_constant_defs(ctx, program, &block); + sm1_generate_vsir_sampler_dcls(ctx, program, &block); +- list_move_head(&entry_func->body.instrs, &block.instrs); ++ list_move_head(&body->instrs, &block.instrs); + ++ sm1_generate_vsir_block(ctx, body, program); + +- sm1_generate_vsir_block(ctx, &entry_func->body, program); + program->ssa_count = ctx->ssa_count; ++ ++ if (ctx->result) ++ return; ++ if (program->normalisation_level >= VSIR_NORMALISED_SM4) ++ ctx->result = vsir_program_lower_d3dbc(program, config_flags, compile_info, ctx->message_context); } D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) -@@ -9922,6 +9974,57 @@ static void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ct +@@ -9922,6 +10359,57 @@ static void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ct ctab->size = buffer.size; } @@ -8671,7 +11914,7 @@ index 38d5c55c26b..afd6169514f 100644 static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vsir_program *program, const struct hlsl_ir_var *var, struct hlsl_block *block, const struct vkd3d_shader_location *loc) { -@@ -9948,16 +10051,16 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -9948,16 +10436,16 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs { case VKD3D_SHADER_SV_NONE: opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) @@ -8692,7 +11935,7 @@ index 38d5c55c26b..afd6169514f 100644 break; case VKD3D_SHADER_SV_INSTANCE_ID: -@@ -9965,16 +10068,16 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -9965,16 +10453,16 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs case VKD3D_SHADER_SV_SAMPLE_INDEX: case VKD3D_SHADER_SV_VERTEX_ID: opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) @@ -8713,7 +11956,7 @@ index 38d5c55c26b..afd6169514f 100644 break; } } -@@ -9982,9 +10085,12 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -9982,9 +10470,12 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs { if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL || (version->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)) @@ -8728,7 +11971,7 @@ index 38d5c55c26b..afd6169514f 100644 } if (sm4_register_from_semantic_name(version, var->semantic.name, output, &type, &has_idx)) -@@ -10004,13 +10110,13 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -10004,13 +10495,13 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, opcode, 0, 0))) return; @@ -8744,7 +11987,29 @@ index 38d5c55c26b..afd6169514f 100644 { VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || is_primitive || version->type == VKD3D_SHADER_TYPE_GEOMETRY); dst_param = &ins->declaration.dst; -@@ -10056,7 +10162,7 @@ static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_ +@@ -10026,18 +10517,18 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs + if (is_primitive) + { + VKD3D_ASSERT(has_idx); +- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 2); ++ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 2); + dst_param->reg.idx[0].offset = var->data_type->e.array.elements_count; + dst_param->reg.idx[1].offset = idx; + } + else if (has_idx) + { +- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 1); + dst_param->reg.idx[0].offset = idx; + } + else + { +- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 0); + } + + if (shader_sm4_is_scalar_register(&dst_param->reg)) +@@ -10056,7 +10547,7 @@ static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_ { struct vkd3d_shader_instruction *ins; @@ -8753,7 +12018,7 @@ index 38d5c55c26b..afd6169514f 100644 return; ins->declaration.count = temp_count; -@@ -10068,7 +10174,7 @@ static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx, +@@ -10068,13 +10559,13 @@ static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx, { struct vkd3d_shader_instruction *ins; @@ -8762,7 +12027,14 @@ index 38d5c55c26b..afd6169514f 100644 return; ins->declaration.indexable_temp.register_idx = idx; -@@ -10095,11 +10201,12 @@ static void sm4_generate_vsir_cast_from_bool(struct hlsl_ctx *ctx, struct vsir_p + ins->declaration.indexable_temp.register_size = size; + ins->declaration.indexable_temp.alignment = 0; +- ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT; ++ ins->declaration.indexable_temp.data_type = VSIR_DATA_F32; + ins->declaration.indexable_temp.component_count = comp_count; + ins->declaration.indexable_temp.has_function_scope = false; + } +@@ -10095,16 +10586,17 @@ static void sm4_generate_vsir_cast_from_bool(struct hlsl_ctx *ctx, struct vsir_p VKD3D_ASSERT(instr->reg.allocated); @@ -8772,11 +12044,17 @@ index 38d5c55c26b..afd6169514f 100644 dst_param = &ins->dst[0]; vsir_dst_from_hlsl_node(dst_param, ctx, instr); -+ ins->dst[0].reg.data_type = VKD3D_DATA_UINT; ++ ins->dst[0].reg.data_type = VSIR_DATA_U32; vsir_src_from_hlsl_node(&ins->src[0], ctx, operand, dst_param->write_mask); -@@ -10131,16 +10238,16 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, + value.u[0].u = bits; +- vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, VKD3D_DATA_UINT, 1, 0); ++ vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, VSIR_DATA_U32, 1, 0); + } + + static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -10131,16 +10623,16 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -8796,7 +12074,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; case HLSL_TYPE_BOOL: -@@ -10158,13 +10265,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -10158,13 +10650,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -8812,7 +12090,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; case HLSL_TYPE_BOOL: -@@ -10183,13 +10290,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -10183,13 +10675,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -8828,7 +12106,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; case HLSL_TYPE_BOOL: -@@ -10253,7 +10360,7 @@ static void sm4_generate_vsir_rcp_using_div(struct hlsl_ctx *ctx, +@@ -10253,7 +10745,7 @@ static void sm4_generate_vsir_rcp_using_div(struct hlsl_ctx *ctx, VKD3D_ASSERT(type_is_float(expr->node.data_type)); @@ -8837,7 +12115,16 @@ index 38d5c55c26b..afd6169514f 100644 return; dst_param = &ins->dst[0]; -@@ -10287,12 +10394,12 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10264,7 +10756,7 @@ static void sm4_generate_vsir_rcp_using_div(struct hlsl_ctx *ctx, + value.u[2].f = 1.0f; + value.u[3].f = 1.0f; + vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, +- VKD3D_DATA_FLOAT, instr->data_type->e.numeric.dimx, dst_param->write_mask); ++ VSIR_DATA_F32, instr->data_type->e.numeric.dimx, dst_param->write_mask); + + vsir_src_from_hlsl_node(&ins->src[1], ctx, operand, dst_param->write_mask); + } +@@ -10287,12 +10779,12 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_OP1_ABS: VKD3D_ASSERT(type_is_float(dst_type)); @@ -8852,7 +12139,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; case HLSL_OP1_CAST: -@@ -10300,92 +10407,92 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10300,92 +10792,92 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_OP1_CEIL: VKD3D_ASSERT(type_is_float(dst_type)); @@ -8962,7 +12249,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10399,7 +10506,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10399,7 +10891,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_TYPE_FLOAT: /* SM5 comes with a RCP opcode */ if (hlsl_version_ge(ctx, 5, 0)) @@ -8971,7 +12258,7 @@ index 38d5c55c26b..afd6169514f 100644 else sm4_generate_vsir_rcp_using_div(ctx, program, expr); return true; -@@ -10410,50 +10517,50 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10410,50 +10902,50 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, } case HLSL_OP1_REINTERPRET: @@ -9031,7 +12318,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10463,29 +10570,29 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10463,29 +10955,29 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_OP2_BIT_AND: VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); @@ -9066,7 +12353,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10500,15 +10607,15 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10500,15 +10992,15 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (expr->operands[0].node->data_type->e.numeric.dimx) { case 4: @@ -9085,7 +12372,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; case 1: -@@ -10527,14 +10634,14 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10527,14 +11019,14 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -9102,7 +12389,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10549,17 +10656,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10549,17 +11041,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -9123,7 +12410,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10574,17 +10681,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10574,17 +11066,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -9144,7 +12431,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10595,31 +10702,31 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10595,31 +11087,31 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_OP2_LOGIC_AND: VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); @@ -9181,7 +12468,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10631,16 +10738,16 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10631,16 +11123,16 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -9201,7 +12488,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10652,16 +10759,16 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10652,16 +11144,16 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -9221,7 +12508,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10674,7 +10781,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10674,7 +11166,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, { case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: @@ -9230,7 +12517,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10686,7 +10793,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10686,7 +11178,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -9239,7 +12526,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; case HLSL_TYPE_INT: -@@ -10694,7 +10801,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10694,7 +11186,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_TYPE_UINT: /* Using IMUL instead of UMUL because we're taking the low * bits, and the native compiler generates IMUL. */ @@ -9248,7 +12535,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10708,14 +10815,14 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10708,14 +11200,14 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -9265,7 +12552,7 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10728,11 +10835,11 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10728,11 +11220,11 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, @@ -9279,16 +12566,25 @@ index 38d5c55c26b..afd6169514f 100644 return true; default: -@@ -10749,7 +10856,7 @@ static bool sm4_generate_vsir_instr_store(struct hlsl_ctx *ctx, +@@ -10749,7 +11241,9 @@ static bool sm4_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) ++ VKD3D_ASSERT(!store->lhs.var->is_tgsm); ++ + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) return false; dst_param = &ins->dst[0]; -@@ -10789,7 +10896,7 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr +@@ -10783,13 +11277,14 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr + struct vkd3d_shader_instruction *ins; + struct hlsl_constant_value value; + ++ VKD3D_ASSERT(!load->src.var->is_tgsm); + VKD3D_ASSERT(hlsl_is_numeric_type(type)); + if (type->e.numeric.type == HLSL_TYPE_BOOL && var_is_user_input(version, load->src.var)) + { /* Uniform bools can be specified as anything, but internal bools * always have 0 for false and ~0 for true. Normalise that here. */ @@ -9297,7 +12593,16 @@ index 38d5c55c26b..afd6169514f 100644 return false; dst_param = &ins->dst[0]; -@@ -10808,7 +10915,7 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr +@@ -10801,14 +11296,14 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr + + memset(&value, 0xff, sizeof(value)); + vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, +- VKD3D_DATA_UINT, type->e.numeric.dimx, dst_param->write_mask); ++ VSIR_DATA_U32, type->e.numeric.dimx, dst_param->write_mask); + memset(&value, 0x00, sizeof(value)); + vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, &value, +- VKD3D_DATA_UINT, type->e.numeric.dimx, dst_param->write_mask); ++ VSIR_DATA_U32, type->e.numeric.dimx, dst_param->write_mask); } else { @@ -9306,7 +12611,13 @@ index 38d5c55c26b..afd6169514f 100644 return false; dst_param = &ins->dst[0]; -@@ -10832,20 +10939,27 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, +@@ -10827,30 +11322,37 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, + struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &store->resource); + struct hlsl_ir_node *coords = store->coords.node, *value = store->value.node; + struct hlsl_ir_node *instr = &store->node; ++ bool tgsm = store->resource.var->is_tgsm; + struct vkd3d_shader_instruction *ins; +- unsigned int writemask; if (store->store_type != HLSL_RESOURCE_STORE) { @@ -9340,17 +12651,37 @@ index 38d5c55c26b..afd6169514f 100644 + return true; } - if (!store->resource.var->is_uniform) -@@ -10862,7 +10976,7 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, +- if (!store->resource.var->is_uniform) ++ if (!store->resource.var->is_uniform && !tgsm) + { +- hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable."); ++ hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform non-groupshared resource variable."); + return false; + } - if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) +@@ -10860,19 +11362,24 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, + return false; + } + +- if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) ++ if (tgsm && !hlsl_is_numeric_type(resource_type)) ++ { ++ hlsl_fixme(ctx, &store->node.loc, "Store to structured TGSM."); ++ return false; ++ } ++ ++ if (tgsm || resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_STORE_RAW, 1, 2))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_RAW, 1, 2))) return false; - writemask = vkd3d_write_mask_from_component_count(value->data_type->e.numeric.dimx); -@@ -10872,7 +10986,7 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, +- writemask = vkd3d_write_mask_from_component_count(value->data_type->e.numeric.dimx); +- if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, +- &ins->dst[0], &store->resource, &instr->loc, writemask)) ++ if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, &ins->dst[0], ++ &store->resource, &instr->loc, store->writemask)) + return false; } else { @@ -9359,9 +12690,46 @@ index 38d5c55c26b..afd6169514f 100644 return false; if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, -@@ -10947,11 +11061,11 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, +@@ -10928,7 +11435,6 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + const struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &load->resource); + bool uav = (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS); + const struct vkd3d_shader_version *version = &program->shader_version; +- bool raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER; + const struct hlsl_ir_node *sample_index = load->sample_index.node; + const struct hlsl_ir_node *texel_offset = load->texel_offset.node; + const struct hlsl_ir_node *coords = load->coords.node; +@@ -10936,22 +11442,39 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + const struct hlsl_deref *resource = &load->resource; + const struct hlsl_ir_node *instr = &load->node; + enum hlsl_sampler_dim dim = load->sampling_dim; ++ bool tgsm = load->resource.var->is_tgsm; + struct vkd3d_shader_instruction *ins; + enum vkd3d_shader_opcode opcode; +- bool multisampled; ++ bool multisampled, raw; + + VKD3D_ASSERT(load->load_type == HLSL_RESOURCE_LOAD); + ++ if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ { ++ hlsl_fixme(ctx, &load->node.loc, "Structured buffer loads."); ++ return false; ++ } ++ + multisampled = resource_type->class == HLSL_CLASS_TEXTURE + && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); ++ if (!tgsm) ++ { ++ raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER; ++ } ++ else if (!(raw = hlsl_is_numeric_type(resource_type))) ++ { ++ hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); ++ return false; ++ } ++ if (uav) - opcode = VKD3DSIH_LD_UAV_TYPED; + opcode = VSIR_OP_LD_UAV_TYPED; @@ -9374,7 +12742,25 @@ index 38d5c55c26b..afd6169514f 100644 if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 2 + multisampled))) return false; -@@ -11012,32 +11126,32 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, +@@ -10966,7 +11489,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); + +- if (!uav) ++ if (!uav && !tgsm) + { + /* Mipmap level is in the last component in the IR, but needs to be in + * the W component in the instruction. */ +@@ -10988,7 +11511,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + { + if (sample_index->type == HLSL_IR_CONSTANT) + vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, +- &hlsl_ir_constant(sample_index)->value, VKD3D_DATA_INT, 1, 0); ++ &hlsl_ir_constant(sample_index)->value, VSIR_DATA_I32, 1, 0); + else if (version->major == 4 && version->minor == 0) + hlsl_error(ctx, &sample_index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expected literal sample index."); + else +@@ -11012,32 +11535,32 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, switch (load->load_type) { case HLSL_RESOURCE_SAMPLE: @@ -9413,7 +12799,7 @@ index 38d5c55c26b..afd6169514f 100644 src_count = 5; break; -@@ -11068,15 +11182,15 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, +@@ -11068,15 +11591,15 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc)) return false; @@ -9432,7 +12818,7 @@ index 38d5c55c26b..afd6169514f 100644 { vsir_src_from_hlsl_node(&ins->src[3], ctx, load->ddx.node, VKD3DSP_WRITEMASK_ALL); vsir_src_from_hlsl_node(&ins->src[4], ctx, load->ddy.node, VKD3DSP_WRITEMASK_ALL); -@@ -11091,7 +11205,7 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro +@@ -11091,7 +11614,7 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro const struct hlsl_ir_node *texel_offset = load->texel_offset.node; const struct hlsl_ir_node *coords = load->coords.node; const struct hlsl_deref *resource = &load->resource; @@ -9441,7 +12827,7 @@ index 38d5c55c26b..afd6169514f 100644 const struct hlsl_deref *sampler = &load->sampler; const struct hlsl_ir_node *instr = &load->node; unsigned int src_count = 3, current_arg = 0; -@@ -11105,13 +11219,13 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro +@@ -11105,13 +11628,13 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro "Offset must resolve to integer literal in the range -8 to 7 for profiles < 5."); return false; } @@ -9457,7 +12843,7 @@ index 38d5c55c26b..afd6169514f 100644 ++src_count; } -@@ -11121,7 +11235,7 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro +@@ -11121,7 +11644,7 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, coords, VKD3DSP_WRITEMASK_ALL); @@ -9466,7 +12852,7 @@ index 38d5c55c26b..afd6169514f 100644 vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, texel_offset, VKD3DSP_WRITEMASK_ALL); else sm4_generate_vsir_encode_texel_offset_as_aoffimmi(ins, texel_offset); -@@ -11153,7 +11267,7 @@ static bool sm4_generate_vsir_instr_sample_info(struct hlsl_ctx *ctx, +@@ -11153,7 +11676,7 @@ static bool sm4_generate_vsir_instr_sample_info(struct hlsl_ctx *ctx, VKD3D_ASSERT(type->e.numeric.type == HLSL_TYPE_UINT || type->e.numeric.type == HLSL_TYPE_FLOAT); @@ -9475,7 +12861,7 @@ index 38d5c55c26b..afd6169514f 100644 return false; if (type->e.numeric.type == HLSL_TYPE_UINT) -@@ -11185,7 +11299,7 @@ static bool sm4_generate_vsir_instr_resinfo(struct hlsl_ctx *ctx, +@@ -11185,7 +11708,7 @@ static bool sm4_generate_vsir_instr_resinfo(struct hlsl_ctx *ctx, VKD3D_ASSERT(type->e.numeric.type == HLSL_TYPE_UINT || type->e.numeric.type == HLSL_TYPE_FLOAT); @@ -9484,7 +12870,16 @@ index 38d5c55c26b..afd6169514f 100644 return false; if (type->e.numeric.type == HLSL_TYPE_UINT) -@@ -11290,25 +11404,25 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx, +@@ -11237,7 +11760,7 @@ static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, + return false; + } + +- if (!load->resource.var->is_uniform) ++ if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm) + { + hlsl_fixme(ctx, &load->node.loc, "Load from non-uniform resource variable."); + return false; +@@ -11290,25 +11813,25 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx, static const enum vkd3d_shader_opcode opcodes[] = { @@ -9525,7 +12920,7 @@ index 38d5c55c26b..afd6169514f 100644 }; struct hlsl_ir_node *cmp_value = interlocked->cmp_value.node, *value = interlocked->value.node; -@@ -11323,14 +11437,14 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx, +@@ -11323,14 +11846,14 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx, if (value->data_type->e.numeric.type == HLSL_TYPE_INT) { @@ -9548,7 +12943,7 @@ index 38d5c55c26b..afd6169514f 100644 } if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, -@@ -11368,13 +11482,13 @@ static bool sm4_generate_vsir_instr_jump(struct hlsl_ctx *ctx, +@@ -11368,13 +11891,13 @@ static bool sm4_generate_vsir_instr_jump(struct hlsl_ctx *ctx, switch (jump->type) { case HLSL_IR_JUMP_BREAK: @@ -9565,7 +12960,7 @@ index 38d5c55c26b..afd6169514f 100644 return false; ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; -@@ -11396,7 +11510,7 @@ static bool sm4_generate_vsir_instr_sync(struct hlsl_ctx *ctx, +@@ -11396,7 +11919,7 @@ static bool sm4_generate_vsir_instr_sync(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr = &sync->node; struct vkd3d_shader_instruction *ins; @@ -9574,7 +12969,7 @@ index 38d5c55c26b..afd6169514f 100644 return false; ins->flags = sync->sync_flags; -@@ -11412,7 +11526,7 @@ static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program +@@ -11412,7 +11935,7 @@ static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program VKD3D_ASSERT(iff->condition.node->data_type->e.numeric.dimx == 1); @@ -9583,7 +12978,7 @@ index 38d5c55c26b..afd6169514f 100644 return; ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; -@@ -11422,12 +11536,12 @@ static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program +@@ -11422,12 +11945,12 @@ static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program if (!list_empty(&iff->else_block.instrs)) { @@ -9598,7 +12993,7 @@ index 38d5c55c26b..afd6169514f 100644 return; } -@@ -11437,12 +11551,12 @@ static void sm4_generate_vsir_instr_loop(struct hlsl_ctx *ctx, +@@ -11437,12 +11960,12 @@ static void sm4_generate_vsir_instr_loop(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr = &loop->node; struct vkd3d_shader_instruction *ins; @@ -9613,7 +13008,7 @@ index 38d5c55c26b..afd6169514f 100644 return; } -@@ -11454,7 +11568,7 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, +@@ -11454,7 +11977,7 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, struct vkd3d_shader_instruction *ins; struct hlsl_ir_switch_case *cas; @@ -9622,7 +13017,7 @@ index 38d5c55c26b..afd6169514f 100644 return; vsir_src_from_hlsl_node(&ins->src[0], ctx, selector, VKD3DSP_WRITEMASK_ALL); -@@ -11462,14 +11576,14 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, +@@ -11462,22 +11985,22 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, { if (cas->is_default) { @@ -9637,9 +13032,10 @@ index 38d5c55c26b..afd6169514f 100644 - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_CASE, 0, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_CASE, 0, 1))) return; - vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VKD3D_DATA_UINT, 1, VKD3DSP_WRITEMASK_ALL); +- vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VKD3D_DATA_UINT, 1, VKD3DSP_WRITEMASK_ALL); ++ vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VSIR_DATA_U32, 1, VKD3DSP_WRITEMASK_ALL); } -@@ -11477,7 +11591,7 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, + sm4_generate_vsir_block(ctx, &cas->body, program); } @@ -9648,16 +13044,86 @@ index 38d5c55c26b..afd6169514f 100644 return; } -@@ -11617,7 +11731,7 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, +@@ -11563,8 +12086,9 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo + } + } - sm4_generate_vsir_block(ctx, &func->body, program); +-static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, +- struct hlsl_ir_function_decl *func, uint64_t config_flags, struct vsir_program *program) ++static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *semantic_vars, ++ struct hlsl_ir_function_decl *func, struct hlsl_block *body, uint64_t config_flags, ++ struct vsir_program *program) + { + struct hlsl_block block = {0}; + struct hlsl_scope *scope; +@@ -11573,16 +12097,16 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, + + ctx->is_patch_constant_func = func == ctx->patch_constant_func; + +- compute_liveness(ctx, func); +- mark_indexable_vars(ctx, func); +- temp_count = allocate_temp_registers(ctx, func); ++ compute_liveness(ctx, body); ++ mark_indexable_vars(ctx, body); ++ temp_count = allocate_temp_registers(ctx, body, semantic_vars); + if (ctx->result) + return; + program->temp_count = max(program->temp_count, temp_count); + + hlsl_block_init(&block); + +- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) ++ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) + { + if ((var->is_input_semantic && var->last_read) + || (var->is_output_semantic && var->first_write)) +@@ -11596,7 +12120,7 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, + { + LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) + { +- if (var->is_uniform || var->is_input_semantic || var->is_output_semantic) ++ if (var->is_uniform || var->is_tgsm || var->is_input_semantic || var->is_output_semantic) + continue; + if (!var->regs[HLSL_REGSET_NUMERIC].allocated) + continue; +@@ -11611,13 +12135,13 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, + } + } + +- list_move_head(&func->body.instrs, &block.instrs); ++ list_move_head(&body->instrs, &block.instrs); + + hlsl_block_cleanup(&block); + +- sm4_generate_vsir_block(ctx, &func->body, program); ++ sm4_generate_vsir_block(ctx, body, program); - generate_vsir_add_program_instruction(ctx, program, &func->loc, VKD3DSIH_RET, 0, 0); + generate_vsir_add_program_instruction(ctx, program, &func->loc, VSIR_OP_RET, 0, 0); } static int sm4_compare_extern_resources(const void *a, const void *b) -@@ -11897,7 +12011,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, +@@ -11839,8 +12363,8 @@ static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vs + * STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */ + } + +-static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, +- struct vsir_program *program, const struct hlsl_ir_function_decl *entry_func) ++static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, struct vsir_program *program, ++ const struct list *semantic_vars, const struct hlsl_ir_function_decl *entry_func) + { + const struct vkd3d_shader_version *version = &program->shader_version; + struct extern_resource *extern_resources; +@@ -11866,7 +12390,7 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, + + sm4_free_extern_resources(extern_resources, extern_resources_count); + +- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) ++ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) + { + const struct hlsl_type *type = var->data_type; + +@@ -11897,7 +12421,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; @@ -9666,7 +13132,16 @@ index 38d5c55c26b..afd6169514f 100644 { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; -@@ -11938,7 +12052,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, +@@ -11906,7 +12430,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, + ins->declaration.cb.size = cbuffer->size; + + src_param = &ins->declaration.cb.src; +- vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 0); ++ vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 0); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; + src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; + +@@ -11938,7 +12462,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) continue; @@ -9675,7 +13150,57 @@ index 38d5c55c26b..afd6169514f 100644 { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; -@@ -12026,14 +12140,11 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, +@@ -11948,7 +12472,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, + ins->flags |= VKD3DSI_SAMPLER_COMPARISON_MODE; + + src_param = &ins->declaration.sampler.src; +- vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 0); ++ vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 0); + + ins->declaration.sampler.range.first = array_first; + ins->declaration.sampler.range.last = array_last; +@@ -11992,30 +12516,33 @@ static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const + } + } + +-static enum vkd3d_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) ++static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) + { + const struct hlsl_type *format = type->e.resource.format; + ++ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ return VSIR_DATA_MIXED; ++ + switch (format->e.numeric.type) + { + case HLSL_TYPE_DOUBLE: +- return VKD3D_DATA_DOUBLE; ++ return VSIR_DATA_F64; + + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + if (format->modifiers & HLSL_MODIFIER_UNORM) +- return VKD3D_DATA_UNORM; ++ return VSIR_DATA_UNORM; + if (format->modifiers & HLSL_MODIFIER_SNORM) +- return VKD3D_DATA_SNORM; +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_SNORM; ++ return VSIR_DATA_F32; + + case HLSL_TYPE_INT: +- return VKD3D_DATA_INT; ++ return VSIR_DATA_I32; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: + case HLSL_TYPE_UINT: +- return VKD3D_DATA_UINT; ++ return VSIR_DATA_U32; + } + + vkd3d_unreachable(); +@@ -12026,14 +12553,11 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, bool uav) { enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES; @@ -9691,7 +13216,7 @@ index 38d5c55c26b..afd6169514f 100644 VKD3D_ASSERT(resource->regset == regset); VKD3D_ASSERT(hlsl_version_lt(ctx, 5, 1) || resource->bind_count == 1); -@@ -12044,6 +12155,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, +@@ -12044,6 +12568,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, { unsigned int array_first = resource->index + i; unsigned int array_last = resource->index + i; /* FIXME: array end. */ @@ -9699,7 +13224,7 @@ index 38d5c55c26b..afd6169514f 100644 if (resource->var && !resource->var->objects_usage[regset][i].used) continue; -@@ -12053,13 +12165,13 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, +@@ -12053,13 +12578,13 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, switch (component_type->sampler_dim) { case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: @@ -9716,7 +13241,7 @@ index 38d5c55c26b..afd6169514f 100644 break; } } -@@ -12068,10 +12180,10 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, +@@ -12068,10 +12593,10 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, switch (component_type->sampler_dim) { case HLSL_SAMPLER_DIM_RAW_BUFFER: @@ -9729,7 +13254,7 @@ index 38d5c55c26b..afd6169514f 100644 break; } } -@@ -12081,13 +12193,16 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, +@@ -12081,13 +12606,16 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; } @@ -9747,25 +13272,25 @@ index 38d5c55c26b..afd6169514f 100644 + else + vsir_resource = &ins->declaration.semantic.resource; + -+ vsir_dst_param_init(&vsir_resource->reg, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 0); ++ vsir_dst_param_init(&vsir_resource->reg, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_UNUSED, 0); + if (uav && component_type->e.resource.rasteriser_ordered) ins->flags = VKD3DSUF_RASTERISER_ORDERED_VIEW; -@@ -12101,30 +12216,52 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, +@@ -12101,64 +12629,103 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, ctx->profile->major_version, ctx->profile->minor_version); } - for (j = 0; j < 4; ++j) - semantic->resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); -- -- semantic->resource.range.first = array_first; -- semantic->resource.range.last = array_last; -- semantic->resource.range.space = resource->space; + vsir_resource->range.first = array_first; + vsir_resource->range.last = array_last; + vsir_resource->range.space = resource->space; +- semantic->resource.range.first = array_first; +- semantic->resource.range.last = array_last; +- semantic->resource.range.space = resource->space; +- - dst_param->reg.idx[0].offset = resource->id; - dst_param->reg.idx[1].offset = array_first; - dst_param->reg.idx[2].offset = array_last; @@ -9788,45 +13313,135 @@ index 38d5c55c26b..afd6169514f 100644 ins->structured = true; ins->resource_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; + ins->declaration.structured_resource.byte_stride = ins->resource_stride; -+ } + } + else + { + for (unsigned int j = 0; j < 4; ++j) + ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); -+ + +- if (multisampled) +- semantic->sample_count = component_type->sample_count; + if (multisampled) + ins->declaration.semantic.sample_count = component_type->sample_count; - } ++ } + } + } + +-/* OBJECTIVE: Translate all the information from ctx and entry_func to the +- * vsir_program, so it can be used as input to tpf_compile() without relying +- * on ctx and entry_func. */ +-static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, +- uint64_t config_flags, struct vsir_program *program) ++static void sm4_generate_vsir_add_dcl_tgsm(struct hlsl_ctx *ctx, ++ struct vsir_program *program, const struct hlsl_ir_var *var) + { +- struct vkd3d_shader_version version = {0}; +- struct extern_resource *extern_resources; +- unsigned int extern_resources_count; +- const struct hlsl_buffer *cbuffer; ++ struct vkd3d_shader_dst_param *dst_param; ++ struct vkd3d_shader_instruction *ins; + +- version.major = ctx->profile->major_version; +- version.minor = ctx->profile->minor_version; +- version.type = ctx->profile->type; ++ if (!hlsl_is_numeric_type(var->data_type)) ++ { ++ hlsl_fixme(ctx, &var->loc, "Structured TGSM declaration."); ++ return; + } -+} + +- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VSIR_OP_DCL_TGSM_RAW, 0, 0))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } + +- generate_vsir_signature(ctx, program, func); +- if (version.type == VKD3D_SHADER_TYPE_HULL) +- generate_vsir_signature(ctx, program, ctx->patch_constant_func); ++ dst_param = &ins->declaration.tgsm_raw.reg; + ++ vsir_dst_param_init(dst_param, VKD3DSPR_GROUPSHAREDMEM, VSIR_DATA_F32, 1); ++ dst_param->reg.dimension = VSIR_DIMENSION_NONE; ++ dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; ++ ++ ins->declaration.tgsm_raw.byte_count = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * 4; ++ ins->declaration.tgsm_raw.zero_init = false; ++} + +- if (version.type == VKD3D_SHADER_TYPE_COMPUTE) +static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct hlsl_ir_var *var) +{ + struct vkd3d_shader_instruction *ins; - -- if (multisampled) -- semantic->sample_count = component_type->sample_count; ++ + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VSIR_OP_DCL_STREAM, 0, 1))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; - } ++ } + -+ vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VKD3D_DATA_OPAQUE, 1); ++ vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VSIR_DATA_UNUSED, 1); + ins->src[0].reg.dimension = VSIR_DIMENSION_NONE; + ins->src[0].reg.idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; - } - - /* OBJECTIVE: Translate all the information from ctx and entry_func to the -@@ -12201,19 +12338,34 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl ++} ++ ++/* OBJECTIVE: Translate all the information from ctx and entry_func to the ++ * vsir_program, so it can be used as input to tpf_compile() without relying ++ * on ctx and entry_func. */ ++static void sm4_generate_vsir(struct hlsl_ctx *ctx, ++ const struct vkd3d_shader_compile_info *compile_info, struct hlsl_ir_function_decl *func, ++ struct list *semantic_vars, struct hlsl_block *body, struct list *patch_semantic_vars, ++ struct hlsl_block *patch_body, uint64_t config_flags, struct vsir_program *program) ++{ ++ const struct vkd3d_shader_version *version = &program->shader_version; ++ struct extern_resource *extern_resources; ++ unsigned int extern_resources_count; ++ const struct hlsl_buffer *cbuffer; ++ const struct hlsl_ir_var *var; ++ ++ if (version->type == VKD3D_SHADER_TYPE_COMPUTE) + { + program->thread_group_size.x = ctx->thread_count[0]; + program->thread_group_size.y = ctx->thread_count[1]; + program->thread_group_size.z = ctx->thread_count[2]; + } +- else if (version.type == VKD3D_SHADER_TYPE_HULL) ++ else if (version->type == VKD3D_SHADER_TYPE_HULL) + { + program->input_control_point_count = ctx->input_control_point_count == UINT_MAX + ? 1 : ctx->input_control_point_count; +@@ -12167,13 +12734,13 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl + program->tess_partitioning = ctx->partitioning; + program->tess_output_primitive = ctx->output_primitive; + } +- else if (version.type == VKD3D_SHADER_TYPE_DOMAIN) ++ else if (version->type == VKD3D_SHADER_TYPE_DOMAIN) + { + program->input_control_point_count = ctx->input_control_point_count == UINT_MAX + ? 0 : ctx->input_control_point_count; + program->tess_domain = ctx->domain; + } +- else if (version.type == VKD3D_SHADER_TYPE_GEOMETRY) ++ else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY) + { + program->input_control_point_count = ctx->input_control_point_count; + program->input_primitive = ctx->input_primitive_type; +@@ -12201,19 +12768,39 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl } sm4_free_extern_resources(extern_resources, extern_resources_count); -+ if (version.type == VKD3D_SHADER_TYPE_GEOMETRY && version.major >= 5) +- if (version.type == VKD3D_SHADER_TYPE_HULL) ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { -+ const struct hlsl_ir_var *var; ++ if (var->is_tgsm && var->regs[HLSL_REGSET_NUMERIC].allocated) ++ sm4_generate_vsir_add_dcl_tgsm(ctx, program, var); ++ } + ++ if (version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) ++ { + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->bind_count[HLSL_REGSET_STREAM_OUTPUTS]) @@ -9836,30 +13451,75 @@ index 38d5c55c26b..afd6169514f 100644 + + program->ssa_count = 0; + - if (version.type == VKD3D_SHADER_TYPE_HULL) ++ if (version->type == VKD3D_SHADER_TYPE_HULL) generate_vsir_add_program_instruction(ctx, program, - &ctx->patch_constant_func->loc, VKD3DSIH_HS_CONTROL_POINT_PHASE, 0, 0); +- sm4_generate_vsir_add_function(ctx, func, config_flags, program); +- if (version.type == VKD3D_SHADER_TYPE_HULL) + &ctx->patch_constant_func->loc, VSIR_OP_HS_CONTROL_POINT_PHASE, 0, 0); - sm4_generate_vsir_add_function(ctx, func, config_flags, program); - if (version.type == VKD3D_SHADER_TYPE_HULL) ++ sm4_generate_vsir_add_function(ctx, semantic_vars, func, body, config_flags, program); ++ if (version->type == VKD3D_SHADER_TYPE_HULL) { generate_vsir_add_program_instruction(ctx, program, - &ctx->patch_constant_func->loc, VKD3DSIH_HS_FORK_PHASE, 0, 0); +- sm4_generate_vsir_add_function(ctx, ctx->patch_constant_func, config_flags, program); + &ctx->patch_constant_func->loc, VSIR_OP_HS_FORK_PHASE, 0, 0); - sm4_generate_vsir_add_function(ctx, ctx->patch_constant_func, config_flags, program); ++ sm4_generate_vsir_add_function(ctx, patch_semantic_vars, ++ ctx->patch_constant_func, patch_body, config_flags, program); } generate_vsir_scan_required_features(ctx, program); - generate_vsir_scan_global_flags(ctx, program, func); +- generate_vsir_scan_global_flags(ctx, program, func); ++ generate_vsir_scan_global_flags(ctx, program, semantic_vars, func); + + program->ssa_count = ctx->ssa_count; } /* For some reason, for matrices, values from default value initializers end -@@ -13401,6 +13553,19 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12297,6 +12884,9 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) + { + const struct hlsl_type *format = type->e.resource.format; + ++ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ return D3D_RETURN_TYPE_MIXED; ++ + switch (format->e.numeric.type) + { + case HLSL_TYPE_DOUBLE: +@@ -13352,15 +13942,14 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct + return true; + } + +-static void process_entry_function(struct hlsl_ctx *ctx, ++static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *body, + const struct hlsl_block *global_uniform_block, struct hlsl_ir_function_decl *entry_func) + { ++ struct stream_append_ctx stream_append_ctx = { .semantic_vars = semantic_vars }; + const struct hlsl_ir_var *input_patch = NULL, *output_patch = NULL; + const struct hlsl_profile_info *profile = ctx->profile; + struct hlsl_block static_initializers, global_uniforms; +- struct hlsl_block *const body = &entry_func->body; + struct recursive_call_ctx recursive_call_ctx; +- struct stream_append_ctx stream_append_ctx; + uint32_t output_reg_count; + struct hlsl_ir_var *var; + unsigned int i; +@@ -13368,6 +13957,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, + + ctx->is_patch_constant_func = entry_func == ctx->patch_constant_func; + ++ hlsl_clone_block(ctx, body, &entry_func->body); ++ + if (!hlsl_clone_block(ctx, &static_initializers, &ctx->static_initializers)) + return; + list_move_head(&body->instrs, &static_initializers.instrs); +@@ -13401,6 +13992,22 @@ static void process_entry_function(struct hlsl_ctx *ctx, lower_ir(ctx, lower_matrix_swizzles, body); lower_ir(ctx, lower_index_loads, body); ++ lower_ir(ctx, lower_tgsm_loads, body); ++ lower_ir(ctx, lower_tgsm_stores, body); ++ + if (entry_func->return_var) + { + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) @@ -9870,13 +13530,36 @@ index 38d5c55c26b..afd6169514f 100644 + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name); + -+ append_output_var_copy(ctx, entry_func, entry_func->return_var); ++ append_output_var_copy(ctx, body, semantic_vars, entry_func->return_var); + } + for (i = 0; i < entry_func->parameters.count; ++i) { var = entry_func->parameters.vars[i]; -@@ -13505,25 +13670,35 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -13454,7 +14061,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, + } + + validate_and_record_prim_type(ctx, var); +- prepend_input_var_copy(ctx, entry_func, var); ++ prepend_input_var_copy(ctx, body, semantic_vars, var); + } + else if (var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) + { +@@ -13490,7 +14097,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, + continue; + } + +- prepend_input_var_copy(ctx, entry_func, var); ++ prepend_input_var_copy(ctx, body, semantic_vars, var); + } + if (var->storage_modifiers & HLSL_STORAGE_OUT) + { +@@ -13501,29 +14108,39 @@ static void process_entry_function(struct hlsl_ctx *ctx, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Output parameters are not allowed in geometry shaders."); + else +- append_output_var_copy(ctx, entry_func, var); ++ append_output_var_copy(ctx, body, semantic_vars, var); } } } @@ -9923,26 +13606,238 @@ index 38d5c55c26b..afd6169514f 100644 } if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && ctx->input_primitive_type == VKD3D_PT_UNDEFINED) -@@ -13741,6 +13916,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - return ctx->result; - } +@@ -13540,8 +14157,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, + hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL); + } -+ vsir_program_trace(&program); -+ - result = d3dbc_compile(&program, config_flags, NULL, &ctab, out, ctx->message_context); - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&ctab); -@@ -13766,6 +13943,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - return ctx->result; - } +- compute_liveness(ctx, entry_func); +- transform_derefs(ctx, divert_written_uniform_derefs_to_temp, &entry_func->body); ++ compute_liveness(ctx, body); ++ transform_derefs(ctx, divert_written_uniform_derefs_to_temp, body); -+ vsir_program_trace(&program); -+ - result = tpf_compile(&program, config_flags, &rdef, out, ctx->message_context); - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&rdef); + loop_unrolling_execute(ctx, body); + hlsl_run_const_passes(ctx, body); +@@ -13561,7 +14178,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, + do + { + progress = vectorize_exprs(ctx, body); +- compute_liveness(ctx, entry_func); ++ compute_liveness(ctx, body); + progress |= hlsl_transform_ir(ctx, dce, body, NULL); + progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); + progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); +@@ -13574,7 +14191,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, + hlsl_transform_ir(ctx, lower_combined_samples, body, NULL); + + do +- compute_liveness(ctx, entry_func); ++ compute_liveness(ctx, body); + while (hlsl_transform_ir(ctx, dce, body, NULL)); + + hlsl_transform_ir(ctx, track_components_usage, body, NULL); +@@ -13587,9 +14204,6 @@ static void process_entry_function(struct hlsl_ctx *ctx, + { + allocate_stream_outputs(ctx); + validate_and_record_stream_outputs(ctx); +- +- memset(&stream_append_ctx, 0, sizeof(stream_append_ctx)); +- stream_append_ctx.func = entry_func; + hlsl_transform_ir(ctx, lower_stream_appends, body, &stream_append_ctx); + } + +@@ -13630,7 +14244,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, + hlsl_run_folding_passes(ctx, body); + + do +- compute_liveness(ctx, entry_func); ++ compute_liveness(ctx, body); + while (hlsl_transform_ir(ctx, dce, body, NULL)); + + /* TODO: move forward, remove when no longer needed */ +@@ -13639,27 +14253,30 @@ static void process_entry_function(struct hlsl_ctx *ctx, + transform_derefs(ctx, clean_constant_deref_offset_srcs, body); + + do +- compute_liveness(ctx, entry_func); ++ compute_liveness(ctx, body); + while (hlsl_transform_ir(ctx, dce, body, NULL)); + +- compute_liveness(ctx, entry_func); ++ compute_liveness(ctx, body); + mark_vars_usage(ctx); + + calculate_resource_register_counts(ctx); + + allocate_register_reservations(ctx, &ctx->extern_vars); +- allocate_register_reservations(ctx, &entry_func->extern_vars); +- allocate_semantic_registers(ctx, entry_func, &output_reg_count); ++ allocate_register_reservations(ctx, semantic_vars); ++ allocate_semantic_registers(ctx, semantic_vars, &output_reg_count); + + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) +- validate_max_output_size(ctx, entry_func, output_reg_count); ++ validate_max_output_size(ctx, semantic_vars, output_reg_count, &entry_func->loc); + } + +-int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, +- enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) ++int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, ++ struct hlsl_ir_function_decl *entry_func, struct vsir_program *program, ++ struct vkd3d_shader_code *reflection_data) + { ++ struct hlsl_block global_uniform_block, body, patch_body; ++ uint32_t config_flags = vkd3d_shader_init_config_flags(); + const struct hlsl_profile_info *profile = ctx->profile; +- struct hlsl_block global_uniform_block; ++ struct list semantic_vars, patch_semantic_vars; + struct hlsl_ir_var *var; + + parse_entry_function_attributes(ctx, entry_func); +@@ -13678,21 +14295,31 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, + "Entry point \"%s\" is missing a [maxvertexcount] attribute.", entry_func->func->name); + ++ list_init(&ctx->extern_vars); ++ list_init(&semantic_vars); ++ list_init(&patch_semantic_vars); + hlsl_block_init(&global_uniform_block); + + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) + { + if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) ++ { + prepend_uniform_copy(ctx, &global_uniform_block, var); ++ } ++ else if (var->storage_modifiers & HLSL_STORAGE_GROUPSHARED) ++ { ++ var->is_tgsm = 1; ++ list_add_tail(&ctx->extern_vars, &var->extern_entry); ++ } + } + +- process_entry_function(ctx, &global_uniform_block, entry_func); ++ process_entry_function(ctx, &semantic_vars, &body, &global_uniform_block, entry_func); + if (ctx->result) + return ctx->result; + + if (profile->type == VKD3D_SHADER_TYPE_HULL) + { +- process_entry_function(ctx, &global_uniform_block, ctx->patch_constant_func); ++ process_entry_function(ctx, &patch_semantic_vars, &patch_body, &global_uniform_block, ctx->patch_constant_func); + if (ctx->result) + return ctx->result; + } +@@ -13701,79 +14328,49 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry + + if (profile->major_version < 4) + { +- mark_indexable_vars(ctx, entry_func); +- allocate_const_registers(ctx, entry_func); ++ mark_indexable_vars(ctx, &body); ++ allocate_const_registers(ctx, &body); + sort_uniforms_by_bind_count(ctx, HLSL_REGSET_SAMPLERS); +- allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS); ++ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS); + } + else + { + allocate_buffers(ctx); +- allocate_objects(ctx, entry_func, HLSL_REGSET_TEXTURES); +- allocate_objects(ctx, entry_func, HLSL_REGSET_UAVS); +- allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS); ++ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_TEXTURES); ++ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_UAVS); ++ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS); ++ allocate_tgsms(ctx); + } + + if (TRACE_ON()) ++ { + rb_for_each_entry(&ctx->functions, dump_function, ctx); ++ hlsl_dump_function(ctx, entry_func, "processed entry point", &body); ++ if (profile->type == VKD3D_SHADER_TYPE_HULL) ++ hlsl_dump_function(ctx, ctx->patch_constant_func, "processed patch-constant function", &patch_body); ++ } + + if (ctx->result) + return ctx->result; + +- switch (target_type) +- { +- case VKD3D_SHADER_TARGET_D3D_BYTECODE: +- { +- uint32_t config_flags = vkd3d_shader_init_config_flags(); +- struct vkd3d_shader_code ctab = {0}; +- struct vsir_program program; +- int result; +- +- sm1_generate_ctab(ctx, &ctab); +- if (ctx->result) +- return ctx->result; +- +- sm1_generate_vsir(ctx, entry_func, config_flags, &program); +- if (ctx->result) +- { +- vsir_program_cleanup(&program); +- vkd3d_shader_free_shader_code(&ctab); +- return ctx->result; +- } ++ generate_vsir_signature(ctx, program, entry_func, &semantic_vars); ++ if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL) ++ generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars); + +- result = d3dbc_compile(&program, config_flags, NULL, &ctab, out, ctx->message_context); +- vsir_program_cleanup(&program); +- vkd3d_shader_free_shader_code(&ctab); +- return result; +- } +- +- case VKD3D_SHADER_TARGET_DXBC_TPF: +- { +- uint32_t config_flags = vkd3d_shader_init_config_flags(); +- struct vkd3d_shader_code rdef = {0}; +- struct vsir_program program; +- int result; +- +- sm4_generate_rdef(ctx, &rdef); +- if (ctx->result) +- return ctx->result; +- +- sm4_generate_vsir(ctx, entry_func, config_flags, &program); +- if (ctx->result) +- { +- vsir_program_cleanup(&program); +- vkd3d_shader_free_shader_code(&rdef); +- return ctx->result; +- } ++ if (program->shader_version.major < 4) ++ sm1_generate_ctab(ctx, reflection_data); ++ else ++ sm4_generate_rdef(ctx, reflection_data); ++ if (ctx->result) ++ return ctx->result; + +- result = tpf_compile(&program, config_flags, &rdef, out, ctx->message_context); +- vsir_program_cleanup(&program); +- vkd3d_shader_free_shader_code(&rdef); +- return result; +- } ++ if (program->shader_version.major < 4) ++ sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program); ++ else ++ sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, ++ &patch_semantic_vars, &patch_body, config_flags, program); ++ if (ctx->result) ++ vkd3d_shader_free_shader_code(reflection_data); + +- default: +- ERR("Unsupported shader target type %#x.\n", target_type); +- return VKD3D_ERROR_INVALID_ARGUMENT; +- } ++ return ctx->result; + } diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 7466f7a2da1..fe7e8c54dfb 100644 +index 7466f7a2da1..23e059a3490 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -29,6 +29,350 @@ struct vsir_transformation_context @@ -10296,7 +14191,33 @@ index 7466f7a2da1..fe7e8c54dfb 100644 static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) { -@@ -163,6 +507,53 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature, +@@ -100,7 +444,16 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c + program->shader_version = *version; + program->cf_type = cf_type; + program->normalisation_level = normalisation_level; +- return shader_instruction_array_init(&program->instructions, reserve); ++ if (!shader_instruction_array_init(&program->instructions, reserve)) ++ { ++ if (program->free_parameters) ++ vkd3d_free((void *)program->parameters); ++ return false; ++ } ++ ++ vkd3d_shader_source_list_init(&program->source_files); ++ ++ return true; + } + + void vsir_program_cleanup(struct vsir_program *program) +@@ -112,6 +465,7 @@ void vsir_program_cleanup(struct vsir_program *program) + for (i = 0; i < program->block_name_count; ++i) + vkd3d_free((void *)program->block_names[i]); + vkd3d_free(program->block_names); ++ vkd3d_shader_source_list_cleanup(&program->source_files); + shader_instruction_array_destroy(&program->instructions); + shader_signature_cleanup(&program->input_signature); + shader_signature_cleanup(&program->output_signature); +@@ -163,8 +517,55 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature, return false; } @@ -10348,15 +14269,81 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +} + void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count) +- enum vkd3d_data_type data_type, unsigned int idx_count) ++ enum vsir_data_type data_type, unsigned int idx_count) { -@@ -249,24 +640,38 @@ static void vsir_src_param_init_sampler(struct vkd3d_shader_src_param *src, unsi + reg->type = reg_type; + reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; +@@ -190,7 +591,7 @@ static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shade + } + + void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, +- enum vkd3d_data_type data_type, unsigned int idx_count) ++ enum vsir_data_type data_type, unsigned int idx_count) + { + vsir_register_init(¶m->reg, reg_type, data_type, idx_count); + param->swizzle = 0; +@@ -199,32 +600,32 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader + + static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value) + { +- vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); ++ vsir_src_param_init(src, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); + src->reg.u.immconst_u32[0] = value; + } + + static void vsir_src_param_init_io(struct vkd3d_shader_src_param *src, + enum vkd3d_shader_register_type reg_type, const struct signature_element *e, unsigned int idx_count) + { +- vsir_src_param_init(src, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count); ++ vsir_src_param_init(src, reg_type, vsir_data_type_from_component_type(e->component_type), idx_count); + src->reg.dimension = VSIR_DIMENSION_VEC4; + src->swizzle = vsir_swizzle_from_writemask(e->mask); + } + + void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id) + { +- vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1); ++ vsir_src_param_init(param, VKD3DSPR_LABEL, VSIR_DATA_UNUSED, 1); + param->reg.dimension = VSIR_DIMENSION_NONE; + param->reg.idx[0].offset = label_id; + } + +-static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type) ++static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vsir_data_type type) + { + vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1); + src->reg.idx[0].offset = idx; + } + +-static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type) ++static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vsir_data_type type) + { + vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1); + src->reg.idx[0].offset = idx; +@@ -234,7 +635,7 @@ static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, ui + + static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx) + { +- vsir_src_param_init(src, VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 2); ++ vsir_src_param_init(src, VKD3DSPR_RESOURCE, VSIR_DATA_UNUSED, 2); + src->reg.idx[0].offset = id; + src->reg.idx[1].offset = idx; + src->reg.dimension = VSIR_DIMENSION_VEC4; +@@ -243,47 +644,61 @@ static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, uns + + static void vsir_src_param_init_sampler(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx) + { +- vsir_src_param_init(src, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 2); ++ vsir_src_param_init(src, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 2); + src->reg.idx[0].offset = id; + src->reg.idx[1].offset = idx; src->reg.dimension = VSIR_DIMENSION_NONE; } -static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx) +static void src_param_init_ssa(struct vkd3d_shader_src_param *src, unsigned int idx, -+ enum vkd3d_data_type data_type, enum vsir_dimension dimension) ++ enum vsir_data_type data_type, enum vsir_dimension dimension) { - vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); + vsir_src_param_init(src, VKD3DSPR_SSA, data_type, 1); @@ -10369,22 +14356,22 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + } +} + -+static void src_param_init_ssa_scalar(struct vkd3d_shader_src_param *src, unsigned int idx, -+ enum vkd3d_data_type data_type) ++static void src_param_init_ssa_scalar(struct vkd3d_shader_src_param *src, ++ unsigned int idx, enum vsir_data_type data_type) +{ + src_param_init_ssa(src, idx, data_type, VSIR_DIMENSION_SCALAR); +} + +static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx) +{ -+ src_param_init_ssa_scalar(src, idx, VKD3D_DATA_BOOL); ++ src_param_init_ssa_scalar(src, idx, VSIR_DATA_BOOL); } static void src_param_init_ssa_float(struct vkd3d_shader_src_param *src, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1); - src->reg.idx[0].offset = idx; -+ src_param_init_ssa_scalar(src, idx, VKD3D_DATA_FLOAT); ++ src_param_init_ssa_scalar(src, idx, VSIR_DATA_F32); } static void src_param_init_ssa_float4(struct vkd3d_shader_src_param *src, unsigned int idx) @@ -10393,17 +14380,66 @@ index 7466f7a2da1..fe7e8c54dfb 100644 - src->reg.idx[0].offset = idx; - src->reg.dimension = VSIR_DIMENSION_VEC4; - src->swizzle = VKD3D_SHADER_NO_SWIZZLE; -+ src_param_init_ssa(src, idx, VKD3D_DATA_FLOAT, VSIR_DIMENSION_VEC4); ++ src_param_init_ssa(src, idx, VSIR_DATA_F32, VSIR_DIMENSION_VEC4); } static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx) -@@ -319,24 +724,38 @@ void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst) + { +- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1); ++ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_BOOL, 1); + src->reg.idx[0].offset = idx; + } + + static void src_param_init_temp_float(struct vkd3d_shader_src_param *src, unsigned int idx) + { +- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); ++ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); + src->reg.idx[0].offset = idx; + } + + static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsigned int idx) + { +- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); ++ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); + src->reg.dimension = VSIR_DIMENSION_VEC4; + src->swizzle = VKD3D_SHADER_NO_SWIZZLE; + src->reg.idx[0].offset = idx; +@@ -291,12 +706,12 @@ static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsig + + static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx) + { +- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + src->reg.idx[0].offset = idx; + } + + void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, +- enum vkd3d_data_type data_type, unsigned int idx_count) ++ enum vsir_data_type data_type, unsigned int idx_count) + { + vsir_register_init(¶m->reg, reg_type, data_type, idx_count); + param->write_mask = VKD3DSP_WRITEMASK_0; +@@ -307,59 +722,73 @@ void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader + static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_register_type reg_type, + const struct signature_element *e, unsigned int idx_count) + { +- vsir_dst_param_init(dst, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count); ++ vsir_dst_param_init(dst, reg_type, vsir_data_type_from_component_type(e->component_type), idx_count); + dst->reg.dimension = VSIR_DIMENSION_VEC4; + dst->write_mask = e->mask; + } + + void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst) + { +- vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); ++ vsir_dst_param_init(dst, VKD3DSPR_NULL, VSIR_DATA_UNUSED, 0); + dst->reg.dimension = VSIR_DIMENSION_NONE; dst->write_mask = 0; } -static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) +static void dst_param_init_ssa(struct vkd3d_shader_dst_param *dst, unsigned int idx, -+ enum vkd3d_data_type data_type, enum vsir_dimension dimension) ++ enum vsir_data_type data_type, enum vsir_dimension dimension) { - vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); + vsir_dst_param_init(dst, VKD3DSPR_SSA, data_type, 1); @@ -10416,22 +14452,22 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + } +} + -+static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *dst, unsigned int idx, -+ enum vkd3d_data_type data_type) ++static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *dst, ++ unsigned int idx, enum vsir_data_type data_type) +{ + dst_param_init_ssa(dst, idx, data_type, VSIR_DIMENSION_SCALAR); +} + +static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) +{ -+ dst_param_init_ssa_scalar(dst, idx, VKD3D_DATA_BOOL); ++ dst_param_init_ssa_scalar(dst, idx, VSIR_DATA_BOOL); } static void dst_param_init_ssa_float(struct vkd3d_shader_dst_param *dst, unsigned int idx) { - vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1); - dst->reg.idx[0].offset = idx; -+ dst_param_init_ssa_scalar(dst, idx, VKD3D_DATA_FLOAT); ++ dst_param_init_ssa_scalar(dst, idx, VSIR_DATA_F32); } static void dst_param_init_ssa_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx) @@ -10440,11 +14476,49 @@ index 7466f7a2da1..fe7e8c54dfb 100644 - dst->reg.idx[0].offset = idx; - dst->reg.dimension = VSIR_DIMENSION_VEC4; - dst->write_mask = VKD3DSP_WRITEMASK_ALL; -+ dst_param_init_ssa(dst, idx, VKD3D_DATA_FLOAT, VSIR_DIMENSION_VEC4); ++ dst_param_init_ssa(dst, idx, VSIR_DATA_F32, VSIR_DIMENSION_VEC4); } static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) -@@ -410,7 +829,7 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, + { +- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1); ++ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_BOOL, 1); + dst->reg.idx[0].offset = idx; + } + + static void dst_param_init_temp_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx) + { +- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); + dst->reg.idx[0].offset = idx; + dst->reg.dimension = VSIR_DIMENSION_VEC4; + } + + static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx) + { +- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + dst->reg.idx[0].offset = idx; + } + + static void dst_param_init_output(struct vkd3d_shader_dst_param *dst, +- enum vkd3d_data_type data_type, uint32_t idx, uint32_t write_mask) ++ enum vsir_data_type data_type, uint32_t idx, uint32_t write_mask) + { + vsir_dst_param_init(dst, VKD3DSPR_OUTPUT, data_type, 1); + dst->reg.idx[0].offset = idx; +@@ -373,6 +802,10 @@ void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vk + memset(ins, 0, sizeof(*ins)); + ins->location = *location; + ins->opcode = opcode; ++ ins->resource_data_type[0] = VSIR_DATA_F32; ++ ins->resource_data_type[1] = VSIR_DATA_F32; ++ ins->resource_data_type[2] = VSIR_DATA_F32; ++ ins->resource_data_type[3] = VSIR_DATA_F32; + } + + bool vsir_instruction_init_with_params(struct vsir_program *program, +@@ -410,7 +843,7 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, vsir_src_param_init_label(src_param, label_id); @@ -10453,7 +14527,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 ins->src = src_param; ins->src_count = 1; -@@ -420,15 +839,15 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, +@@ -420,28 +853,28 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction) { enum vkd3d_shader_opcode opcode = instruction->opcode; @@ -10471,47 +14545,73 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + vsir_instruction_init(ins, &location, VSIR_OP_NOP); } - static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type, -@@ -441,7 +860,7 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d +-static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type, +- enum vkd3d_shader_opcode *opcode, bool *requires_swap) ++static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, ++ enum vsir_data_type data_type, enum vkd3d_shader_opcode *opcode, bool *requires_swap) + { + switch (rel_op) + { + case VKD3D_SHADER_REL_OP_LT: + case VKD3D_SHADER_REL_OP_GT: *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_GT); - if (data_type == VKD3D_DATA_FLOAT) +- if (data_type == VKD3D_DATA_FLOAT) ++ if (data_type == VSIR_DATA_F32) { - *opcode = VKD3DSIH_LTO; + *opcode = VSIR_OP_LTO; return true; } break; -@@ -451,7 +870,7 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d +@@ -449,27 +882,27 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d + case VKD3D_SHADER_REL_OP_GE: + case VKD3D_SHADER_REL_OP_LE: *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_LE); - if (data_type == VKD3D_DATA_FLOAT) +- if (data_type == VKD3D_DATA_FLOAT) ++ if (data_type == VSIR_DATA_F32) { - *opcode = VKD3DSIH_GEO; + *opcode = VSIR_OP_GEO; return true; } break; -@@ -460,7 +879,7 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d + + case VKD3D_SHADER_REL_OP_EQ: *requires_swap = false; - if (data_type == VKD3D_DATA_FLOAT) +- if (data_type == VKD3D_DATA_FLOAT) ++ if (data_type == VSIR_DATA_F32) { - *opcode = VKD3DSIH_EQO; + *opcode = VSIR_OP_EQO; return true; } break; -@@ -469,7 +888,7 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d + + case VKD3D_SHADER_REL_OP_NE: *requires_swap = false; - if (data_type == VKD3D_DATA_FLOAT) +- if (data_type == VKD3D_DATA_FLOAT) ++ if (data_type == VSIR_DATA_F32) { - *opcode = VKD3DSIH_NEO; + *opcode = VSIR_OP_NEO; return true; } break; -@@ -488,17 +907,17 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - { - ins = &program->instructions.elements[i]; +@@ -480,48 +913,47 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d + static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_instruction *ins, *ins2; + unsigned int tmp_idx = ~0u; +- unsigned int i, k, r; ++ unsigned int k, r; +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- - if (ins->opcode == VKD3DSIH_MOV && ins->dst[0].reg.type == VKD3DSPR_ADDR) + if (ins->opcode == VSIR_OP_MOV && ins->dst[0].reg.type == VKD3DSPR_ADDR) { @@ -10519,8 +14619,9 @@ index 7466f7a2da1..fe7e8c54dfb 100644 tmp_idx = program->temp_count++; - ins->opcode = VKD3DSIH_FTOU; +- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + ins->opcode = VSIR_OP_FTOU; - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->dst[0].reg.idx[0].offset = tmp_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; } @@ -10529,60 +14630,215 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { if (tmp_idx == ~0u) tmp_idx = program->temp_count++; -@@ -508,12 +927,12 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - ins = &program->instructions.elements[i]; - ins2 = &program->instructions.elements[i + 1]; + +- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) ++ if (!vsir_program_iterator_insert_after(&it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = &program->instructions.elements[i]; +- ins2 = &program->instructions.elements[i + 1]; ++ ins = vsir_program_iterator_current(&it); - ins->opcode = VKD3DSIH_ROUND_NE; +- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + ins->opcode = VSIR_OP_ROUND_NE; - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = tmp_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VKD3DSIH_FTOU, 1, 1)) ++ ins2 = vsir_program_iterator_next(&it); + if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VSIR_OP_FTOU, 1, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -@@ -591,7 +1010,7 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, +- vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + ins2->dst[0].reg.idx[0].offset = tmp_idx; + ins2->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins2->dst[0].write_mask = ins->dst[0].write_mask; + +- vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); + ins2->src[0].reg.idx[0].offset = tmp_idx; + ins2->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins2->src[0].swizzle = vsir_swizzle_from_writemask(ins2->dst[0].write_mask); +@@ -540,7 +972,7 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra + if (tmp_idx == ~0u) + tmp_idx = program->temp_count++; + +- vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + rel->reg.idx[0].offset = tmp_idx; + rel->reg.dimension = VSIR_DIMENSION_VEC4; + } +@@ -552,18 +984,16 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra + } + + static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, +- struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx, ++ struct vsir_program_iterator *it, unsigned int *tmp_idx, + struct vkd3d_shader_message_context *message_context) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- size_t pos = ifc - instructions->elements; +- struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_instruction *ifc, *ins; + enum vkd3d_shader_opcode opcode; + bool swap; + +- if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) ++ if (!vsir_program_iterator_insert_after(it, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ifc = &instructions->elements[pos]; ++ ifc = vsir_program_iterator_current(it); + + if (*tmp_idx == ~0u) + *tmp_idx = program->temp_count++; +@@ -577,11 +1007,11 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + +- ins = &instructions->elements[pos + 1]; ++ ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, &ifc->location, opcode, 1, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].reg.idx[0].offset = *tmp_idx; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; +@@ -590,12 +1020,12 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, + ins->src[1] = ifc->src[!swap]; /* Create new if instruction using the previous result. */ - ins = &instructions->elements[pos + 2]; +- ins = &instructions->elements[pos + 2]; - if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VKD3DSIH_IF, 0, 1)) ++ ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VSIR_OP_IF, 0, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; -@@ -625,7 +1044,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program +- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].reg.idx[0].offset = *tmp_idx; + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); +@@ -607,35 +1037,33 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, + } + + static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program, +- struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx) ++ struct vsir_program_iterator *it, unsigned int *tmp_idx) + { + const unsigned int components_read = 3 + (program->shader_version.major >= 2); +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- size_t pos = texkill - instructions->elements; +- struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_instruction *ins, *texkill; + unsigned int j; + +- if (!shader_instruction_array_insert_at(instructions, pos + 1, components_read + 1)) ++ if (!vsir_program_iterator_insert_after(it, components_read + 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- texkill = &instructions->elements[pos]; ++ texkill = vsir_program_iterator_current(it); + + if (*tmp_idx == ~0u) + *tmp_idx = program->temp_count++; + /* tmp = ins->src[0] < 0 */ - ins = &instructions->elements[pos + 1]; +- ins = &instructions->elements[pos + 1]; - if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2)) ++ ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_LTO, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -@@ -649,7 +1068,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program +- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].reg.idx[0].offset = *tmp_idx; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; + + ins->src[0].reg = texkill->src[0].reg; + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; +- vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[1].reg.u.immconst_f32[0] = 0.0f; + ins->src[1].reg.u.immconst_f32[1] = 0.0f; +@@ -648,20 +1076,20 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program + for (j = 1; j < components_read; ++j) { - ins = &instructions->elements[pos + 1 + j]; +- ins = &instructions->elements[pos + 1 + j]; - if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_OR, 1, 2))) ++ ins = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_OR, 1, 2))) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -@@ -670,7 +1089,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program +- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].reg.idx[0].offset = *tmp_idx; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; + +- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].reg.idx[0].offset = *tmp_idx; + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); +- vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[1].reg.idx[0].offset = *tmp_idx; + ins->src[1].swizzle = vkd3d_shader_create_swizzle(j, j, j, j); +@@ -669,12 +1097,12 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program + /* discard_nz tmp.x */ - ins = &instructions->elements[pos + 1 + components_read]; +- ins = &instructions->elements[pos + 1 + components_read]; - if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_DISCARD, 0, 1))) ++ ins = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_DISCARD, 0, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; -@@ -712,10 +1131,10 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro - mul_ins = &instructions->elements[pos]; - add_ins = &instructions->elements[pos + 1]; +- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].reg.idx[0].offset = *tmp_idx; + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); +@@ -692,30 +1120,29 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program + * not fused for "precise" operations." + * Windows drivers seem to conform with the latter, for SM 4-5 and SM 6. */ + static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *program, +- struct vkd3d_shader_instruction *mad, unsigned int *tmp_idx) ++ struct vsir_program_iterator *it, unsigned int *tmp_idx) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- struct vkd3d_shader_instruction *mul_ins, *add_ins; +- size_t pos = mad - instructions->elements; ++ struct vkd3d_shader_instruction *mad, *mul_ins, *add_ins; + struct vkd3d_shader_dst_param *mul_dst; + ++ mad = vsir_program_iterator_current(it); ++ + if (!(mad->flags & VKD3DSI_PRECISE_XYZW)) + return VKD3D_OK; + +- if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) ++ if (!vsir_program_iterator_insert_after(it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- mad = &instructions->elements[pos]; + + if (*tmp_idx == ~0u) + *tmp_idx = program->temp_count++; + +- mul_ins = &instructions->elements[pos]; +- add_ins = &instructions->elements[pos + 1]; ++ mul_ins = vsir_program_iterator_current(it); ++ add_ins = vsir_program_iterator_next(it); - mul_ins->opcode = VKD3DSIH_MUL; + mul_ins->opcode = VSIR_OP_MUL; @@ -10593,13 +14849,19 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_ERROR_OUT_OF_MEMORY; add_ins->flags = mul_ins->flags & VKD3DSI_PRECISE_XYZW; -@@ -736,55 +1155,236 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro +@@ -736,84 +1163,308 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro return VKD3D_OK; } +-static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program, +- struct vkd3d_shader_instruction *sincos) +static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program, + struct vkd3d_shader_instruction *imul, struct vsir_transformation_context *ctx) -+{ + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- size_t pos = sincos - instructions->elements; +- struct vkd3d_shader_instruction *ins; +- unsigned int s; + if (imul->dst[0].reg.type != VKD3DSPR_NULL) + { + vkd3d_shader_error(ctx->message_context, &imul->location, @@ -10607,7 +14869,9 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + "Extended multiplication is not implemented."); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } -+ + +- if (sincos->dst_count != 1) +- return VKD3D_OK; + imul->dst[0] = imul->dst[1]; + imul->dst_count = 1; + imul->opcode = VSIR_OP_IMUL_LOW; @@ -10616,18 +14880,18 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +} + +static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, -+ struct vkd3d_shader_instruction *udiv, struct vsir_transformation_context *ctx) ++ struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) +{ -+ struct vkd3d_shader_instruction_array *instructions = &program->instructions; -+ size_t pos = udiv - instructions->elements; -+ struct vkd3d_shader_instruction *ins, *mov; ++ struct vkd3d_shader_instruction *udiv, *ins, *mov; + unsigned int count = 2; + ++ udiv = vsir_program_iterator_current(it); ++ + if (udiv->dst_count != 2) + { + vkd3d_shader_error(ctx->message_context, &udiv->location, + VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, -+ "Internal compiler error: invalid destination count %u for UDIV.", ++ "Internal compiler error: invalid destination count %zu for UDIV.", + udiv->dst_count); + return VKD3D_ERROR; + } @@ -10637,29 +14901,33 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + if (udiv->dst[1].reg.type != VKD3DSPR_NULL) + ++count; + -+ if (!shader_instruction_array_insert_at(instructions, pos + 1, count)) ++ if (!vsir_program_iterator_insert_after(it, count)) + return VKD3D_ERROR_OUT_OF_MEMORY; -+ udiv = &instructions->elements[pos]; -+ -+ ins = &instructions->elements[pos + 1]; ++ udiv = vsir_program_iterator_current(it); + + /* Save the sources in a SSA in case a destination collides with a source. */ -+ mov = ins++; ++ mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + mov->src[0] = udiv->src[0]; + dst_param_init_ssa(&mov->dst[0], program->ssa_count, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); -+ -+ mov = ins++; + +- if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) ++ mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ + return VKD3D_ERROR_OUT_OF_MEMORY; +- sincos = &instructions->elements[pos]; + +- ins = &instructions->elements[pos + 1]; + mov->src[0] = udiv->src[1]; + dst_param_init_ssa(&mov->dst[0], program->ssa_count + 1, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ + +- if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VKD3DSIH_SINCOS, 2, 1))) + if (udiv->dst[0].reg.type != VKD3DSPR_NULL) + { ++ ins = vsir_program_iterator_next(it); ++ + if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_UDIV_SIMPLE, 1, 2))) + return VKD3D_ERROR_OUT_OF_MEMORY; + @@ -10670,12 +14938,12 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + src_param_init_ssa(&ins->src[1], program->ssa_count + 1, + udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + ins->dst[0] = udiv->dst[0]; -+ -+ ++ins; + } + + if (udiv->dst[1].reg.type != VKD3DSPR_NULL) + { ++ ins = vsir_program_iterator_next(it); ++ + if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_UREM, 1, 2))) + return VKD3D_ERROR_OUT_OF_MEMORY; + @@ -10686,8 +14954,6 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + src_param_init_ssa(&ins->src[1], program->ssa_count + 1, + udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + ins->dst[0] = udiv->dst[1]; -+ -+ ++ins; + } + + vkd3d_shader_instruction_make_nop(udiv); @@ -10696,30 +14962,21 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + return VKD3D_OK; +} + - static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program, - struct vkd3d_shader_instruction *sincos) - { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - size_t pos = sincos - instructions->elements; -- struct vkd3d_shader_instruction *ins; -- unsigned int s; -+ struct vkd3d_shader_instruction *ins, *mov; ++static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program, ++ struct vsir_program_iterator *it) ++{ ++ struct vkd3d_shader_instruction *ins, *mov, *sincos; + unsigned int s, count; - -- if (sincos->dst_count != 1) -- return VKD3D_OK; ++ ++ sincos = vsir_program_iterator_current(it); + count = 1 + vkd3d_popcount(sincos->dst[0].write_mask & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1)); - -- if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) -+ if (!shader_instruction_array_insert_at(instructions, pos + 1, count)) - return VKD3D_ERROR_OUT_OF_MEMORY; - sincos = &instructions->elements[pos]; - - ins = &instructions->elements[pos + 1]; - -- if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VKD3DSIH_SINCOS, 2, 1))) ++ ++ if (!vsir_program_iterator_insert_after(it, count)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ sincos = vsir_program_iterator_current(it); ++ + /* Save the source in a SSA in case a destination collides with the source. */ -+ mov = ins++; ++ mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &sincos->location, VSIR_OP_MOV, 1, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -10736,6 +14993,8 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_1) { ++ ins = vsir_program_iterator_next(it); ++ + if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_SIN, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + @@ -10745,14 +15004,14 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + ins->dst[0] = *sincos->dst; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_1; -+ -+ ++ins; } - else + + if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) { - vsir_dst_param_init_null(&ins->dst[0]); ++ ins = vsir_program_iterator_next(it); ++ + if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_COS, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + @@ -10762,8 +15021,6 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + + ins->dst[0] = *sincos->dst; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; -+ -+ ++ins; } - if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) @@ -10774,20 +15031,20 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +} + +static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *program, -+ struct vkd3d_shader_instruction *sincos, struct vsir_transformation_context *ctx) ++ struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) +{ -+ struct vkd3d_shader_instruction_array *instructions = &program->instructions; -+ size_t pos = sincos - instructions->elements; -+ struct vkd3d_shader_instruction *ins, *mov; ++ struct vkd3d_shader_instruction *ins, *mov, *sincos; + unsigned int count = 1; + ++ sincos = vsir_program_iterator_current(it); ++ + if (sincos->dst_count != 2) { - ins->dst[1] = *sincos->dst; - ins->dst[1].write_mask = VKD3DSP_WRITEMASK_0; + vkd3d_shader_error(ctx->message_context, &sincos->location, + VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, -+ "Internal compiler error: invalid destination count %u for SINCOS.", ++ "Internal compiler error: invalid destination count %zu for SINCOS.", + sincos->dst_count); + return VKD3D_ERROR; } @@ -10798,14 +15055,12 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + if (sincos->dst[1].reg.type != VKD3DSPR_NULL) + ++count; + -+ if (!shader_instruction_array_insert_at(instructions, pos + 1, count)) ++ if (!vsir_program_iterator_insert_after(it, count)) + return VKD3D_ERROR_OUT_OF_MEMORY; -+ sincos = &instructions->elements[pos]; -+ -+ ins = &instructions->elements[pos + 1]; ++ sincos = vsir_program_iterator_current(it); + + /* Save the source in a SSA in case a destination collides with the source. */ -+ mov = ins++; ++ mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &sincos->location, VSIR_OP_MOV, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + @@ -10815,6 +15070,8 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + if (sincos->dst[0].reg.type != VKD3DSPR_NULL) { - vsir_dst_param_init_null(&ins->dst[1]); ++ ins = vsir_program_iterator_next(it); ++ + if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_SIN, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + @@ -10823,12 +15080,12 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + src_param_init_ssa(&ins->src[0], program->ssa_count, + sincos->src[0].reg.data_type, sincos->src[0].reg.dimension); + ins->dst[0] = sincos->dst[0]; -+ -+ ++ins; + } + + if (sincos->dst[1].reg.type != VKD3DSPR_NULL) + { ++ ins = vsir_program_iterator_next(it); ++ + if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_COS, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + @@ -10837,35 +15094,114 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + src_param_init_ssa(&ins->src[0], program->ssa_count, + sincos->src[0].reg.data_type, sincos->src[0].reg.dimension); + ins->dst[0] = sincos->dst[1]; -+ -+ ++ins; } - /* Make the original instruction no-op */ vkd3d_shader_instruction_make_nop(sincos); + ++program->ssa_count; ++ ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program, ++ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) ++{ ++ /* texcrd DST, t# -> mov DST, t# */ ++ ++ if (ins->src[0].modifiers) ++ { ++ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Aborting due to not yet implemented feature: texcrd source modifier."); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ ins->opcode = VSIR_OP_MOV; ++ ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program, ++ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) ++{ ++ unsigned int idx = ins->src[0].reg.idx[0].offset; ++ struct vkd3d_shader_src_param *srcs; ++ ++ /* texld DST, t# -> sample DST, t#, resource#, sampler# */ ++ ++ if (ins->src[0].modifiers) ++ { ++ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Aborting due to not yet implemented feature: texld source modifier."); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ /* Note we run before I/O normalization. */ ++ srcs[0] = ins->src[0]; ++ vsir_src_param_init_resource(&srcs[1], idx, idx); ++ vsir_src_param_init_sampler(&srcs[2], idx, idx); ++ ++ ins->opcode = VSIR_OP_SAMPLE; ++ ins->src = srcs; ++ ins->src_count = 3; return VKD3D_OK; } -@@ -810,7 +1410,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, - div_ins = &instructions->elements[pos + 1]; - tex_ins = &instructions->elements[pos + 2]; + + static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, +- struct vkd3d_shader_instruction *tex, unsigned int *tmp_idx) ++ struct vsir_program_iterator *it, unsigned int *tmp_idx) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- struct vkd3d_shader_location *location = &tex->location; +- struct vkd3d_shader_instruction *div_ins, *tex_ins; +- size_t pos = tex - instructions->elements; ++ struct vkd3d_shader_instruction *div_ins, *tex, *tex_ins; ++ struct vsir_program_iterator it2; + unsigned int w_comp; + ++ tex = vsir_program_iterator_current(it); ++ + w_comp = vsir_swizzle_get_component(tex->src[0].swizzle, 3); + +- if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) ++ if (!vsir_program_iterator_insert_after(it, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- tex = &instructions->elements[pos]; ++ tex = vsir_program_iterator_current(it); + + if (*tmp_idx == ~0u) + *tmp_idx = program->temp_count++; + +- div_ins = &instructions->elements[pos + 1]; +- tex_ins = &instructions->elements[pos + 2]; ++ /* Do not increment `it', because we need to scan the generated instructions ++ * again to lower TEXLD. */ ++ it2 = *it; ++ div_ins = vsir_program_iterator_next(&it2); ++ tex_ins = vsir_program_iterator_next(&it2); - if (!vsir_instruction_init_with_params(program, div_ins, location, VKD3DSIH_DIV, 1, 2)) -+ if (!vsir_instruction_init_with_params(program, div_ins, location, VSIR_OP_DIV, 1, 2)) ++ if (!vsir_instruction_init_with_params(program, div_ins, &tex->location, VSIR_OP_DIV, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -@@ -823,7 +1423,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, +- vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VSIR_DATA_F32, 1); + div_ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + div_ins->dst[0].reg.idx[0].offset = *tmp_idx; + div_ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; +@@ -823,7 +1474,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, div_ins->src[1] = tex->src[0]; div_ins->src[1].swizzle = vkd3d_shader_create_swizzle(w_comp, w_comp, w_comp, w_comp); - if (!vsir_instruction_init_with_params(program, tex_ins, location, VKD3DSIH_TEX, 1, 2)) -+ if (!vsir_instruction_init_with_params(program, tex_ins, location, VSIR_OP_TEXLD, 1, 2)) ++ if (!vsir_instruction_init_with_params(program, tex_ins, &tex->location, VSIR_OP_TEXLD, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; tex_ins->dst[0] = tex->dst[0]; -@@ -838,7 +1438,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, +@@ -838,7 +1489,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, return VKD3D_OK; } @@ -10874,7 +15210,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context) { unsigned int idx = tex->src[1].reg.idx[0].offset; -@@ -856,7 +1456,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, +@@ -856,7 +1507,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, if (!tex->flags) { @@ -10883,7 +15219,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 tex->src = srcs; tex->src_count = 3; } -@@ -864,7 +1464,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, +@@ -864,7 +1515,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, { enum vkd3d_shader_swizzle_component w = vsir_swizzle_get_component(srcs[0].swizzle, 3); @@ -10892,7 +15228,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 tex->src = srcs; tex->src_count = 4; -@@ -899,7 +1499,7 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, +@@ -899,13 +1550,41 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, srcs[3] = texldd->src[2]; srcs[4] = texldd->src[3]; @@ -10901,25 +15237,119 @@ index 7466f7a2da1..fe7e8c54dfb 100644 texldd->src = srcs; texldd->src_count = 5; -@@ -990,57 +1590,77 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + return VKD3D_OK; + } ++static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, ++ struct vkd3d_shader_instruction *texldl) ++{ ++ unsigned int idx = texldl->src[1].reg.idx[0].offset; ++ enum vkd3d_shader_swizzle_component w; ++ struct vkd3d_shader_src_param *srcs; ++ ++ VKD3D_ASSERT(texldl->src[1].reg.idx_count == 1); ++ VKD3D_ASSERT(!texldl->src[1].reg.idx[0].rel_addr); ++ ++ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 4))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ srcs[0] = texldl->src[0]; ++ vsir_src_param_init_resource(&srcs[1], idx, idx); ++ vsir_src_param_init_sampler(&srcs[2], idx, idx); ++ ++ texldl->opcode = VSIR_OP_SAMPLE_LOD; ++ texldl->src = srcs; ++ texldl->src_count = 4; ++ ++ w = vsir_swizzle_get_component(srcs[0].swizzle, 3); ++ srcs[3] = texldl->src[0]; ++ srcs[3].swizzle = vkd3d_shader_create_swizzle(w, w, w, w); ++ ++ return VKD3D_OK; ++} ++ + static enum vkd3d_result vsir_program_lower_dcl_input(struct vsir_program *program, + struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) + { +@@ -976,108 +1655,157 @@ static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *prog + return VKD3D_OK; + } + ++static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_message_context *message_context = ctx->message_context; ++ struct vkd3d_shader_instruction *ins; ++ unsigned int tmp_idx = ~0u; ++ ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ enum vkd3d_result ret; ++ ++ switch (ins->opcode) ++ { ++ case VSIR_OP_TEXCRD: ++ ret = vsir_program_lower_texcrd(program, ins, message_context); ++ break; ++ ++ case VSIR_OP_TEXLD: ++ if (program->shader_version.major == 1) ++ ret = vsir_program_lower_texld_sm1(program, ins, message_context); ++ else if (ins->flags == VKD3DSI_TEXLD_PROJECT) ++ ret = vsir_program_lower_texldp(program, &it, &tmp_idx); ++ else ++ ret = vsir_program_lower_texld(program, ins, message_context); ++ break; ++ ++ default: ++ ret = VKD3D_OK; ++ break; ++ } ++ ++ if (ret < 0) ++ return ret; ++ } ++ ++ return VKD3D_OK; ++} ++ + static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; +- unsigned int tmp_idx = ~0u, i; ++ struct vkd3d_shader_instruction *ins; ++ unsigned int tmp_idx = ~0u; + enum vkd3d_result ret; + +- for (i = 0; i < instructions->count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &instructions->elements[i]; +- switch (ins->opcode) { - case VKD3DSIH_IFC: +- if ((ret = vsir_program_lower_ifc(program, ins, &tmp_idx, message_context)) < 0) + case VSIR_OP_IFC: - if ((ret = vsir_program_lower_ifc(program, ins, &tmp_idx, message_context)) < 0) ++ if ((ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context)) < 0) return ret; break; - case VKD3DSIH_TEXKILL: +- if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0) + case VSIR_OP_TEXKILL: - if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0) ++ if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0) return ret; break; - case VKD3DSIH_MAD: +- if ((ret = vsir_program_lower_precise_mad(program, ins, &tmp_idx)) < 0) + case VSIR_OP_MAD: - if ((ret = vsir_program_lower_precise_mad(program, ins, &tmp_idx)) < 0) ++ if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) return ret; break; @@ -10975,38 +15405,27 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + case VSIR_OP_IMUL: + case VSIR_OP_UMUL: + if ((ret = vsir_program_lower_imul(program, ins, ctx)) < 0) -+ return ret; -+ break; -+ -+ case VSIR_OP_UDIV: -+ if ((ret = vsir_program_lower_udiv(program, ins, ctx)) < 0) return ret; break; - case VKD3DSIH_TEX: -+ case VSIR_OP_SINCOS: -+ if (ins->dst_count == 1) -+ { -+ if ((ret = vsir_program_lower_sm1_sincos(program, ins)) < 0) -+ return ret; -+ } -+ else -+ { -+ if ((ret = vsir_program_lower_sm4_sincos(program, ins, ctx)) < 0) -+ return ret; -+ } +- if (ins->flags == VKD3DSI_TEXLD_PROJECT) ++ case VSIR_OP_UDIV: ++ if ((ret = vsir_program_lower_udiv(program, &it, ctx)) < 0) ++ return ret; + break; + -+ case VSIR_OP_TEXLD: - if (ins->flags == VKD3DSI_TEXLD_PROJECT) ++ case VSIR_OP_SINCOS: ++ if (ins->dst_count == 1) { - if ((ret = vsir_program_lower_texldp(program, ins, &tmp_idx)) < 0) -@@ -1048,36 +1668,37 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr +- if ((ret = vsir_program_lower_texldp(program, ins, &tmp_idx)) < 0) ++ if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0) + return ret; } else { - if ((ret = vsir_program_lower_tex(program, ins, message_context)) < 0) -+ if ((ret = vsir_program_lower_texld(program, ins, message_context)) < 0) ++ if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) return ret; } break; @@ -11034,14 +15453,17 @@ index 7466f7a2da1..fe7e8c54dfb 100644 - case VKD3DSIH_TEXREG2AR: - case VKD3DSIH_TEXREG2GB: - case VKD3DSIH_TEXREG2RGB: ++ case VSIR_OP_TEXLDL: ++ if ((ret = vsir_program_lower_texldl(program, ins)) < 0) ++ return ret; ++ break; ++ + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + case VSIR_OP_TEXCOORD: -+ case VSIR_OP_TEXCRD: + case VSIR_OP_TEXDEPTH: + case VSIR_OP_TEXDP3: + case VSIR_OP_TEXDP3TEX: -+ case VSIR_OP_TEXLDL: + case VSIR_OP_TEXM3x2PAD: + case VSIR_OP_TEXM3x2TEX: + case VSIR_OP_TEXM3x3DIFF: @@ -11060,15 +15482,23 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_ERROR_NOT_IMPLEMENTED; default: -@@ -1088,43 +1709,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr +@@ -1088,69 +1816,69 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr return VKD3D_OK; } -static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg, - unsigned int instance_id) --{ ++/* Ensure that the program closes with a ret. sm1 programs do not, by default. ++ * Many of our IR passes rely on this in order to insert instructions at the ++ * end of execution. */ ++static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) + { - unsigned int i; -- ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_instruction *ins; + - for (i = 0; i < reg->idx_count; ++i) - { - if (reg->idx[i].rel_addr && shader_register_is_phase_instance_id(®->idx[i].rel_addr->reg)) @@ -11084,7 +15514,10 @@ index 7466f7a2da1..fe7e8c54dfb 100644 -{ - struct vkd3d_shader_register *reg; - unsigned int i; -- ++ ins = vsir_program_iterator_tail(&it); ++ if (ins && ins->opcode == VSIR_OP_RET) ++ return VKD3D_OK; + - for (i = 0; i < ins->src_count; ++i) - { - reg = (struct vkd3d_shader_register *)&ins->src[i].reg; @@ -11096,26 +15529,54 @@ index 7466f7a2da1..fe7e8c54dfb 100644 - } - shader_register_eliminate_phase_addressing(reg, instance_id); - } -- ++ if (!(ins = vsir_program_append(program))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ vsir_instruction_init(ins, &no_loc, VSIR_OP_RET); + - for (i = 0; i < ins->dst_count; ++i) - shader_register_eliminate_phase_addressing(&ins->dst[i].reg, instance_id); --} -- - /* Ensure that the program closes with a ret. sm1 programs do not, by default. - * Many of our IR passes rely on this in order to insert instructions at the - * end of execution. */ -@@ -1133,24 +1717,24 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, - { - static const struct vkd3d_shader_location no_loc; - if (program->instructions.count -- && program->instructions.elements[program->instructions.count - 1].opcode == VKD3DSIH_RET) -+ && program->instructions.elements[program->instructions.count - 1].opcode == VSIR_OP_RET) - return VKD3D_OK; ++ return VKD3D_OK; + } - if (!shader_instruction_array_insert_at(&program->instructions, program->instructions.count, 1)) +-/* Ensure that the program closes with a ret. sm1 programs do not, by default. +- * Many of our IR passes rely on this in order to insert instructions at the +- * end of execution. */ +-static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, ++/* ps_1_* outputs color in r0. Add an instruction to copy that to oC0. ++ * We don't need to modify the signature since it already contains COLOR. */ ++static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- static const struct vkd3d_shader_location no_loc; +- if (program->instructions.count +- && program->instructions.elements[program->instructions.count - 1].opcode == VKD3DSIH_RET) ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_location loc; ++ ++ if (!(ins = vsir_program_iterator_tail(&it))) + return VKD3D_OK; ++ loc = ins->location; + +- if (!shader_instruction_array_insert_at(&program->instructions, program->instructions.count, 1)) ++ if (!(ins = vsir_program_append(program))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1)) ++ { ++ vsir_instruction_init(ins, &loc, VSIR_OP_NOP); return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_instruction_init(&program->instructions.elements[program->instructions.count - 1], &no_loc, VKD3DSIH_RET); -+ vsir_instruction_init(&program->instructions.elements[program->instructions.count - 1], &no_loc, VSIR_OP_RET); ++ } ++ ++ src_param_init_temp_float4(&ins->src[0], 0); ++ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ /* Note we run before I/O normalization. */ ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_COLOROUT, VSIR_DATA_F32, 1); ++ ins->dst[0].reg.idx[0].offset = 0; ++ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; ++ ins->dst[0].modifiers = VKD3DSPDM_SATURATE; ++ return VKD3D_OK; } @@ -11134,7 +15595,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 signature->elements = new_elements; e = &signature->elements[signature->element_count++]; memset(e, 0, sizeof(*e)); -@@ -1164,7 +1748,7 @@ static bool add_signature_element(struct shader_signature *signature, const char +@@ -1164,7 +1892,7 @@ static bool add_signature_element(struct shader_signature *signature, const char e->register_index = register_index; e->target_location = register_index; e->interpolation_mode = interpolation_mode; @@ -11143,26 +15604,71 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program, -@@ -1209,7 +1793,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra +@@ -1194,6 +1922,7 @@ static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *pr + static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; + unsigned int i; +@@ -1205,24 +1934,23 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra + /* Write the instruction after all LABEL, DCL, and NOP instructions. + * We need to skip NOP instructions because they might result from removed + * DCLs, and there could still be DCLs after NOPs. */ +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - ins = &program->instructions.elements[i]; - +- ins = &program->instructions.elements[i]; +- - if (!vsir_instruction_is_dcl(ins) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP) + if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) break; } -@@ -1217,7 +1801,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra +- if (!shader_instruction_array_insert_at(&program->instructions, i, 1)) ++ vsir_program_iterator_prev(&it); ++ if (!vsir_program_iterator_insert_after(&it, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[i]; +- ins = &program->instructions.elements[i]; ++ ins = vsir_program_iterator_next(&it); - vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); +- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VKD3D_DATA_FLOAT, 1); + vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = 0; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -@@ -1429,7 +2013,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL & ~program->diffuse_written_mask; +- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); ++ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + for (i = 0; i < 4; ++i) + ins->src[0].reg.u.immconst_f32[i] = 1.0f; +@@ -1316,6 +2044,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + struct vsir_transformation_context *ctx) + { + const struct vkd3d_shader_location location = {.source_name = ctx->compile_info->source_name}; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + const struct vkd3d_shader_compile_info *compile_info = ctx->compile_info; + bool allows_subset_masks = target_allows_subset_masks(compile_info); +@@ -1325,6 +2054,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + struct signature_element *new_elements, *e; + unsigned int uninit_varying_count = 0; + unsigned int subset_varying_count = 0; ++ struct vkd3d_shader_instruction *ins; + unsigned int new_register_count = 0; + unsigned int i; + +@@ -1424,31 +2154,29 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + } + + /* Write each uninitialized varying before each ret. */ +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; struct vkd3d_shader_location loc; - if (ins->opcode != VKD3DSIH_RET) @@ -11170,16 +15676,45 @@ index 7466f7a2da1..fe7e8c54dfb 100644 continue; loc = ins->location; -@@ -1441,7 +2025,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program +- if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count)) ++ vsir_program_iterator_prev(&it); ++ if (!vsir_program_iterator_insert_after(&it, uninit_varying_count)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = &program->instructions.elements[i]; ++ ins = vsir_program_iterator_next(&it); + + for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) { e = &signature->elements[j]; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); +- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, e->register_index, e->mask); +- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, e->register_index, e->mask); - vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); ++ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask); ++ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; -@@ -1472,17 +2056,19 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program +- ++ins; ++ ins = vsir_program_iterator_next(&it); + } +- +- i += uninit_varying_count; + } + + /* Vulkan (without KHR_maintenance4) disallows any mismatching masks, +@@ -1459,10 +2187,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + if (!subset_varying_count || allows_subset_masks) + return VKD3D_OK; + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + for (unsigned int j = 0; j < ins->dst_count; ++j) + remove_unread_output_components(signature, ins, &ins->dst[j]); + } +@@ -1472,17 +2198,19 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program struct hull_flattener { @@ -11201,12 +15736,16 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } struct shader_phase_location -@@ -1502,11 +2088,11 @@ struct shader_phase_location_array - static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, - unsigned int index, struct shader_phase_location_array *locations) +@@ -1499,14 +2227,13 @@ struct shader_phase_location_array + unsigned int count; + }; + +-static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, +- unsigned int index, struct shader_phase_location_array *locations) ++static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index, ++ struct vkd3d_shader_instruction *ins, struct shader_phase_location_array *locations) { - struct vkd3d_shader_instruction *ins = &normaliser->instructions.elements[index]; -+ struct vkd3d_shader_instruction *ins = &normaliser->program->instructions.elements[index]; struct shader_phase_location *loc; bool b; @@ -11215,7 +15754,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { b = flattener_is_in_fork_or_join_phase(normaliser); /* Reset the phase info. */ -@@ -1518,21 +2104,21 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal +@@ -1518,21 +2245,21 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal vkd3d_shader_instruction_make_nop(ins); return; } @@ -11241,7 +15780,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { normaliser->last_ret_location = ins->location; vkd3d_shader_instruction_make_nop(ins); -@@ -1548,26 +2134,89 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal +@@ -1548,26 +2275,89 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal } } @@ -11336,7 +15875,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 end = j; count -= (loc->instance_count - 1) * loc->instruction_count; loc->index += count; -@@ -1581,7 +2230,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali +@@ -1581,7 +2371,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali { for (k = 0; k < loc->instruction_count; ++k) { @@ -11345,7 +15884,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 loc->index + loc->instruction_count * j + k, loc->index + k)) return VKD3D_ERROR_OUT_OF_MEMORY; } -@@ -1589,9 +2238,12 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali +@@ -1589,9 +2379,12 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali /* Replace each reference to the instance id with a constant instance id. */ for (j = 0; j < loc->instance_count; ++j) { @@ -11360,24 +15899,30 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } } -@@ -1601,31 +2253,38 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali +@@ -1601,31 +2394,41 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, struct vsir_transformation_context *ctx) { - struct hull_flattener flattener = {program->instructions}; - struct vkd3d_shader_instruction_array *instructions; -+ struct vkd3d_shader_instruction_array *instructions = &program->instructions; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct shader_phase_location_array locations; + struct hull_flattener flattener = {program}; ++ struct vkd3d_shader_instruction *ins; enum vkd3d_result result = VKD3D_OK; unsigned int i; - instructions = &flattener.instructions; - - flattener.phase = VKD3DSIH_INVALID; +- for (i = 0, locations.count = 0; i < instructions->count; ++i) +- flattener_eliminate_phase_related_dcls(&flattener, i, &locations); + flattener.phase = VSIR_OP_INVALID; - for (i = 0, locations.count = 0; i < instructions->count; ++i) - flattener_eliminate_phase_related_dcls(&flattener, i, &locations); ++ locations.count = 0; ++ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) ++ { ++ flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations); ++ } bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID); bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID); @@ -11398,18 +15943,17 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + if (flattener.phase != VSIR_OP_INVALID) { - if (!shader_instruction_array_reserve(&flattener.instructions, flattener.instructions.count + 1)) -+ if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) ++ if (!(ins = vsir_program_append(program))) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_instruction_init(&instructions->elements[instructions->count++], &flattener.last_ret_location, VKD3DSIH_RET); -+ vsir_instruction_init(&instructions->elements[instructions->count++], -+ &flattener.last_ret_location, VSIR_OP_RET); ++ vsir_instruction_init(ins, &flattener.last_ret_location, VSIR_OP_RET); } - program->instructions = flattener.instructions; return result; } -@@ -1638,7 +2297,7 @@ struct control_point_normaliser +@@ -1638,7 +2441,7 @@ struct control_point_normaliser static bool control_point_normaliser_is_in_control_point_phase(const struct control_point_normaliser *normaliser) { @@ -11418,7 +15962,16 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_program *program) -@@ -1696,7 +2355,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p +@@ -1652,7 +2455,7 @@ struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_ + if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1))) + return NULL; + +- vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, 0); ++ vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, 0); + rel_addr->swizzle = 0; + rel_addr->modifiers = 0; + +@@ -1696,7 +2499,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p normaliser->instructions.count += count; ins = &normaliser->instructions.elements[dst]; @@ -11427,7 +15980,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 ++ins; -@@ -1706,7 +2365,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p +@@ -1706,7 +2509,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p if (!e->used_mask) continue; @@ -11436,7 +15989,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 ins->dst = shader_dst_param_allocator_get(&normaliser->instructions.dst_params, 1); ins->dst_count = 1; ins->src = shader_src_param_allocator_get(&normaliser->instructions.src_params, 1); -@@ -1733,7 +2392,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p +@@ -1733,7 +2536,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p ++ins; } @@ -11445,17 +15998,33 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_OK; } -@@ -1764,7 +2423,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -1741,11 +2544,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p + static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io( + struct vsir_program *program, struct vsir_transformation_context *ctx) + { +- struct vkd3d_shader_instruction_array *instructions; + struct control_point_normaliser normaliser; + unsigned int input_control_point_count; + struct vkd3d_shader_location location; + struct vkd3d_shader_instruction *ins; ++ struct vsir_program_iterator it; + enum vkd3d_result ret; + unsigned int i, j; + +@@ -1763,18 +2566,16 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + return VKD3D_ERROR_OUT_OF_MEMORY; } normaliser.instructions = program->instructions; - instructions = &normaliser.instructions; +- instructions = &normaliser.instructions; - normaliser.phase = VKD3DSIH_INVALID; ++ it = vsir_program_iterator(&normaliser.instructions); + normaliser.phase = VSIR_OP_INVALID; - for (i = 0; i < normaliser.instructions.count; ++i) +- for (i = 0; i < normaliser.instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { -@@ -1772,9 +2431,9 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i - +- ins = &instructions->elements[i]; +- switch (ins->opcode) { - case VKD3DSIH_HS_CONTROL_POINT_PHASE: @@ -11467,7 +16036,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 normaliser.phase = ins->opcode; break; default: -@@ -1786,7 +2445,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -1786,24 +2587,22 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i } } @@ -11475,9 +16044,11 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + normaliser.phase = VSIR_OP_INVALID; input_control_point_count = 1; - for (i = 0; i < instructions->count; ++i) -@@ -1795,15 +2454,15 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i - +- for (i = 0; i < instructions->count; ++i) ++ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) + { +- ins = &instructions->elements[i]; +- switch (ins->opcode) { - case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: @@ -11496,15 +16067,16 @@ index 7466f7a2da1..fe7e8c54dfb 100644 /* ins may be relocated if the instruction array expands. */ location = ins->location; ret = control_point_normaliser_emit_hs_input(&normaliser, &program->input_signature, -@@ -1835,6 +2494,7 @@ struct io_normaliser_register_data +@@ -1835,7 +2634,7 @@ struct io_normaliser_register_data struct io_normaliser { struct vkd3d_shader_message_context *message_context; +- struct vkd3d_shader_instruction_array instructions; + enum vkd3d_result result; - struct vkd3d_shader_instruction_array instructions; enum vkd3d_shader_type shader_type; uint8_t major; -@@ -1861,7 +2521,7 @@ struct io_normaliser + struct shader_signature *input_signature; +@@ -1861,7 +2660,7 @@ struct io_normaliser static bool io_normaliser_is_in_fork_or_join_phase(const struct io_normaliser *normaliser) { @@ -11513,7 +16085,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } static bool shader_signature_find_element_for_reg(const struct shader_signature *signature, -@@ -2338,7 +2998,7 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par +@@ -2338,7 +3137,7 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par } static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_param, @@ -11522,7 +16094,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { unsigned int i, id_idx, reg_idx, write_mask, element_idx, component_idx; struct vkd3d_shader_register *reg = &src_param->reg; -@@ -2401,7 +3061,12 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par +@@ -2401,7 +3200,12 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par id_idx = reg->idx_count - 1; write_mask = VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(src_param->swizzle, 0); if (!shader_signature_find_element_for_reg(signature, reg_idx, write_mask, &element_idx)) @@ -11536,7 +16108,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 e = &signature->elements[element_idx]; if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic))) -@@ -2424,9 +3089,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi +@@ -2424,9 +3228,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi switch (ins->opcode) { @@ -11549,7 +16121,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 normaliser->phase = ins->opcode; memset(normaliser->input_dcl_params, 0, sizeof(normaliser->input_dcl_params)); memset(normaliser->output_dcl_params, 0, sizeof(normaliser->output_dcl_params)); -@@ -2438,7 +3103,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi +@@ -2438,7 +3242,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi for (i = 0; i < ins->dst_count; ++i) shader_dst_param_io_normalise(&ins->dst[i], normaliser); for (i = 0; i < ins->src_count; ++i) @@ -11558,15 +16130,16 @@ index 7466f7a2da1..fe7e8c54dfb 100644 break; } } -@@ -2446,14 +3111,14 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi +@@ -2446,37 +3250,35 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program, struct vsir_transformation_context *ctx) { - struct io_normaliser normaliser = {ctx->message_context, program->instructions}; -+ struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK, program->instructions}; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK}; struct vkd3d_shader_instruction *ins; enum vkd3d_result ret; - unsigned int i; +- unsigned int i; VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_HULL_CONTROL_POINT_IO); @@ -11575,8 +16148,14 @@ index 7466f7a2da1..fe7e8c54dfb 100644 normaliser.shader_type = program->shader_version.type; normaliser.major = program->shader_version.major; normaliser.input_signature = &program->input_signature; -@@ -2466,17 +3131,17 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program + normaliser.output_signature = &program->output_signature; + normaliser.patch_constant_signature = &program->patch_constant_signature; +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- switch (ins->opcode) { - case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT: @@ -11598,16 +16177,25 @@ index 7466f7a2da1..fe7e8c54dfb 100644 normaliser.phase = ins->opcode; break; default: -@@ -2494,14 +3159,14 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program +@@ -2489,19 +3291,17 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program + normaliser.output_range_map, false)) < 0 + || (ret = shader_signature_merge(&normaliser, &program->patch_constant_signature, + normaliser.pc_range_map, true)) < 0) +- { +- program->instructions = normaliser.instructions; return ret; - } +- } - normaliser.phase = VKD3DSIH_INVALID; +- for (i = 0; i < normaliser.instructions.count; ++i) +- shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser); + normaliser.phase = VSIR_OP_INVALID; - for (i = 0; i < normaliser.instructions.count; ++i) - shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser); ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ shader_instruction_normalise_io_params(ins, &normaliser); ++ } - program->instructions = normaliser.instructions; +- program->instructions = normaliser.instructions; program->use_vocp = normaliser.use_vocp; program->normalisation_level = VSIR_NORMALISED_SM6; - return VKD3D_OK; @@ -11615,17 +16203,65 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } struct flat_constant_def -@@ -2594,7 +3259,7 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr - { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +@@ -2587,14 +3387,14 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par + static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct flat_constants_normaliser normaliser = {0}; +- unsigned int i, j; ++ struct vkd3d_shader_instruction *ins; ++ unsigned int i; +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- - if (ins->opcode == VKD3DSIH_DEF || ins->opcode == VKD3DSIH_DEFI || ins->opcode == VKD3DSIH_DEFB) + if (ins->opcode == VSIR_OP_DEF || ins->opcode == VSIR_OP_DEFI || ins->opcode == VSIR_OP_DEFB) { struct flat_constant_def *def; -@@ -2636,9 +3301,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog +@@ -2608,15 +3408,19 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr + def = &normaliser.defs[normaliser.def_count++]; + get_flat_constant_register_type(&ins->dst[0].reg, &def->set, &def->index, NULL); +- for (j = 0; j < 4; ++j) +- def->value[j] = ins->src[0].reg.u.immconst_u32[j]; ++ for (i = 0; i < 4; ++i) ++ { ++ def->value[i] = ins->src[0].reg.u.immconst_u32[i]; ++ } + + vkd3d_shader_instruction_make_nop(ins); + } + else + { +- for (j = 0; j < ins->src_count; ++j) +- shader_register_normalise_flat_constants(&ins->src[j], &normaliser); ++ for (i = 0; i < ins->src_count; ++i) ++ { ++ shader_register_normalise_flat_constants(&ins->src[i], &normaliser); ++ } + } + } + +@@ -2627,18 +3431,18 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr + static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- size_t i, depth = 0; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; + bool dead = false; ++ size_t depth = 0; + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- switch (ins->opcode) { - case VKD3DSIH_IF: @@ -11637,7 +16273,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (dead) { vkd3d_shader_instruction_make_nop(ins); -@@ -2646,15 +3311,15 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog +@@ -2646,15 +3450,15 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog } break; @@ -11658,7 +16294,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 --depth; vkd3d_shader_instruction_make_nop(ins); } -@@ -2669,9 +3334,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog +@@ -2669,9 +3473,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog * segment began. So it starts at zero and it signals the * termination of the dead code segment when it would * become negative. */ @@ -11671,7 +16307,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (dead) { vkd3d_shader_instruction_make_nop(ins); -@@ -2686,8 +3351,8 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog +@@ -2686,8 +3490,8 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog /* If `case' or `default' appears at zero depth, it means * that they are a possible target for the corresponding * switch, so the code is live again. */ @@ -11682,7 +16318,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (dead) { if (depth == 0) -@@ -2701,9 +3366,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog +@@ -2701,9 +3505,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog * outside of any block. When a phase returns, control is * moved to the following phase, so they make code live * again. */ @@ -11695,7 +16331,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 dead = false; break; -@@ -2817,7 +3482,7 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, +@@ -2817,7 +3621,7 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, { struct vkd3d_shader_instruction *dst_ins; @@ -11704,7 +16340,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return true; if (!(dst_ins = cf_flattener_require_space(flattener, 1))) -@@ -2871,7 +3536,7 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten +@@ -2871,7 +3675,7 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten if (!(ins = cf_flattener_require_space(flattener, 1))) return NULL; @@ -11713,7 +16349,33 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (condition) { -@@ -3031,9 +3696,9 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3006,10 +3810,11 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte + struct vkd3d_shader_message_context *message_context) + { + struct vkd3d_shader_instruction_array *instructions; ++ const struct vkd3d_shader_instruction *instruction; + struct vsir_program *program = flattener->program; + bool is_hull_shader, after_declarations_section; + struct vkd3d_shader_instruction *dst_ins; +- size_t i; ++ struct vsir_program_iterator it; + + instructions = &program->instructions; + is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL; +@@ -3018,10 +3823,10 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte + if (!cf_flattener_require_space(flattener, instructions->count + 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- for (i = 0; i < instructions->count; ++i) ++ it = vsir_program_iterator(instructions); ++ for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it)) + { + unsigned int loop_header_block_id, loop_body_block_id, continue_block_id, merge_block_id, true_block_id; +- const struct vkd3d_shader_instruction *instruction = &instructions->elements[i]; + const struct vkd3d_shader_src_param *src = instruction->src; + struct cf_flattener_info *cf_info; + +@@ -3031,9 +3836,9 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte * phase instruction, and in all other shader types begins with the first label instruction. * Declaring an indexable temp with function scope is not considered a declaration, * because it needs to live inside a function. */ @@ -11725,7 +16387,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 && instruction->declaration.indexable_temp.has_function_scope; if (!vsir_instruction_is_dcl(instruction) || is_function_indexable) -@@ -3048,22 +3713,22 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3048,22 +3853,22 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte switch (instruction->opcode) { @@ -11754,7 +16416,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -3087,7 +3752,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3087,7 +3892,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte ++flattener->branch_id; break; @@ -11763,7 +16425,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (cf_info->inside_block) cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id); -@@ -3101,7 +3766,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3101,7 +3906,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte cf_info->inside_block = true; break; @@ -11772,7 +16434,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (cf_info->inside_block) cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id); -@@ -3110,7 +3775,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3110,7 +3915,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte cf_flattener_pop_control_flow_level(flattener); break; @@ -11781,7 +16443,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -3139,7 +3804,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3139,7 +3944,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte ++flattener->loop_id; break; @@ -11790,7 +16452,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (cf_info->inside_block) cf_flattener_emit_unconditional_branch(flattener, cf_info->u.loop.continue_block_id); -@@ -3150,7 +3815,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3150,7 +3955,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte cf_flattener_pop_control_flow_level(flattener); break; @@ -11799,7 +16461,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -3161,7 +3826,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3161,7 +3966,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte if (!(dst_ins = cf_flattener_require_space(flattener, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -11808,7 +16470,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 ++flattener->instruction_count; cf_info->u.switch_.id = flattener->switch_id; -@@ -3182,7 +3847,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3182,7 +3987,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; @@ -11817,7 +16479,16 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { struct vkd3d_shader_src_param *src_params; unsigned int j; -@@ -3217,7 +3882,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3207,7 +4012,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte + for (j = 0; j < cf_info->u.switch_.cases_count; ++j) + { + unsigned int index = j * 2 + 3; +- vsir_src_param_init(&src_params[index], VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); ++ vsir_src_param_init(&src_params[index], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); + src_params[index].reg.u.immconst_u32[0] = cf_info->u.switch_.cases[j].value; + vsir_src_param_init_label(&src_params[index + 1], cf_info->u.switch_.cases[j].block_id); + } +@@ -3217,7 +4022,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; } @@ -11826,7 +16497,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { unsigned int label_id, value; -@@ -3249,7 +3914,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3249,7 +4054,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; } @@ -11835,7 +16506,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 cf_info->u.switch_.default_block_id = cf_flattener_alloc_block_id(flattener); if (cf_info->inside_block) /* fall-through */ cf_flattener_emit_unconditional_branch(flattener, cf_info->u.switch_.default_block_id); -@@ -3261,7 +3926,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3261,7 +4066,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte cf_info->inside_block = true; break; @@ -11844,7 +16515,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { struct cf_flattener_info *breakable_cf_info; -@@ -3284,7 +3949,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3284,7 +4089,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; } @@ -11853,7 +16524,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { struct cf_flattener_info *loop_cf_info; -@@ -3299,7 +3964,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3299,7 +4104,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; } @@ -11862,7 +16533,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { struct cf_flattener_info *loop_cf_info; -@@ -3315,7 +3980,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3315,7 +4120,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; } @@ -11871,7 +16542,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { struct cf_flattener_info *loop_cf_info; -@@ -3330,7 +3995,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3330,7 +4135,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; } @@ -11880,7 +16551,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (!cf_flattener_copy_instruction(flattener, instruction)) return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -3447,14 +4112,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -3447,14 +4252,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs switch (ins->opcode) { @@ -11897,7 +16568,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 break; default: -@@ -3475,7 +4140,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -3475,7 +4280,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs goto fail; if (!vsir_instruction_init_with_params(program, &instructions[ins_count], @@ -11906,7 +16577,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 goto fail; vsir_src_param_init_label(&instructions[ins_count].src[0], default_label); ++ins_count; -@@ -3491,7 +4156,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -3491,7 +4296,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]); if (!vsir_instruction_init_with_params(program, @@ -11915,7 +16586,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 goto fail; dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count); instructions[ins_count].src[0] = ins->src[0]; -@@ -3507,7 +4172,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -3507,7 +4312,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs fallthrough_label = block_count + 1; if (!vsir_instruction_init_with_params(program, &instructions[ins_count], @@ -11924,7 +16595,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 goto fail; src_param_init_ssa_bool(&instructions[ins_count].src[0], ssa_count); vsir_src_param_init_label(&instructions[ins_count].src[1], case_label); -@@ -3529,7 +4194,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -3529,7 +4334,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs else { if (!vsir_instruction_init_with_params(program, @@ -11933,7 +16604,31 @@ index 7466f7a2da1..fe7e8c54dfb 100644 goto fail; vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count); ++ins_count; -@@ -3644,7 +4309,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ +@@ -3620,10 +4425,12 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl + static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count; + struct ssas_to_temps_block_info *info, *block_info = NULL; + struct vkd3d_shader_instruction *instructions = NULL; + struct ssas_to_temps_alloc alloc = {0}; ++ struct vkd3d_shader_instruction *ins; + unsigned int current_label = 0; + + VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); +@@ -3637,14 +4444,15 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ + if (!ssas_to_temps_alloc_init(&alloc, program->ssa_count, program->temp_count)) + goto fail; + +- for (i = 0, phi_count = 0, incoming_count = 0; i < program->instructions.count; ++i) ++ phi_count = 0; ++ incoming_count = 0; ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + unsigned int j, temp_idx; /* Only phi src/dst SSA values need be converted here. Structurisation may * introduce new cases of undominated SSA use, which will be handled later. */ @@ -11942,7 +16637,19 @@ index 7466f7a2da1..fe7e8c54dfb 100644 continue; ++phi_count; -@@ -3695,12 +4360,12 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ +@@ -3682,9 +4490,9 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ + if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count)) + goto fail; + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *mov_ins, *ins = &program->instructions.elements[i]; ++ struct vkd3d_shader_instruction *mov_ins; + size_t j; + + for (j = 0; j < ins->dst_count; ++j) +@@ -3695,12 +4503,12 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ switch (ins->opcode) { @@ -11958,7 +16665,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 info = &block_info[current_label - 1]; for (j = 0; j < info->incoming_count; ++j) -@@ -3708,7 +4373,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ +@@ -3708,7 +4516,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ struct phi_incoming_to_temp *incoming = &info->incomings[j]; mov_ins = &instructions[ins_count++]; @@ -11967,7 +16674,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 goto fail; *mov_ins->dst = *incoming->dst; mov_ins->src = incoming->src; -@@ -3716,7 +4381,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ +@@ -3716,7 +4524,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ } break; @@ -11976,7 +16683,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 continue; default: -@@ -3753,7 +4418,7 @@ struct vsir_block_list +@@ -3753,7 +4561,7 @@ struct vsir_block_list static void vsir_block_list_init(struct vsir_block_list *list) { @@ -11985,7 +16692,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } static void vsir_block_list_cleanup(struct vsir_block_list *list) -@@ -4125,11 +4790,11 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg) +@@ -4125,11 +4933,11 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg) switch (block->end->opcode) { @@ -11999,7 +16706,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 shape = vsir_register_is_label(&block->end->src[0].reg) ? "ellipse" : "box"; break; -@@ -4267,11 +4932,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program +@@ -4267,11 +5075,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program switch (instruction->opcode) { @@ -12014,7 +16721,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { unsigned int label = label_from_src_param(&instruction->src[0]); -@@ -4288,16 +4953,16 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program +@@ -4288,16 +5096,16 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program break; } @@ -12036,7 +16743,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 VKD3D_ASSERT(!current_block); finish = true; break; -@@ -4322,10 +4987,10 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program +@@ -4322,10 +5130,10 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program switch (block->end->opcode) { @@ -12049,7 +16756,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (vsir_register_is_label(&block->end->src[0].reg)) { if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[0])) < 0) -@@ -5004,7 +5669,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -5004,7 +5812,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) /* Generate between zero and two jump instructions. */ switch (block->end->opcode) { @@ -12058,7 +16765,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { struct vsir_cfg_edge_action action_true, action_false; bool invert_condition = false; -@@ -5090,7 +5755,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -5090,7 +5898,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) break; } @@ -12067,7 +16774,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_JUMP))) goto fail; structure->u.jump.type = JUMP_RET; -@@ -5584,7 +6249,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, +@@ -5584,7 +6392,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -12076,7 +16783,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0) return ret; -@@ -5592,7 +6257,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, +@@ -5592,7 +6400,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 5)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -12085,7 +16792,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 /* Add a trampoline to implement multilevel jumping depending on the stored * jump_target value. */ -@@ -5607,7 +6272,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, +@@ -5607,7 +6415,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, const unsigned int inner_break_target = loop->idx << 1; if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], @@ -12094,7 +16801,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_ERROR_OUT_OF_MEMORY; dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count); -@@ -5617,7 +6282,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, +@@ -5617,7 +6425,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, ++target->ins_count; if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], @@ -12103,7 +16810,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_ERROR_OUT_OF_MEMORY; src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count); -@@ -5626,7 +6291,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, +@@ -5626,7 +6434,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, ++target->temp_count; if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], @@ -12112,7 +16819,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_ERROR_OUT_OF_MEMORY; dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count); -@@ -5636,7 +6301,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, +@@ -5636,7 +6444,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, ++target->ins_count; if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], @@ -12121,7 +16828,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_ERROR_OUT_OF_MEMORY; target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z; -@@ -5660,7 +6325,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg +@@ -5660,7 +6468,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg return VKD3D_ERROR_OUT_OF_MEMORY; if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], @@ -12130,7 +16837,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_ERROR_OUT_OF_MEMORY; target->instructions[target->ins_count].src[0] = *selection->condition; -@@ -5678,7 +6343,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg +@@ -5678,7 +6486,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -12139,7 +16846,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if ((ret = vsir_cfg_structure_list_emit(cfg, &selection->else_body, loop_idx)) < 0) return ret; -@@ -5687,7 +6352,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg +@@ -5687,7 +6495,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -12148,7 +16855,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_OK; } -@@ -5711,19 +6376,19 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, +@@ -5711,19 +6519,19 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, * in the lowest bit of jump_target. */ if (jump->target == loop_idx) { @@ -12171,7 +16878,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 break; default: -@@ -5736,7 +6401,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, +@@ -5736,7 +6544,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, if (jump->needs_launcher) { if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], @@ -12180,7 +16887,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 return VKD3D_ERROR_OUT_OF_MEMORY; dst_param_init_temp_uint(&target->instructions[target->ins_count].dst[0], target->jump_target_temp_idx); -@@ -5864,7 +6529,7 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, +@@ -5864,7 +6672,7 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, switch (ins->opcode) { @@ -12189,7 +16896,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL); TRACE("Structurizing a non-hull shader.\n"); if ((ret = vsir_program_structurize_function(program, message_context, -@@ -5873,9 +6538,9 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, +@@ -5873,9 +6681,9 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, VKD3D_ASSERT(i == program->instructions.count); break; @@ -12202,7 +16909,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL); TRACE("Structurizing phase %u of a hull shader.\n", ins->opcode); target.instructions[target.ins_count++] = *ins; -@@ -6041,7 +6706,7 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru +@@ -6041,7 +6849,7 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru switch (ins->opcode) { @@ -12211,7 +16918,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL); TRACE("Materializing undominated SSAs in a non-hull shader.\n"); if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function( -@@ -6050,9 +6715,9 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru +@@ -6050,9 +6858,9 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru VKD3D_ASSERT(i == program->instructions.count); break; @@ -12224,7 +16931,25 @@ index 7466f7a2da1..fe7e8c54dfb 100644 VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL); TRACE("Materializing undominated SSAs in phase %u of a hull shader.\n", ins->opcode); ++i; -@@ -6143,12 +6808,12 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6125,14 +6933,12 @@ static enum vkd3d_result vsir_program_apply_flat_interpolation(struct vsir_progr + } + + static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func, ++ struct vsir_program_iterator *it, enum vkd3d_shader_comparison_func compare_func, + const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx, +- uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context) ++ uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- const struct vkd3d_shader_location loc = ret->location; ++ struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; + static const struct vkd3d_shader_location no_loc; +- size_t pos = ret - instructions->elements; + struct vkd3d_shader_instruction *ins; + + static const struct +@@ -6143,33 +6949,33 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr } opcodes[] = { @@ -12243,60 +16968,192 @@ index 7466f7a2da1..fe7e8c54dfb 100644 }; if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER) -@@ -6158,7 +6823,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - ret = NULL; - ins = &program->instructions.elements[pos]; + { +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DISCARD, 0, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; src_param_init_const_uint(&ins->src[0], 0); ++ vsir_program_iterator_next(it); -@@ -6202,14 +6867,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +- *ret_pos = pos + 1; + return VKD3D_OK; + } + +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 3)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 3)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); + + switch (ref->data_type) + { +@@ -6177,14 +6983,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].float_opcode, 1, 2); + src_param_init_temp_float(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); + src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], +- VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_FLOAT); ++ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VSIR_DATA_F32); + break; + + case VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32: + vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].uint_opcode, 1, 2); + src_param_init_temp_uint(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); + src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], +- VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_UINT); ++ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VSIR_DATA_U32); + break; + + case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4: +@@ -6201,16 +7007,16 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + ins->src[opcodes[compare_func].swap ? 1 : 0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); - ++ins; +- ++ins; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DISCARD, 0, 1); ++ ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; src_param_init_ssa_bool(&ins->src[0], program->ssa_count); ++program->ssa_count; - ++ins; +- ++ins; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); +- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); ++ ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = colour_signature_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -@@ -6275,7 +6940,7 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro + ins->dst[0].write_mask = program->output_signature.elements[colour_signature_idx].mask; +@@ -6218,20 +7024,21 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + +- *ret_pos = pos + 3; ++ vsir_program_iterator_next(it); ++ + return VKD3D_OK; + } + + static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL; + uint32_t colour_signature_idx, colour_temp = ~0u; + static const struct vkd3d_shader_location no_loc; + enum vkd3d_shader_comparison_func compare_func; + struct vkd3d_shader_instruction *ins; +- size_t new_pos; + int ret; + + if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) +@@ -6268,19 +7075,16 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro + if (compare_func != VKD3D_SHADER_COMPARISON_FUNC_NEVER) + colour_temp = program->temp_count++; + +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- if (vsir_instruction_is_dcl(ins)) continue; - if (ins->opcode == VKD3DSIH_RET) + if (ins->opcode == VSIR_OP_RET) { - if ((ret = insert_alpha_test_before_ret(program, ins, compare_func, - ref, colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) -@@ -6325,7 +6990,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog +- if ((ret = insert_alpha_test_before_ret(program, ins, compare_func, +- ref, colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) ++ if ((ret = insert_alpha_test_before_ret(program, &it, compare_func, ++ ref, colour_signature_idx, colour_temp, message_context)) < 0) + return ret; +- i = new_pos; + continue; + } + +@@ -6306,32 +7110,30 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro + } + + static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, uint32_t mask, uint32_t position_signature_idx, +- uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos) ++ struct vsir_program_iterator *it, uint32_t mask, uint32_t position_signature_idx, ++ uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- const struct vkd3d_shader_location loc = ret->location; +- size_t pos = ret - instructions->elements; ++ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; + struct vkd3d_shader_instruction *ins; + unsigned int output_idx = 0; + +- if (!shader_instruction_array_insert_at(&program->instructions, pos, vkd3d_popcount(mask) + 1)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); + + for (unsigned int i = 0; i < 8; ++i) + { if (!(mask & (1u << i))) continue; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DP4, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DP4, 1, 2); src_param_init_temp_float4(&ins->src[0], position_temp); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VKD3D_DATA_FLOAT); +- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VKD3D_DATA_FLOAT); ++ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VSIR_DATA_F32); ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE; -@@ -6343,7 +7008,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog - ++ins; + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + +- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); + if (output_idx < 4) + ins->dst[0].reg.idx[0].offset = low_signature_idx; + else +@@ -6340,34 +7142,34 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog + ins->dst[0].write_mask = (1u << (output_idx % 4)); + ++output_idx; + +- ++ins; ++ ins = vsir_program_iterator_next(it); } - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); +- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = position_signature_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -@@ -6362,9 +7027,9 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + ins->dst[0].write_mask = program->output_signature.elements[position_signature_idx].mask; + src_param_init_temp_float(&ins->src[0], position_temp); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ ins = vsir_program_iterator_next(it); + +- *ret_pos = pos + vkd3d_popcount(mask) + 1; + return VKD3D_OK; + } + + static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct shader_signature *signature = &program->output_signature; unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; const struct vkd3d_shader_parameter1 *mask_parameter = NULL; @@ -12306,8 +17163,11 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + struct signature_element *clip_element; struct vkd3d_shader_instruction *ins; unsigned int plane_count; - size_t new_pos; -@@ -6422,33 +7087,20 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr +- size_t new_pos; + int ret; + + if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX) +@@ -6422,33 +7224,20 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr plane_count = vkd3d_popcount(mask); @@ -12349,88 +17209,257 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } /* We're going to be reading from the output position, so we need to go -@@ -6463,7 +7115,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr +@@ -6456,19 +7245,16 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + + position_temp = program->temp_count++; + +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- if (vsir_instruction_is_dcl(ins)) continue; - if (ins->opcode == VKD3DSIH_RET) + if (ins->opcode == VSIR_OP_RET) { - if ((ret = insert_clip_planes_before_ret(program, ins, mask, position_signature_idx, - position_temp, low_signature_idx, high_signature_idx, &new_pos)) < 0) -@@ -6509,7 +7161,7 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr - ret = NULL; - ins = &program->instructions.elements[pos]; +- if ((ret = insert_clip_planes_before_ret(program, ins, mask, position_signature_idx, +- position_temp, low_signature_idx, high_signature_idx, &new_pos)) < 0) ++ if ((ret = insert_clip_planes_before_ret(program, &it, mask, position_signature_idx, ++ position_temp, low_signature_idx, high_signature_idx)) < 0) + return ret; +- i = new_pos; + continue; + } + +@@ -6497,32 +7283,32 @@ static bool is_pre_rasterization_shader(enum vkd3d_shader_type type) + } + + static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, size_t *ret_pos) ++ struct vsir_program_iterator *it) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- const struct vkd3d_shader_location loc = ret->location; +- size_t pos = ret - instructions->elements; ++ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; + struct vkd3d_shader_instruction *ins; + +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); +- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VKD3D_DATA_FLOAT); -@@ -6555,7 +7207,7 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro - { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VKD3D_DATA_FLOAT); ++ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VSIR_DATA_F32); ++ ins = vsir_program_iterator_next(it); +- *ret_pos = pos + 1; + return VKD3D_OK; + } + + static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + const struct vkd3d_shader_parameter1 *size_parameter = NULL; + static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_instruction *ins; + + if (program->has_point_size) + return VKD3D_OK; +@@ -6551,18 +7337,14 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro + program->has_point_size = true; + + /* Append a point size write before each ret. */ +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- - if (ins->opcode == VKD3DSIH_RET) + if (ins->opcode == VSIR_OP_RET) { - size_t new_pos; +- size_t new_pos; int ret; -@@ -6644,7 +7296,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + +- if ((ret = insert_point_size_before_ret(program, ins, &new_pos)) < 0) ++ if ((ret = insert_point_size_before_ret(program, &it)) < 0) + return ret; +- i = new_pos; + } + } + +@@ -6573,7 +7355,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + struct vsir_transformation_context *ctx) + { + const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_instruction *ins; + + if (!program->has_point_size) + return VKD3D_OK; +@@ -6610,9 +7394,8 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + + /* Replace writes to the point size by inserting a clamp before each write. */ + +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + const struct vkd3d_shader_location *loc; + unsigned int ssa_value; + bool clamp = false; +@@ -6636,17 +7419,17 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + if (!clamp) + continue; + +- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter)) ++ if (!vsir_program_iterator_insert_after(&it, !!min_parameter + !!max_parameter)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = &program->instructions.elements[i + 1]; + +- loc = &program->instructions.elements[i].location; ++ loc = &vsir_program_iterator_current(&it)->location; ++ ins = vsir_program_iterator_next(&it); if (min_parameter) { - vsir_instruction_init_with_params(program, ins, loc, VKD3DSIH_MAX, 1, 2); + vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAX, 1, 2); src_param_init_ssa_float(&ins->src[0], ssa_value); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VKD3D_DATA_FLOAT); +- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VKD3D_DATA_FLOAT); ++ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VSIR_DATA_F32); if (max_parameter) -@@ -6663,7 +7315,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + { + dst_param_init_ssa_float(&ins->dst[0], program->ssa_count); +@@ -6654,22 +7437,20 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + } + else + { +- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; + } +- ++ins; +- ++i; ++ ins = vsir_program_iterator_next(&it); + } if (max_parameter) { - vsir_instruction_init_with_params(program, ins, loc, VKD3DSIH_MIN, 1, 2); + vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MIN, 1, 2); src_param_init_ssa_float(&ins->src[0], ssa_value); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VKD3D_DATA_FLOAT); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); -@@ -6797,7 +7449,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - { - ins = &program->instructions.elements[i]; +- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VKD3D_DATA_FLOAT); +- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); ++ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VSIR_DATA_F32); ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; +- +- ++i; ++ ins = vsir_program_iterator_next(&it); + } + } +@@ -6747,12 +7528,13 @@ static bool replace_texcoord_with_point_coord(struct vsir_program *program, + static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2; + const struct vkd3d_shader_parameter1 *sprite_parameter = NULL; + static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; + bool used_texcoord = false; + unsigned int coord_temp; +- size_t i, insert_pos; ++ size_t i; + + if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) + return VKD3D_OK; +@@ -6793,21 +7575,16 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + /* Construct the new temp after all LABEL, DCL, and NOP instructions. + * We need to skip NOP instructions because they might result from removed + * DCLs, and there could still be DCLs after NOPs. */ +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- - if (!vsir_instruction_is_dcl(ins) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP) + if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) break; } -@@ -6840,7 +7492,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr +- insert_pos = i; +- ++ it2 = it; + /* Replace each texcoord read with a read from the point coord. */ +- for (; i < program->instructions.count; ++i) ++ for (; ins; ins = vsir_program_iterator_next(&it2)) + { +- ins = &program->instructions.elements[i]; +- + if (vsir_instruction_is_dcl(ins)) + continue; + +@@ -6836,24 +7613,25 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + + if (used_texcoord) + { +- if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2)) ++ vsir_program_iterator_prev(&it); ++ if (!vsir_program_iterator_insert_after(&it, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[insert_pos]; +- ins = &program->instructions.elements[insert_pos]; ++ ins = vsir_program_iterator_next(&it); - vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); dst_param_init_temp_float4(&ins->dst[0], coord_temp); ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; - vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0); -@@ -6848,7 +7500,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr +- vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0); ++ vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - ++ins; +- ++ins; ++ ins = vsir_program_iterator_next(&it); - vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); dst_param_init_temp_float4(&ins->dst[0], coord_temp); ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; - vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); -@@ -6919,7 +7571,7 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); ++ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; +- ++ins; ++ vsir_program_iterator_next(&it); + + program->has_point_coord = true; + } +@@ -6919,20 +7697,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins = &program->instructions.elements[pos]; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_ADD, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VKD3D_DATA_FLOAT); - vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); -@@ -6928,7 +7580,7 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VKD3D_DATA_FLOAT); +- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); ++ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); ++ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); + ins->src[1].reg.idx[0].offset = fog_signature_idx; + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ins->src[1].modifiers = VKD3DSPSM_NEG; @@ -12439,16 +17468,23 @@ index 7466f7a2da1..fe7e8c54dfb 100644 dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp); -@@ -6951,7 +7603,7 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); ++ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); + break; + + case VKD3D_SHADER_FOG_FRAGMENT_EXP: +@@ -6951,15 +7729,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins = &program->instructions.elements[pos]; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MUL, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); - vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); -@@ -6959,7 +7611,7 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); +- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); ++ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); ++ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); + ins->src[1].reg.idx[0].offset = fog_signature_idx; ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); @@ -12457,16 +17493,18 @@ index 7466f7a2da1..fe7e8c54dfb 100644 dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp); -@@ -6984,7 +7636,7 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -6984,20 +7762,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins = &program->instructions.elements[pos]; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MUL, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); - vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); -@@ -6992,12 +7644,12 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); +- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); ++ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); ++ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); + ins->src[1].reg.idx[0].offset = fog_signature_idx; ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); @@ -12481,7 +17519,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp2); -@@ -7014,13 +7666,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -7014,18 +7792,18 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * mad oC0, sr0, srFACTOR, FOG_COLOUR */ @@ -12489,32 +17527,92 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_ADD, 1, 2); dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); src_param_init_temp_float4(&ins->src[0], colour_temp); - src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT); +- src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT); ++ src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); ins->src[1].modifiers = VKD3DSPSM_NEG; - vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_MAD, 1, 3); +- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, colour_signature_idx, + vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MAD, 1, 3); - dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, colour_signature_idx, ++ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, program->output_signature.elements[colour_signature_idx].mask); src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); -@@ -7088,7 +7740,7 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p + src_param_init_ssa_float(&ins->src[1], ssa_factor); +- src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT); ++ src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); + + return VKD3D_OK; + } +@@ -7088,200 +7866,1096 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p if (vsir_instruction_is_dcl(ins)) continue; - if (ins->opcode == VKD3DSIH_RET) + if (ins->opcode == VSIR_OP_RET) - { - if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx, - colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) -@@ -7153,137 +7805,1026 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr - const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp, - uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos) - { -- const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- const struct vkd3d_shader_location loc = ret->location; -- size_t pos = ret - instructions->elements; -- struct vkd3d_shader_instruction *ins; ++ { ++ if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx, ++ colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) ++ return ret; ++ i = new_pos; ++ continue; ++ } ++ ++ for (size_t j = 0; j < ins->dst_count; ++j) ++ { ++ struct vkd3d_shader_dst_param *dst = &ins->dst[j]; ++ ++ /* Note we run after I/O normalization. */ ++ if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx) ++ { ++ dst->reg.type = VKD3DSPR_TEMP; ++ dst->reg.idx[0].offset = colour_temp; ++ } ++ } ++ } ++ ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct shader_signature *signature = &program->output_signature; ++ const struct vkd3d_shader_parameter1 *source_parameter; ++ uint32_t register_idx = 0; ++ ++ if (!is_pre_rasterization_shader(program->shader_version.type)) ++ return VKD3D_OK; ++ ++ if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE))) ++ return VKD3D_OK; ++ ++ if (source_parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) ++ { ++ enum vkd3d_shader_fog_source source = source_parameter->u.immediate_constant.u.u32; ++ ++ if (source == VKD3D_SHADER_FOG_SOURCE_FOG) ++ return VKD3D_OK; ++ ++ if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W ++ && !vsir_signature_find_element_by_name(signature, "COLOR", 1)) ++ return VKD3D_OK; ++ } ++ ++ if (vsir_signature_find_element_by_name(signature, "FOG", 0)) ++ return VKD3D_OK; ++ ++ for (unsigned int i = 0; i < signature->element_count; ++i) ++ register_idx = max(register_idx, signature->elements[i].register_index + 1); ++ ++ if (!add_signature_element(signature, "FOG", 0, VKD3DSP_WRITEMASK_0, register_idx, VKD3DSIM_LINEAR)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, ++ const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp, ++ uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos) ++{ + const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; + struct vkd3d_shader_instruction_array *instructions = &program->instructions; + const struct vkd3d_shader_location loc = ret->location; @@ -12529,7 +17627,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + + /* Write the fog output. */ + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -+ dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, fog_signature_idx, 0x1); ++ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, fog_signature_idx, 0x1); + src_param_init_temp_float4(&ins->src[0], temp); + if (source == VKD3D_SHADER_FOG_SOURCE_Z) + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); @@ -12539,7 +17637,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + + /* Write the position or specular output. */ + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -+ dst_param_init_output(&ins->dst[0], vkd3d_data_type_from_component_type(e->component_type), ++ dst_param_init_output(&ins->dst[0], vsir_data_type_from_component_type(e->component_type), + source_signature_idx, e->mask); + src_param_init_temp_float4(&ins->src[0], temp); + ++ins; @@ -13249,11 +18347,11 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + return writemask; +} + -+static void temp_allocator_allocate(struct temp_allocator *allocator, struct liveness_tracker *tracker, ++static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liveness_tracker *tracker, + struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg, uint32_t base_id) +{ + if (!liveness_reg->written) -+ return; ++ return false; + + for (uint32_t id = base_id;; ++id) + { @@ -13261,52 +18359,103 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + liveness_reg->first_write, liveness_reg->last_access, id); + + if (liveness_reg->fixed_mask) -+ { + { +- if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx, +- colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) +- return ret; +- i = new_pos; +- continue; + if ((available_mask & liveness_reg->mask) == liveness_reg->mask) + { + reg->temp_id = id; + reg->allocated_mask = liveness_reg->mask; -+ return; ++ return true; + } -+ } + } +- +- for (size_t j = 0; j < ins->dst_count; ++j) + else -+ { + { +- struct vkd3d_shader_dst_param *dst = &ins->dst[j]; + /* For SSA values the mask is always zero-based and contiguous. + * We don't correctly handle cases where it's not, currently. */ + VKD3D_ASSERT((liveness_reg->mask | (liveness_reg->mask - 1)) == liveness_reg->mask); -+ + +- /* Note we run after I/O normalization. */ +- if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx) + if (vkd3d_popcount(available_mask) >= vkd3d_popcount(liveness_reg->mask)) -+ { + { +- dst->reg.type = VKD3DSPR_TEMP; +- dst->reg.idx[0].offset = colour_temp; + reg->temp_id = id; + reg->allocated_mask = vsir_combine_write_masks(available_mask, liveness_reg->mask); -+ return; -+ } -+ } -+ } -+} -+ ++ return true; + } + } + } +- +- return VKD3D_OK; + } + +-static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *program, +- struct vsir_transformation_context *ctx) +static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3d_shader_src_param *src) -+{ + { +- struct shader_signature *signature = &program->output_signature; +- const struct vkd3d_shader_parameter1 *source_parameter; +- uint32_t register_idx = 0; + struct temp_allocator_reg *reg; -+ + +- if (!is_pre_rasterization_shader(program->shader_version.type)) +- return VKD3D_OK; +- +- if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE))) +- return VKD3D_OK; +- +- if (source_parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + for (unsigned int k = 0; k < src->reg.idx_count; ++k) -+ { + { +- enum vkd3d_shader_fog_source source = source_parameter->u.immediate_constant.u.u32; +- +- if (source == VKD3D_SHADER_FOG_SOURCE_FOG) +- return VKD3D_OK; +- +- if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W +- && !vsir_signature_find_element_by_name(signature, "COLOR", 1)) +- return VKD3D_OK; + if (src->reg.idx[k].rel_addr) + temp_allocator_set_src(allocator, src->reg.idx[k].rel_addr); -+ } -+ + } + +- if (vsir_signature_find_element_by_name(signature, "FOG", 0)) +- return VKD3D_OK; +- +- for (unsigned int i = 0; i < signature->element_count; ++i) +- register_idx = max(register_idx, signature->elements[i].register_index + 1); + if (src->reg.type == VKD3DSPR_SSA) + reg = &allocator->ssa_regs[src->reg.idx[0].offset]; + else + return; -+ + +- if (!add_signature_element(signature, "FOG", 0, VKD3DSP_WRITEMASK_0, register_idx, VKD3DSIM_LINEAR)) +- return VKD3D_ERROR_OUT_OF_MEMORY; +- return VKD3D_OK; + src->reg.type = VKD3DSPR_TEMP; ++ src->reg.dimension = VSIR_DIMENSION_VEC4; + src->reg.idx[0].offset = reg->temp_id; + src->swizzle = vsir_combine_swizzles(vsir_swizzle_from_writemask(reg->allocated_mask), src->swizzle); -+} -+ + } + +-static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp, +- uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos) +static uint32_t vsir_map_swizzle(uint32_t swizzle, unsigned int writemask) -+{ + { +- const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- const struct vkd3d_shader_location loc = ret->location; +- size_t pos = ret - instructions->elements; +- struct vkd3d_shader_instruction *ins; + unsigned int src_component = 0; + uint32_t ret = 0; @@ -13426,6 +18575,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + return; + + dst->reg.type = VKD3DSPR_TEMP; ++ dst->reg.dimension = VSIR_DIMENSION_VEC4; + dst->reg.idx[0].offset = reg->temp_id; + if (reg->allocated_mask != dst->write_mask) { @@ -13463,10 +18613,10 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) +{ ++ const unsigned int prev_temp_count = program->temp_count; + struct temp_allocator allocator = {0}; + struct temp_allocator_reg *regs; + struct liveness_tracker tracker; -+ uint32_t temp_count = 0; + enum vkd3d_result ret; - if (source == VKD3D_SHADER_FOG_SOURCE_FOG) @@ -13493,18 +18643,19 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { - if (!vsir_signature_find_sysval(&program->output_signature, - VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx)) -- { -- vkd3d_shader_error(ctx->message_context, &no_loc, -- VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position."); -- return VKD3D_ERROR_INVALID_SHADER; -- } + const struct liveness_tracker_reg *liveness_reg = &tracker.ssa_regs[i]; + struct temp_allocator_reg *reg = &allocator.ssa_regs[i]; + -+ temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, program->temp_count); -+ TRACE("Allocated r%u%s to sr%u (liveness %u-%u).\n", -+ reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, -+ liveness_reg->first_write, liveness_reg->last_access); ++ if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, prev_temp_count)) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, +- VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position."); +- return VKD3D_ERROR_INVALID_SHADER; ++ TRACE("Allocated r%u%s to sr%u (liveness %u-%u).\n", ++ reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, ++ liveness_reg->first_write, liveness_reg->last_access); ++ program->temp_count = max(program->temp_count, reg->temp_id + 1); + } + ++allocator.allocated_ssa_count; } @@ -13513,29 +18664,40 @@ index 7466f7a2da1..fe7e8c54dfb 100644 { - ERR("Fog output not found.\n"); - return VKD3D_ERROR_INVALID_SHADER; -- } -- fog_signature_idx = e - program->output_signature.elements; + const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - -- temp = program->temp_count++; ++ + /* Make sure we do the srcs first; setting the dst writemask may need + * to remap their swizzles. */ + for (unsigned int j = 0; j < ins->src_count; ++j) + temp_allocator_set_src(&allocator, &ins->src[j]); + for (unsigned int j = 0; j < ins->dst_count; ++j) + temp_allocator_set_dst(&allocator, &ins->dst[j], ins); -+ } + } +- fog_signature_idx = e - program->output_signature.elements; + +- temp = program->temp_count++; ++ program->ssa_count = 0; - /* Insert a fog write before each ret, and convert either specular or - * position output to a temp. */ - for (size_t i = 0; i < program->instructions.count; ++i) -+ /* Rewrite dcl_temps to reflect the new temp count. -+ * Note that dcl_temps appears once per phase, and should reflect only the -+ * number of temps needed by that phase. -+ * Therefore we iterate backwards through the shader, finding the maximum -+ * register used by any instruction, update the dcl_temps at the beginning -+ * of each phase, and then reset the temp count back to 0 for the next -+ * phase (if any). */ ++ vkd3d_free(regs); ++ liveness_tracker_cleanup(&tracker); ++ return allocator.result; ++} ++ ++/* Rewrite dcl_temps to reflect the new temp count. ++ * Note that dcl_temps appears once per phase, and should reflect only the ++ * number of temps needed by that phase. ++ * Therefore we iterate backwards through the shader, finding the maximum ++ * register used by any instruction, update the dcl_temps at the beginning ++ * of each phase, and then reset the temp count back to 0 for the next ++ * phase (if any). */ ++enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, ++ struct vkd3d_shader_message_context *message_context) ++{ ++ unsigned int temp_count = 0; ++ + for (int i = program->instructions.count - 1; i >= 0; --i) { struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; @@ -13546,9 +18708,9 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + ins->declaration.count = temp_count; + temp_count = 0; continue; -- -- if (ins->opcode == VKD3DSIH_RET) + } + +- if (ins->opcode == VKD3DSIH_RET) + if (temp_count && program->shader_version.major >= 4 + && (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE + || ins->opcode == VSIR_OP_HS_FORK_PHASE @@ -13559,11 +18721,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + /* The phase didn't have a dcl_temps instruction, but we added + * temps here, so we need to insert one. */ + if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) -+ { -+ vkd3d_free(regs); -+ liveness_tracker_cleanup(&tracker); + return VKD3D_ERROR_OUT_OF_MEMORY; -+ } - if ((ret = insert_vertex_fog_before_ret(program, ins, source, temp, - fog_signature_idx, source_signature_idx, &new_pos)) < 0) @@ -13577,21 +18735,23 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } - for (size_t j = 0; j < ins->dst_count; ++j) -+ /* No need to check sources. If we've produced an unwritten source then -+ * that's a bug somewhere in this pass. */ -+ for (unsigned int j = 0; j < ins->dst_count; ++j) ++ for (unsigned int j = 0; j < ins->src_count; ++j) { - struct vkd3d_shader_dst_param *dst = &ins->dst[j]; -- ++ if (ins->src[j].reg.type == VKD3DSPR_TEMP) ++ temp_count = max(temp_count, ins->src[j].reg.idx[0].offset + 1); ++ } + - /* Note we run after I/O normalization. */ - if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == source_signature_idx) -+ if (ins->dst[j].reg.type == VKD3DSPR_TEMP) - { +- { - dst->reg.type = VKD3DSPR_TEMP; - dst->reg.idx[0].offset = temp; +- } ++ for (unsigned int j = 0; j < ins->dst_count; ++j) ++ { ++ if (ins->dst[j].reg.type == VKD3DSPR_TEMP) + temp_count = max(temp_count, ins->dst[j].reg.idx[0].offset + 1); -+ program->temp_count = max(program->temp_count, temp_count); - } } } @@ -13599,29 +18759,27 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + if (temp_count && program->shader_version.major >= 4) + { + struct vkd3d_shader_instruction *ins; - -- return VKD3D_OK; ++ + if (!shader_instruction_array_insert_at(&program->instructions, 0, 1)) -+ { -+ vkd3d_free(regs); -+ liveness_tracker_cleanup(&tracker); + return VKD3D_ERROR_OUT_OF_MEMORY; -+ } + + ins = &program->instructions.elements[0]; + vsir_instruction_init(ins, &program->instructions.elements[1].location, VSIR_OP_DCL_TEMPS); + ins->declaration.count = temp_count; + } -+ -+ program->ssa_count = 0; -+ -+ vkd3d_free(regs); -+ liveness_tracker_cleanup(&tracker); -+ return allocator.result; - } - struct validation_context -@@ -7538,10 +9079,10 @@ static const bool vsir_get_io_register_data(struct validation_context *ctx, + return VKD3D_OK; + } +@@ -7307,7 +8981,7 @@ struct validation_context + struct validation_context_ssa_data + { + enum vsir_dimension dimension; +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + size_t first_seen; + uint32_t write_mask; + uint32_t read_mask; +@@ -7538,10 +9212,10 @@ static const bool vsir_get_io_register_data(struct validation_context *ctx, switch (ctx->phase) { @@ -13636,7 +18794,16 @@ index 7466f7a2da1..fe7e8c54dfb 100644 default: vkd3d_unreachable(); -@@ -7841,10 +9382,6 @@ static void vsir_validate_descriptor_indices(struct validation_context *ctx, +@@ -7783,7 +9457,7 @@ static void vsir_validate_label_register(struct validation_context *ctx, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, + "Invalid precision %#x for a LABEL register.", reg->precision); + +- if (reg->data_type != VKD3D_DATA_UNUSED) ++ if (reg->data_type != VSIR_DATA_UNUSED) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid data type %#x for a LABEL register.", reg->data_type); + +@@ -7841,10 +9515,6 @@ static void vsir_validate_descriptor_indices(struct validation_context *ctx, static void vsir_validate_constbuffer_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg) { @@ -13647,7 +18814,208 @@ index 7466f7a2da1..fe7e8c54dfb 100644 if (reg->dimension != VSIR_DIMENSION_VEC4) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid dimension %#x for a CONSTBUFFER register.", reg->dimension); -@@ -8242,15 +9779,37 @@ static void vsir_validate_dst_param(struct validation_context *ctx, +@@ -7866,7 +9536,7 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, + "Invalid precision %#x for a SAMPLER register.", reg->precision); + +- if (reg->data_type != VKD3D_DATA_UNUSED) ++ if (reg->data_type != VSIR_DATA_UNUSED) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid data type %#x for a SAMPLER register.", reg->data_type); + +@@ -7892,7 +9562,7 @@ static void vsir_validate_resource_register(struct validation_context *ctx, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, + "Invalid precision %#x for a RESOURCE register.", reg->precision); + +- if (reg->data_type != VKD3D_DATA_UNUSED) ++ if (reg->data_type != VSIR_DATA_UNUSED) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid data type %#x for a RESOURCE register.", reg->data_type); + +@@ -7918,7 +9588,7 @@ static void vsir_validate_uav_register(struct validation_context *ctx, + "Invalid precision %#x for a UAV register.", + reg->precision); + +- if (reg->data_type != VKD3D_DATA_UNUSED) ++ if (reg->data_type != VSIR_DATA_UNUSED) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid data type %#x for a UAV register.", + reg->data_type); +@@ -8005,6 +9675,30 @@ static void vsir_validate_src_param(struct validation_context *ctx, + static void vsir_validate_register(struct validation_context *ctx, + const struct vkd3d_shader_register *reg) + { ++ static const struct register_validation_data ++ { ++ bool valid; ++ unsigned int idx_count; ++ enum vsir_dimension dimension; ++ } ++ register_validation_data[] = ++ { ++ [VKD3DSPR_DEPTHOUT] = {true, 0, VSIR_DIMENSION_SCALAR}, ++ [VKD3DSPR_PRIMID] = {true, 0, VSIR_DIMENSION_SCALAR}, ++ [VKD3DSPR_OUTPOINTID] = {true, 0, VSIR_DIMENSION_SCALAR}, ++ [VKD3DSPR_THREADID] = {true, 0, VSIR_DIMENSION_VEC4}, ++ [VKD3DSPR_THREADGROUPID] = {true, 0, VSIR_DIMENSION_VEC4}, ++ [VKD3DSPR_LOCALTHREADID] = {true, 0, VSIR_DIMENSION_VEC4}, ++ [VKD3DSPR_LOCALTHREADINDEX] = {true, 0, VSIR_DIMENSION_VEC4}, ++ [VKD3DSPR_COVERAGE] = {true, 0, VSIR_DIMENSION_VEC4}, ++ [VKD3DSPR_SAMPLEMASK] = {true, 0, VSIR_DIMENSION_SCALAR}, ++ [VKD3DSPR_GSINSTID] = {true, 0, VSIR_DIMENSION_VEC4}, ++ [VKD3DSPR_DEPTHOUTGE] = {true, 0, VSIR_DIMENSION_SCALAR}, ++ [VKD3DSPR_DEPTHOUTLE] = {true, 0, VSIR_DIMENSION_SCALAR}, ++ [VKD3DSPR_OUTSTENCILREF] = {true, 0, VSIR_DIMENSION_SCALAR}, ++ }; ++ ++ const struct register_validation_data *validation_data; + unsigned int i; + + if (reg->type >= VKD3DSPR_COUNT) +@@ -8015,7 +9709,7 @@ static void vsir_validate_register(struct validation_context *ctx, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.", + reg->precision); + +- if (reg->data_type >= VKD3D_DATA_COUNT) ++ if (reg->data_type >= VSIR_DATA_TYPE_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.", + reg->data_type); + +@@ -8070,10 +9764,6 @@ static void vsir_validate_register(struct validation_context *ctx, + vsir_validate_io_register(ctx, reg); + break; + +- case VKD3DSPR_DEPTHOUT: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- + case VKD3DSPR_MISCTYPE: + vsir_validate_misctype_register(ctx, reg); + break; +@@ -8094,10 +9784,6 @@ static void vsir_validate_register(struct validation_context *ctx, + vsir_validate_constbuffer_register(ctx, reg); + break; + +- case VKD3DSPR_PRIMID: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- + case VKD3DSPR_NULL: + vsir_validate_register_without_indices(ctx, reg); + break; +@@ -8110,75 +9796,31 @@ static void vsir_validate_register(struct validation_context *ctx, + vsir_validate_resource_register(ctx, reg); + break; + +- case VKD3DSPR_UAV: +- vsir_validate_uav_register(ctx, reg); +- break; +- +- case VKD3DSPR_OUTPOINTID: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- +- case VKD3DSPR_FORKINSTID: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- +- case VKD3DSPR_JOININSTID: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- +- case VKD3DSPR_INCONTROLPOINT: +- vsir_validate_io_register(ctx, reg); +- break; +- +- case VKD3DSPR_OUTCONTROLPOINT: +- vsir_validate_io_register(ctx, reg); +- break; +- +- case VKD3DSPR_PATCHCONST: +- vsir_validate_io_register(ctx, reg); +- break; +- +- case VKD3DSPR_TESSCOORD: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- +- case VKD3DSPR_THREADID: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- +- case VKD3DSPR_THREADGROUPID: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- +- case VKD3DSPR_LOCALTHREADID: +- vsir_validate_register_without_indices(ctx, reg); +- break; +- +- case VKD3DSPR_LOCALTHREADINDEX: +- vsir_validate_register_without_indices(ctx, reg); ++ case VKD3DSPR_UAV: ++ vsir_validate_uav_register(ctx, reg); + break; + +- case VKD3DSPR_COVERAGE: ++ case VKD3DSPR_FORKINSTID: + vsir_validate_register_without_indices(ctx, reg); + break; + +- case VKD3DSPR_SAMPLEMASK: ++ case VKD3DSPR_JOININSTID: + vsir_validate_register_without_indices(ctx, reg); + break; + +- case VKD3DSPR_GSINSTID: +- vsir_validate_register_without_indices(ctx, reg); ++ case VKD3DSPR_INCONTROLPOINT: ++ vsir_validate_io_register(ctx, reg); + break; + +- case VKD3DSPR_DEPTHOUTGE: +- vsir_validate_register_without_indices(ctx, reg); ++ case VKD3DSPR_OUTCONTROLPOINT: ++ vsir_validate_io_register(ctx, reg); + break; + +- case VKD3DSPR_DEPTHOUTLE: +- vsir_validate_register_without_indices(ctx, reg); ++ case VKD3DSPR_PATCHCONST: ++ vsir_validate_io_register(ctx, reg); + break; + +- case VKD3DSPR_OUTSTENCILREF: ++ case VKD3DSPR_TESSCOORD: + vsir_validate_register_without_indices(ctx, reg); + break; + +@@ -8197,6 +9839,24 @@ static void vsir_validate_register(struct validation_context *ctx, + default: + break; + } ++ ++ if (reg->type >= ARRAY_SIZE(register_validation_data)) ++ return; ++ ++ validation_data = ®ister_validation_data[reg->type]; ++ ++ if (!validation_data->valid) ++ return; ++ ++ if (reg->idx_count != validation_data->idx_count) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, ++ "Invalid index count %u for a register of type %#x, expected %u.", ++ reg->idx_count, reg->type, validation_data->idx_count); ++ ++ if (reg->dimension != validation_data->dimension) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, ++ "Invalid dimension %#x for a register of type %#x, expected %#x.", ++ reg->dimension, reg->type, validation_data->dimension); + } + + static void vsir_validate_io_dst_param(struct validation_context *ctx, +@@ -8242,15 +9902,37 @@ static void vsir_validate_dst_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.", dst->modifiers); @@ -13655,9 +19023,9 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + { + switch (dst->reg.data_type) + { -+ case VKD3D_DATA_FLOAT: -+ case VKD3D_DATA_DOUBLE: -+ case VKD3D_DATA_HALF: ++ case VSIR_DATA_F16: ++ case VSIR_DATA_F32: ++ case VSIR_DATA_F64: + break; + + default: @@ -13679,25 +19047,25 @@ index 7466f7a2da1..fe7e8c54dfb 100644 case 13: case 14: case 15: -+ if (dst->reg.data_type != VKD3D_DATA_FLOAT) ++ if (dst->reg.data_type != VSIR_DATA_F32) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid data type %#x for destination with shift.", dst->reg.data_type); break; default: -@@ -8332,9 +9891,44 @@ static void vsir_validate_io_src_param(struct validation_context *ctx, +@@ -8332,9 +10014,44 @@ static void vsir_validate_io_src_param(struct validation_context *ctx, "Invalid register type %#x used as source parameter.", src->reg.type); } -+#define F64_BIT (1u << VKD3D_DATA_DOUBLE) -+#define F32_BIT (1u << VKD3D_DATA_FLOAT) -+#define F16_BIT (1u << VKD3D_DATA_HALF) ++#define F64_BIT (1u << VSIR_DATA_F64) ++#define F32_BIT (1u << VSIR_DATA_F32) ++#define F16_BIT (1u << VSIR_DATA_F16) + -+#define I32_BIT (1u << VKD3D_DATA_INT) ++#define I32_BIT (1u << VSIR_DATA_I32) + -+#define U64_BIT (1u << VKD3D_DATA_UINT64) -+#define U32_BIT (1u << VKD3D_DATA_UINT) -+#define U16_BIT (1u << VKD3D_DATA_UINT16) ++#define U64_BIT (1u << VSIR_DATA_U64) ++#define U32_BIT (1u << VSIR_DATA_U32) ++#define U16_BIT (1u << VSIR_DATA_U16) + static void vsir_validate_src_param(struct validation_context *ctx, const struct vkd3d_shader_src_param *src) @@ -13730,7 +19098,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 vsir_validate_register(ctx, &src->reg); if (src->swizzle & ~0x03030303u) -@@ -8349,6 +9943,13 @@ static void vsir_validate_src_param(struct validation_context *ctx, +@@ -8349,6 +10066,13 @@ static void vsir_validate_src_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.", src->modifiers); @@ -13744,55 +19112,120 @@ index 7466f7a2da1..fe7e8c54dfb 100644 switch (src->reg.type) { case VKD3DSPR_SSA: -@@ -8400,8 +10001,9 @@ static void vsir_validate_dst_count(struct validation_context *ctx, +@@ -8400,8 +10124,9 @@ static void vsir_validate_dst_count(struct validation_context *ctx, { if (instruction->dst_count != count) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, - "Invalid destination count %u for an instruction of type %#x, expected %u.", - instruction->dst_count, instruction->opcode, count); -+ "Invalid destination parameter count %u for instruction \"%s\" (%#x); expected %u.", ++ "Invalid destination parameter count %zu for instruction \"%s\" (%#x); expected %u.", + instruction->dst_count, vsir_opcode_get_name(instruction->opcode, ""), + instruction->opcode, count); } static void vsir_validate_src_count(struct validation_context *ctx, -@@ -8409,8 +10011,9 @@ static void vsir_validate_src_count(struct validation_context *ctx, +@@ -8409,8 +10134,9 @@ static void vsir_validate_src_count(struct validation_context *ctx, { if (instruction->src_count != count) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, - "Invalid source count %u for an instruction of type %#x, expected %u.", - instruction->src_count, instruction->opcode, count); -+ "Invalid source parameter count %u for instruction \"%s\" (%#x); expected %u.", ++ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected %u.", + instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), + instruction->opcode, count); } static bool vsir_validate_src_min_count(struct validation_context *ctx, -@@ -8419,8 +10022,9 @@ static bool vsir_validate_src_min_count(struct validation_context *ctx, +@@ -8419,8 +10145,9 @@ static bool vsir_validate_src_min_count(struct validation_context *ctx, if (instruction->src_count < count) { validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, - "Invalid source count %u for an instruction of type %#x, expected at least %u.", - instruction->src_count, instruction->opcode, count); -+ "Invalid source parameter count %u for instruction \"%s\" (%#x); expected at least %u.", ++ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected at least %u.", + instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), + instruction->opcode, count); return false; } -@@ -8433,8 +10037,9 @@ static bool vsir_validate_src_max_count(struct validation_context *ctx, +@@ -8433,8 +10160,9 @@ static bool vsir_validate_src_max_count(struct validation_context *ctx, if (instruction->src_count > count) { validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, - "Invalid source count %u for an instruction of type %#x, expected at most %u.", - instruction->src_count, instruction->opcode, count); -+ "Invalid source parameter count %u for instruction \"%s\" (%#x); expected at most %u.", ++ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected at most %u.", + instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), + instruction->opcode, count); return false; } -@@ -8922,7 +10527,9 @@ static void vsir_validate_cf_type(struct validation_context *ctx, +@@ -8874,6 +10602,7 @@ static void vsir_validate_descriptors(struct validation_context *ctx) + for (i = 0; i < descriptors->descriptor_count; ++i) + { + const struct vkd3d_shader_descriptor_info1 *descriptor = &descriptors->descriptors[i]; ++ uint32_t flags_mask = 0, uav_flags_mask = 0; + + if (descriptor->type >= VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE, +@@ -8888,10 +10617,10 @@ static void vsir_validate_descriptors(struct validation_context *ctx) + "Descriptor %u has invalid resource type %#x for descriptor type %#x.", + i, descriptor->resource_type, descriptor->type); + +- if (descriptor->resource_data_type >= VKD3D_DATA_COUNT) ++ if (descriptor->resource_data_type >= VSIR_DATA_TYPE_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Descriptor %u has invalid resource data type %#x.", i, descriptor->resource_data_type); +- else if ((descriptor->resource_data_type == VKD3D_DATA_UNUSED) ++ else if ((descriptor->resource_data_type == VSIR_DATA_UNUSED) + != (descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Descriptor %u has invalid resource data type %#x for descriptor type %#x.", +@@ -8902,6 +10631,43 @@ static void vsir_validate_descriptors(struct validation_context *ctx) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT, + "Descriptor %u has invalid descriptor count %u starting at index %u.", + i, descriptor->count, descriptor->register_index); ++ ++ switch (descriptor->type) ++ { ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: ++ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; ++ break; ++ ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: ++ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER ++ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ ++ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS ++ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; ++ uav_flags_mask = VKD3DSUF_GLOBALLY_COHERENT ++ | VKD3DSUF_RASTERISER_ORDERED_VIEW ++ | VKD3DSUF_ORDER_PRESERVING_COUNTER; ++ break; ++ ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: ++ break; ++ ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: ++ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; ++ break; ++ ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_FORCE_32BIT: ++ break; ++ } ++ ++ if (descriptor->flags & ~flags_mask) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS, ++ "Descriptor %u of type %#x has invalid flags %#x.", ++ i, descriptor->type, descriptor->flags); ++ ++ if (descriptor->uav_flags & ~uav_flags_mask) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS, ++ "Descriptor %u of type %#x has invalid UAV flags %#x.", ++ i, descriptor->type, descriptor->uav_flags); + } + } + +@@ -8922,7 +10688,9 @@ static void vsir_validate_cf_type(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, enum vsir_control_flow_type expected_type) { if (ctx->program->cf_type != expected_type) @@ -13803,7 +19236,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 instruction->opcode, name_from_cf_type(ctx->program->cf_type)); } -@@ -8940,17 +10547,171 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, +@@ -8940,17 +10708,230 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL) @@ -13824,9 +19257,9 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } +static void vsir_validate_elementwise_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction, const bool types[VKD3D_DATA_COUNT]) ++ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) +{ -+ enum vkd3d_data_type dst_data_type; ++ enum vsir_data_type dst_data_type; + unsigned int i; + + if (instruction->dst_count < 1) @@ -13834,7 +19267,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + + dst_data_type = instruction->dst[0].reg.data_type; + -+ if (dst_data_type >= VKD3D_DATA_COUNT) ++ if (dst_data_type >= VSIR_DATA_TYPE_COUNT) + return; + + if (!types[dst_data_type]) @@ -13856,9 +19289,9 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +static void vsir_validate_double_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ -+ static const bool types[VKD3D_DATA_COUNT] = ++ static const bool types[VSIR_DATA_TYPE_COUNT] = + { -+ [VKD3D_DATA_DOUBLE] = true, ++ [VSIR_DATA_F64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); @@ -13867,9 +19300,9 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +static void vsir_validate_float_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ -+ static const bool types[VKD3D_DATA_COUNT] = ++ static const bool types[VSIR_DATA_TYPE_COUNT] = + { -+ [VKD3D_DATA_FLOAT] = true, ++ [VSIR_DATA_F32] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); @@ -13878,11 +19311,11 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +static void vsir_validate_integer_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ -+ static const bool types[VKD3D_DATA_COUNT] = ++ static const bool types[VSIR_DATA_TYPE_COUNT] = + { -+ [VKD3D_DATA_INT] = true, -+ [VKD3D_DATA_UINT] = true, -+ [VKD3D_DATA_UINT64] = true, ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_U32] = true, ++ [VSIR_DATA_U64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); @@ -13891,21 +19324,21 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +static void vsir_validate_logic_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ -+ static const bool types[VKD3D_DATA_COUNT] = ++ static const bool types[VSIR_DATA_TYPE_COUNT] = + { -+ [VKD3D_DATA_INT] = true, -+ [VKD3D_DATA_UINT] = true, -+ [VKD3D_DATA_UINT64] = true, -+ [VKD3D_DATA_BOOL] = true, ++ [VSIR_DATA_BOOL] = true, ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_U32] = true, ++ [VSIR_DATA_U64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); +} + +static void vsir_validate_comparison_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction, const bool types[VKD3D_DATA_COUNT]) ++ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) +{ -+ enum vkd3d_data_type dst_data_type, src_data_type; ++ enum vsir_data_type dst_data_type, src_data_type; + unsigned int i; + + if (instruction->dst_count < 1) @@ -13913,7 +19346,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + + dst_data_type = instruction->dst[0].reg.data_type; + -+ if (dst_data_type != VKD3D_DATA_UINT && dst_data_type != VKD3D_DATA_BOOL) ++ if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VSIR_DATA_BOOL) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid data type %#x for result of comparison operation \"%s\" (%#x).", + dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); @@ -13923,7 +19356,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + + src_data_type = instruction->src[0].reg.data_type; + -+ if (src_data_type >= VKD3D_DATA_COUNT) ++ if (src_data_type >= VSIR_DATA_TYPE_COUNT) + return; + + if (!types[src_data_type]) @@ -13945,9 +19378,9 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +static void vsir_validate_double_comparison_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ -+ static const bool types[VKD3D_DATA_COUNT] = ++ static const bool types[VSIR_DATA_TYPE_COUNT] = + { -+ [VKD3D_DATA_DOUBLE] = true, ++ [VSIR_DATA_F64] = true, + }; + + vsir_validate_comparison_operation(ctx, instruction, types); @@ -13956,9 +19389,10 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +static void vsir_validate_float_comparison_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ -+ static const bool types[VKD3D_DATA_COUNT] = ++ static const bool types[VSIR_DATA_TYPE_COUNT] = + { -+ [VKD3D_DATA_FLOAT] = true, ++ [VSIR_DATA_F32] = true, ++ [VSIR_DATA_F64] = true, + }; + + vsir_validate_comparison_operation(ctx, instruction, types); @@ -13967,20 +19401,78 @@ index 7466f7a2da1..fe7e8c54dfb 100644 +static void vsir_validate_integer_comparison_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ -+ static const bool types[VKD3D_DATA_COUNT] = ++ static const bool types[VSIR_DATA_TYPE_COUNT] = + { -+ [VKD3D_DATA_INT] = true, -+ [VKD3D_DATA_UINT] = true, -+ [VKD3D_DATA_UINT64] = true, ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_U32] = true, ++ [VSIR_DATA_U64] = true, + }; + + vsir_validate_comparison_operation(ctx, instruction, types); +} ++ ++static void vsir_validate_cast_operation(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction, ++ const bool src_types[VSIR_DATA_TYPE_COUNT], const bool dst_types[VSIR_DATA_TYPE_COUNT]) ++{ ++ enum vsir_data_type dst_data_type, src_data_type; ++ ++ if (instruction->dst_count < 1 || instruction->src_count < 1) ++ return; ++ ++ dst_data_type = instruction->dst[0].reg.data_type; ++ src_data_type = instruction->src[0].reg.data_type; ++ ++ if (src_data_type >= VSIR_DATA_TYPE_COUNT || dst_data_type >= VSIR_DATA_TYPE_COUNT) ++ return; ++ ++ if (!src_types[src_data_type]) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Invalid source data type %#x for cast operation \"%s\" (%#x).", ++ src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ ++ if (!dst_types[dst_data_type]) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Invalid destination data type %#x for cast operation \"%s\" (%#x).", ++ dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++} ++ ++static void vsir_validate_shift_operation(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ enum vsir_data_type data_type; ++ ++ static const bool types[] = ++ { ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_U32] = true, ++ [VSIR_DATA_U64] = true, ++ }; ++ ++ data_type = instruction->dst[0].reg.data_type; ++ if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Invalid destination data type %#x for shift operation \"%s\" (%#x).", ++ data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ ++ if (instruction->src[0].reg.data_type != data_type) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Data type %#x for source operand 0 doesn't match destination data type %#x " ++ "for shift operation \"%s\" (%#x).", ++ instruction->src[0].reg.data_type, data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ ++ data_type = instruction->src[1].reg.data_type; ++ if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Invalid source operand 1 data type %#x for shift operation \"%s\" (%#x).", ++ data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++} + static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { size_t i; -@@ -9026,7 +10787,7 @@ static void vsir_validate_dcl_index_range(struct validation_context *ctx, +@@ -9026,7 +11007,7 @@ static void vsir_validate_dcl_index_range(struct validation_context *ctx, if (ctx->program->normalisation_level >= VSIR_NORMALISED_SM6) { @@ -13989,7 +19481,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 "DCL_INDEX_RANGE is not allowed with fully normalised input/output."); return; } -@@ -9416,18 +11177,18 @@ static void vsir_validate_dcl_vertices_out(struct validation_context *ctx, +@@ -9416,18 +11397,18 @@ static void vsir_validate_dcl_vertices_out(struct validation_context *ctx, static void vsir_validate_else(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); @@ -14012,7 +19504,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDIF instruction doesn't terminate IF/ELSE block."); else -@@ -9437,7 +11198,7 @@ static void vsir_validate_endif(struct validation_context *ctx, const struct vkd +@@ -9437,7 +11418,7 @@ static void vsir_validate_endif(struct validation_context *ctx, const struct vkd static void vsir_validate_endloop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); @@ -14021,7 +19513,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDLOOP instruction doesn't terminate LOOP block."); else -@@ -9447,7 +11208,7 @@ static void vsir_validate_endloop(struct validation_context *ctx, const struct v +@@ -9447,7 +11428,7 @@ static void vsir_validate_endloop(struct validation_context *ctx, const struct v static void vsir_validate_endrep(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); @@ -14030,7 +19522,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDREP instruction doesn't terminate REP block."); else -@@ -9457,7 +11218,7 @@ static void vsir_validate_endrep(struct validation_context *ctx, const struct vk +@@ -9457,23 +11438,88 @@ static void vsir_validate_endrep(struct validation_context *ctx, const struct vk static void vsir_validate_endswitch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); @@ -14039,7 +19531,42 @@ index 7466f7a2da1..fe7e8c54dfb 100644 validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDSWITCH instruction doesn't terminate SWITCH block."); else -@@ -9467,13 +11228,13 @@ static void vsir_validate_endswitch(struct validation_context *ctx, const struct + --ctx->depth; + } + ++static void vsir_validate_ftoi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool src_types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_F16] = true, ++ [VSIR_DATA_F32] = true, ++ [VSIR_DATA_F64] = true, ++ }; ++ static const bool dst_types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_U32] = true, ++ }; ++ ++ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); ++} ++ ++static void vsir_validate_ftou(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool src_types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_F16] = true, ++ [VSIR_DATA_F32] = true, ++ [VSIR_DATA_F64] = true, ++ }; ++ static const bool dst_types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_U32] = true, ++ }; ++ ++ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); ++} ++ static void vsir_validate_if(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); @@ -14052,10 +19579,42 @@ index 7466f7a2da1..fe7e8c54dfb 100644 vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - vsir_validator_push_block(ctx, VKD3DSIH_IF); + vsir_validator_push_block(ctx, VSIR_OP_IF); ++} ++ ++static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool src_types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_BOOL] = true, ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_U32] = true, ++ [VSIR_DATA_U64] = true, ++ }; ++ static const bool dst_types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_F16] = true, ++ [VSIR_DATA_F32] = true, ++ [VSIR_DATA_F64] = true, ++ }; ++ ++ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); ++} ++ ++static void vsir_validate_itoi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_BOOL] = true, ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_U32] = true, ++ [VSIR_DATA_U64] = true, ++ }; ++ ++ vsir_validate_cast_operation(ctx, instruction, types, types); } static void vsir_validate_label(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -@@ -9494,7 +11255,7 @@ static void vsir_validate_loop(struct validation_context *ctx, const struct vkd3 +@@ -9494,7 +11540,7 @@ static void vsir_validate_loop(struct validation_context *ctx, const struct vkd3 { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); vsir_validate_src_count(ctx, instruction, ctx->program->shader_version.major <= 3 ? 2 : 0); @@ -14064,7 +19623,16 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } static void vsir_validate_nop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -@@ -9564,7 +11325,7 @@ static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d +@@ -9511,7 +11557,7 @@ static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d + + if (instruction->src_count % 2 != 0) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, +- "Invalid source count %u for a PHI instruction, it must be an even number.", ++ "Invalid source count %zu for a PHI instruction, it must be an even number.", + instruction->src_count); + incoming_count = instruction->src_count / 2; + +@@ -9564,7 +11610,7 @@ static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d static void vsir_validate_rep(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); @@ -14073,7 +19641,58 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -@@ -9575,7 +11336,7 @@ static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d +@@ -9572,10 +11618,58 @@ static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d + ctx->inside_block = false; + } + ++static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; ++ ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Invalid destination data type %#x for operation \"%s\" (%#x) with flags %#x.", dst_data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode, instruction->flags); ++} ++ ++static void vsir_validate_sample_info(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; ++ ++ switch (dst_data_type) ++ { ++ case VSIR_DATA_F32: ++ case VSIR_DATA_U32: ++ if (!!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT) != (dst_data_type == VSIR_DATA_U32)) ++ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); ++ break; ++ ++ default: ++ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); ++ break; ++ } ++} ++ ++static void vsir_validate_resinfo(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; ++ ++ switch (dst_data_type) ++ { ++ case VSIR_DATA_F32: ++ case VSIR_DATA_U32: ++ if (!!(instruction->flags & VKD3DSI_RESINFO_UINT) != (dst_data_type == VSIR_DATA_U32)) ++ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); ++ break; ++ ++ default: ++ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); ++ break; ++ } ++} ++ static void vsir_validate_switch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); @@ -14082,7 +19701,16 @@ index 7466f7a2da1..fe7e8c54dfb 100644 } static void vsir_validate_switch_monolithic(struct validation_context *ctx, -@@ -9636,45 +11397,84 @@ struct vsir_validator_instruction_desc +@@ -9593,7 +11687,7 @@ static void vsir_validate_switch_monolithic(struct validation_context *ctx, + + if (instruction->src_count % 2 != 1) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, +- "Invalid source count %u for a monolithic SWITCH instruction, it must be an odd number.", ++ "Invalid source count %zu for a monolithic SWITCH instruction, it must be an odd number.", + instruction->src_count); + + if (!vsir_register_is_label(&instruction->src[1].reg)) +@@ -9636,45 +11730,116 @@ struct vsir_validator_instruction_desc static const struct vsir_validator_instruction_desc vsir_validator_instructions[] = { @@ -14133,42 +19761,6 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + [VSIR_OP_ATAN] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_BRANCH] = {0, ~0u, vsir_validate_branch}, + [VSIR_OP_DADD] = {1, 2, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DDIV] = {1, 2, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DEQO] = {1, 2, vsir_validate_double_comparison_operation}, -+ [VSIR_OP_DFMA] = {1, 3, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DGEO] = {1, 2, vsir_validate_double_comparison_operation}, -+ [VSIR_OP_DIV] = {1, 2, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_DLT] = {1, 2, vsir_validate_double_comparison_operation}, -+ [VSIR_OP_DMAX] = {1, 2, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DMIN] = {1, 2, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DMOV] = {1, 1, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DMUL] = {1, 2, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DNE] = {1, 2, vsir_validate_double_comparison_operation}, -+ [VSIR_OP_DRCP] = {1, 1, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DSX] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_DSX_COARSE] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_DSX_FINE] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_DSY] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_DSY_COARSE] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_DSY_FINE] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_EQO] = {1, 2, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_EQU] = {1, 2, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_EXP] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_FRC] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_FREM] = {1, 2, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_GEO] = {1, 2, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_GEU] = {1, 2, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_HCOS] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_HSIN] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_HTAN] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_HS_CONTROL_POINT_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, -+ [VSIR_OP_HS_DECLS] = {0, 0, vsir_validate_hull_shader_phase}, -+ [VSIR_OP_HS_FORK_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, -+ [VSIR_OP_HS_JOIN_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, -+ [VSIR_OP_IADD] = {1, 2, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_IEQ] = {1, 2, vsir_validate_integer_comparison_operation}, -+ [VSIR_OP_IGE] = {1, 2, vsir_validate_integer_comparison_operation}, -+ [VSIR_OP_ILT] = {1, 2, vsir_validate_integer_comparison_operation}, + [VSIR_OP_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances}, + [VSIR_OP_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor}, + [VSIR_OP_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range}, @@ -14188,25 +19780,93 @@ index 7466f7a2da1..fe7e8c54dfb 100644 + [VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_tessellator_output_primitive}, + [VSIR_OP_DCL_TESSELLATOR_PARTITIONING] = {0, 0, vsir_validate_dcl_tessellator_partitioning}, + [VSIR_OP_DCL_VERTICES_OUT] = {0, 0, vsir_validate_dcl_vertices_out}, ++ [VSIR_OP_DDIV] = {1, 2, vsir_validate_double_elementwise_operation}, ++ [VSIR_OP_DEQO] = {1, 2, vsir_validate_double_comparison_operation}, ++ [VSIR_OP_DFMA] = {1, 3, vsir_validate_double_elementwise_operation}, ++ [VSIR_OP_DGEO] = {1, 2, vsir_validate_double_comparison_operation}, ++ [VSIR_OP_DIV] = {1, 2, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_DLT] = {1, 2, vsir_validate_double_comparison_operation}, ++ [VSIR_OP_DMAX] = {1, 2, vsir_validate_double_elementwise_operation}, ++ [VSIR_OP_DMIN] = {1, 2, vsir_validate_double_elementwise_operation}, ++ [VSIR_OP_DMOV] = {1, 1, vsir_validate_double_elementwise_operation}, ++ [VSIR_OP_DMUL] = {1, 2, vsir_validate_double_elementwise_operation}, ++ [VSIR_OP_DNE] = {1, 2, vsir_validate_double_comparison_operation}, ++ [VSIR_OP_DRCP] = {1, 1, vsir_validate_double_elementwise_operation}, ++ [VSIR_OP_DSX] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_DSX_COARSE] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_DSX_FINE] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_DSY] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_DSY_COARSE] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_DSY_FINE] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_ELSE] = {0, 0, vsir_validate_else}, + [VSIR_OP_ENDIF] = {0, 0, vsir_validate_endif}, + [VSIR_OP_ENDLOOP] = {0, 0, vsir_validate_endloop}, + [VSIR_OP_ENDREP] = {0, 0, vsir_validate_endrep}, + [VSIR_OP_ENDSWITCH] = {0, 0, vsir_validate_endswitch}, ++ [VSIR_OP_EQO] = {1, 2, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_EQU] = {1, 2, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_EXP] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_FRC] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_FREM] = {1, 2, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_FTOI] = {1, 1, vsir_validate_ftoi}, ++ [VSIR_OP_FTOU] = {1, 1, vsir_validate_ftou}, ++ [VSIR_OP_GEO] = {1, 2, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_GEU] = {1, 2, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_HCOS] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_HSIN] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_HS_CONTROL_POINT_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, ++ [VSIR_OP_HS_DECLS] = {0, 0, vsir_validate_hull_shader_phase}, ++ [VSIR_OP_HS_FORK_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, ++ [VSIR_OP_HS_JOIN_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, ++ [VSIR_OP_HTAN] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_IADD] = {1, 2, vsir_validate_integer_elementwise_operation}, ++ [VSIR_OP_IEQ] = {1, 2, vsir_validate_integer_comparison_operation}, + [VSIR_OP_IF] = {0, 1, vsir_validate_if}, + [VSIR_OP_IFC] = {0, 2, vsir_validate_ifc}, ++ [VSIR_OP_IGE] = {1, 2, vsir_validate_integer_comparison_operation}, ++ [VSIR_OP_ILT] = {1, 2, vsir_validate_integer_comparison_operation}, ++ [VSIR_OP_IMAD] = {1, 3, vsir_validate_integer_elementwise_operation}, ++ [VSIR_OP_IMAX] = {1, 2, vsir_validate_integer_elementwise_operation}, ++ [VSIR_OP_IMIN] = {1, 2, vsir_validate_integer_elementwise_operation}, ++ [VSIR_OP_INE] = {1, 2, vsir_validate_integer_comparison_operation}, ++ [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation}, ++ [VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation}, ++ [VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_ISHL] = {1, 2, vsir_validate_shift_operation}, ++ [VSIR_OP_ISHR] = {1, 2, vsir_validate_shift_operation}, ++ [VSIR_OP_ISINF] = {1, 1, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_ISNAN] = {1, 1, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_ITOF] = {1, 1, vsir_validate_itof}, ++ [VSIR_OP_ITOI] = {1, 1, vsir_validate_itoi}, + [VSIR_OP_LABEL] = {0, 1, vsir_validate_label}, ++ [VSIR_OP_LOG] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_LOOP] = {0, ~0u, vsir_validate_loop}, ++ [VSIR_OP_LTO] = {1, 2, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_LTU] = {1, 2, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_MAD] = {1, 3, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_NEO] = {1, 2, vsir_validate_float_comparison_operation}, ++ [VSIR_OP_NEU] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_NOP] = {0, 0, vsir_validate_nop}, ++ [VSIR_OP_NOT] = {1, 1, vsir_validate_logic_elementwise_operation}, ++ [VSIR_OP_OR] = {1, 2, vsir_validate_logic_elementwise_operation}, ++ [VSIR_OP_ORD] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_PHI] = {1, ~0u, vsir_validate_phi}, ++ [VSIR_OP_RCP] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_REP] = {0, 1, vsir_validate_rep}, ++ [VSIR_OP_RESINFO] = {1, 2, vsir_validate_resinfo}, + [VSIR_OP_RET] = {0, 0, vsir_validate_ret}, ++ [VSIR_OP_ROUND_NE] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_ROUND_NI] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_SAMPLE_INFO] = {1, 1, vsir_validate_sample_info}, + [VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch}, + [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, }; static void vsir_validate_instruction(struct validation_context *ctx) -@@ -9691,28 +11491,28 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -9691,28 +11856,28 @@ static void vsir_validate_instruction(struct validation_context *ctx) for (i = 0; i < instruction->src_count; ++i) vsir_validate_src_param(ctx, &instruction->src[i]); @@ -14247,7 +19907,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 break; } } -@@ -9721,19 +11521,19 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -9721,19 +11886,19 @@ static void vsir_validate_instruction(struct validation_context *ctx) { switch (instruction->opcode) { @@ -14275,7 +19935,7 @@ index 7466f7a2da1..fe7e8c54dfb 100644 break; } } -@@ -9764,7 +11564,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c +@@ -9764,7 +11929,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c .program = program, .null_location = {.source_name = source_name}, .status = VKD3D_OK, @@ -14284,11 +19944,63 @@ index 7466f7a2da1..fe7e8c54dfb 100644 .invalid_instruction_idx = true, .outer_tess_idxs[0] = ~0u, .outer_tess_idxs[1] = ~0u, +@@ -9970,6 +12135,28 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin + return ctx.result; + } + ++enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, ++ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) ++{ ++ struct vsir_transformation_context ctx = ++ { ++ .result = VKD3D_OK, ++ .program = program, ++ .config_flags = config_flags, ++ .compile_info = compile_info, ++ .message_context = message_context, ++ }; ++ ++ vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); ++ if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ++ vsir_transform(&ctx, vsir_program_normalise_ps1_output); ++ ++ if (TRACE_ON()) ++ vsir_program_trace(program); ++ ++ return ctx.result; ++} ++ + enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) + { +@@ -9989,8 +12176,11 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t + vsir_transform(&ctx, vsir_program_materialise_phi_ssas_to_temps); + vsir_transform(&ctx, vsir_program_lower_switch_to_selection_ladder); + vsir_transform(&ctx, vsir_program_structurize); +- vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); +- vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); ++ if (compile_info->target_type != VKD3D_SHADER_TARGET_MSL) ++ { ++ vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); ++ vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); ++ } + } + else + { diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index 4f37468af86..032b5504319 100644 +index 4f37468af86..c6e048adb20 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -48,19 +48,29 @@ struct msl_generator +@@ -18,6 +18,8 @@ + + #include "vkd3d_shader_private.h" + ++#define MAX_IO_REG_COUNT 32 ++ + enum msl_data_type + { + MSL_DATA_FLOAT, +@@ -48,19 +50,29 @@ struct msl_generator const char *prefix; bool failed; @@ -14321,7 +20033,7 @@ index 4f37468af86..032b5504319 100644 static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen, enum vkd3d_shader_error error, const char *fmt, ...) { -@@ -76,17 +86,17 @@ static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3 +@@ -76,17 +88,17 @@ static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3 { static const struct msl_resource_type_info info[] = { @@ -14350,7 +20062,56 @@ index 4f37468af86..032b5504319 100644 }; if (!t || t >= ARRAY_SIZE(info)) -@@ -226,6 +236,35 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const s +@@ -123,19 +135,19 @@ static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int in + } + + static void msl_print_resource_datatype(struct msl_generator *gen, +- struct vkd3d_string_buffer *buffer, enum vkd3d_data_type data_type) ++ struct vkd3d_string_buffer *buffer, enum vsir_data_type data_type) + { + switch (data_type) + { +- case VKD3D_DATA_FLOAT: +- case VKD3D_DATA_UNORM: +- case VKD3D_DATA_SNORM: ++ case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: + vkd3d_string_buffer_printf(buffer, "float"); + break; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + vkd3d_string_buffer_printf(buffer, "int"); + break; +- case VKD3D_DATA_UINT: ++ case VSIR_DATA_U32: + vkd3d_string_buffer_printf(buffer, "uint"); + break; + default: +@@ -147,18 +159,18 @@ static void msl_print_resource_datatype(struct msl_generator *gen, + } + + static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, +- struct msl_generator *gen, enum vkd3d_data_type data_type) ++ struct msl_generator *gen, enum vsir_data_type data_type) + { + vkd3d_string_buffer_printf(buffer, "."); + switch (data_type) + { +- case VKD3D_DATA_FLOAT: ++ case VSIR_DATA_F32: + vkd3d_string_buffer_printf(buffer, "f"); + break; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + vkd3d_string_buffer_printf(buffer, "i"); + break; +- case VKD3D_DATA_UINT: ++ case VSIR_DATA_U32: + vkd3d_string_buffer_printf(buffer, "u"); + break; + default: +@@ -226,6 +238,35 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const s return NULL; } @@ -14386,7 +20147,7 @@ index 4f37468af86..032b5504319 100644 static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const struct msl_generator *gen, unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) { -@@ -260,20 +299,71 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const s +@@ -260,20 +301,71 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const s return NULL; } @@ -14437,7 +20198,7 @@ index 4f37468af86..032b5504319 100644 + static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, - const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type) -+ const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type, bool compare) ++ const struct msl_resource_type_info *resource_type_info, enum vsir_data_type resource_data_type, bool compare) { - vkd3d_string_buffer_printf(buffer, "descriptors[%u].textype_suffix); @@ -14449,7 +20210,7 @@ index 4f37468af86..032b5504319 100644 } +static void msl_print_uav_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, -+ const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type) ++ const struct msl_resource_type_info *resource_type_info, enum vsir_data_type resource_data_type) +{ + vkd3d_string_buffer_printf(buffer, "descriptors[%u].astype_suffix, @@ -14461,7 +20222,7 @@ index 4f37468af86..032b5504319 100644 static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, const struct vkd3d_shader_register *reg) { -@@ -359,25 +449,40 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu +@@ -359,25 +451,40 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu vkd3d_string_buffer_printf(buffer, "", reg->type); return MSL_DATA_UNION; } @@ -14500,12 +20261,48 @@ index 4f37468af86..032b5504319 100644 + "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; ++ return MSL_DATA_UNION; + default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled register type %#x.", reg->type); -@@ -488,6 +593,9 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m +@@ -418,21 +525,21 @@ static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cach + } + + static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_generator *gen, const char *src, +- enum vkd3d_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) ++ enum vsir_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) + { + bool write_cast = false; + +- if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) +- dst_data_type = VKD3D_DATA_FLOAT; ++ if (dst_data_type == VSIR_DATA_UNORM || dst_data_type == VSIR_DATA_SNORM) ++ dst_data_type = VSIR_DATA_F32; + + switch (src_data_type) + { + case MSL_DATA_FLOAT: +- write_cast = dst_data_type != VKD3D_DATA_FLOAT; ++ write_cast = dst_data_type != VSIR_DATA_F32; + break; + + case MSL_DATA_UINT: +- write_cast = dst_data_type != VKD3D_DATA_UINT; ++ write_cast = dst_data_type != VSIR_DATA_U32; + break; + + case MSL_DATA_UNION: +@@ -456,7 +563,7 @@ static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_genera + } + + static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, +- const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) ++ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vsir_data_type data_type) + { + const struct vkd3d_shader_register *reg = &vsir_src->reg; + struct vkd3d_string_buffer *register_name, *str; +@@ -488,6 +595,9 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m case VKD3DSPSM_ABS: vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); break; @@ -14515,7 +20312,7 @@ index 4f37468af86..032b5504319 100644 default: vkd3d_string_buffer_printf(buffer, "(%s)", vsir_src->modifiers, str->buffer); -@@ -539,12 +647,34 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, +@@ -539,12 +649,34 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, return write_mask; } @@ -14550,7 +20347,7 @@ index 4f37468af86..032b5504319 100644 if (dst->vsir->shift) msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift); -@@ -570,10 +700,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment( +@@ -570,10 +702,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment( static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { @@ -14565,7 +20362,7 @@ index 4f37468af86..032b5504319 100644 } static void msl_binop(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) -@@ -695,19 +827,36 @@ static void msl_begin_block(struct msl_generator *gen) +@@ -695,19 +829,36 @@ static void msl_begin_block(struct msl_generator *gen) ++gen->indent; } @@ -14587,7 +20384,7 @@ index 4f37468af86..032b5504319 100644 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 @@ -14599,7 +20396,7 @@ index 4f37468af86..032b5504319 100644 + 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); @@ -14607,7 +20404,7 @@ index 4f37468af86..032b5504319 100644 msl_begin_block(gen); } -@@ -719,6 +868,77 @@ static void msl_else(struct msl_generator *gen) +@@ -719,6 +870,77 @@ static void msl_else(struct msl_generator *gen) msl_begin_block(gen); } @@ -14685,16 +20482,25 @@ index 4f37468af86..032b5504319 100644 static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { const struct msl_resource_type_info *resource_type_info; -@@ -728,6 +948,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct +@@ -726,9 +948,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + const struct vkd3d_shader_descriptor_info1 *descriptor; + const struct vkd3d_shader_descriptor_binding *binding; enum vkd3d_shader_resource_type resource_type; ++ uint32_t coord_mask, write_mask_size; struct vkd3d_string_buffer *read; - enum vkd3d_data_type data_type; +- enum vkd3d_data_type data_type; +- uint32_t coord_mask; ++ enum vsir_data_type data_type; + unsigned int srv_binding; - uint32_t coord_mask; struct msl_dst dst; -@@ -757,30 +978,39 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - data_type = VKD3D_DATA_FLOAT; + if (vkd3d_shader_instruction_has_texel_offset(ins)) +@@ -754,47 +977,65 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + "Internal compiler error: Undeclared resource descriptor %u.", resource_id); + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; +- data_type = VKD3D_DATA_FLOAT; ++ data_type = VSIR_DATA_F32; } - if ((resource_type_info = msl_get_resource_type_info(resource_type))) @@ -14737,15 +20543,23 @@ index 4f37468af86..032b5504319 100644 msl_dst_init(&dst, gen, ins, &ins->dst[0]); read = vkd3d_string_buffer_get(&gen->string_buffers); - vkd3d_string_buffer_printf(read, "as_type("); +- vkd3d_string_buffer_printf(read, "as_type("); - msl_print_srv_name(read, gen, binding->binding, resource_type_info, data_type); ++ vkd3d_string_buffer_printf(read, "as_type<"); ++ msl_print_resource_datatype(gen, read, ins->dst[0].reg.data_type); ++ write_mask_size = vkd3d_popcount(ins->dst[0].write_mask); ++ if (write_mask_size != 1) ++ vkd3d_string_buffer_printf(read, "%u", write_mask_size); ++ vkd3d_string_buffer_printf(read, ">("); + msl_print_srv_name(read, gen, srv_binding, resource_type_info, data_type, false); vkd3d_string_buffer_printf(read, ".read("); - msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); +- msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); ++ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VSIR_DATA_U32); if (resource_type_info->array) -@@ -788,10 +1018,13 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + { vkd3d_string_buffer_printf(read, ", "); - msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT); +- msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT); ++ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VSIR_DATA_U32); } - if (resource_type_info->lod) + if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) @@ -14753,13 +20567,18 @@ index 4f37468af86..032b5504319 100644 vkd3d_string_buffer_printf(read, ", "); - msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); + if (ins->opcode != VSIR_OP_LD2DMS) -+ msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); ++ msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VSIR_DATA_U32); + else -+ msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VKD3D_DATA_UINT); ++ msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32); } - vkd3d_string_buffer_printf(read, "))"); +- vkd3d_string_buffer_printf(read, "))"); ++ vkd3d_string_buffer_printf(read, ")"); msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask); -@@ -802,6 +1035,310 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct ++ vkd3d_string_buffer_printf(read, ")"); + + msl_print_assignment(gen, &dst, "%s", read->buffer); + +@@ -802,6 +1043,313 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct msl_dst_cleanup(&dst, &gen->string_buffers); } @@ -14774,10 +20593,10 @@ index 4f37468af86..032b5504319 100644 + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_resource_type resource_type; + unsigned int srv_binding, sampler_binding; ++ uint32_t coord_mask, write_mask_size; + struct vkd3d_string_buffer *sample; -+ enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + unsigned int component_idx; -+ uint32_t coord_mask; + struct msl_dst dst; + + bias = ins->opcode == VSIR_OP_SAMPLE_B; @@ -14814,7 +20633,7 @@ index 4f37468af86..032b5504319 100644 + "Internal compiler error: Undeclared resource descriptor %u.", resource_id); + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -+ data_type = VKD3D_DATA_FLOAT; ++ data_type = VSIR_DATA_F32; + } + + if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER @@ -14896,8 +20715,12 @@ index 4f37468af86..032b5504319 100644 + msl_dst_init(&dst, gen, ins, &ins->dst[0]); + sample = vkd3d_string_buffer_get(&gen->string_buffers); + -+ if (ins->dst[0].reg.data_type == VKD3D_DATA_UINT) -+ vkd3d_string_buffer_printf(sample, "as_type("); ++ vkd3d_string_buffer_printf(sample, "as_type<"); ++ msl_print_resource_datatype(gen, sample, ins->dst[0].reg.data_type); ++ write_mask_size = vkd3d_popcount(ins->dst[0].write_mask); ++ if (write_mask_size != 1) ++ vkd3d_string_buffer_printf(sample, "%u", write_mask_size); ++ vkd3d_string_buffer_printf(sample, ">("); + msl_print_srv_name(sample, gen, srv_binding, resource_type_info, data_type, compare); + if (gather && compare) + vkd3d_string_buffer_printf(sample, ".gather_compare("); @@ -14966,10 +20789,9 @@ index 4f37468af86..032b5504319 100644 + vkd3d_string_buffer_printf(sample, ", component::%c", "xyzw"[component_idx]); + } + vkd3d_string_buffer_printf(sample, ")"); -+ if (ins->dst[0].reg.data_type == VKD3D_DATA_UINT) -+ vkd3d_string_buffer_printf(sample, ")"); + if (!compare || gather) + msl_print_swizzle(sample, resource->swizzle, ins->dst[0].write_mask); ++ vkd3d_string_buffer_printf(sample, ")"); + + msl_print_assignment(gen, &dst, "%s", sample->buffer); + @@ -14985,7 +20807,7 @@ index 4f37468af86..032b5504319 100644 + enum vkd3d_shader_resource_type resource_type; + unsigned int uav_id, uav_idx, uav_space; + struct vkd3d_string_buffer *image_data; -+ enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + unsigned int uav_binding; + uint32_t coord_mask; + @@ -15008,7 +20830,7 @@ index 4f37468af86..032b5504319 100644 + "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); + uav_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -+ data_type = VKD3D_DATA_FLOAT; ++ data_type = VSIR_DATA_F32; + } + + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) @@ -15037,19 +20859,19 @@ index 4f37468af86..032b5504319 100644 + { + switch (data_type) + { -+ case VKD3D_DATA_UINT: ++ case VSIR_DATA_U32: + vkd3d_string_buffer_printf(image_data, "uint4("); + break; -+ case VKD3D_DATA_INT: ++ case VSIR_DATA_I32: + vkd3d_string_buffer_printf(image_data, "int4("); + break; + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled data type %#x.", data_type); + /* fall through */ -+ case VKD3D_DATA_FLOAT: -+ case VKD3D_DATA_UNORM: -+ case VKD3D_DATA_SNORM: ++ case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: + vkd3d_string_buffer_printf(image_data, "float4("); + break; + } @@ -15061,7 +20883,7 @@ index 4f37468af86..032b5504319 100644 + msl_print_indent(gen->buffer, gen->indent); + msl_print_uav_name(gen->buffer, gen, uav_binding, resource_type_info, data_type); + vkd3d_string_buffer_printf(gen->buffer, ".write(%s, ", image_data->buffer); -+ msl_print_src_with_type(gen->buffer, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); ++ msl_print_src_with_type(gen->buffer, gen, &ins->src[0], coord_mask, VSIR_DATA_U32); + vkd3d_string_buffer_printf(gen->buffer, ");\n"); + + vkd3d_string_buffer_release(&gen->string_buffers, image_data); @@ -15070,14 +20892,15 @@ index 4f37468af86..032b5504319 100644 static void msl_unary_op(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) { struct msl_src src; -@@ -863,128 +1400,208 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc +@@ -863,128 +1411,209 @@ 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) +{ ++ const char *type = ins->declaration.indexable_temp.component_count == 4 ? "vkd3d_vec4" : "vkd3d_scalar"; + msl_print_indent(gen->buffer, gen->indent); -+ vkd3d_string_buffer_printf(gen->buffer, "vkd3d_vec4 x%u[%u];\n", ++ vkd3d_string_buffer_printf(gen->buffer, "%s x%u[%u];\n", type, + ins->declaration.indexable_temp.register_idx, + ins->declaration.indexable_temp.register_size); +} @@ -15109,10 +20932,10 @@ index 4f37468af86..032b5504319 100644 + break; + case VSIR_OP_DCL_INDEXABLE_TEMP: + msl_dcl_indexable_temp(gen, ins); ++ break; ++ case VSIR_OP_NOP: break; - case VKD3DSIH_DIV: -+ case VSIR_OP_NOP: -+ break; + case VSIR_OP_DEFAULT: + msl_default(gen); + break; @@ -15320,15 +21143,35 @@ index 4f37468af86..032b5504319 100644 default: msl_unhandled(gen, ins); break; -@@ -1008,21 +1625,48 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) +@@ -996,6 +1625,7 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) + const struct shader_signature *signature = &gen->program->input_signature; + enum vkd3d_shader_type type = gen->program->shader_version.type; + struct vkd3d_string_buffer *buffer = gen->buffer; ++ bool locations[MAX_IO_REG_COUNT] = {0}; + const struct signature_element *e; + unsigned int i; + +@@ -1008,21 +1638,60 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) continue; - if (e->sysval_semantic) -+ switch (e->sysval_semantic) ++ if (e->target_location >= ARRAY_SIZE(locations)) { - if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) - { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled input target location %u.", e->target_location); ++ continue; ++ } ++ ++ if (locations[e->target_location]) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location); ++ locations[e->target_location] = true; ++ ++ switch (e->sysval_semantic) ++ { + case VKD3D_SHADER_SV_NONE: + break; + @@ -15340,14 +21183,14 @@ index 4f37468af86..032b5504319 100644 + msl_print_indent(gen->buffer, 1); + vkd3d_string_buffer_printf(buffer, "float4 position [[position]];\n"); + continue; -+ + + case VKD3D_SHADER_SV_VERTEX_ID: + if (type != VKD3D_SHADER_TYPE_VERTEX) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled SV_VERTEX_ID in shader type #%x.", type); + gen->read_vertex_id = true; + continue; - ++ + case VKD3D_SHADER_SV_IS_FRONT_FACE: + if (type != VKD3D_SHADER_TYPE_PIXEL) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -15377,7 +21220,7 @@ index 4f37468af86..032b5504319 100644 } if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) -@@ -1059,15 +1703,15 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) +@@ -1059,15 +1728,15 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) break; } @@ -15396,7 +21239,7 @@ index 4f37468af86..032b5504319 100644 break; default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -1081,13 +1725,16 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) +@@ -1081,13 +1750,16 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) case VKD3DSIM_LINEAR: case VKD3DSIM_NONE: break; @@ -15414,7 +21257,15 @@ index 4f37468af86..032b5504319 100644 } vkd3d_string_buffer_printf(buffer, "};\n\n"); -@@ -1138,15 +1785,8 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) +@@ -1129,6 +1801,7 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) + const struct shader_signature *signature = &gen->program->output_signature; + enum vkd3d_shader_type type = gen->program->shader_version.type; + struct vkd3d_string_buffer *buffer = gen->buffer; ++ bool locations[MAX_IO_REG_COUNT] = {0}; + const struct signature_element *e; + unsigned int i; + +@@ -1138,28 +1811,26 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) { e = &signature->elements[i]; @@ -15423,16 +21274,38 @@ index 4f37468af86..032b5504319 100644 - gen->write_depth = true; - msl_print_indent(gen->buffer, 1); - vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); -- continue; -- } -- -- if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) + if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED + || e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) continue; +- } - if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) -@@ -1209,6 +1849,18 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) +- if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) +- continue; +- +- if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) ++ if (e->target_location >= ARRAY_SIZE(locations)) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision); ++ "Internal compiler error: Unhandled input target location %u.", e->target_location); + continue; + } + +- if (e->interpolation_mode != VKD3DSIM_NONE) ++ if (locations[e->target_location]) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location); ++ locations[e->target_location] = true; ++ ++ if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); ++ "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision); + continue; + } + +@@ -1209,6 +1880,18 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) vkd3d_string_buffer_printf(buffer, ";\n"); } @@ -15451,7 +21324,7 @@ index 4f37468af86..032b5504319 100644 vkd3d_string_buffer_printf(buffer, "};\n\n"); } -@@ -1227,23 +1879,45 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) +@@ -1227,23 +1910,45 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) continue; vkd3d_string_buffer_printf(buffer, " %s_in[%u]", gen->prefix, e->register_index); @@ -15473,31 +21346,31 @@ index 4f37468af86..032b5504319 100644 - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic); + case VKD3D_SHADER_SV_NONE: -+ msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); ++ msl_print_register_datatype(buffer, gen, vsir_data_type_from_component_type(e->component_type)); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i); + break; + + case VKD3D_SHADER_SV_POSITION: -+ msl_print_register_datatype(buffer, gen, VKD3D_DATA_FLOAT); ++ msl_print_register_datatype(buffer, gen, VSIR_DATA_F32); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = float4(input.position.xyz, 1.0f / input.position.w)"); + break; + + case VKD3D_SHADER_SV_VERTEX_ID: -+ msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); ++ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = uint4(vertex_id, 0u, 0u, 0u)"); + break; + + case VKD3D_SHADER_SV_IS_FRONT_FACE: -+ msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); ++ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)"); + break; + + case VKD3D_SHADER_SV_SAMPLE_INDEX: -+ msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); ++ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = uint4(input.sample_index, 0u, 0u, 0u)"); + break; @@ -15512,7 +21385,7 @@ index 4f37468af86..032b5504319 100644 vkd3d_string_buffer_printf(buffer, ";\n"); } } -@@ -1259,12 +1933,6 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) +@@ -1259,12 +1964,6 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) { e = &signature->elements[i]; @@ -15525,8 +21398,12 @@ index 4f37468af86..032b5504319 100644 if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) continue; -@@ -1279,6 +1947,8 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) - msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); +@@ -1276,9 +1975,11 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) + vkd3d_string_buffer_printf(buffer, " output.shader_out_%u", i); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = %s_out[%u]", gen->prefix, e->register_index); +- msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); ++ msl_print_register_datatype(buffer, gen, vsir_data_type_from_component_type(e->component_type)); msl_print_write_mask(buffer, e->mask); break; + case VKD3D_SHADER_SV_DEPTH: @@ -15534,17 +21411,17 @@ index 4f37468af86..032b5504319 100644 default: vkd3d_string_buffer_printf(buffer, " ", e->sysval_semantic); msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -1286,6 +1956,9 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) +@@ -1286,6 +1987,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"); ++ vkd3d_string_buffer_printf(gen->buffer, " output.shader_out_mask = o_mask.u;\n"); } static void msl_generate_entrypoint(struct msl_generator *gen) -@@ -1298,6 +1971,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen) +@@ -1298,6 +2002,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, "vertex "); break; case VKD3D_SHADER_TYPE_PIXEL: @@ -15553,7 +21430,7 @@ index 4f37468af86..032b5504319 100644 vkd3d_string_buffer_printf(gen->buffer, "fragment "); break; default: -@@ -1316,6 +1991,12 @@ static void msl_generate_entrypoint(struct msl_generator *gen) +@@ -1316,25 +2022,35 @@ static void msl_generate_entrypoint(struct msl_generator *gen) "constant descriptor *descriptors [[buffer(0)]],\n"); } @@ -15566,15 +21443,17 @@ index 4f37468af86..032b5504319 100644 msl_print_indent(gen->buffer, 2); vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix); -@@ -1323,18 +2004,22 @@ 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); + /* TODO: declare #maximum_register + 1 */ +- 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_vec4 %s_in[%u];\n", gen->prefix, MAX_IO_REG_COUNT); ++ vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, MAX_IO_REG_COUNT); vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix); - - if (gen->write_depth) - vkd3d_string_buffer_printf(gen->buffer, " float shader_out_depth;\n"); + 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, " vkd3d_scalar o_mask;\n"); + vkd3d_string_buffer_printf(gen->buffer, "\n"); msl_generate_entrypoint_prologue(gen); @@ -15595,7 +21474,18 @@ index 4f37468af86..032b5504319 100644 msl_generate_entrypoint_epilogue(gen); -@@ -1353,7 +2038,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader +@@ -1343,8 +2059,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + + static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out) + { +- const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions; +- unsigned int i; ++ struct vkd3d_shader_instruction *ins; ++ struct vsir_program_iterator it; + + MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); + +@@ -1353,10 +2069,15 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader vkd3d_string_buffer_printf(gen->buffer, "#include \n\n"); vkd3d_string_buffer_printf(gen->buffer, "using namespace metal;\n\n"); @@ -15604,7 +21494,15 @@ index 4f37468af86..032b5504319 100644 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)gen->program->global_flags); -@@ -1370,7 +2055,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader ++ vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_scalar\n{\n"); ++ vkd3d_string_buffer_printf(gen->buffer, " uint u;\n"); ++ vkd3d_string_buffer_printf(gen->buffer, " int i;\n"); ++ vkd3d_string_buffer_printf(gen->buffer, " float f;\n};\n\n"); ++ + vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_vec4\n{\n"); + vkd3d_string_buffer_printf(gen->buffer, " uint4 u;\n"); + vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n"); +@@ -1370,7 +2091,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader " const device void *ptr;\n" "\n" " template\n" @@ -15613,7 +21511,7 @@ index 4f37468af86..032b5504319 100644 " {\n" " return reinterpret_cast(this->ptr);\n" " }\n" -@@ -1388,11 +2073,16 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader +@@ -1388,11 +2109,16 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader msl_generate_output_struct_declarations(gen); vkd3d_string_buffer_printf(gen->buffer, @@ -15629,10 +21527,33 @@ index 4f37468af86..032b5504319 100644 + 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"); ++ vkd3d_string_buffer_printf(gen->buffer, ", thread vkd3d_scalar &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"); +@@ -1405,9 +2131,10 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + vkd3d_string_buffer_printf(gen->buffer, "vkd3d_vec4 r[%u];\n\n", gen->program->temp_count); + } + +- for (i = 0; i < instructions->count; ++i) ++ it = vsir_program_iterator(&gen->program->instructions); ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- msl_handle_instruction(gen, &instructions->elements[i]); ++ msl_handle_instruction(gen, ins); + } + + --gen->indent; +@@ -1469,6 +2196,9 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, + if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) + return ret; + ++ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0) ++ return ret; ++ + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); + diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.h b/libs/vkd3d/libs/vkd3d-shader/preproc.h index a98c8ae3df5..9217237d8d3 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.h @@ -15771,7 +21692,7 @@ index 4a8d0fddae1..5c56fba0229 100644 ctx->last_was_newline = true; return true; diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 1f967c22406..c51a6a394c0 100644 +index 1f967c22406..a4990d982bc 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -847,57 +847,6 @@ static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, enum vkd3d_s @@ -15832,7 +21753,15 @@ index 1f967c22406..c51a6a394c0 100644 struct vkd3d_spirv_stream { uint32_t *words; -@@ -1602,6 +1551,29 @@ static void vkd3d_spirv_build_op_name(struct vkd3d_spirv_builder *builder, +@@ -1033,6 +982,7 @@ struct vkd3d_spirv_builder + SpvExecutionModel execution_model; + + uint32_t current_id; ++ uint32_t source_name_id; + uint32_t main_function_id; + struct rb_tree declarations; + uint32_t type_sampler_id; +@@ -1602,6 +1552,34 @@ static void vkd3d_spirv_build_op_name(struct vkd3d_spirv_builder *builder, vkd3d_spirv_build_string(stream, name, name_size); } @@ -15853,16 +21782,21 @@ index 1f967c22406..c51a6a394c0 100644 +static void vkd3d_spirv_build_op_source(struct vkd3d_spirv_builder *builder, const char *source_name) +{ + struct vkd3d_spirv_stream *stream = &builder->debug_stream; -+ uint32_t source_id; + -+ source_id = vkd3d_spirv_build_op_string(builder, source_name ? source_name : ""); -+ vkd3d_spirv_build_op3(stream, SpvOpSource, 0, 0, source_id); ++ builder->source_name_id = vkd3d_spirv_build_op_string(builder, source_name ? source_name : ""); ++ vkd3d_spirv_build_op3(stream, SpvOpSource, 0, 0, builder->source_name_id); ++} ++ ++static void vkd3d_spirv_build_op_line(struct vkd3d_spirv_builder *builder, const struct vkd3d_shader_location *location) ++{ ++ vkd3d_spirv_build_op3(&builder->function_stream, SpvOpLine, ++ builder->source_name_id, location->line, location->column); +} + static void vkd3d_spirv_build_op_member_name(struct vkd3d_spirv_builder *builder, uint32_t type_id, uint32_t member, const char *fmt, ...) { -@@ -2513,18 +2485,6 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder +@@ -2513,18 +2491,6 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450FAbs, result_type, operand); } @@ -15881,7 +21815,16 @@ index 1f967c22406..c51a6a394c0 100644 static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t x, uint32_t y) { -@@ -2616,7 +2576,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder +@@ -2608,7 +2574,7 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, + } + + static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, +- enum vkd3d_data_type data_type, unsigned int component_count) ++ enum vsir_data_type data_type, unsigned int component_count) + { + enum vkd3d_shader_component_type component_type; + +@@ -2616,7 +2582,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder return vkd3d_spirv_get_type_id(builder, component_type, component_count); } @@ -15891,7 +21834,7 @@ index 1f967c22406..c51a6a394c0 100644 { vkd3d_spirv_stream_init(&builder->debug_stream); vkd3d_spirv_stream_init(&builder->annotation_stream); -@@ -2631,6 +2592,7 @@ static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const +@@ -2631,6 +2598,7 @@ static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const rb_init(&builder->declarations, vkd3d_spirv_declaration_compare); @@ -15899,7 +21842,25 @@ index 1f967c22406..c51a6a394c0 100644 builder->main_function_id = vkd3d_spirv_alloc_id(builder); vkd3d_spirv_build_op_name(builder, builder->main_function_id, "%s", entry_point); } -@@ -3140,17 +3102,17 @@ struct spirv_compiler +@@ -3050,7 +3018,7 @@ struct vkd3d_hull_shader_variables + + struct ssa_register_info + { +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + uint8_t write_mask; + uint32_t id; + }; +@@ -3058,7 +3026,7 @@ struct ssa_register_info + struct spirv_compiler + { + struct vkd3d_spirv_builder spirv_builder; +- const struct vsir_program *program; ++ struct vsir_program *program; + + struct vkd3d_shader_message_context *message_context; + struct vkd3d_shader_location location; +@@ -3140,17 +3108,17 @@ struct spirv_compiler static bool is_in_default_phase(const struct spirv_compiler *compiler) { @@ -15920,7 +21881,16 @@ index 1f967c22406..c51a6a394c0 100644 } static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler); -@@ -3224,7 +3186,8 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p +@@ -3188,7 +3156,7 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) + vkd3d_free(compiler); + } + +-static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *program, ++static struct spirv_compiler *spirv_compiler_create(struct vsir_program *program, + const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, uint64_t config_flags) + { +@@ -3224,7 +3192,8 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p compiler->spirv_target_info = target_info; } @@ -15930,7 +21900,7 @@ index 1f967c22406..c51a6a394c0 100644 compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER; -@@ -3332,7 +3295,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p +@@ -3332,7 +3301,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p else if (compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY) compiler->emit_point_size = compiler->xfb_info && compiler->xfb_info->element_count; @@ -15939,7 +21909,7 @@ index 1f967c22406..c51a6a394c0 100644 vkd3d_string_buffer_cache_init(&compiler->string_buffers); -@@ -3559,8 +3522,12 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind +@@ -3559,8 +3528,12 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind goto done; } @@ -15954,7 +21924,7 @@ index 1f967c22406..c51a6a394c0 100644 if (is_uav_counter) { -@@ -3604,7 +3571,7 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind +@@ -3604,7 +3577,7 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind { const struct vkd3d_shader_resource_binding *current = &shader_interface->bindings[i]; @@ -15963,7 +21933,58 @@ index 1f967c22406..c51a6a394c0 100644 continue; if (!spirv_compiler_check_shader_visibility(compiler, current->shader_visibility)) -@@ -4239,7 +4206,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, +@@ -4018,7 +3991,7 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com + + static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compiler, + enum vkd3d_shader_parameter_name name, uint32_t spec_id, +- enum vkd3d_data_type type, unsigned int component_count) ++ enum vsir_data_type type, unsigned int component_count) + { + uint32_t scalar_type_id, vector_type_id, id, default_value, components[4]; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +@@ -4057,7 +4030,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile + + static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler, + enum vkd3d_shader_parameter_name name, uint32_t spec_id, +- enum vkd3d_data_type type, unsigned int component_count) ++ enum vsir_data_type type, unsigned int component_count) + { + unsigned int i; + +@@ -4071,7 +4044,7 @@ static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler + } + + static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compiler, +- const struct vkd3d_shader_parameter1 *parameter, enum vkd3d_data_type type, unsigned int component_count) ++ const struct vkd3d_shader_parameter1 *parameter, enum vsir_data_type type, unsigned int component_count) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + unsigned int index = parameter - compiler->program->parameters; +@@ -4087,18 +4060,18 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi + + static const struct + { +- enum vkd3d_data_type type; ++ enum vsir_data_type type; + unsigned int component_count; + } + parameter_data_type_map[] = + { +- [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VKD3D_DATA_FLOAT, 1}, +- [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VKD3D_DATA_UINT, 1}, +- [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VKD3D_DATA_FLOAT, 4}, ++ [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VSIR_DATA_F32, 1}, ++ [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VSIR_DATA_U32, 1}, ++ [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VSIR_DATA_F32, 4}, + }; + + static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *compiler, +- enum vkd3d_shader_parameter_name name, enum vkd3d_data_type type, unsigned int component_count) ++ enum vkd3d_shader_parameter_name name, enum vsir_data_type type, unsigned int component_count) + { + const struct vkd3d_shader_parameter1 *parameter; + +@@ -4239,7 +4212,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, if (!(entry = rb_get(&compiler->symbol_table, ®_symbol))) { spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE, @@ -15972,7 +21993,25 @@ index 1f967c22406..c51a6a394c0 100644 memset(register_info, 0, sizeof(*register_info)); return false; } -@@ -4578,70 +4545,6 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil +@@ -4512,7 +4485,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil + } + + static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, +- enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, ++ enum vkd3d_shader_conditional_op condition, enum vsir_data_type data_type, + unsigned int component_count, uint32_t val_id) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +@@ -4524,7 +4497,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, + type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; + return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, +- data_type == VKD3D_DATA_UINT64 ++ data_type == VSIR_DATA_U64 + ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) + : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); + } +@@ -4578,70 +4551,6 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } @@ -16043,7 +22082,7 @@ index 1f967c22406..c51a6a394c0 100644 static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask) { -@@ -4654,15 +4557,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile +@@ -4654,15 +4563,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile if (reg->dimension == VSIR_DIMENSION_SCALAR) { for (i = 0; i < component_count; ++i) @@ -16061,7 +22100,18 @@ index 1f967c22406..c51a6a394c0 100644 } } -@@ -4806,13 +4708,6 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil +@@ -4758,8 +4666,8 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, + type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } +- val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, +- VKD3D_DATA_UINT, 1, val_id); ++ val_id = spirv_compiler_emit_int_to_bool(compiler, ++ VKD3D_SHADER_CONDITIONAL_OP_NZ, VSIR_DATA_U32, 1, val_id); + } + else + { +@@ -4806,22 +4714,15 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil switch (icb->data_type) { @@ -16072,10 +22122,71 @@ index 1f967c22406..c51a6a394c0 100644 - elements[i] = vkd3d_spirv_get_op_constant(builder, elem_type_id, - convert_raw_constant32(icb->data_type, icb->data[i])); - break; - case VKD3D_DATA_FLOAT: - case VKD3D_DATA_INT: - case VKD3D_DATA_UINT: -@@ -5641,13 +5536,13 @@ static void spirv_compiler_emit_shader_phase_name(struct spirv_compiler *compile +- case VKD3D_DATA_FLOAT: +- case VKD3D_DATA_INT: +- case VKD3D_DATA_UINT: ++ case VSIR_DATA_F32: ++ case VSIR_DATA_I32: ++ case VSIR_DATA_U32: + for (i = 0; i < element_count; ++i) + elements[i] = spirv_compiler_get_constant(compiler, component_type, component_count, + &icb->data[component_count * i]); + break; +- case VKD3D_DATA_DOUBLE: +- case VKD3D_DATA_UINT64: ++ case VSIR_DATA_F64: ++ case VSIR_DATA_U64: + { + uint64_t *data = (uint64_t *)icb->data; + for (i = 0; i < element_count; ++i) +@@ -4913,8 +4814,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, + type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } +- val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, +- VKD3D_DATA_UINT, component_count, val_id); ++ val_id = spirv_compiler_emit_int_to_bool(compiler, ++ VKD3D_SHADER_CONDITIONAL_OP_NZ, VSIR_DATA_U32, component_count, val_id); + } + else + { +@@ -5008,7 +4909,7 @@ static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *co + { + struct vkd3d_shader_src_param src_param = *src; + +- src_param.reg.data_type = vkd3d_data_type_from_component_type(component_type); ++ src_param.reg.data_type = vsir_data_type_from_component_type(component_type); + return spirv_compiler_emit_load_src(compiler, &src_param, write_mask); + } + +@@ -5134,7 +5035,7 @@ static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, zero_id, one_id; + +- if (reg->data_type == VKD3D_DATA_DOUBLE) ++ if (reg->data_type == VSIR_DATA_F64) + { + zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); + one_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count); +@@ -5188,7 +5089,7 @@ static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compil + /* XXX: The register data type could be fixed by the shader parser. For SM5 + * shaders the data types are stored in instructions modifiers. + */ +- typed_dst.reg.data_type = vkd3d_data_type_from_component_type(component_type); ++ typed_dst.reg.data_type = vsir_data_type_from_component_type(component_type); + spirv_compiler_emit_store_dst(compiler, &typed_dst, val_id); + } + +@@ -5616,7 +5517,7 @@ static uint32_t spirv_compiler_get_invocation_id(struct spirv_compiler *compiler + + VKD3D_ASSERT(compiler->shader_type == VKD3D_SHADER_TYPE_HULL); + +- vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0); ++ vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VSIR_DATA_F32, 0); + return spirv_compiler_get_register_id(compiler, &r); + } + +@@ -5641,13 +5542,13 @@ static void spirv_compiler_emit_shader_phase_name(struct spirv_compiler *compile switch (compiler->phase) { @@ -16092,7 +22203,218 @@ index 1f967c22406..c51a6a394c0 100644 name = "join"; break; default: -@@ -7510,7 +7405,7 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, +@@ -5775,6 +5676,48 @@ static unsigned int shader_signature_next_location(const struct shader_signature + return max_row; + } + ++static const struct vkd3d_symbol *spirv_compiler_emit_io_register(struct spirv_compiler *compiler, ++ const struct vkd3d_shader_dst_param *dst) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ const struct vkd3d_shader_register *reg = &dst->reg; ++ const struct vkd3d_spirv_builtin *builtin; ++ struct vkd3d_symbol reg_symbol; ++ SpvStorageClass storage_class; ++ uint32_t write_mask, id; ++ struct rb_entry *entry; ++ ++ VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); ++ VKD3D_ASSERT(reg->idx_count < 2); ++ ++ if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) ++ { ++ builtin = &vkd3d_output_point_size_builtin; ++ storage_class = SpvStorageClassOutput; ++ } ++ else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) ++ { ++ FIXME("Unhandled register %#x.\n", reg->type); ++ return NULL; ++ } ++ ++ /* vPrim may be declared in multiple hull shader phases. */ ++ vkd3d_symbol_make_register(®_symbol, reg); ++ if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) ++ return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); ++ ++ id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); ++ spirv_compiler_emit_register_execution_mode(compiler, reg->type); ++ spirv_compiler_emit_register_debug_name(builder, id, reg); ++ ++ write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); ++ vkd3d_symbol_set_register_info(®_symbol, id, ++ storage_class, builtin->component_type, write_mask); ++ reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; ++ ++ return spirv_compiler_put_symbol(compiler, ®_symbol); ++} ++ + static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + enum vkd3d_shader_register_type reg_type, unsigned int element_idx) + { +@@ -5783,6 +5726,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + const struct signature_element *signature_element; + const struct shader_signature *shader_signature; + enum vkd3d_shader_component_type component_type; ++ enum vkd3d_shader_register_type sysval_reg_type; + const struct vkd3d_spirv_builtin *builtin; + enum vkd3d_shader_sysval_semantic sysval; + uint32_t write_mask, reg_write_mask; +@@ -5807,6 +5751,22 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + if (!signature_element->used_mask) + return; + ++ sysval_reg_type = vsir_register_type_from_sysval_input(signature_element->sysval_semantic); ++ if (sysval_reg_type != VKD3DSPR_INPUT) ++ { ++ struct vkd3d_shader_dst_param dst; ++ const struct vkd3d_symbol *symbol; ++ ++ vsir_dst_param_init(&dst, sysval_reg_type, VSIR_DATA_F32, 0); ++ symbol = spirv_compiler_emit_io_register(compiler, &dst); ++ ++ vkd3d_symbol_make_io(®_symbol, reg_type, element_idx); ++ reg_symbol.id = symbol->id; ++ reg_symbol.info.reg = symbol->info.reg; ++ spirv_compiler_put_symbol(compiler, ®_symbol); ++ return; ++ } ++ + builtin = get_spirv_builtin_for_sysval(compiler, sysval); + + array_sizes[0] = signature_element->register_count; +@@ -5823,15 +5783,15 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + { + component_type = builtin->component_type; + input_component_count = builtin->component_count; +- component_idx = 0; + } + else + { + component_type = signature_element->component_type; + input_component_count = vsir_write_mask_component_count(signature_element->mask); +- component_idx = vsir_write_mask_get_component_idx(signature_element->mask); + } + ++ component_idx = vsir_write_mask_get_component_idx(write_mask); ++ + if (needs_private_io_variable(builtin)) + { + use_private_var = true; +@@ -5839,7 +5799,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + } + else + { +- component_idx = vsir_write_mask_get_component_idx(write_mask); + reg_write_mask = write_mask >> component_idx; + } + +@@ -5905,7 +5864,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + { + struct vkd3d_shader_register dst_reg; + +- vsir_register_init(&dst_reg, reg_type, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(&dst_reg, reg_type, VSIR_DATA_F32, 1); + dst_reg.idx[0].offset = element_idx; + + type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count); +@@ -5925,49 +5884,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + vkd3d_write_mask_from_component_count(input_component_count), + VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx); + +- spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask, val_id); +- } +-} +- +-static void spirv_compiler_emit_io_register(struct spirv_compiler *compiler, +- const struct vkd3d_shader_dst_param *dst) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- const struct vkd3d_shader_register *reg = &dst->reg; +- const struct vkd3d_spirv_builtin *builtin; +- struct vkd3d_symbol reg_symbol; +- SpvStorageClass storage_class; +- uint32_t write_mask, id; +- struct rb_entry *entry; +- +- VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); +- VKD3D_ASSERT(reg->idx_count < 2); +- +- if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) +- { +- builtin = &vkd3d_output_point_size_builtin; +- storage_class = SpvStorageClassOutput; +- } +- else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) +- { +- FIXME("Unhandled register %#x.\n", reg->type); +- return; ++ spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask >> component_idx, val_id); + } +- +- /* vPrim may be declared in multiple hull shader phases. */ +- vkd3d_symbol_make_register(®_symbol, reg); +- if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) +- return; +- +- id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); +- +- write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); +- vkd3d_symbol_set_register_info(®_symbol, id, +- storage_class, builtin->component_type, write_mask); +- reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; +- spirv_compiler_put_symbol(compiler, ®_symbol); +- spirv_compiler_emit_register_execution_mode(compiler, reg->type); +- spirv_compiler_emit_register_debug_name(builder, id, reg); + } + + static unsigned int get_shader_output_swizzle(const struct spirv_compiler *compiler, +@@ -6607,7 +6525,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil + * scope is specified, e.g. DXIL alloca. */ + storage_class = temp->has_function_scope ? SpvStorageClassFunction : SpvStorageClassPrivate; + +- vsir_register_init(®, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(®, VKD3DSPR_IDXTEMP, VSIR_DATA_F32, 1); + reg.idx[0].offset = temp->register_idx; + + /* Alignment is supported only in the Kernel execution model and is an optimisation only. */ +@@ -6847,7 +6765,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, + struct vkd3d_symbol reg_symbol; + unsigned int size; + +- vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); ++ vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 3); + reg.idx[0].offset = descriptor->register_id; + reg.idx[1].offset = range->first; + reg.idx[2].offset = range->last; +@@ -6907,7 +6825,7 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi + vkd3d_spirv_build_op_name(builder, icb_id, "icb"); + + /* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */ +- vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 2); ++ vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VSIR_DATA_F32, 2); + reg.idx[0].offset = icb->register_idx; + vkd3d_symbol_make_register(®_symbol, ®); + vkd3d_symbol_set_register_info(®_symbol, icb_id, SpvStorageClassPrivate, +@@ -6926,7 +6844,7 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi + struct vkd3d_symbol reg_symbol; + uint32_t type_id, var_id; + +- vsir_register_init(®, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(®, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1); + reg.idx[0].offset = descriptor->register_id; + + vkd3d_symbol_make_sampler(®_symbol, ®); +@@ -7107,7 +7025,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + struct vkd3d_symbol resource_symbol; + struct vkd3d_shader_register reg; + +- vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_F32, 1); + reg.idx[0].offset = descriptor->register_id; + + if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && sample_count == 1) +@@ -7510,7 +7428,7 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, compiler->phase = instruction->opcode; spirv_compiler_emit_shader_phase_name(compiler, function_id, NULL); @@ -16101,7 +22423,7 @@ index 1f967c22406..c51a6a394c0 100644 ? &compiler->control_point_phase : &compiler->patch_constant_phase; phase->function_id = function_id; /* The insertion location must be set after the label is emitted. */ -@@ -7524,7 +7419,7 @@ static void spirv_compiler_initialise_block(struct spirv_compiler *compiler) +@@ -7524,7 +7442,7 @@ static void spirv_compiler_initialise_block(struct spirv_compiler *compiler) /* Insertion locations must point immediately after the function's initial label. */ if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL) { @@ -16110,7 +22432,7 @@ index 1f967c22406..c51a6a394c0 100644 ? &compiler->control_point_phase : &compiler->patch_constant_phase; if (!phase->function_location) phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream); -@@ -7626,35 +7521,40 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru +@@ -7626,35 +7544,40 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru } alu_ops[] = { @@ -16180,7 +22502,7 @@ index 1f967c22406..c51a6a394c0 100644 }; unsigned int i; -@@ -7671,11 +7571,11 @@ static SpvOp spirv_compiler_map_logical_instruction(const struct vkd3d_shader_in +@@ -7671,11 +7594,11 @@ static SpvOp spirv_compiler_map_logical_instruction(const struct vkd3d_shader_in { switch (instruction->opcode) { @@ -16195,32 +22517,42 @@ index 1f967c22406..c51a6a394c0 100644 return SpvOpLogicalNotEqual; default: return SpvOpMax; -@@ -7694,20 +7594,20 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, +@@ -7689,25 +7612,25 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t val_id; + +- VKD3D_ASSERT(src->reg.data_type == VKD3D_DATA_BOOL && dst->reg.data_type != VKD3D_DATA_BOOL); ++ VKD3D_ASSERT(src->reg.data_type == VSIR_DATA_BOOL && dst->reg.data_type != VSIR_DATA_BOOL); + val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); - if (dst->reg.data_type == VKD3D_DATA_HALF || dst->reg.data_type == VKD3D_DATA_FLOAT) +- if (dst->reg.data_type == VKD3D_DATA_HALF || dst->reg.data_type == VKD3D_DATA_FLOAT) ++ if (dst->reg.data_type == VSIR_DATA_F16 || dst->reg.data_type == VSIR_DATA_F32) { - val_id = spirv_compiler_emit_bool_to_float(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOF); + val_id = spirv_compiler_emit_bool_to_float(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); } - else if (dst->reg.data_type == VKD3D_DATA_DOUBLE) +- else if (dst->reg.data_type == VKD3D_DATA_DOUBLE) ++ else if (dst->reg.data_type == VSIR_DATA_F64) { /* ITOD is not supported. Frontends which emit bool casts must use ITOF for double. */ - val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOF); + val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); } - else if (dst->reg.data_type == VKD3D_DATA_UINT16 || dst->reg.data_type == VKD3D_DATA_UINT) +- else if (dst->reg.data_type == VKD3D_DATA_UINT16 || dst->reg.data_type == VKD3D_DATA_UINT) ++ else if (dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32) { - val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOI); + val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); } - else if (dst->reg.data_type == VKD3D_DATA_UINT64) +- else if (dst->reg.data_type == VKD3D_DATA_UINT64) ++ else if (dst->reg.data_type == VSIR_DATA_U64) { - val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOI); + val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); } else { -@@ -7722,15 +7622,16 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, +@@ -7722,15 +7645,16 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -16236,11 +22568,20 @@ index 1f967c22406..c51a6a394c0 100644 + bool check_zero; - if (src->reg.data_type == VKD3D_DATA_UINT64 && instruction->opcode == VKD3DSIH_COUNTBITS) -+ if (src->reg.data_type == VKD3D_DATA_UINT64 && instruction->opcode == VSIR_OP_COUNTBITS) ++ if (src->reg.data_type == VSIR_DATA_U64 && instruction->opcode == VSIR_OP_COUNTBITS) { /* At least some drivers support this anyway, but if validation is enabled it will fail. */ FIXME("Unsupported 64-bit source for bit count.\n"); -@@ -7746,8 +7647,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -7739,15 +7663,15 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil + return VKD3D_ERROR_INVALID_SHADER; + } + +- if (src->reg.data_type == VKD3D_DATA_BOOL) ++ if (src->reg.data_type == VSIR_DATA_BOOL) + { +- if (dst->reg.data_type == VKD3D_DATA_BOOL) ++ if (dst->reg.data_type == VSIR_DATA_BOOL) + { /* VSIR supports logic ops AND/OR/XOR on bool values. */ op = spirv_compiler_map_logical_instruction(instruction); } @@ -16251,7 +22592,7 @@ index 1f967c22406..c51a6a394c0 100644 { /* VSIR supports cast from bool to signed/unsigned integer types and floating point types, * where bool is treated as a 1-bit integer and a signed 'true' value converts to -1. */ -@@ -7762,20 +7663,50 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -7762,20 +7686,50 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil if (op == SpvOpMax) { @@ -16295,7 +22636,7 @@ index 1f967c22406..c51a6a394c0 100644 + condition_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]); + -+ if (dst[0].reg.data_type == VKD3D_DATA_UINT64) ++ if (dst[0].reg.data_type == VSIR_DATA_U64) + uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count); + else + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); @@ -16304,7 +22645,7 @@ index 1f967c22406..c51a6a394c0 100644 /* The SPIR-V specification states, "The resulting value is undefined if * Shift is greater than or equal to the bit width of the components of * Base." Direct3D applies only the lowest 5 bits of the shift. -@@ -7783,8 +7714,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -7783,8 +7737,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil * Microsoft fxc will compile immediate constants larger than 5 bits. * Fixing up the constants would be more elegant, but the simplest way is * to let this handle constants too. */ @@ -16315,7 +22656,7 @@ index 1f967c22406..c51a6a394c0 100644 { uint32_t mask_id = spirv_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, vsir_write_mask_component_count(dst->write_mask), 0x1f); -@@ -7796,6 +7727,9 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -7796,6 +7750,9 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); @@ -16325,7 +22666,7 @@ index 1f967c22406..c51a6a394c0 100644 spirv_compiler_emit_store_dst(compiler, dst, val_id); return VKD3D_OK; } -@@ -7827,36 +7761,38 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( +@@ -7827,36 +7784,38 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( } glsl_insts[] = { @@ -16394,13 +22735,13 @@ index 1f967c22406..c51a6a394c0 100644 }; unsigned int i; -@@ -7880,20 +7816,22 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp +@@ -7880,20 +7839,22 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp unsigned int i, component_count; enum GLSLstd450 glsl_inst; - if (src[0].reg.data_type == VKD3D_DATA_UINT64 && (instruction->opcode == VKD3DSIH_FIRSTBIT_HI - || instruction->opcode == VKD3DSIH_FIRSTBIT_LO || instruction->opcode == VKD3DSIH_FIRSTBIT_SHI)) -+ if (src[0].reg.data_type == VKD3D_DATA_UINT64 && (instruction->opcode == VSIR_OP_FIRSTBIT_HI ++ if (src[0].reg.data_type == VSIR_DATA_U64 && (instruction->opcode == VSIR_OP_FIRSTBIT_HI + || instruction->opcode == VSIR_OP_FIRSTBIT_LO || instruction->opcode == VSIR_OP_FIRSTBIT_SHI)) { /* At least some drivers support this anyway, but if validation is enabled it will fail. */ @@ -16422,7 +22763,7 @@ index 1f967c22406..c51a6a394c0 100644 return; } -@@ -7910,8 +7848,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp +@@ -7910,8 +7871,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, glsl_inst, src_id, instruction->src_count); @@ -16433,7 +22774,7 @@ index 1f967c22406..c51a6a394c0 100644 { /* In D3D bits are numbered from the most significant bit. */ component_count = vsir_write_mask_component_count(dst->write_mask); -@@ -7948,7 +7886,8 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, +@@ -7948,7 +7909,8 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, || dst_reg_info.write_mask != src_reg_info.write_mask) goto general_implementation; @@ -16443,16 +22784,19 @@ index 1f967c22406..c51a6a394c0 100644 { dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); src_id = spirv_compiler_get_register_id(compiler, &src->reg); -@@ -8019,7 +7958,7 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, +@@ -8017,9 +7979,9 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, + component_count = vsir_write_mask_component_count(dst->write_mask); + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); - if (src[0].reg.data_type != VKD3D_DATA_BOOL) +- if (src[0].reg.data_type != VKD3D_DATA_BOOL) ++ if (src[0].reg.data_type != VSIR_DATA_BOOL) { - if (instruction->opcode == VKD3DSIH_CMP) + if (instruction->opcode == VSIR_OP_CMP) condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), condition_id, spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); -@@ -8073,9 +8012,9 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, +@@ -8073,9 +8035,9 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, component_count = vsir_write_mask_component_count(dst->write_mask); component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); @@ -16464,7 +22808,16 @@ index 1f967c22406..c51a6a394c0 100644 write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2; else write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; -@@ -8120,65 +8059,6 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, +@@ -8112,7 +8074,7 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); + + src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); +- if (src->reg.data_type == VKD3D_DATA_DOUBLE) ++ if (src->reg.data_type == VSIR_DATA_F64) + div_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count); + else + div_id = spirv_compiler_get_constant_float_vector(compiler, 1.0f, component_count); +@@ -8120,65 +8082,6 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); } @@ -16530,7 +22883,7 @@ index 1f967c22406..c51a6a394c0 100644 static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { -@@ -8200,67 +8080,6 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, +@@ -8200,67 +8103,6 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); } @@ -16598,7 +22951,32 @@ index 1f967c22406..c51a6a394c0 100644 static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { -@@ -8413,11 +8232,13 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp +@@ -8282,7 +8124,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, + + component_count = vsir_write_mask_component_count(dst->write_mask); + +- if (src->reg.data_type == VKD3D_DATA_DOUBLE) ++ if (src->reg.data_type == VSIR_DATA_F64) + { + write_mask = vkd3d_write_mask_from_component_count(component_count); + int_min_id = spirv_compiler_get_constant_double_vector(compiler, -2147483648.0, component_count); +@@ -8338,7 +8180,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, + + component_count = vsir_write_mask_component_count(dst->write_mask); + +- if (src->reg.data_type == VKD3D_DATA_DOUBLE) ++ if (src->reg.data_type == VSIR_DATA_F64) + { + write_mask = vkd3d_write_mask_from_component_count(component_count); + zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); +@@ -8407,17 +8249,19 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp + + component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); + type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); +- size = (src[src_count - 1].reg.data_type == VKD3D_DATA_UINT64) ? 0x40 : 0x20; ++ size = (src[src_count - 1].reg.data_type == VSIR_DATA_U64) ? 0x40 : 0x20; + mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); + size_id = spirv_compiler_get_constant_uint(compiler, size); switch (instruction->opcode) { @@ -16616,7 +22994,7 @@ index 1f967c22406..c51a6a394c0 100644 return; } -@@ -8531,26 +8352,28 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co +@@ -8531,26 +8375,28 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co switch (instruction->opcode) { @@ -16664,7 +23042,7 @@ index 1f967c22406..c51a6a394c0 100644 return; } -@@ -8558,10 +8381,10 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co +@@ -8558,10 +8404,10 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co switch (instruction->opcode) { @@ -16679,7 +23057,16 @@ index 1f967c22406..c51a6a394c0 100644 write_mask = vkd3d_write_mask_from_component_count(component_count); break; -@@ -8596,7 +8419,7 @@ static void spirv_compiler_emit_orderedness_instruction(struct spirv_compiler *c +@@ -8576,7 +8422,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co + result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + op, type_id, src0_id, src1_id); + +- if (dst->reg.data_type != VKD3D_DATA_BOOL) ++ if (dst->reg.data_type != VSIR_DATA_BOOL) + result_id = spirv_compiler_emit_bool_to_int(compiler, component_count, result_id, true); + spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, result_id); + } +@@ -8596,7 +8442,7 @@ static void spirv_compiler_emit_orderedness_instruction(struct spirv_compiler *c src0_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src0_id); src1_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src1_id); val_id = vkd3d_spirv_build_op_logical_or(builder, type_id, src0_id, src1_id); @@ -16688,7 +23075,7 @@ index 1f967c22406..c51a6a394c0 100644 val_id = vkd3d_spirv_build_op_logical_not(builder, type_id, val_id); spirv_compiler_emit_store_dst(compiler, dst, val_id); } -@@ -8613,8 +8436,8 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil +@@ -8613,8 +8459,8 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil switch (instruction->opcode) { @@ -16699,7 +23086,43 @@ index 1f967c22406..c51a6a394c0 100644 default: vkd3d_unreachable(); } -@@ -8917,12 +8740,12 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile +@@ -8757,7 +8603,7 @@ static void spirv_compiler_emit_discard(struct spirv_compiler *compiler, + * a mismatch between the VSIR structure and the SPIR-V one, which would cause problems if + * structurisation is necessary. Therefore we emit it as a function call. */ + condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); +- if (src->reg.data_type != VKD3D_DATA_BOOL) ++ if (src->reg.data_type != VSIR_DATA_BOOL) + condition_id = spirv_compiler_emit_int_to_bool(compiler, + instruction->flags, src->reg.data_type, 1, condition_id); + else if (instruction->flags & VKD3D_SHADER_CONDITIONAL_OP_Z) +@@ -8830,7 +8676,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, + if (instruction->src_count == 3) + spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset); + else +- ERR("Invalid branch with %u sources.\n", instruction->src_count); ++ ERR("Invalid branch with %zu sources.\n", instruction->src_count); + } + vkd3d_spirv_build_op_branch(builder, spirv_compiler_get_label_id(compiler, src[0].reg.idx[0].offset)); + return; +@@ -8844,7 +8690,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, + } + + condition_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); +- if (src[0].reg.data_type != VKD3D_DATA_BOOL) ++ if (src[0].reg.data_type != VSIR_DATA_BOOL) + condition_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id); + /* Emit the merge immediately before the branch instruction. */ +@@ -8852,7 +8698,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, + spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset, + (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0); + else +- ERR("Invalid branch with %u sources.\n", instruction->src_count); ++ ERR("Invalid branch with %zu sources.\n", instruction->src_count); + vkd3d_spirv_build_op_branch_conditional(builder, condition_id, + spirv_compiler_get_label_id(compiler, src[1].reg.idx[0].offset), + spirv_compiler_get_label_id(compiler, src[2].reg.idx[0].offset)); +@@ -8917,12 +8763,12 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile } deriv_instructions[] = { @@ -16718,7 +23141,7 @@ index 1f967c22406..c51a6a394c0 100644 }; info = NULL; -@@ -8936,7 +8759,9 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile +@@ -8936,7 +8782,9 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile } if (!info) { @@ -16729,7 +23152,7 @@ index 1f967c22406..c51a6a394c0 100644 return; } -@@ -9147,7 +8972,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, +@@ -9147,7 +8995,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, uint32_t coordinate_mask; bool multisample; @@ -16738,7 +23161,7 @@ index 1f967c22406..c51a6a394c0 100644 spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); -@@ -9228,16 +9053,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, +@@ -9228,16 +9076,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, switch (instruction->opcode) { @@ -16758,7 +23181,7 @@ index 1f967c22406..c51a6a394c0 100644 op = SpvOpImageSampleExplicitLod; operands_mask |= SpvImageOperandsGradMask; component_count = image.resource_type_info->coordinate_component_count - image.resource_type_info->arrayed; -@@ -9247,14 +9072,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, +@@ -9247,14 +9095,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[4], coordinate_mask); break; @@ -16777,7 +23200,7 @@ index 1f967c22406..c51a6a394c0 100644 return; } -@@ -9288,7 +9115,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, +@@ -9288,7 +9138,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, uint32_t image_operands[2]; SpvOp op; @@ -16786,7 +23209,7 @@ index 1f967c22406..c51a6a394c0 100644 { op = SpvOpImageSampleDrefExplicitLod; operands_mask |= SpvImageOperandsLodMask; -@@ -9338,12 +9165,12 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, +@@ -9338,12 +9188,12 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, uint32_t coordinate_mask; bool extended_offset; @@ -16803,7 +23226,34 @@ index 1f967c22406..c51a6a394c0 100644 addr = &src[0]; offset = extended_offset ? &src[1] : NULL; -@@ -9801,7 +9628,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c +@@ -9597,7 +9447,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * + &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); + + data = &src[instruction->src_count - 1]; +- VKD3D_ASSERT(data->reg.data_type == VKD3D_DATA_UINT); ++ VKD3D_ASSERT(data->reg.data_type == VSIR_DATA_U32); + val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); + + component_count = vsir_write_mask_component_count(dst->write_mask); +@@ -9625,7 +9475,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * + type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); + + data = &src[instruction->src_count - 1]; +- VKD3D_ASSERT(data->reg.data_type == VKD3D_DATA_UINT); ++ VKD3D_ASSERT(data->reg.data_type == VSIR_DATA_U32); + val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); + + component_count = vsir_write_mask_component_count(dst->write_mask); +@@ -9668,7 +9518,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, + type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); + + data = src[instruction->src_count - 1]; +- data.reg.data_type = VKD3D_DATA_UINT; ++ data.reg.data_type = VSIR_DATA_U32; + val_id = spirv_compiler_emit_load_src(compiler, &data, dst->write_mask); + + component_count = vsir_write_mask_component_count(dst->write_mask); +@@ -9801,7 +9651,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c uint32_t operands[3]; SpvOp op; @@ -16812,7 +23262,7 @@ index 1f967c22406..c51a6a394c0 100644 ? SpvOpAtomicIIncrement : SpvOpAtomicIDecrement; resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); -@@ -9872,25 +9699,25 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins +@@ -9872,25 +9722,25 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins } atomic_ops[] = { @@ -16857,7 +23307,7 @@ index 1f967c22406..c51a6a394c0 100644 }; unsigned int i; -@@ -9905,7 +9732,7 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins +@@ -9905,7 +9755,7 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins static bool is_imm_atomic_instruction(enum vkd3d_shader_opcode opcode) { @@ -16866,7 +23316,7 @@ index 1f967c22406..c51a6a394c0 100644 } static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compiler, -@@ -9935,7 +9762,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9935,7 +9785,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil op = spirv_compiler_map_atomic_instruction(instruction); if (op == SpvOpMax) { @@ -16877,7 +23327,7 @@ index 1f967c22406..c51a6a394c0 100644 return; } -@@ -10014,9 +9843,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -10014,9 +9866,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil if (instruction->flags & VKD3DARF_VOLATILE) { @@ -16889,7 +23339,112 @@ index 1f967c22406..c51a6a394c0 100644 } memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) -@@ -10340,13 +10169,13 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, +@@ -10094,16 +9946,20 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, + static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) + { ++ enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_UINT; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_dst_param *dst = instruction->dst; + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t type_id, lod_id, val_id, miplevel_count_id; +- enum vkd3d_shader_component_type component_type; + uint32_t constituents[VKD3D_VEC4_SIZE]; + unsigned int i, size_component_count; + struct vkd3d_shader_image image; + bool supports_mipmaps; + ++ if (instruction->flags & ~(VKD3DSI_RESINFO_UINT | VKD3DSI_PRECISE_XYZW)) ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unhandled resinfo flags %#x.\n", ++ instruction->flags & ~(VKD3DSI_RESINFO_UINT | VKD3DSI_PRECISE_XYZW)); ++ + vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); + + spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); +@@ -10135,22 +9991,13 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, + val_id = vkd3d_spirv_build_op_composite_construct(builder, + type_id, constituents, i + 2); + +- component_type = VKD3D_SHADER_COMPONENT_FLOAT; +- +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); +- if (instruction->flags == VKD3DSI_RESINFO_UINT) +- { +- /* SSA registers must match the specified result type. */ +- if (!register_is_ssa(&dst->reg)) +- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); +- else +- component_type = VKD3D_SHADER_COMPONENT_UINT; +- } +- else ++ if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) + { +- if (instruction->flags) +- FIXME("Unhandled flags %#x.\n", instruction->flags); ++ component_type = VKD3D_SHADER_COMPONENT_FLOAT; ++ type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); ++ if (instruction->flags & VKD3DSI_PRECISE_XYZW) ++ vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); + } + val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, + component_type, src[1].swizzle, dst->write_mask); +@@ -10168,7 +10015,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co + if (src->reg.type == VKD3DSPR_RASTERIZER) + { + val_id = spirv_compiler_emit_shader_parameter(compiler, +- VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VKD3D_DATA_UINT, 1); ++ VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VSIR_DATA_U32, 1); + } + else + { +@@ -10185,6 +10032,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co + static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) + { ++ enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_UINT; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_dst_param *dst = instruction->dst; + const struct vkd3d_shader_src_param *src = instruction->src; +@@ -10192,6 +10040,10 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, + uint32_t type_id, val_id; + unsigned int i; + ++ if (instruction->flags & ~(VKD3DSI_SAMPLE_INFO_UINT | VKD3DSI_PRECISE_XYZW)) ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unhandled sample info flags %#x.\n", ++ instruction->flags & ~(VKD3DSI_SAMPLE_INFO_UINT | VKD3DSI_PRECISE_XYZW)); ++ + val_id = spirv_compiler_emit_query_sample_count(compiler, src); + + constituents[0] = val_id; +@@ -10200,20 +10052,16 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, + type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); +- if (instruction->flags == VKD3DSI_SAMPLE_INFO_UINT) +- { +- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); +- } +- else ++ if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) + { +- if (instruction->flags) +- FIXME("Unhandled flags %#x.\n", instruction->flags); ++ component_type = VKD3D_SHADER_COMPONENT_FLOAT; ++ type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); ++ if (instruction->flags & VKD3DSI_PRECISE_XYZW) ++ vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); + } +- + val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, +- VKD3D_SHADER_COMPONENT_FLOAT, src->swizzle, dst->write_mask); ++ component_type, src->swizzle, dst->write_mask); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); + } +@@ -10340,13 +10188,13 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, src_ids[src_count++] = register_info.id; @@ -16905,7 +23460,7 @@ index 1f967c22406..c51a6a394c0 100644 op = GLSLstd450InterpolateAtSample; src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); } -@@ -10428,7 +10257,7 @@ static void spirv_compiler_emit_emit_stream(struct spirv_compiler *compiler, +@@ -10428,7 +10276,7 @@ static void spirv_compiler_emit_emit_stream(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int stream_idx; @@ -16914,7 +23469,7 @@ index 1f967c22406..c51a6a394c0 100644 stream_idx = instruction->src[0].reg.idx[0].offset; else stream_idx = 0; -@@ -10449,7 +10278,7 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, +@@ -10449,7 +10297,7 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int stream_idx; @@ -16923,7 +23478,7 @@ index 1f967c22406..c51a6a394c0 100644 stream_idx = instruction->src[0].reg.idx[0].offset; else stream_idx = 0; -@@ -10467,11 +10296,11 @@ static uint32_t map_quad_read_across_direction(enum vkd3d_shader_opcode opcode) +@@ -10467,11 +10315,11 @@ static uint32_t map_quad_read_across_direction(enum vkd3d_shader_opcode opcode) { switch (opcode) { @@ -16938,7 +23493,16 @@ index 1f967c22406..c51a6a394c0 100644 return 2; default: vkd3d_unreachable(); -@@ -10526,11 +10355,11 @@ static SpvOp map_wave_bool_op(enum vkd3d_shader_opcode opcode) +@@ -10488,7 +10336,7 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler + + type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, + vsir_write_mask_component_count(dst->write_mask)); +- direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VKD3D_DATA_UINT, 1); ++ direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VSIR_DATA_U32, 1); + val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + direction_id = map_quad_read_across_direction(instruction->opcode); + direction_id = vkd3d_spirv_get_op_constant(builder, direction_type_id, direction_id); +@@ -10526,11 +10374,11 @@ static SpvOp map_wave_bool_op(enum vkd3d_shader_opcode opcode) { switch (opcode) { @@ -16953,7 +23517,7 @@ index 1f967c22406..c51a6a394c0 100644 return SpvOpGroupNonUniformAny; default: vkd3d_unreachable(); -@@ -10584,27 +10413,27 @@ static SpvOp map_wave_alu_op(enum vkd3d_shader_opcode opcode, bool is_float) +@@ -10584,27 +10432,27 @@ static SpvOp map_wave_alu_op(enum vkd3d_shader_opcode opcode, bool is_float) { switch (opcode) { @@ -16992,7 +23556,7 @@ index 1f967c22406..c51a6a394c0 100644 return SpvOpGroupNonUniformUMin; default: vkd3d_unreachable(); -@@ -10643,7 +10472,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, +@@ -10643,7 +10491,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, SpvGroupOperation group_op; uint32_t type_id, val_id; @@ -17001,7 +23565,21 @@ index 1f967c22406..c51a6a394c0 100644 : SpvGroupOperationReduce; val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); -@@ -10731,369 +10560,365 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -10728,372 +10576,379 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + int ret = VKD3D_OK; + + compiler->location = instruction->location; ++ /* radeonsi from Mesa 20.3.5 seems to get confused by OpLine instructions ++ * before OpFunction, seemingly causing it to fail to find the entry ++ * point. As far as I can tell that's not prohibited, and the validation ++ * layers don't seem to mind either, but perhaps it's best avoided. ++ * Notably, radv from the same Mesa version doesn't mind either. ++ * ++ * This is an issue for hull shaders in particular, because we don't go ++ * through vkd3d_spirv_builder_begin_main_function() before getting here ++ * in that case. */ ++ if (!compiler->strip_debug && compiler->spirv_builder.function_stream.word_count) ++ vkd3d_spirv_build_op_line(&compiler->spirv_builder, &instruction->location); switch (instruction->opcode) { @@ -17592,8 +24170,71 @@ index 1f967c22406..c51a6a394c0 100644 break; } +@@ -11127,14 +10982,14 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) + + if (compiler->program->has_point_size) + { +- vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); ++ vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); + dst.reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; + spirv_compiler_emit_io_register(compiler, &dst); + } + + if (compiler->program->has_point_coord) + { +- vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0); ++ vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); + spirv_compiler_emit_io_register(compiler, &dst); + } + +@@ -11145,7 +11000,7 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) + if (bitmap_is_set(compiler->program->io_dcls, i) + || (compiler->program->shader_version.type == VKD3D_SHADER_TYPE_HULL && i == VKD3DSPR_OUTPOINTID)) + { +- vsir_dst_param_init(&dst, i, VKD3D_DATA_FLOAT, 0); ++ vsir_dst_param_init(&dst, i, VSIR_DATA_F32, 0); + spirv_compiler_emit_io_register(compiler, &dst); + } + } +@@ -11195,11 +11050,12 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; + const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- const struct vsir_program *program = compiler->program; +- struct vkd3d_shader_instruction_array instructions; ++ struct vsir_program *program = compiler->program; + enum vkd3d_shader_spirv_environment environment; ++ struct vkd3d_shader_instruction *ins; + enum vkd3d_result result = VKD3D_OK; + unsigned int i, max_element_count; ++ struct vsir_program_iterator it; + + max_element_count = max(program->output_signature.element_count, program->patch_constant_signature.element_count); + if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info)))) +@@ -11247,8 +11103,6 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + if (program->block_count && !spirv_compiler_init_blocks(compiler, program->block_count)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- instructions = program->instructions; +- + compiler->use_vocp = program->use_vocp; + compiler->block_names = program->block_names; + compiler->block_name_count = program->block_name_count; +@@ -11263,9 +11117,10 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) + spirv_compiler_emit_shader_signature_outputs(compiler); + +- for (i = 0; i < instructions.count && result >= 0; ++i) ++ it = vsir_program_iterator(&program->instructions); ++ for (ins = vsir_program_iterator_head(&it); ins && result >= 0; ins = vsir_program_iterator_next(&it)) + { +- result = spirv_compiler_handle_instruction(compiler, &instructions.elements[i]); ++ result = spirv_compiler_handle_instruction(compiler, ins); + } + + if (result < 0) diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 29b03871e05..c7eafbc79f3 100644 +index 29b03871e05..ea15c1a9ad5 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -261,6 +261,7 @@ enum vkd3d_sm4_opcode @@ -17613,6 +24254,67 @@ index 29b03871e05..c7eafbc79f3 100644 const struct vkd3d_sm4_register_type_info *register_type_info_from_sm4[VKD3D_SM4_REGISTER_TYPE_COUNT]; const struct vkd3d_sm4_register_type_info *register_type_info_from_vkd3d[VKD3DSPR_COUNT]; const struct vkd3d_sm4_stat_field_info *stat_field_from_sm4[VKD3D_SM4_OP_COUNT]; +@@ -747,18 +748,18 @@ static const enum vkd3d_shader_resource_type resource_type_table[] = + /* VKD3D_SM4_RESOURCE_STRUCTURED_BUFFER */ VKD3D_SHADER_RESOURCE_BUFFER, + }; + +-static const enum vkd3d_data_type data_type_table[] = +-{ +- /* 0 */ VKD3D_DATA_FLOAT, +- /* VKD3D_SM4_DATA_UNORM */ VKD3D_DATA_UNORM, +- /* VKD3D_SM4_DATA_SNORM */ VKD3D_DATA_SNORM, +- /* VKD3D_SM4_DATA_INT */ VKD3D_DATA_INT, +- /* VKD3D_SM4_DATA_UINT */ VKD3D_DATA_UINT, +- /* VKD3D_SM4_DATA_FLOAT */ VKD3D_DATA_FLOAT, +- /* VKD3D_SM4_DATA_MIXED */ VKD3D_DATA_MIXED, +- /* VKD3D_SM4_DATA_DOUBLE */ VKD3D_DATA_DOUBLE, +- /* VKD3D_SM4_DATA_CONTINUED */ VKD3D_DATA_CONTINUED, +- /* VKD3D_SM4_DATA_UNUSED */ VKD3D_DATA_UNUSED, ++static const enum vsir_data_type data_type_table[] = ++{ ++ /* 0 */ VSIR_DATA_F32, ++ /* VKD3D_SM4_DATA_UNORM */ VSIR_DATA_UNORM, ++ /* VKD3D_SM4_DATA_SNORM */ VSIR_DATA_SNORM, ++ /* VKD3D_SM4_DATA_INT */ VSIR_DATA_I32, ++ /* VKD3D_SM4_DATA_UINT */ VSIR_DATA_U32, ++ /* VKD3D_SM4_DATA_FLOAT */ VSIR_DATA_F32, ++ /* VKD3D_SM4_DATA_MIXED */ VSIR_DATA_MIXED, ++ /* VKD3D_SM4_DATA_DOUBLE */ VSIR_DATA_F64, ++ /* VKD3D_SM4_DATA_CONTINUED */ VSIR_DATA_CONTINUED, ++ /* VKD3D_SM4_DATA_UNUSED */ VSIR_DATA_UNUSED, + }; + + static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) +@@ -769,9 +770,9 @@ static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) + } + + static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, +- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param); ++ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_src_param *src_param); + static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, +- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param); ++ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_dst_param *dst_param); + + static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv, + const uint32_t **ptr, const uint32_t *end, unsigned int *register_space) +@@ -794,7 +795,7 @@ static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv, + static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { +- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]); ++ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_U32, &ins->src[0]); + ins->flags = (opcode_token & VKD3D_SM4_CONDITIONAL_NZ) ? + VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z; + } +@@ -802,7 +803,7 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, + static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { +- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]); ++ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_U32, &ins->src[0]); + if (ins->src[0].reg.type != VKD3DSPR_IMMCONST) + { + FIXME("Switch case value is not a 32-bit constant.\n"); @@ -822,7 +823,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui if (type != VKD3D_SM4_SHADER_DATA_IMMEDIATE_CONSTANT_BUFFER) { @@ -17631,7 +24333,7 @@ index 29b03871e05..c7eafbc79f3 100644 return; } -@@ -839,7 +840,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui +@@ -839,11 +840,11 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui { ERR("Failed to allocate immediate constant buffer, size %u.\n", icb_size); vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); @@ -17640,7 +24342,56 @@ index 29b03871e05..c7eafbc79f3 100644 return; } icb->register_idx = 0; -@@ -963,7 +964,7 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins, ui +- icb->data_type = VKD3D_DATA_FLOAT; ++ icb->data_type = VSIR_DATA_F32; + icb->component_count = VKD3D_VEC4_SIZE; + icb->element_count = icb_size / VKD3D_VEC4_SIZE; + icb->is_null = false; +@@ -872,7 +873,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u + enum vkd3d_sm4_resource_type resource_type; + const uint32_t *end = &tokens[token_count]; + enum vkd3d_sm4_data_type data_type; +- enum vkd3d_data_type reg_data_type; ++ enum vsir_data_type reg_data_type; + uint32_t components; + unsigned int i; + +@@ -894,7 +895,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u + >> VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; + } + +- reg_data_type = VKD3D_DATA_UNUSED; ++ reg_data_type = VSIR_DATA_UNUSED; + shader_sm4_read_dst_param(priv, &tokens, end, reg_data_type, &semantic->resource.reg); + shader_sm4_set_descriptor_register_range(priv, &semantic->resource.reg.reg, &semantic->resource.range); + +@@ -906,7 +907,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u + if (!data_type || (data_type >= ARRAY_SIZE(data_type_table))) + { + FIXME("Unhandled data type %#x.\n", data_type); +- semantic->resource_data_type[i] = VKD3D_DATA_FLOAT; ++ semantic->resource_data_type[i] = VSIR_DATA_F32; + } + else + { +@@ -925,7 +926,7 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction + { + const uint32_t *end = &tokens[token_count]; + +- shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_FLOAT, &ins->declaration.cb.src); ++ shader_sm4_read_src_param(priv, &tokens, end, VSIR_DATA_F32, &ins->declaration.cb.src); + shader_sm4_set_descriptor_register_range(priv, &ins->declaration.cb.src.reg, &ins->declaration.cb.range); + if (opcode_token & VKD3D_SM4_INDEX_TYPE_MASK) + ins->flags |= VKD3DSI_INDEXED_DYNAMIC; +@@ -956,14 +957,14 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins, ui + ins->flags = (opcode_token & VKD3D_SM4_SAMPLER_MODE_MASK) >> VKD3D_SM4_SAMPLER_MODE_SHIFT; + if (ins->flags & ~VKD3D_SM4_SAMPLER_COMPARISON) + FIXME("Unhandled sampler mode %#x.\n", ins->flags); +- shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &ins->declaration.sampler.src); ++ shader_sm4_read_src_param(priv, &tokens, end, VSIR_DATA_UNUSED, &ins->declaration.sampler.src); + shader_sm4_set_descriptor_register_range(priv, &ins->declaration.sampler.src.reg, &ins->declaration.sampler.range); + shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.range.space); + } static bool sm4_parser_is_in_fork_or_join_phase(const struct vkd3d_shader_sm4_parser *sm4) { @@ -17649,7 +24400,44 @@ index 29b03871e05..c7eafbc79f3 100644 } static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins, uint32_t opcode, -@@ -1168,7 +1169,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u +@@ -978,8 +979,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins + unsigned int *io_masks; + uint32_t write_mask; + +- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, +- &index_range->dst); ++ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_OPAQUE, &index_range->dst); + index_range->register_count = *tokens; + + register_idx = index_range->dst.reg.idx[index_range->dst.reg.idx_count - 1].offset; +@@ -1141,14 +1141,14 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i + static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { +- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, &ins->declaration.dst); ++ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, &ins->declaration.dst); + } + + static void shader_sm4_read_declaration_register_semantic(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { +- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, +- &ins->declaration.register_semantic.reg); ++ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], ++ VSIR_DATA_F32, &ins->declaration.register_semantic.reg); + ins->declaration.register_semantic.sysval_semantic = *tokens; + } + +@@ -1158,7 +1158,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u + struct vkd3d_shader_dst_param *dst = &ins->declaration.dst; + + ins->flags = (opcode_token & VKD3D_SM4_INTERPOLATION_MODE_MASK) >> VKD3D_SM4_INTERPOLATION_MODE_SHIFT; +- if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst)) ++ if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) + { + struct signature_element *e = vsir_signature_find_element_for_reg( + &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); +@@ -1168,7 +1168,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u WARN("No matching signature element for input register %u with mask %#x.\n", dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DCL, @@ -17658,7 +24446,16 @@ index 29b03871e05..c7eafbc79f3 100644 dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); } else -@@ -1194,7 +1195,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in +@@ -1184,7 +1184,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in + struct vkd3d_shader_dst_param *dst = &ins->declaration.register_semantic.reg; + + ins->flags = (opcode_token & VKD3D_SM4_INTERPOLATION_MODE_MASK) >> VKD3D_SM4_INTERPOLATION_MODE_SHIFT; +- if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst)) ++ if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) + { + struct signature_element *e = vsir_signature_find_element_for_reg( + &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); +@@ -1194,7 +1194,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in WARN("No matching signature element for input register %u with mask %#x.\n", dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DCL, @@ -17667,7 +24464,98 @@ index 29b03871e05..c7eafbc79f3 100644 dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); } else -@@ -1440,273 +1441,275 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) +@@ -1211,7 +1211,7 @@ static void shader_sm4_read_dcl_indexable_temp(struct vkd3d_shader_instruction * + ins->declaration.indexable_temp.register_idx = *tokens++; + ins->declaration.indexable_temp.register_size = *tokens++; + ins->declaration.indexable_temp.alignment = 0; +- ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT; ++ ins->declaration.indexable_temp.data_type = VSIR_DATA_F32; + ins->declaration.indexable_temp.component_count = *tokens; + ins->declaration.indexable_temp.has_function_scope = false; + } +@@ -1227,7 +1227,7 @@ static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t + const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { + ins->src[0].reg.u.fp_body_idx = *tokens++; +- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &ins->src[0]); ++ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_OPAQUE, &ins->src[0]); + } + + static void shader_sm5_read_dcl_function_body(struct vkd3d_shader_instruction *ins, uint32_t opcode, +@@ -1314,7 +1314,7 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins, ui + struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource; + const uint32_t *end = &tokens[token_count]; + +- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); ++ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); + shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); + ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT; + shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.range.space); +@@ -1326,7 +1326,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction * + struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource; + const uint32_t *end = &tokens[token_count]; + +- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); ++ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); + shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); + ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT; + resource->byte_stride = *tokens++; +@@ -1338,7 +1338,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction * + static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { +- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg); ++ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, &ins->declaration.tgsm_raw.reg); + ins->declaration.tgsm_raw.byte_count = *tokens; + if (ins->declaration.tgsm_raw.byte_count % 4) + FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count); +@@ -1348,8 +1348,8 @@ static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins, u + static void shader_sm5_read_dcl_tgsm_structured(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { +- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, +- &ins->declaration.tgsm_structured.reg); ++ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], ++ VSIR_DATA_F32, &ins->declaration.tgsm_structured.reg); + ins->declaration.tgsm_structured.byte_stride = *tokens++; + ins->declaration.tgsm_structured.structure_count = *tokens; + if (ins->declaration.tgsm_structured.byte_stride % 4) +@@ -1363,7 +1363,7 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct + struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource; + const uint32_t *end = &tokens[token_count]; + +- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); ++ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); + shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); + resource->byte_stride = *tokens++; + if (resource->byte_stride % 4) +@@ -1377,7 +1377,7 @@ static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *in + struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource; + const uint32_t *end = &tokens[token_count]; + +- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); ++ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); + shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); + shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.range.space); + } +@@ -1429,284 +1429,284 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) + unsigned int i; + + /* +- * d -> VKD3D_DATA_DOUBLE +- * f -> VKD3D_DATA_FLOAT +- * i -> VKD3D_DATA_INT +- * u -> VKD3D_DATA_UINT +- * O -> VKD3D_DATA_OPAQUE +- * R -> VKD3D_DATA_RESOURCE +- * S -> VKD3D_DATA_SAMPLER +- * U -> VKD3D_DATA_UAV ++ * d -> VSIR_DATA_F64 ++ * f -> VSIR_DATA_F32 ++ * i -> VSIR_DATA_I32 ++ * u -> VSIR_DATA_U32 ++ * O -> VSIR_DATA_OPAQUE ++ * * -> VSIR_DATA_UNUSED */ static const struct vkd3d_sm4_opcode_info opcode_table[] = { @@ -17921,8 +24809,8 @@ index 29b03871e05..c7eafbc79f3 100644 + {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VSIR_OP_HS_CONTROL_POINT_PHASE, "", ""}, + {VKD3D_SM5_OP_HS_FORK_PHASE, VSIR_OP_HS_FORK_PHASE, "", ""}, + {VKD3D_SM5_OP_HS_JOIN_PHASE, VSIR_OP_HS_JOIN_PHASE, "", ""}, -+ {VKD3D_SM5_OP_EMIT_STREAM, VSIR_OP_EMIT_STREAM, "", "f"}, -+ {VKD3D_SM5_OP_CUT_STREAM, VSIR_OP_CUT_STREAM, "", "f"}, ++ {VKD3D_SM5_OP_EMIT_STREAM, VSIR_OP_EMIT_STREAM, "", "*"}, ++ {VKD3D_SM5_OP_CUT_STREAM, VSIR_OP_CUT_STREAM, "", "*"}, + {VKD3D_SM5_OP_FCALL, VSIR_OP_FCALL, "", "O", shader_sm5_read_fcall}, - {VKD3D_SM5_OP_BUFINFO, VKD3DSIH_BUFINFO, "i", "*"}, @@ -17967,7 +24855,7 @@ index 29b03871e05..c7eafbc79f3 100644 + {VKD3D_SM5_OP_BFI, VSIR_OP_BFI, "u", "iiuu"}, + {VKD3D_SM5_OP_BFREV, VSIR_OP_BFREV, "u", "u"}, + {VKD3D_SM5_OP_SWAPC, VSIR_OP_SWAPC, "ff", "uff"}, -+ {VKD3D_SM5_OP_DCL_STREAM, VSIR_OP_DCL_STREAM, "", "O"}, ++ {VKD3D_SM5_OP_DCL_STREAM, VSIR_OP_DCL_STREAM, "", "*"}, + {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VSIR_OP_DCL_FUNCTION_BODY, "", "", shader_sm5_read_dcl_function_body}, - {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VKD3DSIH_DCL_FUNCTION_TABLE, "", "", @@ -18163,7 +25051,7 @@ index 29b03871e05..c7eafbc79f3 100644 }; static const struct vkd3d_sm4_register_type_info register_type_table[] = -@@ -1941,7 +1944,7 @@ static const struct vkd3d_sm4_opcode_info *get_info_from_sm4_opcode( +@@ -1941,7 +1941,7 @@ static const struct vkd3d_sm4_opcode_info *get_info_from_sm4_opcode( static const struct vkd3d_sm4_opcode_info *get_info_from_vsir_opcode( const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_shader_opcode vsir_opcode) { @@ -18172,7 +25060,72 @@ index 29b03871e05..c7eafbc79f3 100644 return NULL; return lookup->opcode_info_from_vsir[vsir_opcode]; } -@@ -2286,7 +2289,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register * +@@ -1982,25 +1982,25 @@ static enum vkd3d_sm4_stat_field get_stat_field_from_sm4_opcode( + return field_info->field; + } + +-static enum vkd3d_data_type map_data_type(char t) ++static enum vsir_data_type map_data_type(char t) + { + switch (t) + { + case 'd': +- return VKD3D_DATA_DOUBLE; ++ return VSIR_DATA_F64; + case 'f': +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + case 'i': +- return VKD3D_DATA_INT; ++ return VSIR_DATA_I32; + case 'u': +- return VKD3D_DATA_UINT; ++ return VSIR_DATA_U32; + case 'O': +- return VKD3D_DATA_OPAQUE; ++ return VSIR_DATA_OPAQUE; + case '*': +- return VKD3D_DATA_UNUSED; ++ return VSIR_DATA_UNUSED; + default: + ERR("Invalid data type '%c'.\n", t); +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + } + } + +@@ -2021,7 +2021,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const + reg_idx->offset = *(*ptr)++; + else + reg_idx->offset = 0; +- shader_sm4_read_src_param(priv, ptr, end, VKD3D_DATA_INT, rel_addr); ++ shader_sm4_read_src_param(priv, ptr, end, VSIR_DATA_I32, rel_addr); + } + else + { +@@ -2033,7 +2033,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const + } + + static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, const uint32_t *end, +- enum vkd3d_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier) ++ enum vsir_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier) + { + const struct vkd3d_sm4_register_type_info *register_type_info; + enum vkd3d_shader_register_type vsir_register_type; +@@ -2234,12 +2234,9 @@ bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg) + { + switch (reg->type) + { +- case VKD3DSPR_COVERAGE: + case VKD3DSPR_DEPTHOUT: + case VKD3DSPR_DEPTHOUTGE: + case VKD3DSPR_DEPTHOUTLE: +- case VKD3DSPR_GSINSTID: +- case VKD3DSPR_LOCALTHREADINDEX: + case VKD3DSPR_OUTPOINTID: + case VKD3DSPR_PRIMID: + case VKD3DSPR_SAMPLEMASK: +@@ -2286,7 +2283,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register * const struct vkd3d_shader_sm4_parser *priv) { return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT @@ -18181,7 +25134,43 @@ index 29b03871e05..c7eafbc79f3 100644 || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); } -@@ -2653,16 +2656,16 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2351,7 +2348,7 @@ static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_pa + } + + static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, +- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param) ++ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_src_param *src_param) + { + unsigned int dimension, mask; + uint32_t token; +@@ -2439,7 +2436,7 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons + } + + static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, +- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param) ++ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_dst_param *dst_param) + { + enum vkd3d_sm4_swizzle_type swizzle_type; + enum vkd3d_shader_src_modifier modifier; +@@ -2509,7 +2506,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons + break; + } + +- if (data_type == VKD3D_DATA_DOUBLE) ++ if (data_type == VSIR_DATA_F64) + dst_param->write_mask = vsir_write_mask_64_from_32(dst_param->write_mask); + /* Some scalar registers are declared with no write mask in shader bytecode. */ + if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg)) +@@ -2570,7 +2567,7 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d + if (!data_type || (data_type >= ARRAY_SIZE(data_type_table))) + { + FIXME("Unhandled data type %#x.\n", data_type); +- ins->resource_data_type[i] = VKD3D_DATA_FLOAT; ++ ins->resource_data_type[i] = VSIR_DATA_F32; + } + else + { +@@ -2653,16 +2650,16 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(opcode_info = get_info_from_sm4_opcode(&sm4->lookup, opcode))) { FIXME("Unrecognized opcode %#x, opcode_token 0x%08x.\n", opcode, opcode_token); @@ -18202,7 +25191,7 @@ index 29b03871e05..c7eafbc79f3 100644 ins->flags = 0; ins->coissue = false; ins->raw = false; -@@ -2675,7 +2678,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2675,15 +2672,15 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str { ERR("Failed to allocate src parameters.\n"); vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); @@ -18211,7 +25200,19 @@ index 29b03871e05..c7eafbc79f3 100644 return; } ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; -@@ -2717,7 +2720,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str + ins->resource_stride = 0; +- ins->resource_data_type[0] = VKD3D_DATA_FLOAT; +- ins->resource_data_type[1] = VKD3D_DATA_FLOAT; +- ins->resource_data_type[2] = VKD3D_DATA_FLOAT; +- ins->resource_data_type[3] = VKD3D_DATA_FLOAT; ++ ins->resource_data_type[0] = VSIR_DATA_F32; ++ ins->resource_data_type[1] = VSIR_DATA_F32; ++ ins->resource_data_type[2] = VSIR_DATA_F32; ++ ins->resource_data_type[3] = VSIR_DATA_F32; + memset(&ins->texel_offset, 0, sizeof(ins->texel_offset)); + + p = *ptr; +@@ -2717,7 +2714,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str { ERR("Failed to allocate dst parameters.\n"); vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); @@ -18220,7 +25221,7 @@ index 29b03871e05..c7eafbc79f3 100644 return; } for (i = 0; i < ins->dst_count; ++i) -@@ -2725,7 +2728,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2725,7 +2722,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(shader_sm4_read_dst_param(sm4, &p, *ptr, map_data_type(opcode_info->dst_info[i]), &dst_params[i]))) { @@ -18229,7 +25230,7 @@ index 29b03871e05..c7eafbc79f3 100644 return; } dst_params[i].modifiers |= instruction_dst_modifier; -@@ -2736,7 +2739,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2736,17 +2733,21 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(shader_sm4_read_src_param(sm4, &p, *ptr, map_data_type(opcode_info->src_info[i]), &src_params[i]))) { @@ -18238,7 +25239,13 @@ index 29b03871e05..c7eafbc79f3 100644 return; } } -@@ -2746,7 +2749,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str + } + ++ if ((ins->opcode == VSIR_OP_SAMPLE_INFO && ins->flags & VKD3DSI_SAMPLE_INFO_UINT) ++ || (ins->opcode == VSIR_OP_RESINFO && ins->flags & VKD3DSI_RESINFO_UINT)) ++ ins->dst[0].reg.data_type = VSIR_DATA_U32; ++ + return; fail: *ptr = sm4->end; @@ -18247,8 +25254,30 @@ index 29b03871e05..c7eafbc79f3 100644 return; } -@@ -2968,7 +2971,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con - ins = &instructions->elements[instructions->count]; +@@ -2895,7 +2896,6 @@ static void shader_sm4_validate_default_phase_index_ranges(struct vkd3d_shader_s + int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, + struct vkd3d_shader_message_context *message_context, struct vsir_program *program) + { +- struct vkd3d_shader_instruction_array *instructions; + struct vkd3d_shader_sm4_parser sm4 = {0}; + struct dxbc_shader_desc dxbc_desc = {0}; + struct vkd3d_shader_instruction *ins; +@@ -2955,26 +2955,22 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con + return VKD3D_ERROR_INVALID_SHADER; + } + +- instructions = &program->instructions; + while (sm4.ptr != sm4.end) + { +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) ++ if (!(ins = vsir_program_append(program))) + { +- ERR("Failed to allocate instructions.\n"); + vkd3d_shader_parser_error(&sm4.p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); + vsir_program_cleanup(program); + return VKD3D_ERROR_OUT_OF_MEMORY; + } +- ins = &instructions->elements[instructions->count]; shader_sm4_read_instruction(&sm4, ins); - if (ins->opcode == VKD3DSIH_INVALID) @@ -18256,7 +25285,13 @@ index 29b03871e05..c7eafbc79f3 100644 { WARN("Encountered unrecognized or invalid instruction.\n"); vsir_program_cleanup(program); -@@ -3129,6 +3132,9 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s + return VKD3D_ERROR_OUT_OF_MEMORY; + } +- ++instructions->count; + } + if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL + && !sm4.has_control_point_phase && !sm4.p.failed) +@@ -3129,6 +3125,9 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s {"position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, {"sv_position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, {"sv_primitiveid", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_PRIMITIVE_ID}, @@ -18266,7 +25301,7 @@ index 29b03871e05..c7eafbc79f3 100644 {"sv_outputcontrolpointid", false, VKD3D_SHADER_TYPE_HULL, ~0u}, {"sv_position", false, VKD3D_SHADER_TYPE_HULL, ~0u}, -@@ -3255,6 +3261,8 @@ static int signature_element_pointer_compare(const void *x, const void *y) +@@ -3255,6 +3254,8 @@ static int signature_element_pointer_compare(const void *x, const void *y) const struct signature_element *f = *(const struct signature_element **)y; int ret; @@ -18275,7 +25310,7 @@ index 29b03871e05..c7eafbc79f3 100644 if ((ret = vkd3d_u32_compare(e->register_index, f->register_index))) return ret; return vkd3d_u32_compare(e->mask, f->mask); -@@ -3263,12 +3271,17 @@ static int signature_element_pointer_compare(const void *x, const void *y) +@@ -3263,12 +3264,17 @@ static int signature_element_pointer_compare(const void *x, const void *y) static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_signature *signature, uint32_t tag) { bool has_minimum_precision = tpf->program->global_flags & VKD3DSGF_ENABLE_MINIMUM_PRECISION; @@ -18295,7 +25330,7 @@ index 29b03871e05..c7eafbc79f3 100644 put_u32(&buffer, signature->element_count); put_u32(&buffer, 8); /* unknown */ -@@ -3291,8 +3304,8 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si +@@ -3291,8 +3297,8 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si if (sysval >= VKD3D_SHADER_SV_TARGET) sysval = VKD3D_SHADER_SV_NONE; @@ -18306,7 +25341,7 @@ index 29b03871e05..c7eafbc79f3 100644 put_u32(&buffer, 0); /* name */ put_u32(&buffer, element->semantic_index); put_u32(&buffer, sysval); -@@ -3306,13 +3319,16 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si +@@ -3306,13 +3312,16 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si for (i = 0; i < signature->element_count; ++i) { const struct signature_element *element = sorted_elements[i]; @@ -18327,7 +25362,16 @@ index 29b03871e05..c7eafbc79f3 100644 } if (has_minimum_precision) -@@ -3843,9 +3859,8 @@ static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_dat +@@ -3822,7 +3831,7 @@ static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_s + write_sm4_instruction(tpf, &instr); + } + +-static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_data_type) ++static uint32_t pack_resource_data_type(const enum vsir_data_type *resource_data_type) + { + unsigned int i, k, type = 0; + +@@ -3843,9 +3852,8 @@ static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_dat static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) { @@ -18338,7 +25382,7 @@ index 29b03871e05..c7eafbc79f3 100644 const struct vkd3d_sm4_opcode_info *info; struct sm4_instruction instr = {0}; bool uav; -@@ -3853,33 +3868,44 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s +@@ -3853,33 +3861,44 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s info = get_info_from_vsir_opcode(&tpf->lookup, ins->opcode); VKD3D_ASSERT(info); @@ -18362,7 +25406,7 @@ index 29b03871e05..c7eafbc79f3 100644 instr.idx_count = 1; + instr.extra_bits |= ins->declaration.semantic.sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; + resource = &ins->declaration.semantic.resource; -+ } + } + else if (ins->opcode == VSIR_OP_DCL_RESOURCE_RAW || ins->opcode == VSIR_OP_DCL_UAV_RAW) + { + resource = &ins->declaration.raw_resource.resource; @@ -18371,11 +25415,11 @@ index 29b03871e05..c7eafbc79f3 100644 + { + instr.byte_stride = ins->declaration.structured_resource.byte_stride; + resource = &ins->declaration.structured_resource.resource; - } - ++ } ++ + instr.dsts[0] = resource->reg; + instr.dst_count = 1; -+ + if (vkd3d_shader_ver_ge(version, 5, 1)) { - instr.dsts[0].reg.idx[0].offset = semantic->resource.reg.reg.idx[0].offset; @@ -18396,18 +25440,34 @@ index 29b03871e05..c7eafbc79f3 100644 instr.dsts[0].reg.idx_count = 1; } -@@ -3887,10 +3913,6 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s +@@ -3887,10 +3906,23 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s instr.extra_bits |= ins->flags << VKD3D_SM5_UAV_FLAGS_SHIFT; instr.extra_bits |= (sm4_resource_dimension(ins->resource_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); - instr.extra_bits |= semantic->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; -- + - if (ins->structured) - instr.byte_stride = structured_resource->byte_stride; ++ write_sm4_instruction(tpf, &instr); ++} ++ ++static void tpf_dcl_tgsm_raw(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) ++{ ++ const struct vkd3d_shader_tgsm_raw *tgsm = &ins->declaration.tgsm_raw; ++ struct sm4_instruction instr = ++ { ++ .opcode = VKD3D_SM5_OP_DCL_TGSM_RAW, ++ ++ .dsts[0] = tgsm->reg, ++ .dst_count = 1, ++ ++ .idx[0] = tgsm->byte_count, ++ .idx_count = 1, ++ }; write_sm4_instruction(tpf, &instr); } -@@ -4024,6 +4046,39 @@ static void tpf_write_dcl_vertices_out(const struct tpf_compiler *tpf, unsigned +@@ -4024,6 +4056,39 @@ static void tpf_write_dcl_vertices_out(const struct tpf_compiler *tpf, unsigned write_sm4_instruction(tpf, &instr); } @@ -18447,7 +25507,24 @@ index 29b03871e05..c7eafbc79f3 100644 static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) { struct sm4_instruction_modifier *modifier; -@@ -4060,6 +4115,7 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_ +@@ -4039,14 +4104,14 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + + if (ins->dst_count != dst_count) + { +- ERR("Invalid destination count %u for vsir instruction %#x (expected %u).\n", ++ ERR("Invalid destination count %zu for vsir instruction %#x (expected %u).\n", + ins->dst_count, ins->opcode, dst_count); + tpf->result = VKD3D_ERROR_INVALID_SHADER; + return; + } + if (ins->src_count != src_count) + { +- ERR("Invalid source count %u for vsir instruction %#x (expected %u).\n", ++ ERR("Invalid source count %zu for vsir instruction %#x (expected %u).\n", + ins->src_count, ins->opcode, src_count); + tpf->result = VKD3D_ERROR_INVALID_SHADER; + return; +@@ -4060,6 +4125,7 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_ for (unsigned int i = 0; i < ins->dst_count; ++i) { instr.dsts[i] = ins->dst[i]; @@ -18455,7 +25532,7 @@ index 29b03871e05..c7eafbc79f3 100644 if (instr.dsts[i].modifiers & VKD3DSPDM_SATURATE) { -@@ -4070,7 +4126,10 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_ +@@ -4070,7 +4136,10 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_ } } for (unsigned int i = 0; i < ins->src_count; ++i) @@ -18466,7 +25543,7 @@ index 29b03871e05..c7eafbc79f3 100644 if (ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w) { -@@ -4095,177 +4154,184 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ +@@ -4095,177 +4164,188 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ { switch (ins->opcode) { @@ -18539,6 +25616,10 @@ index 29b03871e05..c7eafbc79f3 100644 - case VKD3DSIH_DCL_UAV_RAW: - case VKD3DSIH_DCL_UAV_STRUCTURED: - case VKD3DSIH_DCL_UAV_TYPED: ++ case VSIR_OP_DCL_TGSM_RAW: ++ tpf_dcl_tgsm_raw(tpf, ins); ++ break; ++ + case VSIR_OP_DCL: + case VSIR_OP_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_UAV_RAW: @@ -18783,18 +25864,50 @@ index 29b03871e05..c7eafbc79f3 100644 tpf_simple_instruction(tpf, ins); break; -@@ -4434,6 +4500,9 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struc +@@ -4275,20 +4355,23 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + } + } + +-static void tpf_write_program(struct tpf_compiler *tpf, const struct vsir_program *program) ++static void tpf_write_program(struct tpf_compiler *tpf, struct vsir_program *program) + { +- unsigned int i; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; + + if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE) + tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size); + +- for (i = 0; i < program->instructions.count; ++i) +- tpf_handle_instruction(tpf, &program->instructions.elements[i]); ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ tpf_handle_instruction(tpf, ins); ++ } + } + + static void tpf_write_shdr(struct tpf_compiler *tpf) + { +- const struct vsir_program *program = tpf->program; ++ struct vsir_program *program = tpf->program; + const struct vkd3d_shader_version *version; + struct vkd3d_bytecode_buffer buffer = {0}; + size_t token_count_position; +@@ -4434,6 +4517,12 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struc size_t i; int ret; + if ((ret = vsir_allocate_temp_registers(program, message_context))) + return ret; ++ ++ if ((ret = vsir_update_dcl_temps(program, message_context))) ++ return ret; + tpf.program = program; tpf.buffer = NULL; tpf.stat = &stat; diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index f56608940db..4cda8493696 100644 +index f56608940db..d1992c9d446 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -23,6 +23,8 @@ @@ -18806,7 +25919,83 @@ index f56608940db..4cda8493696 100644 static inline int char_to_int(char c) { if ('0' <= c && c <= '9') -@@ -336,7 +338,10 @@ bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_cont +@@ -55,6 +57,39 @@ uint32_t vkd3d_parse_integer(const char *s) + return ret; + } + ++bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source) ++{ ++ char *s; ++ ++ if (!(s = vkd3d_strdup(source))) ++ return false; ++ ++ if (!vkd3d_array_reserve((void **)&l->sources, &l->capacity, l->count + 1, sizeof(*l->sources))) ++ { ++ vkd3d_free(s); ++ return false; ++ } ++ l->sources[l->count++] = s; ++ ++ return true; ++} ++ ++void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l) ++{ ++ size_t i; ++ ++ for (i = 0; i < l->count; ++i) ++ { ++ vkd3d_free((void *)l->sources[i]); ++ } ++ vkd3d_free(l->sources); ++} ++ ++void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l) ++{ ++ memset(l, 0, sizeof(*l)); ++} ++ + void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) + { + buffer->buffer_size = 16; +@@ -85,7 +120,7 @@ void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t siz + + static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int rc) + { +- unsigned int new_buffer_size = rc >= 0 ? buffer->content_size + rc + 1 : buffer->buffer_size * 2; ++ size_t new_buffer_size = rc >= 0 ? buffer->content_size + rc + 1 : buffer->buffer_size * 2; + + if (!vkd3d_array_reserve((void **)&buffer->buffer, &buffer->buffer_size, new_buffer_size, 1)) + { +@@ -98,7 +133,7 @@ static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int r + + int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args) + { +- unsigned int rem; ++ size_t rem; + va_list a; + int rc; + +@@ -133,7 +168,7 @@ int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *f + + int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f) + { +- unsigned int idx = buffer->content_size + 1; ++ size_t idx = buffer->content_size + 1; + int ret; + + if (!(ret = vkd3d_string_buffer_printf(buffer, "%.8e", f)) && isfinite(f)) +@@ -148,7 +183,7 @@ int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f) + + int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d) + { +- unsigned int idx = buffer->content_size + 1; ++ size_t idx = buffer->content_size + 1; + int ret; + + if (!(ret = vkd3d_string_buffer_printf(buffer, "%.16e", d)) && isfinite(d)) +@@ -336,7 +371,10 @@ bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_cont void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_log_level level, const char *format, va_list args) { @@ -18818,7 +26007,7 @@ index f56608940db..4cda8493696 100644 return; if (location) -@@ -344,19 +349,26 @@ void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const stru +@@ -344,19 +382,26 @@ void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const stru const char *source_name = location->source_name ? location->source_name : ""; if (location->line) @@ -18850,7 +26039,7 @@ index f56608940db..4cda8493696 100644 return; if (location) -@@ -364,17 +376,21 @@ void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const s +@@ -364,17 +409,21 @@ void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const s const char *source_name = location->source_name ? location->source_name : ""; if (location->line) @@ -18877,7 +26066,7 @@ index f56608940db..4cda8493696 100644 } void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, -@@ -390,7 +406,10 @@ void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const st +@@ -390,7 +439,10 @@ void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const st void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_error error, const char *format, va_list args) { @@ -18889,7 +26078,7 @@ index f56608940db..4cda8493696 100644 return; if (location) -@@ -398,17 +417,21 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str +@@ -398,17 +450,21 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str const char *source_name = location->source_name ? location->source_name : ""; if (location->line) @@ -18916,7 +26105,62 @@ index f56608940db..4cda8493696 100644 } void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, -@@ -1018,11 +1041,11 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr +@@ -744,12 +800,28 @@ static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_ + } + + static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, +- struct vkd3d_shader_message_context *message_context, struct vsir_program *program) ++ const struct shader_dump_data *dump_data, struct vkd3d_shader_message_context *message_context, ++ struct vsir_program *program, struct vkd3d_shader_code *reflection_data) + { ++ struct vkd3d_shader_compile_info preprocessed_info; ++ struct vkd3d_shader_code preprocessed; + enum vkd3d_result ret; + + switch (compile_info->source_type) + { ++ case VKD3D_SHADER_SOURCE_HLSL: ++ if ((ret = preproc_lexer_parse(compile_info, &preprocessed, message_context)) >= 0) ++ { ++ vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC); ++ ++ preprocessed_info = *compile_info; ++ preprocessed_info.source = preprocessed; ++ ret = hlsl_parse(&preprocessed_info, message_context, program, reflection_data); ++ ++ vkd3d_shader_free_shader_code(&preprocessed); ++ } ++ break; ++ + case VKD3D_SHADER_SOURCE_D3D_BYTECODE: + ret = d3dbc_parse(compile_info, config_flags, message_context, program); + break; +@@ -780,13 +852,19 @@ static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *comp + + if (TRACE_ON()) + vsir_program_trace(program); +- +- vsir_program_cleanup(program); +- return ret; ++ goto fail; + } + +- if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE) +- ret = vsir_program_transform_early(program, config_flags, compile_info, message_context); ++ if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE ++ && (ret = vsir_program_transform_early(program, config_flags, compile_info, message_context)) < 0) ++ goto fail; ++ ++ return ret; ++ ++fail: ++ vkd3d_shader_free_shader_code(reflection_data); ++ vsir_program_cleanup(program); ++ + return ret; + } + +@@ -1018,11 +1096,11 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr { enum vkd3d_shader_opcode opcode = instruction->opcode; @@ -18933,7 +26177,7 @@ index f56608940db..4cda8493696 100644 } static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *context, -@@ -1035,7 +1058,7 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in +@@ -1035,7 +1113,7 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in { enum vkd3d_shader_opcode opcode = instruction->opcode; @@ -18942,7 +26186,7 @@ index f56608940db..4cda8493696 100644 } static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_context *context, -@@ -1048,8 +1071,8 @@ static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_ +@@ -1048,8 +1126,8 @@ static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_ { enum vkd3d_shader_opcode opcode = instruction->opcode; @@ -18953,7 +26197,91 @@ index f56608940db..4cda8493696 100644 } static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context, -@@ -1260,13 +1283,13 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1061,7 +1139,7 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont + static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, + enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, + const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, +- enum vkd3d_data_type resource_data_type) ++ enum vsir_data_type resource_data_type) + { + struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; + struct vkd3d_shader_descriptor_info1 *d; +@@ -1097,7 +1175,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc + struct vkd3d_shader_descriptor_info1 *d; + + if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, +- &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) ++ &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) + return; + d->buffer_size = cb->size; + } +@@ -1109,7 +1187,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte + struct vkd3d_shader_descriptor_info1 *d; + + if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, +- &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED))) ++ &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) + return; + + if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) +@@ -1120,9 +1198,9 @@ static void vkd3d_shader_scan_combined_sampler_declaration( + struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) + { + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, +- &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED); ++ &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, +- &semantic->resource.range, semantic->resource_type, VKD3D_DATA_FLOAT); ++ &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32); + } + + const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( +@@ -1210,9 +1288,43 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co + s->sampler_index = sampler_idx; + } + ++static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context, ++ const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler) ++{ ++ unsigned int resource_idx = resource->idx[0].offset; ++ unsigned int sampler_idx = sampler->idx[0].offset; ++ ++ vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler); ++ ++ if (!context->scan_descriptor_info) ++ return; ++ ++ /* Sample instructions lowered from 1.x texture instructions have no ++ * DCL, so we need to add the resource if it didn't already exist. ++ * Such descriptors have a fixed count, type, etc. */ ++ ++ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, ++ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx)) ++ { ++ struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx}; ++ ++ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource, ++ &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32); ++ } ++ ++ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, ++ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx)) ++ { ++ struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; ++ ++ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource, ++ &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); ++ } ++} ++ + static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, +- enum vkd3d_data_type resource_data_type, unsigned int sample_count, ++ enum vsir_data_type resource_data_type, unsigned int sample_count, + unsigned int structure_stride, bool raw, uint32_t flags) + { + struct vkd3d_shader_descriptor_info1 *d; +@@ -1260,13 +1372,13 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte switch (instruction->opcode) { @@ -18970,7 +26298,7 @@ index f56608940db..4cda8493696 100644 if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE) break; -@@ -1276,33 +1299,33 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1276,33 +1388,33 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte break; } /* fall through */ @@ -18983,14 +26311,16 @@ index f56608940db..4cda8493696 100644 + case VSIR_OP_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_UAV_RAW: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, 0, true, instruction->flags); +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, 0, true, instruction->flags); ++ VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32, 0, 0, true, instruction->flags); break; - case VKD3DSIH_DCL_RESOURCE_STRUCTURED: - case VKD3DSIH_DCL_UAV_STRUCTURED: + case VSIR_OP_DCL_RESOURCE_STRUCTURED: + case VSIR_OP_DCL_UAV_STRUCTURED: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, ++ VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32, 0, instruction->declaration.structured_resource.byte_stride, false, instruction->flags); break; - case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: @@ -19014,7 +26344,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_IF) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, -@@ -1311,7 +1334,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1311,7 +1423,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } cf_info->inside_block = true; break; @@ -19023,7 +26353,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_IF) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, -@@ -1320,12 +1343,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1320,12 +1432,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } vkd3d_shader_scan_pop_cf_info(context); break; @@ -19038,7 +26368,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_LOOP) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, -@@ -1334,11 +1357,11 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1334,11 +1446,11 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } vkd3d_shader_scan_pop_cf_info(context); break; @@ -19052,7 +26382,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH || cf_info->inside_block) { -@@ -1348,7 +1371,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1348,7 +1460,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } vkd3d_shader_scan_pop_cf_info(context); break; @@ -19061,7 +26391,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH) { -@@ -1358,7 +1381,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1358,7 +1470,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } cf_info->inside_block = true; break; @@ -19070,7 +26400,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH) { -@@ -1375,7 +1398,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1375,7 +1487,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte cf_info->inside_block = true; cf_info->has_default = true; break; @@ -19079,7 +26409,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_find_innermost_breakable_cf_info(context))) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, -@@ -1384,7 +1407,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1384,7 +1496,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } cf_info->inside_block = false; break; @@ -19088,7 +26418,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context))) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, -@@ -1392,7 +1415,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1392,7 +1504,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_ERROR_INVALID_SHADER; } break; @@ -19097,7 +26427,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context))) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, -@@ -1401,7 +1424,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1401,7 +1513,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } cf_info->inside_block = false; break; @@ -19106,7 +26436,7 @@ index f56608940db..4cda8493696 100644 if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context))) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, -@@ -1409,59 +1432,60 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -1409,59 +1521,55 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_ERROR_INVALID_SHADER; } break; @@ -19116,13 +26446,12 @@ index f56608940db..4cda8493696 100644 context->cf_info[context->cf_info_count - 1].inside_block = false; break; - case VKD3DSIH_TEX: -+ case VSIR_OP_TEXLD: - if (context->version->major == 1) - sampler_reg = &instruction->dst[0].reg; - else - sampler_reg = &instruction->src[1].reg; - vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg); - break; +- if (context->version->major == 1) +- sampler_reg = &instruction->dst[0].reg; +- else +- sampler_reg = &instruction->src[1].reg; +- vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg); +- break; - case VKD3DSIH_TEXBEM: - case VKD3DSIH_TEXBEML: - case VKD3DSIH_TEXDP3TEX: @@ -19157,7 +26486,6 @@ index f56608940db..4cda8493696 100644 - case VKD3DSIH_SAMPLE_LOD: + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_C: -+ case VSIR_OP_SAMPLE: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_C_LZ: @@ -19167,6 +26495,9 @@ index f56608940db..4cda8493696 100644 break; - case VKD3DSIH_GATHER4_PO: - case VKD3DSIH_GATHER4_PO_C: ++ case VSIR_OP_SAMPLE: ++ vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg); ++ break; + case VSIR_OP_GATHER4_PO: + case VSIR_OP_GATHER4_PO_C: vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg); @@ -19196,7 +26527,204 @@ index f56608940db..4cda8493696 100644 if (instruction->src[2].reg.type == VKD3DSPR_RESOURCE) vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, NULL); break; -@@ -1805,6 +1829,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, +@@ -1498,27 +1606,27 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + return VKD3D_OK; + } + +-static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vkd3d_data_type data_type) ++static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vsir_data_type data_type) + { + switch (data_type) + { +- case VKD3D_DATA_UNORM: +- return VKD3D_SHADER_RESOURCE_DATA_UNORM; +- case VKD3D_DATA_SNORM: +- return VKD3D_SHADER_RESOURCE_DATA_SNORM; +- case VKD3D_DATA_INT: ++ case VSIR_DATA_F32: ++ return VKD3D_SHADER_RESOURCE_DATA_FLOAT; ++ case VSIR_DATA_F64: ++ return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; ++ case VSIR_DATA_I32: + return VKD3D_SHADER_RESOURCE_DATA_INT; +- case VKD3D_DATA_UINT: ++ case VSIR_DATA_U32: + return VKD3D_SHADER_RESOURCE_DATA_UINT; +- case VKD3D_DATA_FLOAT: +- return VKD3D_SHADER_RESOURCE_DATA_FLOAT; +- case VKD3D_DATA_MIXED: ++ case VSIR_DATA_SNORM: ++ return VKD3D_SHADER_RESOURCE_DATA_SNORM; ++ case VSIR_DATA_UNORM: ++ return VKD3D_SHADER_RESOURCE_DATA_UNORM; ++ case VSIR_DATA_MIXED: + return VKD3D_SHADER_RESOURCE_DATA_MIXED; +- case VKD3D_DATA_DOUBLE: +- return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; +- case VKD3D_DATA_CONTINUED: ++ case VSIR_DATA_CONTINUED: + return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; +- case VKD3D_DATA_UNUSED: ++ case VSIR_DATA_UNUSED: + return VKD3D_SHADER_RESOURCE_DATA_NONE; + default: + ERR("Invalid resource data type %#x.\n", data_type); +@@ -1574,12 +1682,13 @@ void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor + static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, bool add_descriptor_info) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; + struct vkd3d_shader_scan_hull_shader_tessellation_info *tessellation_info; + struct vkd3d_shader_scan_descriptor_info *descriptor_info; + struct vkd3d_shader_scan_signature_info *signature_info; +- struct vkd3d_shader_instruction *instruction; + struct vkd3d_shader_scan_context context; ++ struct vkd3d_shader_instruction *ins; + int ret = VKD3D_OK; + unsigned int i; + +@@ -1607,10 +1716,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + if (TRACE_ON()) + vsir_program_trace(program); + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- instruction = &program->instructions.elements[i]; +- if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0) ++ if ((ret = vkd3d_shader_scan_instruction(&context, ins)) < 0) + break; + } + +@@ -1623,8 +1731,8 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + + if (size) + { +- if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, +- &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) ++ if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ++ ®, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) + d->buffer_size = size * 16; + } + } +@@ -1667,7 +1775,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages) + { + struct vkd3d_shader_message_context message_context; ++ struct vkd3d_shader_code reflection_data = {0}; + struct shader_dump_data dump_data; ++ struct vsir_program program; + int ret; + + TRACE("compile_info %p, messages %p.\n", compile_info, messages); +@@ -1685,21 +1795,12 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char + fill_shader_dump_data(compile_info, &dump_data); + vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); + +- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) ++ if (!(ret = vsir_parse(compile_info, vkd3d_shader_init_config_flags(), ++ &dump_data, &message_context, &program, &reflection_data))) + { +- FIXME("HLSL support not implemented.\n"); +- ret = VKD3D_ERROR_NOT_IMPLEMENTED; +- } +- else +- { +- uint64_t config_flags = vkd3d_shader_init_config_flags(); +- struct vsir_program program; +- +- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) +- { +- ret = vsir_program_scan(&program, compile_info, &message_context, false); +- vsir_program_cleanup(&program); +- } ++ ret = vsir_program_scan(&program, compile_info, &message_context, false); ++ vkd3d_shader_free_shader_code(&reflection_data); ++ vsir_program_cleanup(&program); + } + + vkd3d_shader_message_context_trace_messages(&message_context); +@@ -1709,12 +1810,13 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char + return ret; + } + +-int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, +- const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, +- struct vkd3d_shader_message_context *message_context) ++static int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, ++ uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) + { + struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info; + struct vkd3d_shader_compile_info scan_info; ++ enum vsir_asm_flags asm_flags; + int ret; + + scan_info = *compile_info; +@@ -1722,7 +1824,25 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, + switch (compile_info->target_type) + { + case VKD3D_SHADER_TARGET_D3D_ASM: +- ret = d3d_asm_compile(program, compile_info, out, VSIR_ASM_FLAG_NONE); ++ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) ++ return ret; ++ asm_flags = VSIR_ASM_FLAG_NONE; ++ if (program->shader_version.major < 6 && compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF ++ && compile_info->source_type != VKD3D_SHADER_SOURCE_D3D_BYTECODE) ++ asm_flags |= VSIR_ASM_FLAG_ALLOCATE_TEMPS; ++ ret = d3d_asm_compile(program, compile_info, out, asm_flags, message_context); ++ break; ++ ++ case VKD3D_SHADER_TARGET_D3D_BYTECODE: ++ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) ++ return ret; ++ ret = d3dbc_compile(program, config_flags, compile_info, reflection_data, out, message_context); ++ break; ++ ++ case VKD3D_SHADER_TARGET_DXBC_TPF: ++ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) ++ return ret; ++ ret = tpf_compile(program, config_flags, reflection_data, out, message_context); + break; + + case VKD3D_SHADER_TARGET_GLSL: +@@ -1757,10 +1877,11 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, + return ret; + } + +-static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, ++static int fx_compile(const struct vkd3d_shader_compile_info *compile_info, + const struct shader_dump_data *dump_data, struct vkd3d_shader_code *out, + struct vkd3d_shader_message_context *message_context) + { ++ struct vkd3d_shader_compile_info preprocessed_info; + struct vkd3d_shader_code preprocessed; + int ret; + +@@ -1769,7 +1890,9 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, + + vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC); + +- ret = hlsl_compile_shader(&preprocessed, compile_info, out, message_context); ++ preprocessed_info = *compile_info; ++ preprocessed_info.source = preprocessed; ++ ret = hlsl_compile_effect(&preprocessed_info, message_context, out); + + vkd3d_shader_free_shader_code(&preprocessed); + return ret; +@@ -1797,22 +1920,30 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, + fill_shader_dump_data(compile_info, &dump_data); + vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); + +- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) ++ if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL ++ && compile_info->target_type == VKD3D_SHADER_TARGET_FX) + { +- ret = compile_hlsl(compile_info, &dump_data, out, &message_context); ++ ret = fx_compile(compile_info, &dump_data, out, &message_context); + } + else if (compile_info->source_type == VKD3D_SHADER_SOURCE_FX) { ret = fx_parse(compile_info, out, &message_context); } @@ -19207,7 +26735,20 @@ index f56608940db..4cda8493696 100644 else { uint64_t config_flags = vkd3d_shader_init_config_flags(); -@@ -2013,6 +2041,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns ++ struct vkd3d_shader_code reflection_data = {0}; + struct vsir_program program; + +- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) ++ if (!(ret = vsir_parse(compile_info, config_flags, &dump_data, ++ &message_context, &program, &reflection_data))) + { +- ret = vsir_program_compile(&program, config_flags, compile_info, out, &message_context); ++ ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, &message_context); ++ vkd3d_shader_free_shader_code(&reflection_data); + vsir_program_cleanup(&program); + } + } +@@ -2013,6 +2144,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns VKD3D_SHADER_SOURCE_D3D_BYTECODE, VKD3D_SHADER_SOURCE_DXBC_DXIL, VKD3D_SHADER_SOURCE_FX, @@ -19215,7 +26756,17 @@ index f56608940db..4cda8493696 100644 }; TRACE("count %p.\n", count); -@@ -2077,6 +2106,11 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( +@@ -2070,6 +2202,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( + VKD3D_SHADER_TARGET_SPIRV_TEXT, + # endif + VKD3D_SHADER_TARGET_D3D_ASM, ++#ifdef VKD3D_SHADER_UNSUPPORTED_MSL ++ VKD3D_SHADER_TARGET_MSL, ++#endif + }; + + static const enum vkd3d_shader_target_type fx_types[] = +@@ -2077,6 +2212,11 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_D3D_ASM, }; @@ -19227,7 +26778,7 @@ index f56608940db..4cda8493696 100644 TRACE("source_type %#x, count %p.\n", source_type, count); switch (source_type) -@@ -2101,6 +2135,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( +@@ -2101,6 +2241,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( *count = ARRAY_SIZE(fx_types); return fx_types; @@ -19238,8 +26789,102 @@ index f56608940db..4cda8493696 100644 default: *count = 0; return NULL; +@@ -2149,7 +2293,7 @@ static struct vkd3d_shader_param_node *shader_param_allocator_node_create( + } + + static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, +- unsigned int count, unsigned int stride) ++ size_t count, size_t stride) + { + allocator->count = max(count, MAX_REG_OUTPUT); + allocator->stride = stride; +@@ -2170,7 +2314,7 @@ static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator * + } + } + +-void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count) ++void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) + { + void *params; + +@@ -2196,18 +2340,18 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, + return params; + } + +-bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve) ++bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve) + { + memset(instructions, 0, sizeof(*instructions)); + /* Size the parameter initial allocations so they are large enough for most shaders. The + * code path for chained allocations will be tested if a few shaders need to use it. */ + shader_param_allocator_init(&instructions->dst_params, reserve - reserve / 8u, +- sizeof(*instructions->elements->dst)); +- shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(*instructions->elements->src)); ++ sizeof(struct vkd3d_shader_dst_param)); ++ shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); + return shader_instruction_array_reserve(instructions, reserve); + } + +-bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve) ++bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve) + { + if (!vkd3d_array_reserve((void **)&instructions->elements, &instructions->capacity, reserve, + sizeof(*instructions->elements))) +@@ -2219,7 +2363,7 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins + } + + bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, +- unsigned int idx, unsigned int count) ++ size_t idx, size_t count) + { + VKD3D_ASSERT(idx <= instructions->count); + +@@ -2247,7 +2391,7 @@ bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *ins + + static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( + struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, +- unsigned int count); ++ size_t count); + + static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, + struct vkd3d_shader_instruction_array *instructions) +@@ -2268,10 +2412,10 @@ static bool shader_register_clone_relative_addresses(struct vkd3d_shader_registe + + static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( + struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_dst_param *params, +- unsigned int count) ++ size_t count) + { + struct vkd3d_shader_dst_param *dst_params; +- unsigned int i; ++ size_t i; + + if (!(dst_params = shader_dst_param_allocator_get(&instructions->dst_params, count))) + return NULL; +@@ -2288,10 +2432,10 @@ static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( + + static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( + struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, +- unsigned int count) ++ size_t count) + { + struct vkd3d_shader_src_param *src_params; +- unsigned int i; ++ size_t i; + + if (!(src_params = shader_src_param_allocator_get(&instructions->src_params, count))) + return NULL; +@@ -2309,7 +2453,7 @@ static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( + /* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the + * destination is in use. This seems like a reasonable requirement given how this is currently used. */ + bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, +- unsigned int dst, unsigned int src) ++ size_t dst, size_t src) + { + struct vkd3d_shader_instruction *ins = &instructions->elements[dst]; + diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 3b4fb626fcc..5d7fc6e1209 100644 +index 3b4fb626fcc..e758c16b3d4 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -174,6 +174,7 @@ enum vkd3d_shader_error @@ -19250,15 +26895,16 @@ index 3b4fb626fcc..5d7fc6e1209 100644 VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, -@@ -182,6 +183,7 @@ enum vkd3d_shader_error +@@ -182,6 +183,8 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT = 5304, VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305, VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE = 5306, + VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER = 5307, ++ VKD3D_SHADER_WARNING_HLSL_OVERRIDDEN_SEMANTIC = 5308, VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND = 6001, -@@ -222,6 +224,7 @@ enum vkd3d_shader_error +@@ -222,6 +225,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, @@ -19266,7 +26912,7 @@ index 3b4fb626fcc..5d7fc6e1209 100644 VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, -@@ -236,7 +239,7 @@ enum vkd3d_shader_error +@@ -236,7 +240,7 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_DXIL_UNDEFINED_OPERAND = 8310, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, @@ -19275,7 +26921,15 @@ index 3b4fb626fcc..5d7fc6e1209 100644 VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE = 9002, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK = 9003, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS = 9004, -@@ -278,334 +281,345 @@ enum vkd3d_shader_error +@@ -262,6 +266,7 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE = 9024, + VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE = 9025, + VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT = 9026, ++ VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS = 9027, + + VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300, + +@@ -278,334 +283,345 @@ enum vkd3d_shader_error enum vkd3d_shader_opcode { @@ -19949,7 +27603,127 @@ index 3b4fb626fcc..5d7fc6e1209 100644 enum vkd3d_shader_register_type { -@@ -964,7 +978,7 @@ struct vkd3d_shader_register +@@ -692,46 +708,51 @@ enum vkd3d_shader_register_precision + VKD3D_SHADER_REGISTER_PRECISION_INVALID = ~0u, + }; + +-enum vkd3d_data_type ++enum vsir_data_type + { +- VKD3D_DATA_FLOAT, +- VKD3D_DATA_INT, +- VKD3D_DATA_UINT, +- VKD3D_DATA_UNORM, +- VKD3D_DATA_SNORM, +- VKD3D_DATA_OPAQUE, +- VKD3D_DATA_MIXED, +- VKD3D_DATA_DOUBLE, +- VKD3D_DATA_CONTINUED, +- VKD3D_DATA_UNUSED, +- VKD3D_DATA_UINT8, +- VKD3D_DATA_UINT64, +- VKD3D_DATA_BOOL, +- VKD3D_DATA_UINT16, +- VKD3D_DATA_HALF, ++ VSIR_DATA_BOOL, ++ ++ VSIR_DATA_F16, ++ VSIR_DATA_F32, ++ VSIR_DATA_F64, ++ ++ VSIR_DATA_I32, ++ ++ VSIR_DATA_U8, ++ VSIR_DATA_U16, ++ VSIR_DATA_U32, ++ VSIR_DATA_U64, ++ ++ VSIR_DATA_SNORM, ++ VSIR_DATA_UNORM, ++ ++ VSIR_DATA_OPAQUE, ++ VSIR_DATA_MIXED, ++ VSIR_DATA_CONTINUED, ++ VSIR_DATA_UNUSED, + +- VKD3D_DATA_COUNT, ++ VSIR_DATA_TYPE_COUNT, + }; + +-static inline bool data_type_is_integer(enum vkd3d_data_type data_type) ++static inline bool data_type_is_integer(enum vsir_data_type data_type) + { +- return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT16 +- || data_type == VKD3D_DATA_UINT || data_type == VKD3D_DATA_UINT64; ++ return data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 ++ || data_type == VSIR_DATA_U32 || data_type == VSIR_DATA_U64; + } + +-static inline bool data_type_is_bool(enum vkd3d_data_type data_type) ++static inline bool data_type_is_bool(enum vsir_data_type data_type) + { +- return data_type == VKD3D_DATA_BOOL; ++ return data_type == VSIR_DATA_BOOL; + } + +-static inline bool data_type_is_floating_point(enum vkd3d_data_type data_type) ++static inline bool data_type_is_floating_point(enum vsir_data_type data_type) + { +- return data_type == VKD3D_DATA_HALF || data_type == VKD3D_DATA_FLOAT || data_type == VKD3D_DATA_DOUBLE; ++ return data_type == VSIR_DATA_F16 || data_type == VSIR_DATA_F32 || data_type == VSIR_DATA_F64; + } + +-static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type) ++static inline bool data_type_is_64_bit(enum vsir_data_type data_type) + { +- return data_type == VKD3D_DATA_DOUBLE || data_type == VKD3D_DATA_UINT64; ++ return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_U64; + } + + enum vsir_dimension +@@ -916,6 +937,16 @@ enum vkd3d_shader_type + + struct vkd3d_shader_message_context; + ++struct vkd3d_shader_source_list ++{ ++ const char **sources; ++ size_t capacity, count; ++}; ++ ++bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source); ++void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l); ++void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l); ++ + struct vkd3d_shader_version + { + enum vkd3d_shader_type type; +@@ -926,7 +957,7 @@ struct vkd3d_shader_version + struct vkd3d_shader_immediate_constant_buffer + { + unsigned int register_idx; +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + /* total count is element_count * component_count */ + unsigned int element_count; + unsigned int component_count; +@@ -939,7 +970,7 @@ struct vkd3d_shader_indexable_temp + unsigned int register_idx; + unsigned int register_size; + unsigned int alignment; +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + unsigned int component_count; + bool has_function_scope; + const struct vkd3d_shader_immediate_constant_buffer *initialiser; +@@ -958,13 +989,13 @@ struct vkd3d_shader_register + enum vkd3d_shader_register_type type; + enum vkd3d_shader_register_precision precision; + bool non_uniform; +- enum vkd3d_data_type data_type; ++ enum vsir_data_type data_type; + struct vkd3d_shader_register_index idx[3]; + unsigned int idx_count; enum vsir_dimension dimension; /* known address alignment for optimisation, or zero */ unsigned int alignment; @@ -19958,7 +27732,76 @@ index 3b4fb626fcc..5d7fc6e1209 100644 { uint32_t immconst_u32[VKD3D_VEC4_SIZE]; float immconst_f32[VKD3D_VEC4_SIZE]; -@@ -1332,12 +1346,6 @@ static inline bool register_is_constant_or_undef(const struct vkd3d_shader_regis +@@ -975,7 +1006,7 @@ struct vkd3d_shader_register + }; + + void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, +- enum vkd3d_data_type data_type, unsigned int idx_count); ++ enum vsir_data_type data_type, unsigned int idx_count); + + static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_register *reg) + { +@@ -992,6 +1023,20 @@ static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_registe + } + } + ++static inline enum vkd3d_shader_register_type vsir_register_type_from_sysval_input( ++ enum vkd3d_shader_sysval_semantic sysval) ++{ ++ switch (sysval) ++ { ++ case VKD3D_SHADER_SV_PRIMITIVE_ID: ++ return VKD3DSPR_PRIMID; ++ case VKD3D_SHADER_SV_COVERAGE: ++ return VKD3DSPR_COVERAGE; ++ default: ++ return VKD3DSPR_INPUT; ++ } ++} ++ + struct vkd3d_shader_dst_param + { + struct vkd3d_shader_register reg; +@@ -1008,9 +1053,9 @@ struct vkd3d_shader_src_param + }; + + void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, +- enum vkd3d_data_type data_type, unsigned int idx_count); ++ enum vsir_data_type data_type, unsigned int idx_count); + void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, +- enum vkd3d_data_type data_type, unsigned int idx_count); ++ enum vsir_data_type data_type, unsigned int idx_count); + void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst); + void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id); + +@@ -1056,7 +1101,7 @@ struct vkd3d_shader_semantic + unsigned int usage_idx; + enum vkd3d_shader_resource_type resource_type; + unsigned int sample_count; +- enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE]; ++ enum vsir_data_type resource_data_type[VKD3D_VEC4_SIZE]; + struct vkd3d_shader_resource resource; + }; + +@@ -1262,14 +1307,14 @@ struct vkd3d_shader_instruction + struct vkd3d_shader_location location; + enum vkd3d_shader_opcode opcode; + uint32_t flags; +- unsigned int dst_count; +- unsigned int src_count; ++ size_t dst_count; ++ size_t src_count; + struct vkd3d_shader_dst_param *dst; + struct vkd3d_shader_src_param *src; + struct vkd3d_shader_texel_offset texel_offset; + enum vkd3d_shader_resource_type resource_type; + unsigned int resource_stride; +- enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE]; ++ enum vsir_data_type resource_data_type[VKD3D_VEC4_SIZE]; + bool coissue, structured, raw; + const struct vkd3d_shader_src_param *predicate; + union +@@ -1332,12 +1377,6 @@ static inline bool register_is_constant_or_undef(const struct vkd3d_shader_regis return register_is_constant(reg) || register_is_undef(reg); } @@ -19971,16 +27814,196 @@ index 3b4fb626fcc..5d7fc6e1209 100644 static inline bool register_is_numeric_array(const struct vkd3d_shader_register *reg) { return (reg->type == VKD3DSPR_IMMCONSTBUFFER || reg->type == VKD3DSPR_IDXTEMP -@@ -1500,6 +1508,8 @@ struct vsir_program +@@ -1364,22 +1403,22 @@ struct vkd3d_shader_param_allocator + { + struct vkd3d_shader_param_node *head; + struct vkd3d_shader_param_node *current; +- unsigned int count; +- unsigned int stride; +- unsigned int index; ++ size_t count; ++ size_t stride; ++ size_t index; + }; + +-void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count); ++void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count); + + static inline struct vkd3d_shader_src_param *shader_src_param_allocator_get( +- struct vkd3d_shader_param_allocator *allocator, unsigned int count) ++ struct vkd3d_shader_param_allocator *allocator, size_t count) + { + VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_src_param)); + return shader_param_allocator_get(allocator, count); + } + + static inline struct vkd3d_shader_dst_param *shader_dst_param_allocator_get( +- struct vkd3d_shader_param_allocator *allocator, unsigned int count) ++ struct vkd3d_shader_param_allocator *allocator, size_t count) + { + VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_dst_param)); + return shader_param_allocator_get(allocator, count); +@@ -1400,16 +1439,77 @@ struct vkd3d_shader_instruction_array + struct vkd3d_shader_src_param *outpointid_param; + }; + +-bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); +-bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); ++bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve); ++bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve); + bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, +- unsigned int idx, unsigned int count); ++ size_t idx, size_t count); + bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, + struct vkd3d_shader_immediate_constant_buffer *icb); + bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, +- unsigned int dst, unsigned int src); ++ size_t dst, size_t src); + void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); + ++struct vsir_program_iterator ++{ ++ struct vkd3d_shader_instruction_array *array; ++ size_t idx; ++}; ++ ++static inline struct vsir_program_iterator vsir_program_iterator(struct vkd3d_shader_instruction_array *array) ++{ ++ return (struct vsir_program_iterator){ .array = array }; ++} ++ ++static inline struct vkd3d_shader_instruction *vsir_program_iterator_current( ++ struct vsir_program_iterator *iterator) ++{ ++ if (iterator->idx >= iterator->array->count) ++ return NULL; ++ ++ return &iterator->array->elements[iterator->idx]; ++} ++ ++static inline struct vkd3d_shader_instruction *vsir_program_iterator_head( ++ struct vsir_program_iterator *iterator) ++{ ++ iterator->idx = 0; ++ ++ return vsir_program_iterator_current(iterator); ++} ++ ++static inline struct vkd3d_shader_instruction *vsir_program_iterator_tail(struct vsir_program_iterator *iterator) ++{ ++ iterator->idx = iterator->array->count - 1; ++ ++ return vsir_program_iterator_current(iterator); ++} ++ ++static inline struct vkd3d_shader_instruction *vsir_program_iterator_next( ++ struct vsir_program_iterator *iterator) ++{ ++ if (iterator->idx < iterator->array->count || iterator->idx == SIZE_MAX) ++ ++iterator->idx; ++ ++ return vsir_program_iterator_current(iterator); ++} ++ ++static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev( ++ struct vsir_program_iterator *iterator) ++{ ++ if (iterator->idx != SIZE_MAX) ++ --iterator->idx; ++ ++ return vsir_program_iterator_current(iterator); ++} ++ ++/* When insertion takes place, argument `it' is updated to point to the same ++ * instruction as before the insertion, but all other iterators and pointers ++ * to the same container are invalidated and cannot be used any more. */ ++static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterator *it, size_t count) ++{ ++ return shader_instruction_array_insert_at(it->array, it->idx + 1, count); ++} ++ + enum vkd3d_shader_config_flags + { + VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, +@@ -1436,7 +1536,7 @@ struct vkd3d_shader_descriptor_info1 + unsigned int register_index; + unsigned int register_id; + enum vkd3d_shader_resource_type resource_type; +- enum vkd3d_data_type resource_data_type; ++ enum vsir_data_type resource_data_type; + unsigned int flags; + unsigned int sample_count; + unsigned int buffer_size; +@@ -1496,19 +1596,23 @@ struct vsir_program + + struct vsir_features features; + ++ struct vkd3d_shader_source_list source_files; + const char **block_names; size_t block_name_count; }; +-void vsir_program_cleanup(struct vsir_program *program); +-int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, +- const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, +enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context); - void vsir_program_cleanup(struct vsir_program *program); - int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, -@@ -1682,6 +1692,8 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con ++enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context); ++void vsir_program_cleanup(struct vsir_program *program); + const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( + const struct vsir_program *program, enum vkd3d_shader_parameter_name name); + bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, + const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type, + enum vsir_normalisation_level normalisation_level); ++enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, ++ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context); + enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context); + enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags, +@@ -1521,6 +1625,16 @@ bool vsir_instruction_init_with_params(struct vsir_program *program, + struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, + enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count); + ++static inline struct vkd3d_shader_instruction *vsir_program_append(struct vsir_program *program) ++{ ++ struct vkd3d_shader_instruction_array *array = &program->instructions; ++ ++ if (!shader_instruction_array_insert_at(array, array->count, 1)) ++ return NULL; ++ ++ return &array->elements[array->count - 1]; ++} ++ + static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params( + struct vsir_program *program, unsigned int count) + { +@@ -1548,7 +1662,7 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr + void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, + enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); + +-void vsir_program_trace(const struct vsir_program *program); ++void vsir_program_trace(struct vsir_program *program); + + const char *shader_get_type_prefix(enum vkd3d_shader_type type); + +@@ -1571,11 +1685,12 @@ enum vsir_asm_flags + VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2, + VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4, + VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8, ++ VSIR_ASM_FLAG_ALLOCATE_TEMPS = 0x10, + }; + +-enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, +- const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_code *out, enum vsir_asm_flags flags); ++enum vkd3d_result d3d_asm_compile(struct vsir_program *program, ++ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, ++ enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context); + void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer); + struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list); + void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer); +@@ -1682,6 +1797,8 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con struct vkd3d_shader_message_context *message_context, struct vsir_program *program); int fx_parse(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); @@ -19989,7 +28012,88 @@ index 3b4fb626fcc..5d7fc6e1209 100644 void free_dxbc_shader_desc(struct dxbc_shader_desc *desc); -@@ -1779,14 +1791,6 @@ static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type com +@@ -1723,54 +1840,55 @@ void vkd3d_compute_md5(const void *dxbc, size_t size, uint32_t checksum[4], enum + int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); + +-int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); ++int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); ++int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_message_context *message_context, ++ struct vsir_program *program, struct vkd3d_shader_code *reflection_data); + +-static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( +- enum vkd3d_data_type data_type) ++static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) + { + switch (data_type) + { +- case VKD3D_DATA_HALF: /* Minimum precision. TODO: native 16-bit */ +- case VKD3D_DATA_FLOAT: +- case VKD3D_DATA_UNORM: +- case VKD3D_DATA_SNORM: ++ case VSIR_DATA_BOOL: ++ return VKD3D_SHADER_COMPONENT_BOOL; ++ case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */ ++ case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: + return VKD3D_SHADER_COMPONENT_FLOAT; +- case VKD3D_DATA_UINT16: /* Minimum precision. TODO: native 16-bit */ +- case VKD3D_DATA_UINT: +- return VKD3D_SHADER_COMPONENT_UINT; +- case VKD3D_DATA_INT: +- return VKD3D_SHADER_COMPONENT_INT; +- case VKD3D_DATA_DOUBLE: ++ case VSIR_DATA_F64: + return VKD3D_SHADER_COMPONENT_DOUBLE; +- case VKD3D_DATA_UINT64: ++ case VSIR_DATA_I32: ++ return VKD3D_SHADER_COMPONENT_INT; ++ case VSIR_DATA_U16: /* Minimum precision. TODO: native 16-bit */ ++ case VSIR_DATA_U32: ++ return VKD3D_SHADER_COMPONENT_UINT; ++ case VSIR_DATA_U64: + return VKD3D_SHADER_COMPONENT_UINT64; +- case VKD3D_DATA_BOOL: +- return VKD3D_SHADER_COMPONENT_BOOL; + default: + FIXME("Unhandled data type %#x.\n", data_type); + /* fall-through */ +- case VKD3D_DATA_MIXED: ++ case VSIR_DATA_MIXED: + return VKD3D_SHADER_COMPONENT_UINT; + } + } + +-static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( +- enum vkd3d_shader_component_type component_type) ++static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_shader_component_type component_type) + { + switch (component_type) + { + case VKD3D_SHADER_COMPONENT_FLOAT: +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + case VKD3D_SHADER_COMPONENT_UINT: +- return VKD3D_DATA_UINT; ++ return VSIR_DATA_U32; + case VKD3D_SHADER_COMPONENT_INT: +- return VKD3D_DATA_INT; ++ return VSIR_DATA_I32; + case VKD3D_SHADER_COMPONENT_DOUBLE: +- return VKD3D_DATA_DOUBLE; ++ return VSIR_DATA_F64; + default: + FIXME("Unhandled component type %#x.\n", component_type); +- return VKD3D_DATA_FLOAT; ++ return VSIR_DATA_F32; + } + } + +@@ -1779,14 +1897,6 @@ static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type com return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; } @@ -20004,7 +28108,7 @@ index 3b4fb626fcc..5d7fc6e1209 100644 static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) { unsigned int i; -@@ -1853,6 +1857,8 @@ static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64) +@@ -1853,6 +1963,8 @@ static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64) } } @@ -20013,7 +28117,7 @@ index 3b4fb626fcc..5d7fc6e1209 100644 static inline uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32) { switch (swizzle32) -@@ -1902,6 +1908,12 @@ static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned +@@ -1902,6 +2014,12 @@ static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK; } @@ -20039,6 +28143,80 @@ index f2b18b665f8..c41f8bae806 100644 static const char *debug_d3d_blob_part(D3D_BLOB_PART part) { switch (part) +diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c +index e487ed0b9ad..074d8430585 100644 +--- a/libs/vkd3d/libs/vkd3d/command.c ++++ b/libs/vkd3d/libs/vkd3d/command.c +@@ -4221,13 +4221,21 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo + TRACE("iface %p, viewport_count %u, viewports %p.\n", iface, viewport_count, viewports); + + if (viewport_count > ARRAY_SIZE(vk_viewports)) +- { + FIXME("Viewport count %u > D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE.\n", viewport_count); +- viewport_count = ARRAY_SIZE(vk_viewports); +- } + +- for (i = 0; i < viewport_count; ++i) ++ for (i = 0; i < ARRAY_SIZE(vk_viewports); ++i) + { ++ if (i >= viewport_count) ++ { ++ vk_viewports[i].x = 0.0f; ++ vk_viewports[i].y = 0.0f; ++ vk_viewports[i].width = 1.0f; ++ vk_viewports[i].height = 1.0f; ++ vk_viewports[i].minDepth = 0.0f; ++ vk_viewports[i].maxDepth = 0.0f; ++ continue; ++ } ++ + vk_viewports[i].x = viewports[i].TopLeftX; + vk_viewports[i].y = viewports[i].TopLeftY + viewports[i].Height; + vk_viewports[i].width = viewports[i].Width; +@@ -4245,7 +4253,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo + } + + vk_procs = &list->device->vk_procs; +- VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports)); ++ VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, ARRAY_SIZE(vk_viewports), vk_viewports)); + } + + static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList6 *iface, +@@ -4264,6 +4272,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic + rect_count = ARRAY_SIZE(vk_rects); + } + ++ memset(vk_rects, 0, sizeof(vk_rects)); + for (i = 0; i < rect_count; ++i) + { + vk_rects[i].offset.x = rects[i].left; +@@ -4273,7 +4282,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic + } + + vk_procs = &list->device->vk_procs; +- VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects)); ++ VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, ARRAY_SIZE(vk_rects), vk_rects)); + } + + static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList6 *iface, +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index b2636fd5585..67f84aafa29 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -5193,7 +5193,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device + FIXME("iface %p, num_meta_commands %p, command_desc %p stub!\n", iface, + num_meta_commands, command_desc); + +- return E_NOTIMPL; ++ if (!num_meta_commands) ++ return E_INVALIDARG; ++ ++ *num_meta_commands = 0; ++ ++ return S_OK; + } + + static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device9 *iface, diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c index cb184986f2a..7946445ad07 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c @@ -20207,7 +28385,7 @@ index cb184986f2a..7946445ad07 100644 struct d3d12_device *device, const D3D12_DESCRIPTOR_HEAP_DESC *desc) { diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 819185796c0..0a5bd1122e3 100644 +index 819185796c0..413892789ba 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c @@ -2383,7 +2383,9 @@ static HRESULT create_shader_stage(struct d3d12_device *device, @@ -20237,6 +28415,52 @@ index 819185796c0..0a5bd1122e3 100644 if ((ret = vkd3d_shader_parse_dxbc_source_type(&compile_info.source, &compile_info.source_type, NULL)) < 0 || (ret = vkd3d_shader_compile(&compile_info, &spirv, NULL)) < 0) { +@@ -3220,17 +3232,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s + uint32_t mask; + HRESULT hr; + +- static const DWORD default_ps_code[] = +- { +-#if 0 +- ps_4_0 +- ret +-#endif +- 0x43425844, 0x19cbf606, 0x18f562b9, 0xdaeed4db, 0xc324aa46, 0x00000001, 0x00000060, 0x00000003, +- 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, +- 0x00000008, 0x00000000, 0x00000008, 0x52444853, 0x0000000c, 0x00000040, 0x00000003, 0x0100003e, +- }; +- static const D3D12_SHADER_BYTECODE default_ps = {default_ps_code, sizeof(default_ps_code)}; + static const struct + { + enum VkShaderStageFlagBits stage; +@@ -3389,11 +3390,10 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s + + if (!desc->ps.pShaderBytecode) + { +- if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count], +- VK_SHADER_STAGE_FRAGMENT_BIT, &default_ps, NULL))) +- goto fail; +- +- ++graphics->stage_count; ++ for (i = 0; i < rt_count; i++) ++ { ++ graphics->blend_attachments[i].colorWriteMask = 0; ++ } + } + } + +@@ -3971,9 +3971,9 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pNext = NULL, + .flags = 0, +- .viewportCount = 1, ++ .viewportCount = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, + .pViewports = NULL, +- .scissorCount = 1, ++ .scissorCount = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, + .pScissors = NULL, + }; + static const VkDynamicState dynamic_states[] = diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h index 7e54738b19e..9fb6834158f 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch new file mode 100644 index 00000000..c4522449 --- /dev/null +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch @@ -0,0 +1,2042 @@ +From 9385c0987fde1070c8e9e1054c57fa16eeab2c7d Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Fri, 22 Aug 2025 07:26:18 +1000 +Subject: [PATCH] Updated vkd3d to 3b41d99fa9e80dda5844738a226f70f14f778c8b. + +--- + libs/vkd3d/include/vkd3d.h | 1 + + libs/vkd3d/include/vkd3d_shader.h | 24 ++ + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 34 ++- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 73 ++--- + libs/vkd3d/libs/vkd3d-shader/fx.c | 2 +- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 1 + + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 70 +++++ + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 9 + + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 48 +++ + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 281 +++++++++++++++++- + .../libs/vkd3d-shader/hlsl_constant_ops.c | 83 +----- + libs/vkd3d/libs/vkd3d-shader/ir.c | 208 ++++++------- + libs/vkd3d/libs/vkd3d-shader/msl.c | 1 + + libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 39 +-- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 15 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 3 +- + .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 6 +- + libs/vkd3d/libs/vkd3d/state.c | 6 +- + 19 files changed, 640 insertions(+), 266 deletions(-) + +diff --git a/libs/vkd3d/include/vkd3d.h b/libs/vkd3d/include/vkd3d.h +index 2cb150dce16..8286f36f6ba 100644 +--- a/libs/vkd3d/include/vkd3d.h ++++ b/libs/vkd3d/include/vkd3d.h +@@ -101,6 +101,7 @@ enum vkd3d_api_version + VKD3D_API_VERSION_1_14, + VKD3D_API_VERSION_1_15, + VKD3D_API_VERSION_1_16, ++ VKD3D_API_VERSION_1_17, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_API_VERSION), + }; +diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h +index 0fd3c67b7e0..a1f85dbbd05 100644 +--- a/libs/vkd3d/include/vkd3d_shader.h ++++ b/libs/vkd3d/include/vkd3d_shader.h +@@ -59,6 +59,7 @@ enum vkd3d_shader_api_version + VKD3D_SHADER_API_VERSION_1_14, + VKD3D_SHADER_API_VERSION_1_15, + VKD3D_SHADER_API_VERSION_1_16, ++ VKD3D_SHADER_API_VERSION_1_17, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_API_VERSION), + }; +@@ -119,6 +120,11 @@ enum vkd3d_shader_structure_type + * \since 1.15 + */ + VKD3D_SHADER_STRUCTURE_TYPE_SCAN_HULL_SHADER_TESSELLATION_INFO, ++ /** ++ * The structure is a vkd3d_shader_scan_thread_group_size_info structure. ++ * \since 1.18 ++ */ ++ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), + }; +@@ -2281,6 +2287,24 @@ struct vkd3d_shader_scan_hull_shader_tessellation_info + enum vkd3d_shader_tessellator_partitioning partitioning; + }; + ++/** ++ * A chained structure describing the thread group size in a compute shader. ++ * ++ * This structure extends vkd3d_shader_compile_info. ++ * ++ * \since 1.18 ++ */ ++struct vkd3d_shader_scan_thread_group_size_info ++{ ++ /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO. */ ++ enum vkd3d_shader_structure_type type; ++ /** Optional pointer to a structure containing further parameters. */ ++ const void *next; ++ ++ /** The thread group size in the x/y/z direction. */ ++ unsigned int x, y, z; ++}; ++ + /** + * Data type of a shader varying, returned as part of struct + * vkd3d_shader_signature_element. +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index 751e5578276..0272271b782 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -246,6 +246,7 @@ struct vkd3d_shader_sm1_parser + bool abort; + + struct vkd3d_shader_parser p; ++ struct vsir_program *program; + + struct + { +@@ -468,7 +469,7 @@ static bool has_relative_address(uint32_t param) + static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info( + const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode) + { +- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; ++ const struct vkd3d_shader_version *version = &sm1->program->shader_version; + const struct vkd3d_sm1_opcode_info *info; + unsigned int i = 0; + +@@ -542,9 +543,9 @@ static enum vkd3d_shader_register_type parse_register_type( + } + + if (d3dbc_type == VKD3D_SM1_REG_ADDR) +- return sm1->p.program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; ++ return sm1->program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; + if (d3dbc_type == VKD3D_SM1_REG_TEXCRDOUT) +- return vkd3d_shader_ver_ge(&sm1->p.program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; ++ return vkd3d_shader_ver_ge(&sm1->program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; + + for (unsigned int i = 0; i < ARRAY_SIZE(register_types); ++i) + { +@@ -660,7 +661,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp + const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval, + unsigned int register_index, bool is_dcl, unsigned int mask) + { +- struct vsir_program *program = sm1->p.program; ++ struct vsir_program *program = sm1->program; + struct shader_signature *signature; + struct signature_element *element; + +@@ -702,7 +703,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp + static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, + unsigned int register_index, unsigned int mask) + { +- struct vsir_program *program = sm1->p.program; ++ struct vsir_program *program = sm1->program; + struct shader_signature *signature; + struct signature_element *element; + +@@ -749,7 +750,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, + static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1, + const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) + { +- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; ++ const struct vkd3d_shader_version *version = &sm1->program->shader_version; + unsigned int register_index = reg->idx_count > 0 ? reg->idx[0].offset : 0; + + switch (reg->type) +@@ -844,7 +845,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * + static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1, + const struct vkd3d_shader_semantic *semantic) + { +- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; ++ const struct vkd3d_shader_version *version = &sm1->program->shader_version; + const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg; + enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; + unsigned int mask = semantic->resource.reg.write_mask; +@@ -906,7 +907,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, + static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, + const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def) + { +- struct vsir_program *program = sm1->p.program; ++ struct vsir_program *program = sm1->program; + uint32_t register_index = reg->idx[0].offset; + + switch (reg->type) +@@ -955,7 +956,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, + * VS >= 2.0 have relative addressing (with token) + * VS >= 1.0 < 2.0 have relative addressing (without token) + * The version check below should work in general. */ +- if (sm1->p.program->shader_version.major < 2) ++ if (sm1->program->shader_version.major < 2) + { + *addr_token = (1u << 31) + | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2) +@@ -984,7 +985,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co + /* Version 2.0+ shaders may contain address tokens, but fortunately they + * have a useful length mask - use it here. Version 1.x shaders contain no + * such tokens. */ +- if (sm1->p.program->shader_version.major >= 2) ++ if (sm1->program->shader_version.major >= 2) + { + length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; + *ptr += length; +@@ -1019,7 +1020,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const + shader_sm1_read_param(sm1, ptr, &token, &addr_token); + if (has_relative_address(token)) + { +- if (!(src_rel_addr = vsir_program_get_src_params(sm1->p.program, 1))) ++ if (!(src_rel_addr = vsir_program_get_src_params(sm1->program, 1))) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Out of memory."); +@@ -1040,7 +1041,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const + shader_sm1_read_param(sm1, ptr, &token, &addr_token); + if (has_relative_address(token)) + { +- if (!(dst_rel_addr = vsir_program_get_src_params(sm1->p.program, 1))) ++ if (!(dst_rel_addr = vsir_program_get_src_params(sm1->program, 1))) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Out of memory."); +@@ -1052,9 +1053,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const + shader_sm1_parse_dst_param(sm1, token, dst_rel_addr, dst_param); + + if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_POINT_SIZE) +- sm1->p.program->has_point_size = true; ++ sm1->program->has_point_size = true; + if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_FOG) +- sm1->p.program->has_fog = true; ++ sm1->program->has_fog = true; + } + + static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, +@@ -1214,7 +1215,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + { + struct vkd3d_shader_src_param *src_params, *predicate; + const struct vkd3d_sm1_opcode_info *opcode_info; +- struct vsir_program *program = sm1->p.program; ++ struct vsir_program *program = sm1->program; + unsigned int vsir_dst_count, vsir_src_count; + struct vkd3d_shader_dst_param *dst_param; + const uint32_t **ptr = &sm1->ptr; +@@ -1446,7 +1447,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st + code_size != ~(size_t)0 ? token_count / 4u + 4 : 16, VSIR_CF_STRUCTURED, normalisation_level)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name); ++ vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name); ++ sm1->program = program; + sm1->ptr = sm1->start; + + return VKD3D_OK; +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index c448e000cf9..6a12dec14bf 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -892,6 +892,8 @@ struct sm6_parser + const uint32_t *ptr, *start, *end; + unsigned int bitpos; + ++ struct vsir_program *program; ++ + struct dxil_block root_block; + struct dxil_block *current_block; + +@@ -2437,7 +2439,7 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ + { + struct vkd3d_shader_src_param *params; + +- if (!(params = vsir_program_get_src_params(sm6->p.program, count))) ++ if (!(params = vsir_program_get_src_params(sm6->program, count))) + { + ERR("Failed to allocate src params.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +@@ -2454,7 +2456,7 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ + { + struct vkd3d_shader_dst_param *params; + +- if (!(params = vsir_program_get_dst_params(sm6->p.program, count))) ++ if (!(params = vsir_program_get_dst_params(sm6->program, count))) + { + ERR("Failed to allocate dst params.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +@@ -2756,7 +2758,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, + } + else + { +- struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1); ++ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->program, 1); + if (rel_addr) + src_param_init_from_value(rel_addr, address, sm6); + idx->offset = 0; +@@ -3224,7 +3226,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co + "Out of memory allocating an immediate constant buffer of count %u.", count); + return VKD3D_ERROR_OUT_OF_MEMORY; + } +- if (!shader_instruction_array_add_icb(&sm6->p.program->instructions, icb)) ++ if (!shader_instruction_array_add_icb(&sm6->program->instructions, icb)) + { + ERR("Failed to store icb object.\n"); + vkd3d_free(icb); +@@ -3653,7 +3655,7 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al + + static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra) + { +- struct vkd3d_shader_instruction_array *instructions = &sm6->p.program->instructions; ++ struct vkd3d_shader_instruction_array *instructions = &sm6->program->instructions; + + if (!shader_instruction_array_reserve(instructions, instructions->count + extra)) + { +@@ -3670,7 +3672,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa + struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); + VKD3D_ASSERT(ins); + vsir_instruction_init(ins, &sm6->p.location, handler_idx); +- ++sm6->p.program->instructions.count; ++ ++sm6->program->instructions.count; + return ins; + } + +@@ -3969,7 +3971,7 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm + + static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + { +- struct vsir_program_iterator it = vsir_program_iterator(&sm6->p.program->instructions); ++ struct vsir_program_iterator it = vsir_program_iterator(&sm6->program->instructions); + size_t i, count, base_value_idx = sm6->value_count; + const struct dxil_block *block = &sm6->root_block; + struct vkd3d_shader_instruction *ins; +@@ -4125,7 +4127,7 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( + static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, + bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) + { +- enum vkd3d_shader_type shader_type = sm6->p.program->shader_version.type; ++ enum vkd3d_shader_type shader_type = sm6->program->shader_version.type; + enum vkd3d_shader_register_type io_reg_type; + bool is_patch_constant, is_control_point; + struct vkd3d_shader_dst_param *param; +@@ -4175,7 +4177,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade + if (is_control_point) + { + if (reg_type == VKD3DSPR_OUTPUT) +- param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->p.program); ++ param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->program); + param->reg.idx[count++].offset = 0; + } + +@@ -4190,7 +4192,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade + + static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) + { +- if (!(sm6->output_params = vsir_program_get_dst_params(sm6->p.program, output_signature->element_count))) ++ if (!(sm6->output_params = vsir_program_get_dst_params(sm6->program, output_signature->element_count))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Failed to allocate output parameters."); +@@ -4204,7 +4206,7 @@ static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct + + static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature) + { +- if (!(sm6->input_params = vsir_program_get_dst_params(sm6->p.program, input_signature->element_count))) ++ if (!(sm6->input_params = vsir_program_get_dst_params(sm6->program, input_signature->element_count))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Failed to allocate input parameters."); +@@ -4219,9 +4221,9 @@ static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct + static int sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6, + const struct shader_signature *patch_constant_signature) + { +- bool is_input = sm6->p.program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; ++ bool is_input = sm6->program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; + +- if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->p.program, ++ if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->program, + patch_constant_signature->element_count))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +@@ -5407,7 +5409,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri + 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; ++ signature = &sm6->program->input_signature; + if (row_index >= signature->element_count) + { + WARN("Invalid row index %u.\n", row_index); +@@ -5638,7 +5640,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin + bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT; + bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT; + struct vkd3d_shader_instruction *ins = state->ins; +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + unsigned int count, row_index, column_index; + const struct vkd3d_shader_dst_param *params; + struct vkd3d_shader_src_param *src_param; +@@ -6148,7 +6150,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ + static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) + { +- const struct shader_signature *signature = &sm6->p.program->input_signature; ++ const struct shader_signature *signature = &sm6->program->input_signature; + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + unsigned int element_idx; +@@ -6207,7 +6209,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr + { + bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT; + struct vkd3d_shader_instruction *ins = state->ins; +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + struct vkd3d_shader_src_param *src_param; + struct vkd3d_shader_dst_param *dst_param; + const struct shader_signature *signature; +@@ -8206,7 +8208,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun + static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, + struct sm6_function *function) + { +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + struct vkd3d_shader_instruction *ins; + size_t i, block_idx, block_count; + const struct dxil_record *record; +@@ -8586,7 +8588,7 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) + + static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6) + { +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + unsigned int i; + + program->block_count = function->block_count; +@@ -9592,7 +9594,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, + } + + ++sm6->descriptor_count; +- ++sm6->p.program->instructions.count; ++ ++sm6->program->instructions.count; + } + + return VKD3D_OK; +@@ -9711,7 +9713,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const + { + unsigned int i, j, column_count, operand_count, index; + const struct sm6_metadata_node *node, *element_node; +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + struct signature_element *elements, *e; + unsigned int values[10]; + bool native_16bit; +@@ -9930,7 +9932,7 @@ invalid: + static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m, + enum vkd3d_tessellator_domain tessellator_domain) + { +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + enum vkd3d_result ret; + + if (!sm6_metadata_value_is_node(m)) +@@ -9985,12 +9987,12 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm + + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_GLOBAL_FLAGS); + ins->declaration.global_flags = global_flags; +- sm6->p.program->global_flags = global_flags; ++ sm6->program->global_flags = global_flags; + } + + static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m) + { +- struct vkd3d_shader_version *version = &sm6->p.program->shader_version; ++ struct vkd3d_shader_version *version = &sm6->program->shader_version; + const struct sm6_metadata_node *node; + struct vkd3d_shader_instruction *ins; + unsigned int group_sizes[3]; +@@ -10044,7 +10046,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co + ins->declaration.thread_group_size.x = group_sizes[0]; + ins->declaration.thread_group_size.y = group_sizes[1]; + ins->declaration.thread_group_size.z = group_sizes[2]; +- sm6->p.program->thread_group_size = ins->declaration.thread_group_size; ++ sm6->program->thread_group_size = ins->declaration.thread_group_size; + + return VKD3D_OK; + } +@@ -10082,7 +10084,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, + + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_DOMAIN); + ins->declaration.tessellator_domain = tessellator_domain; +- sm6->p.program->tess_domain = tessellator_domain; ++ sm6->program->tess_domain = tessellator_domain; + } + + static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, +@@ -10111,7 +10113,7 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_PARTITIONING); + ins->declaration.tessellator_partitioning = tessellator_partitioning; + +- sm6->p.program->tess_partitioning = tessellator_partitioning; ++ sm6->program->tess_partitioning = tessellator_partitioning; + } + + static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *sm6, +@@ -10129,7 +10131,7 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE); + ins->declaration.tessellator_output_primitive = primitive; + +- sm6->p.program->tess_output_primitive = primitive; ++ sm6->program->tess_output_primitive = primitive; + } + + static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, struct sm6_metadata_value *m) +@@ -10241,8 +10243,8 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s + } + + sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); +- sm6->p.program->input_primitive = input_primitive; +- sm6->p.program->input_control_point_count = input_control_point_count; ++ sm6->program->input_primitive = input_primitive; ++ sm6->program->input_control_point_count = input_control_point_count; + + i = operands[1]; + /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */ +@@ -10253,7 +10255,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s + "Geometry shader output vertex count %u is invalid.", i); + } + sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_VERTICES_OUT, i); +- sm6->p.program->vertices_out_count = i; ++ sm6->program->vertices_out_count = i; + + if (operands[2] > 1) + { +@@ -10271,7 +10273,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s + output_primitive = VKD3D_PT_TRIANGLELIST; + } + sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); +- sm6->p.program->output_topology = output_primitive; ++ sm6->program->output_topology = output_primitive; + + i = operands[4]; + if (!i || i > MAX_GS_INSTANCE_COUNT) +@@ -10326,7 +10328,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa + + sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]); + sm6_parser_validate_control_point_count(sm6, operands[1], true, "Domain shader input"); +- sm6->p.program->input_control_point_count = operands[1]; ++ sm6->program->input_control_point_count = operands[1]; + + return operands[0]; + } +@@ -10334,7 +10336,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa + static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, + const struct sm6_metadata_value *m) + { +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + const struct sm6_metadata_node *node; + unsigned int operands[6] = {0}; + unsigned int i; +@@ -10727,9 +10729,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro + if (!vsir_program_init(program, compile_info, &version, + (count + (count >> 2)) / 2u + 10, VSIR_CF_BLOCKS, VSIR_NORMALISED_SM6)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name); ++ vkd3d_shader_parser_init(&sm6->p, message_context, compile_info->source_name); + sm6->ptr = &sm6->start[1]; + sm6->bitpos = 2; ++ sm6->program = program; + + switch (program->shader_version.type) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index 5b776108c95..676c501bb08 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -4205,7 +4205,7 @@ static void fx_parse_shader_blob(struct fx_parser *parser, enum vkd3d_shader_sou + + static const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + }; + + info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index dfe0a40ddf0..5988e7b3a30 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -1531,6 +1531,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + break; + case VSIR_OP_GEO: + case VSIR_OP_IGE: ++ case VSIR_OP_UGE: + shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); + break; + case VSIR_OP_IF: +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index 62335086e20..d8eb18e39c7 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -1809,6 +1809,76 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v + return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); + } + ++bool hlsl_constant_is_zero(struct hlsl_ir_constant *c) ++{ ++ struct hlsl_type *data_type = c->node.data_type; ++ unsigned int k; ++ ++ for (k = 0; k < data_type->e.numeric.dimx; ++k) ++ { ++ switch (data_type->e.numeric.type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ if (c->value.u[k].f != 0.0f) ++ return false; ++ break; ++ ++ case HLSL_TYPE_DOUBLE: ++ if (c->value.u[k].d != 0.0) ++ return false; ++ break; ++ ++ case HLSL_TYPE_UINT: ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_BOOL: ++ case HLSL_TYPE_MIN16UINT: ++ if (c->value.u[k].u != 0) ++ return false; ++ break; ++ } ++ } ++ ++ return true; ++} ++ ++bool hlsl_constant_is_one(struct hlsl_ir_constant *c) ++{ ++ struct hlsl_type *data_type = c->node.data_type; ++ unsigned int k; ++ ++ for (k = 0; k < data_type->e.numeric.dimx; ++k) ++ { ++ switch (data_type->e.numeric.type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ if (c->value.u[k].f != 1.0f) ++ return false; ++ break; ++ ++ case HLSL_TYPE_DOUBLE: ++ if (c->value.u[k].d != 1.0) ++ return false; ++ break; ++ ++ case HLSL_TYPE_UINT: ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_MIN16UINT: ++ if (c->value.u[k].u != 1) ++ return false; ++ break; ++ ++ case HLSL_TYPE_BOOL: ++ if (c->value.u[k].u != ~0) ++ return false; ++ break; ++ } ++ } ++ ++ return true; ++} ++ + static struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index d67f820fe8b..b6e5f4f2cf3 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -1541,6 +1541,12 @@ static inline bool hlsl_var_has_buffer_offset_register_reservation(struct hlsl_c + return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer; + } + ++static inline bool hlsl_is_comparison_op(enum hlsl_ir_expr_op op) ++{ ++ return op == HLSL_OP2_EQUAL || op == HLSL_OP2_GEQUAL ++ || op == HLSL_OP2_LESS || op == HLSL_OP2_NEQUAL; ++} ++ + char *hlsl_sprintf_alloc(struct hlsl_ctx *ctx, const char *fmt, ...) VKD3D_PRINTF_FUNC(2, 3); + + const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); +@@ -1693,6 +1699,9 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, + struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct hlsl_ir_node *arg3); + ++bool hlsl_constant_is_zero(struct hlsl_ir_constant *c); ++bool hlsl_constant_is_one(struct hlsl_ir_constant *c); ++ + void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var); + + struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 024d96c5663..e20a12bb42d 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -3983,6 +3983,53 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); + } + ++static bool intrinsic_frexp(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_type *type, *uint_dim_type, *int_dim_type, *bool_dim_type; ++ struct hlsl_ir_function_decl *func; ++ char *body; ++ ++ static const char template[] = ++ "%s frexp(%s x, out %s exp)\n" ++ "{\n" ++ /* If x is zero, always return zero for exp and mantissa. */ ++ " %s is_nonzero_mask = x != 0.0;\n" ++ " %s bits = asuint(x);\n" ++ /* Subtract 126, not 127, to increase the exponent */ ++ " %s exp_int = asint((bits & 0x7f800000u) >> 23) - 126;\n" ++ /* Clear the given exponent and replace it with the bit pattern ++ * for 2^-1 */ ++ " %s mantissa = asfloat((bits & 0x007fffffu) | 0x3f000000);\n" ++ " exp = is_nonzero_mask * %s(exp_int);\n" ++ " return is_nonzero_mask * mantissa;\n" ++ "}\n"; ++ ++ if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) ++ return false; ++ type = params->args[0]->data_type; ++ ++ if (type->e.numeric.type == HLSL_TYPE_DOUBLE) ++ { ++ hlsl_fixme(ctx, loc, "frexp() on doubles."); ++ return false; ++ } ++ type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->e.numeric.dimx, type->e.numeric.dimy); ++ uint_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); ++ int_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_INT, type->e.numeric.dimx, type->e.numeric.dimy); ++ bool_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); ++ ++ if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name, type->name, ++ bool_dim_type->name, uint_dim_type->name, int_dim_type->name, type->name, type->name))) ++ return false; ++ func = hlsl_compile_internal_function(ctx, "frexp", body); ++ vkd3d_free(body); ++ if (!func) ++ return false; ++ ++ return !!add_user_call(ctx, func, params, false, loc); ++} ++ + static bool intrinsic_fwidth(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -5283,6 +5330,7 @@ intrinsic_functions[] = + {"floor", 1, true, intrinsic_floor}, + {"fmod", 2, true, intrinsic_fmod}, + {"frac", 1, true, intrinsic_frac}, ++ {"frexp", 2, true, intrinsic_frexp}, + {"fwidth", 1, true, intrinsic_fwidth}, + {"isinf", 1, true, intrinsic_isinf}, + {"ldexp", 2, true, intrinsic_ldexp}, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 0b3dee4d2ce..8e3ed0a1b8d 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -5029,8 +5029,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); +- if (expr->op != HLSL_OP2_EQUAL && expr->op != HLSL_OP2_NEQUAL && expr->op != HLSL_OP2_LESS +- && expr->op != HLSL_OP2_GEQUAL) ++ if (!hlsl_is_comparison_op(expr->op)) + return false; + + arg1 = expr->operands[0].node; +@@ -8266,6 +8265,282 @@ void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) + lower_ir(ctx, lower_index_loads, body); + } + ++static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op) ++{ ++ switch (op) ++ { ++ case HLSL_OP2_EQUAL: ++ return HLSL_OP2_NEQUAL; ++ ++ case HLSL_OP2_GEQUAL: ++ return HLSL_OP2_LESS; ++ ++ case HLSL_OP2_LESS: ++ return HLSL_OP2_GEQUAL; ++ ++ case HLSL_OP2_NEQUAL: ++ return HLSL_OP2_EQUAL; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++} ++ ++static bool fold_unary_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *res = NULL; ++ struct hlsl_ir_expr *expr, *x; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return false; ++ ++ if (instr->data_type->class > HLSL_CLASS_VECTOR) ++ return false; ++ ++ expr = hlsl_ir_expr(instr); ++ if (!expr->operands[0].node) ++ return false; ++ ++ if (expr->operands[0].node->type != HLSL_IR_EXPR) ++ return false; ++ x = hlsl_ir_expr(expr->operands[0].node); ++ ++ switch (expr->op) ++ { ++ case HLSL_OP1_ABS: ++ if (x->op == HLSL_OP1_ABS) ++ { ++ /* ||x|| -> |x| */ ++ hlsl_replace_node(instr, &x->node); ++ return true; ++ } ++ ++ if (x->op == HLSL_OP1_NEG) ++ { ++ /* |-x| -> |x| */ ++ hlsl_src_remove(&expr->operands[0]); ++ hlsl_src_from_node(&expr->operands[0], x->operands[0].node); ++ return true; ++ } ++ break; ++ ++ case HLSL_OP1_BIT_NOT: ++ if (x->op == HLSL_OP1_BIT_NOT) ++ { ++ /* ~(~x) -> x */ ++ hlsl_replace_node(instr, x->operands[0].node); ++ return true; ++ } ++ break; ++ ++ case HLSL_OP1_CEIL: ++ case HLSL_OP1_FLOOR: ++ if (x->op == HLSL_OP1_CEIL || x->op == HLSL_OP1_FLOOR) ++ { ++ /* f(g(x)) -> g(x), where f(), g() are floor() or ceil() functions. */ ++ hlsl_replace_node(instr, &x->node); ++ return true; ++ } ++ break; ++ ++ case HLSL_OP1_NEG: ++ if (x->op == HLSL_OP1_NEG) ++ { ++ /* -(-x) -> x */ ++ hlsl_replace_node(instr, x->operands[0].node); ++ return true; ++ } ++ break; ++ ++ case HLSL_OP1_LOGIC_NOT: ++ if (x->op == HLSL_OP1_LOGIC_NOT) ++ { ++ /* !!x -> x */ ++ hlsl_replace_node(instr, x->operands[0].node); ++ return true; ++ } ++ ++ if (hlsl_is_comparison_op(x->op) ++ && hlsl_base_type_is_integer(x->operands[0].node->data_type->e.numeric.type) ++ && hlsl_base_type_is_integer(x->operands[1].node->data_type->e.numeric.type)) ++ { ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {x->operands[0].node, x->operands[1].node}; ++ struct hlsl_block block; ++ ++ hlsl_block_init(&block); ++ ++ /* !(x == y) -> x != y, !(x < y) -> x >= y, etc. */ ++ res = hlsl_block_add_expr(ctx, &block, invert_comparison_op(x->op), ++ operands, instr->data_type, &instr->loc); ++ ++ list_move_before(&instr->entry, &block.instrs); ++ hlsl_replace_node(instr, res); ++ return true; ++ } ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ return false; ++} ++ ++static bool nodes_are_equivalent(const struct hlsl_ir_node *c1, const struct hlsl_ir_node *c2) ++{ ++ if (c1 == c2) ++ return true; ++ ++ if (c1->type == HLSL_IR_SWIZZLE && c2->type == HLSL_IR_SWIZZLE ++ && hlsl_types_are_equal(c1->data_type, c2->data_type)) ++ { ++ const struct hlsl_ir_swizzle *s1 = hlsl_ir_swizzle(c1), *s2 = hlsl_ir_swizzle(c2); ++ ++ VKD3D_ASSERT(c1->data_type->class <= HLSL_CLASS_VECTOR); ++ ++ if (s1->val.node == s2->val.node && s1->u.vector == s2->u.vector) ++ return true; ++ } ++ ++ return false; ++} ++ ++/* Replaces all conditionals in an expression chain of the form (cond ? x : y) ++ * with x or y, assuming cond = cond_value. */ ++static struct hlsl_ir_node *evaluate_conditionals_recurse(struct hlsl_ctx *ctx, ++ struct hlsl_block *block, const struct hlsl_ir_node *cond, bool cond_value, ++ struct hlsl_ir_node *instr, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; ++ struct hlsl_ir_expr *expr; ++ struct hlsl_ir_node *res; ++ bool progress = false; ++ unsigned int i; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return NULL; ++ expr = hlsl_ir_expr(instr); ++ ++ if (expr->op == HLSL_OP3_TERNARY && nodes_are_equivalent(cond, expr->operands[0].node)) ++ { ++ struct hlsl_ir_node *x = cond_value ? expr->operands[1].node : expr->operands[2].node; ++ ++ res = evaluate_conditionals_recurse(ctx, block, cond, cond_value, x, loc); ++ return res ? res : x; ++ } ++ ++ for (i = 0; i < HLSL_MAX_OPERANDS; ++i) ++ { ++ if (!expr->operands[i].node) ++ break; ++ ++ operands[i] = evaluate_conditionals_recurse(ctx, block, cond, cond_value, expr->operands[i].node, loc); ++ ++ if (operands[i]) ++ progress = true; ++ else ++ operands[i] = expr->operands[i].node; ++ } ++ ++ if (progress) ++ return hlsl_block_add_expr(ctx, block, expr->op, operands, expr->node.data_type, loc); ++ ++ return NULL; ++} ++ ++static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *c, *x, *y, *res_x, *res_y; ++ struct hlsl_ir_node *res = NULL; ++ struct hlsl_ir_expr *expr, *ec; ++ struct hlsl_block block; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return false; ++ ++ if (instr->data_type->class > HLSL_CLASS_VECTOR) ++ return false; ++ ++ expr = hlsl_ir_expr(instr); ++ if (expr->op != HLSL_OP3_TERNARY) ++ return false; ++ ++ c = expr->operands[0].node; ++ x = expr->operands[1].node; ++ y = expr->operands[2].node; ++ ++ VKD3D_ASSERT(c->data_type->e.numeric.type == HLSL_TYPE_BOOL); ++ ++ if (nodes_are_equivalent(x, y)) ++ { ++ /* c ? x : x -> x */ ++ hlsl_replace_node(instr, x); ++ return true; ++ } ++ ++ if (c->type == HLSL_IR_CONSTANT) ++ { ++ if (hlsl_constant_is_zero(hlsl_ir_constant(c))) ++ { ++ /* false ? x : y -> y */ ++ hlsl_replace_node(instr, y); ++ return true; ++ } ++ ++ if (hlsl_constant_is_one(hlsl_ir_constant(c))) ++ { ++ /* true ? x : y -> x */ ++ hlsl_replace_node(instr, x); ++ return true; ++ } ++ } ++ ++ hlsl_block_init(&block); ++ ++ if (x->type == HLSL_IR_CONSTANT && y->type == HLSL_IR_CONSTANT ++ && hlsl_types_are_equal(c->data_type, x->data_type) ++ && hlsl_types_are_equal(c->data_type, y->data_type)) ++ { ++ if (hlsl_constant_is_one(hlsl_ir_constant(x)) && hlsl_constant_is_zero(hlsl_ir_constant(y))) ++ { ++ /* c ? true : false -> c */ ++ res = c; ++ goto done; ++ } ++ ++ if (hlsl_constant_is_zero(hlsl_ir_constant(x)) && hlsl_constant_is_one(hlsl_ir_constant(y))) ++ { ++ /* c ? false : true -> !c */ ++ res = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); ++ goto done; ++ } ++ } ++ ++ ec = c->type == HLSL_IR_EXPR ? hlsl_ir_expr(c) : NULL; ++ if (ec && ec->op == HLSL_OP1_LOGIC_NOT) ++ { ++ /* !c ? x : y -> c ? y : x */ ++ res = hlsl_add_conditional(ctx, &block, ec->operands[0].node, y, x); ++ goto done; ++ } ++ ++ res_x = evaluate_conditionals_recurse(ctx, &block, c, true, x, &instr->loc); ++ res_y = evaluate_conditionals_recurse(ctx, &block, c, false, y, &instr->loc); ++ if (res_x || res_y) ++ res = hlsl_add_conditional(ctx, &block, c, res_x ? res_x : x, res_y ? res_y : y); ++ ++done: ++ if (res) ++ { ++ list_move_before(&instr->entry, &block.instrs); ++ hlsl_replace_node(instr, res); ++ return true; ++ } ++ ++ hlsl_block_cleanup(&block); ++ return false; ++} + + static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) + { +@@ -8275,6 +8550,8 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) + { + progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); + progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL); ++ progress |= hlsl_transform_ir(ctx, fold_unary_identities, block, NULL); ++ progress |= hlsl_transform_ir(ctx, fold_conditional_identities, block, NULL); + progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); + progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +index d339a06e6c7..4cd47a0632e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +@@ -1393,74 +1393,6 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return success; + } + +-static bool constant_is_zero(struct hlsl_ir_constant *const_arg) +-{ +- struct hlsl_type *data_type = const_arg->node.data_type; +- unsigned int k; +- +- for (k = 0; k < data_type->e.numeric.dimx; ++k) +- { +- switch (data_type->e.numeric.type) +- { +- case HLSL_TYPE_FLOAT: +- case HLSL_TYPE_HALF: +- if (const_arg->value.u[k].f != 0.0f) +- return false; +- break; +- +- case HLSL_TYPE_DOUBLE: +- if (const_arg->value.u[k].d != 0.0) +- return false; +- break; +- +- case HLSL_TYPE_UINT: +- case HLSL_TYPE_INT: +- case HLSL_TYPE_BOOL: +- case HLSL_TYPE_MIN16UINT: +- if (const_arg->value.u[k].u != 0) +- return false; +- break; +- } +- } +- return true; +-} +- +-static bool constant_is_one(struct hlsl_ir_constant *const_arg) +-{ +- struct hlsl_type *data_type = const_arg->node.data_type; +- unsigned int k; +- +- for (k = 0; k < data_type->e.numeric.dimx; ++k) +- { +- switch (data_type->e.numeric.type) +- { +- case HLSL_TYPE_FLOAT: +- case HLSL_TYPE_HALF: +- if (const_arg->value.u[k].f != 1.0f) +- return false; +- break; +- +- case HLSL_TYPE_DOUBLE: +- if (const_arg->value.u[k].d != 1.0) +- return false; +- break; +- +- case HLSL_TYPE_UINT: +- case HLSL_TYPE_INT: +- case HLSL_TYPE_MIN16UINT: +- if (const_arg->value.u[k].u != 1) +- return false; +- break; +- +- case HLSL_TYPE_BOOL: +- if (const_arg->value.u[k].u != ~0) +- return false; +- break; +- } +- } +- return true; +-} +- + bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + struct hlsl_ir_constant *const_arg = NULL; +@@ -1502,26 +1434,26 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + switch (expr->op) + { + case HLSL_OP2_ADD: +- if (constant_is_zero(const_arg)) ++ if (hlsl_constant_is_zero(const_arg)) + res_node = mut_arg; + break; + + case HLSL_OP2_MUL: +- if (constant_is_one(const_arg)) ++ if (hlsl_constant_is_one(const_arg)) + res_node = mut_arg; + break; + + case HLSL_OP2_LOGIC_AND: +- if (constant_is_zero(const_arg)) ++ if (hlsl_constant_is_zero(const_arg)) + res_node = &const_arg->node; +- else if (constant_is_one(const_arg)) ++ else if (hlsl_constant_is_one(const_arg)) + res_node = mut_arg; + break; + + case HLSL_OP2_LOGIC_OR: +- if (constant_is_zero(const_arg)) ++ if (hlsl_constant_is_zero(const_arg)) + res_node = mut_arg; +- else if (constant_is_one(const_arg)) ++ else if (hlsl_constant_is_one(const_arg)) + res_node = &const_arg->node; + break; + +@@ -1649,6 +1581,9 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + if (instr->data_type->class > HLSL_CLASS_VECTOR) + return false; + ++ if (expr->operands[2].node) ++ return false; ++ + hlsl_block_init(&block); + + arg1 = expr->operands[0].node; +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 23e059a3490..fef186ac34b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -1669,10 +1669,22 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr + + switch (ins->opcode) + { ++ case VSIR_OP_IFC: ++ ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context); ++ break; ++ ++ case VSIR_OP_SINCOS: ++ ret = vsir_program_lower_sm1_sincos(program, &it); ++ break; ++ + case VSIR_OP_TEXCRD: + ret = vsir_program_lower_texcrd(program, ins, message_context); + break; + ++ case VSIR_OP_TEXKILL: ++ ret = vsir_program_lower_texkill(program, &it, &tmp_idx); ++ break; ++ + case VSIR_OP_TEXLD: + if (program->shader_version.major == 1) + ret = vsir_program_lower_texld_sm1(program, ins, message_context); +@@ -1682,6 +1694,14 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr + ret = vsir_program_lower_texld(program, ins, message_context); + break; + ++ case VSIR_OP_TEXLDD: ++ ret = vsir_program_lower_texldd(program, ins); ++ break; ++ ++ case VSIR_OP_TEXLDL: ++ ret = vsir_program_lower_texldl(program, ins); ++ break; ++ + default: + ret = VKD3D_OK; + break; +@@ -1698,7 +1718,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + struct vsir_transformation_context *ctx) + { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); +- struct vkd3d_shader_message_context *message_context = ctx->message_context; + struct vkd3d_shader_instruction *ins; + unsigned int tmp_idx = ~0u; + enum vkd3d_result ret; +@@ -1707,16 +1726,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + { + switch (ins->opcode) + { +- case VSIR_OP_IFC: +- if ((ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context)) < 0) +- return ret; +- break; +- +- case VSIR_OP_TEXKILL: +- if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0) +- return ret; +- break; +- + case VSIR_OP_MAD: + if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) + return ret; +@@ -1765,25 +1774,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + break; + + case VSIR_OP_SINCOS: +- if (ins->dst_count == 1) +- { +- if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0) +- return ret; +- } +- else +- { +- if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) +- return ret; +- } +- break; +- +- case VSIR_OP_TEXLDD: +- if ((ret = vsir_program_lower_texldd(program, ins)) < 0) +- return ret; +- break; +- +- case VSIR_OP_TEXLDL: +- if ((ret = vsir_program_lower_texldl(program, ins)) < 0) ++ if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) + return ret; + break; + +@@ -7668,15 +7659,12 @@ static enum vkd3d_result vsir_program_add_fog_input(struct vsir_program *program + } + + static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_fragment_mode mode, +- uint32_t fog_signature_idx, uint32_t colour_signature_idx, uint32_t colour_temp, +- size_t *ret_pos, struct vkd3d_shader_message_context *message_context) ++ struct vsir_program_iterator *it, enum vkd3d_shader_fog_fragment_mode mode, uint32_t fog_signature_idx, ++ uint32_t colour_signature_idx, uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- struct vkd3d_shader_location loc = ret->location; ++ struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); ++ struct vkd3d_shader_location loc = ins->location; + uint32_t ssa_factor = program->ssa_count++; +- size_t pos = ret - instructions->elements; +- struct vkd3d_shader_instruction *ins; + uint32_t ssa_temp, ssa_temp2; + + switch (mode) +@@ -7687,16 +7675,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * add sr0, FOG_END, -vFOG.x + * mul_sat srFACTOR, sr0, FOG_SCALE + */ +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 4)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- +- *ret_pos = pos + 4; ++ ins = vsir_program_iterator_next(it); + + ssa_temp = program->ssa_count++; + +- ins = &program->instructions.elements[pos]; +- + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); +@@ -7705,12 +7690,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + ins->src[1].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_factor); + ins->dst[0].modifiers = VKD3DSPDM_SATURATE; + src_param_init_ssa_float(&ins->src[0], ssa_temp); + src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); ++ ins = vsir_program_iterator_next(it); ++ + break; + + case VKD3D_SHADER_FOG_FRAGMENT_EXP: +@@ -7719,16 +7707,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * mul sr0, FOG_SCALE, vFOG.x + * exp_sat srFACTOR, -sr0 + */ +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 4)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- +- *ret_pos = pos + 4; ++ ins = vsir_program_iterator_next(it); + + ssa_temp = program->ssa_count++; + +- ins = &program->instructions.elements[pos]; +- + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); +@@ -7736,12 +7721,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + ins->src[1].reg.idx[0].offset = fog_signature_idx; + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); + dst_param_init_ssa_float(&ins->dst[0], ssa_factor); + ins->dst[0].modifiers = VKD3DSPDM_SATURATE; + src_param_init_ssa_float(&ins->src[0], ssa_temp); + ins->src[0].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); + break; + + case VKD3D_SHADER_FOG_FRAGMENT_EXP2: +@@ -7751,17 +7738,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * mul sr1, sr0, sr0 + * exp_sat srFACTOR, -sr1 + */ +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 5)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 5)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- +- *ret_pos = pos + 5; ++ ins = vsir_program_iterator_next(it); + + ssa_temp = program->ssa_count++; + ssa_temp2 = program->ssa_count++; + +- ins = &program->instructions.elements[pos]; +- + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); +@@ -7769,17 +7753,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + ins->src[1].reg.idx[0].offset = fog_signature_idx; + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); + src_param_init_ssa_float(&ins->src[0], ssa_temp); + src_param_init_ssa_float(&ins->src[1], ssa_temp); ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); + dst_param_init_ssa_float(&ins->dst[0], ssa_factor); + ins->dst[0].modifiers = VKD3DSPDM_SATURATE; + src_param_init_ssa_float(&ins->src[0], ssa_temp2); + ins->src[0].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); + break; + + default: +@@ -7792,18 +7779,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * mad oC0, sr0, srFACTOR, FOG_COLOUR + */ + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_ADD, 1, 2); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); + dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); + src_param_init_temp_float4(&ins->src[0], colour_temp); + src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); + ins->src[1].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MAD, 1, 3); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MAD, 1, 3); + dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, + program->output_signature.elements[colour_signature_idx].mask); + src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); + src_param_init_ssa_float(&ins->src[1], ssa_factor); + src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); ++ ins = vsir_program_iterator_next(it); + + return VKD3D_OK; + } +@@ -7811,6 +7800,7 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + uint32_t colour_signature_idx, fog_signature_idx, colour_temp; + const struct vkd3d_shader_parameter1 *mode_parameter = NULL; +@@ -7818,7 +7808,6 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p + const struct signature_element *fog_element; + enum vkd3d_shader_fog_fragment_mode mode; + struct vkd3d_shader_instruction *ins; +- size_t new_pos; + int ret; + + if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) +@@ -7859,19 +7848,16 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p + * through the whole shader and convert it to a temp. */ + colour_temp = program->temp_count++; + +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- + if (vsir_instruction_is_dcl(ins)) + continue; + + if (ins->opcode == VSIR_OP_RET) + { +- if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx, +- colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) ++ if ((ret = insert_fragment_fog_before_ret(program, &it, mode, fog_signature_idx, ++ colour_signature_idx, colour_temp, message_context)) < 0) + return ret; +- i = new_pos; + continue; + } + +@@ -7927,21 +7913,18 @@ static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *progra + return VKD3D_OK; + } + +-static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp, +- uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos) ++static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, struct vsir_program_iterator *it, ++ enum vkd3d_shader_fog_source source, uint32_t temp, uint32_t fog_signature_idx, uint32_t source_signature_idx) + { + const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; ++ struct vkd3d_shader_instruction *ret = vsir_program_iterator_current(it); + const struct vkd3d_shader_location loc = ret->location; +- size_t pos = ret - instructions->elements; + struct vkd3d_shader_instruction *ins; + +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 2)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); + + /* Write the fog output. */ + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); +@@ -7951,26 +7934,27 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); + else /* Position or specular W. */ + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); +- ++ins; ++ ins = vsir_program_iterator_next(it); + + /* Write the position or specular output. */ + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + dst_param_init_output(&ins->dst[0], vsir_data_type_from_component_type(e->component_type), + source_signature_idx, e->mask); + src_param_init_temp_float4(&ins->src[0], temp); +- ++ins; ++ ins = vsir_program_iterator_next(it); + +- *ret_pos = pos + 2; + return VKD3D_OK; + } + + static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + const struct vkd3d_shader_parameter1 *source_parameter = NULL; + uint32_t fog_signature_idx, source_signature_idx, temp; + static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_instruction *ins; + enum vkd3d_shader_fog_source source; + const struct signature_element *e; + +@@ -8027,22 +8011,18 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro + + /* Insert a fog write before each ret, and convert either specular or + * position output to a temp. */ +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + if (vsir_instruction_is_dcl(ins)) + continue; + + if (ins->opcode == VSIR_OP_RET) + { +- size_t new_pos; + int ret; + +- if ((ret = insert_vertex_fog_before_ret(program, ins, source, temp, +- fog_signature_idx, source_signature_idx, &new_pos)) < 0) ++ if ((ret = insert_vertex_fog_before_ret(program, &it, source, temp, ++ fog_signature_idx, source_signature_idx)) < 0) + return ret; +- i = new_pos; + continue; + } + +@@ -8565,9 +8545,12 @@ static void liveness_tracker_cleanup(struct liveness_tracker *tracker) + + static enum vkd3d_result track_liveness(struct vsir_program *program, struct liveness_tracker *tracker) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; + struct liveness_tracker_reg *regs; + unsigned int loop_depth = 0; + unsigned int loop_start = 0; ++ unsigned int i; + + memset(tracker, 0, sizeof(*tracker)); + +@@ -8575,10 +8558,8 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv + return VKD3D_ERROR_OUT_OF_MEMORY; + tracker->ssa_regs = regs; + +- for (unsigned int i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) + { +- const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + if (ins->opcode == VSIR_OP_LOOP || ins->opcode == VSIR_OP_REP) + { + if (!loop_depth++) +@@ -8838,8 +8819,10 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, + enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + const unsigned int prev_temp_count = program->temp_count; + struct temp_allocator allocator = {0}; ++ struct vkd3d_shader_instruction *ins; + struct temp_allocator_reg *regs; + struct liveness_tracker tracker; + enum vkd3d_result ret; +@@ -8873,10 +8856,8 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + ++allocator.allocated_ssa_count; + } + +- for (unsigned int i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + /* Make sure we do the srcs first; setting the dst writemask may need + * to remap their swizzles. */ + for (unsigned int j = 0; j < ins->src_count; ++j) +@@ -8902,11 +8883,14 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_location location; ++ struct vkd3d_shader_instruction *ins; + unsigned int temp_count = 0; + +- for (int i = program->instructions.count - 1; i >= 0; --i) ++ for (ins = vsir_program_iterator_tail(&it); ins; ins = vsir_program_iterator_prev(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; ++ location = ins->location; + + if (ins->opcode == VSIR_OP_DCL_TEMPS) + { +@@ -8922,11 +8906,11 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + { + /* The phase didn't have a dcl_temps instruction, but we added + * temps here, so we need to insert one. */ +- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) ++ if (!vsir_program_iterator_insert_after(&it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- ins = &program->instructions.elements[i + 1]; +- vsir_instruction_init(ins, &program->instructions.elements[i].location, VSIR_OP_DCL_TEMPS); ++ ins = vsir_program_iterator_next(&it); ++ vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); + ins->declaration.count = temp_count; + temp_count = 0; + continue; +@@ -8947,13 +8931,15 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + + if (temp_count && program->shader_version.major >= 4) + { +- struct vkd3d_shader_instruction *ins; ++ ins = vsir_program_iterator_head(&it); ++ location = ins->location; + +- if (!shader_instruction_array_insert_at(&program->instructions, 0, 1)) ++ vsir_program_iterator_prev(&it); ++ if (!vsir_program_iterator_insert_after(&it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- ins = &program->instructions.elements[0]; +- vsir_instruction_init(ins, &program->instructions.elements[1].location, VSIR_OP_DCL_TEMPS); ++ ins = vsir_program_iterator_next(&it); ++ vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); + ins->declaration.count = temp_count; + } + +@@ -11842,14 +11828,12 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ + [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, + }; + +-static void vsir_validate_instruction(struct validation_context *ctx) ++static void vsir_validate_instruction(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) + { + const struct vkd3d_shader_version *version = &ctx->program->shader_version; +- const struct vkd3d_shader_instruction *instruction; + size_t i; + +- instruction = &ctx->program->instructions.elements[ctx->instruction_idx]; +- + for (i = 0; i < instruction->dst_count; ++i) + vsir_validate_dst_param(ctx, &instruction->dst[i]); + +@@ -11938,6 +11922,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c + .inner_tess_idxs[0] = ~0u, + .inner_tess_idxs[1] = ~0u, + }; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; + unsigned int i; + + if (!(config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) +@@ -12046,9 +12032,13 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c + + ctx.invalid_instruction_idx = false; + +- for (ctx.instruction_idx = 0; ctx.instruction_idx < program->instructions.count +- && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; ++ctx.instruction_idx) +- vsir_validate_instruction(&ctx); ++ ctx.instruction_idx = 0; ++ for (ins = vsir_program_iterator_head(&it); ins && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; ++ ins = vsir_program_iterator_next(&it)) ++ { ++ vsir_validate_instruction(&ctx, ins); ++ ++ctx.instruction_idx; ++ } + + ctx.invalid_instruction_idx = true; + +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index c6e048adb20..88d1160d4e8 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -1516,6 +1516,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + break; + case VSIR_OP_GEO: + case VSIR_OP_IGE: ++ case VSIR_OP_UGE: + msl_relop(gen, ins, ">="); + break; + case VSIR_OP_IF: +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index a4990d982bc..97c0d0e73a8 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -38,7 +38,7 @@ + #define VKD3D_SPIRV_VERSION_1_0 0x00010000 + #define VKD3D_SPIRV_VERSION_1_3 0x00010300 + #define VKD3D_SPIRV_GENERATOR_ID 18 +-#define VKD3D_SPIRV_GENERATOR_VERSION 16 ++#define VKD3D_SPIRV_GENERATOR_VERSION 17 + #define VKD3D_SPIRV_GENERATOR_MAGIC vkd3d_make_u32(VKD3D_SPIRV_GENERATOR_VERSION, VKD3D_SPIRV_GENERATOR_ID) + #ifndef VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER + # define VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER 0 +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index ea15c1a9ad5..e2123656557 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -665,6 +665,8 @@ struct vkd3d_shader_sm4_parser + { + const uint32_t *start, *end, *ptr; + ++ struct vsir_program *program; ++ + enum vkd3d_shader_opcode phase; + bool has_control_point_phase; + unsigned int input_register_masks[MAX_REG_OUTPUT]; +@@ -764,7 +766,7 @@ static const enum vsir_data_type data_type_table[] = + + static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) + { +- const struct vkd3d_shader_version *version = &sm4->p.program->shader_version; ++ const struct vkd3d_shader_version *version = &sm4->program->shader_version; + + return version->major >= 5 && version->minor >= 1; + } +@@ -849,7 +851,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui + icb->element_count = icb_size / VKD3D_VEC4_SIZE; + icb->is_null = false; + memcpy(icb->data, tokens, sizeof(*tokens) * icb_size); +- shader_instruction_array_add_icb(&priv->p.program->instructions, icb); ++ shader_instruction_array_add_icb(&priv->program->instructions, icb); + ins->declaration.icb = icb; + } + +@@ -971,7 +973,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { + struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range; +- struct vsir_program *program = priv->p.program; ++ struct vsir_program *program = priv->program; + unsigned int i, register_idx, register_count; + const struct shader_signature *signature; + enum vkd3d_shader_register_type type; +@@ -1094,14 +1096,14 @@ static void shader_sm4_read_dcl_output_topology(struct vkd3d_shader_instruction + if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED) + FIXME("Unhandled output primitive type %#x.\n", primitive_type); + +- priv->p.program->output_topology = ins->declaration.primitive_type.type; ++ priv->program->output_topology = ins->declaration.primitive_type.type; + } + + static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) + { + enum vkd3d_sm4_input_primitive_type primitive_type; +- struct vsir_program *program = sm4->p.program; ++ struct vsir_program *program = sm4->program; + + primitive_type = (opcode_token & VKD3D_SM4_PRIMITIVE_TYPE_MASK) >> VKD3D_SM4_PRIMITIVE_TYPE_SHIFT; + if (VKD3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= VKD3D_SM5_INPUT_PT_PATCH32) +@@ -1129,7 +1131,7 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction + static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) + { +- struct vsir_program *program = sm4->p.program; ++ struct vsir_program *program = sm4->program; + + ins->declaration.count = *tokens; + if (opcode == VKD3D_SM4_OP_DCL_TEMPS) +@@ -1161,7 +1163,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u + if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) + { + struct signature_element *e = vsir_signature_find_element_for_reg( +- &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); ++ &priv->program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + + if (!e) + { +@@ -1187,7 +1189,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in + if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) + { + struct signature_element *e = vsir_signature_find_element_for_reg( +- &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); ++ &priv->program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + + if (!e) + { +@@ -1220,7 +1222,7 @@ static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *in + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) + { + ins->declaration.global_flags = (opcode_token & VKD3D_SM4_GLOBAL_FLAGS_MASK) >> VKD3D_SM4_GLOBAL_FLAGS_SHIFT; +- sm4->p.program->global_flags = ins->declaration.global_flags; ++ sm4->program->global_flags = ins->declaration.global_flags; + } + + static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, +@@ -1256,7 +1258,7 @@ static void shader_sm5_read_dcl_interface(struct vkd3d_shader_instruction *ins, + static void shader_sm5_read_control_point_count(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) + { +- struct vsir_program *program = sm4->p.program; ++ struct vsir_program *program = sm4->program; + + ins->declaration.count = (opcode_token & VKD3D_SM5_CONTROL_POINT_COUNT_MASK) + >> VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT; +@@ -1272,7 +1274,7 @@ static void shader_sm5_read_dcl_tessellator_domain(struct vkd3d_shader_instructi + { + ins->declaration.tessellator_domain = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) + >> VKD3D_SM5_TESSELLATOR_SHIFT; +- priv->p.program->tess_domain = ins->declaration.tessellator_domain; ++ priv->program->tess_domain = ins->declaration.tessellator_domain; + } + + static void shader_sm5_read_dcl_tessellator_partitioning(struct vkd3d_shader_instruction *ins, uint32_t opcode, +@@ -1280,7 +1282,7 @@ static void shader_sm5_read_dcl_tessellator_partitioning(struct vkd3d_shader_ins + { + ins->declaration.tessellator_partitioning = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) + >> VKD3D_SM5_TESSELLATOR_SHIFT; +- priv->p.program->tess_partitioning = ins->declaration.tessellator_partitioning; ++ priv->program->tess_partitioning = ins->declaration.tessellator_partitioning; + } + + static void shader_sm5_read_dcl_tessellator_output_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode, +@@ -1288,7 +1290,7 @@ static void shader_sm5_read_dcl_tessellator_output_primitive(struct vkd3d_shader + { + ins->declaration.tessellator_output_primitive = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) + >> VKD3D_SM5_TESSELLATOR_SHIFT; +- priv->p.program->tess_output_primitive = ins->declaration.tessellator_output_primitive; ++ priv->program->tess_output_primitive = ins->declaration.tessellator_output_primitive; + } + + static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instruction *ins, uint32_t opcode, +@@ -1300,7 +1302,7 @@ static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instructio + static void shader_sm5_read_dcl_thread_group(struct vkd3d_shader_instruction *ins, uint32_t opcode, + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) + { +- struct vsir_program *program = sm4->p.program; ++ struct vsir_program *program = sm4->program; + + ins->declaration.thread_group_size.x = *tokens++; + ins->declaration.thread_group_size.y = *tokens++; +@@ -2009,7 +2011,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const + { + if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) + { +- struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->p.program, 1); ++ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->program, 1); + + if (!(reg_idx->rel_addr = rel_addr)) + { +@@ -2284,7 +2286,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register * + { + return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT + || (reg->type == VKD3DSPR_INPUT && (priv->phase == VSIR_OP_HS_CONTROL_POINT_PHASE +- || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); ++ || priv->program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); + } + + static uint32_t mask_from_swizzle(uint32_t swizzle) +@@ -2608,8 +2610,8 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d + static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins) + { + const struct vkd3d_sm4_opcode_info *opcode_info; +- struct vsir_program *program = sm4->p.program; + uint32_t opcode_token, opcode, previous_token; ++ struct vsir_program *program = sm4->program; + struct vkd3d_shader_dst_param *dst_params; + struct vkd3d_shader_src_param *src_params; + const uint32_t **ptr = &sm4->ptr; +@@ -2814,8 +2816,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro + if (!vsir_program_init(program, compile_info, + &version, token_count / 7u + 20, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) + return false; +- vkd3d_shader_parser_init(&sm4->p, program, message_context, compile_info->source_name); ++ vkd3d_shader_parser_init(&sm4->p, message_context, compile_info->source_name); + sm4->ptr = sm4->start; ++ sm4->program = program; + + init_sm4_lookup_tables(&sm4->lookup); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index d1992c9d446..75b7f9aa769 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -724,14 +724,13 @@ uint64_t vkd3d_shader_init_config_flags(void) + return config_flags; + } + +-void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, ++void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, + struct vkd3d_shader_message_context *message_context, const char *source_name) + { + parser->message_context = message_context; + parser->location.source_name = source_name; + parser->location.line = 1; + parser->location.column = 0; +- parser->program = program; + } + + void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, +@@ -1685,6 +1684,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; + struct vkd3d_shader_scan_hull_shader_tessellation_info *tessellation_info; ++ struct vkd3d_shader_scan_thread_group_size_info *thread_group_size_info; + struct vkd3d_shader_scan_descriptor_info *descriptor_info; + struct vkd3d_shader_scan_signature_info *signature_info; + struct vkd3d_shader_scan_context context; +@@ -1706,6 +1706,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + } + + tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO); ++ thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO); + + vkd3d_shader_scan_context_init(&context, &program->shader_version, compile_info, + add_descriptor_info ? &program->descriptors : NULL, combined_sampler_info, message_context); +@@ -1758,6 +1759,13 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + tessellation_info->partitioning = context.partitioning; + } + ++ if (!ret && thread_group_size_info) ++ { ++ thread_group_size_info->x = program->thread_group_size.x; ++ thread_group_size_info->y = program->thread_group_size.y; ++ thread_group_size_info->z = program->thread_group_size.z; ++ } ++ + if (ret < 0) + { + if (combined_sampler_info) +@@ -2184,6 +2192,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( + VKD3D_SHADER_TARGET_D3D_BYTECODE, + VKD3D_SHADER_TARGET_DXBC_TPF, + VKD3D_SHADER_TARGET_FX, ++#ifdef VKD3D_SHADER_UNSUPPORTED_MSL ++ VKD3D_SHADER_TARGET_MSL, ++#endif + }; + + static const enum vkd3d_shader_target_type d3dbc_types[] = +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index e758c16b3d4..b63c5785770 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -1651,13 +1651,12 @@ struct vkd3d_shader_parser + { + struct vkd3d_shader_message_context *message_context; + struct vkd3d_shader_location location; +- struct vsir_program *program; + bool failed; + }; + + void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, + enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); +-void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, ++void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, + struct vkd3d_shader_message_context *message_context, const char *source_name); + void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, + enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); +diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +index c41f8bae806..f804c1f0c24 100644 +--- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c ++++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +@@ -271,7 +271,7 @@ HRESULT WINAPI D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char * + + option = &options[0]; + option->name = VKD3D_SHADER_COMPILE_OPTION_API_VERSION; +- option->value = VKD3D_SHADER_API_VERSION_1_16; ++ option->value = VKD3D_SHADER_API_VERSION_1_17; + + compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; + compile_info.next = &preprocess_info; +@@ -435,7 +435,7 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename + + static const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + }; + + TRACE("data %p, size %"PRIuPTR", filename %s, macros %p, include %p, preprocessed_blob %p, messages_blob %p.\n", +@@ -981,7 +981,7 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, + + static const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + }; + + TRACE("data %p, data_size %"PRIuPTR", flags %#x, comments %p, blob %p.\n", +diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c +index 413892789ba..6bbd6533b74 100644 +--- a/libs/vkd3d/libs/vkd3d/state.c ++++ b/libs/vkd3d/libs/vkd3d/state.c +@@ -2391,7 +2391,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device, + + const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, + {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0}, + {VKD3D_SHADER_COMPILE_OPTION_FEATURE, feature_flags_compile_option(device)}, +@@ -2456,7 +2456,7 @@ static int vkd3d_scan_dxbc(const struct d3d12_device *device, const D3D12_SHADER + + const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, + }; + +@@ -4135,7 +4135,7 @@ static int compile_hlsl_cs(const struct vkd3d_shader_code *hlsl, struct vkd3d_sh + + static const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + }; + + info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; +-- +2.50.1 + diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch deleted file mode 100644 index 5f70079f..00000000 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 4874b0a352c091813dc9372412ac76e976b5eb64 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 17 Jul 2025 07:20:27 +1000 -Subject: [PATCH] Updated vkd3d to ba545669cd09682960f5da17b9131780642daf8e. - ---- - libs/vkd3d/libs/vkd3d-shader/ir.c | 46 +++++++++++++++++++ - .../libs/vkd3d-shader/vkd3d_shader_private.h | 1 + - libs/vkd3d/libs/vkd3d/state.c | 20 ++------ - 3 files changed, 51 insertions(+), 16 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index fe7e8c54dfb..b060ccbb2bc 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -10479,6 +10479,7 @@ static void vsir_validate_descriptors(struct validation_context *ctx) - for (i = 0; i < descriptors->descriptor_count; ++i) - { - const struct vkd3d_shader_descriptor_info1 *descriptor = &descriptors->descriptors[i]; -+ uint32_t flags_mask = 0, uav_flags_mask = 0; - - if (descriptor->type >= VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE, -@@ -10507,6 +10508,43 @@ static void vsir_validate_descriptors(struct validation_context *ctx) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT, - "Descriptor %u has invalid descriptor count %u starting at index %u.", - i, descriptor->count, descriptor->register_index); -+ -+ switch (descriptor->type) -+ { -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: -+ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; -+ break; -+ -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: -+ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER -+ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ -+ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS -+ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; -+ uav_flags_mask = VKD3DSUF_GLOBALLY_COHERENT -+ | VKD3DSUF_RASTERISER_ORDERED_VIEW -+ | VKD3DSUF_ORDER_PRESERVING_COUNTER; -+ break; -+ -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: -+ break; -+ -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: -+ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; -+ break; -+ -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_FORCE_32BIT: -+ break; -+ } -+ -+ if (descriptor->flags & ~flags_mask) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS, -+ "Descriptor %u of type %#x has invalid flags %#x.", -+ i, descriptor->type, descriptor->flags); -+ -+ if (descriptor->uav_flags & ~uav_flags_mask) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS, -+ "Descriptor %u of type %#x has invalid UAV flags %#x.", -+ i, descriptor->type, descriptor->uav_flags); - } - } - -@@ -11441,6 +11479,14 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_IEQ] = {1, 2, vsir_validate_integer_comparison_operation}, - [VSIR_OP_IGE] = {1, 2, vsir_validate_integer_comparison_operation}, - [VSIR_OP_ILT] = {1, 2, vsir_validate_integer_comparison_operation}, -+ [VSIR_OP_IMAD] = {1, 3, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_IMAX] = {1, 2, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_IMIN] = {1, 2, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_INE] = {1, 2, vsir_validate_integer_comparison_operation}, -+ [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_ISHL] = {1, 2, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_ISHR] = {1, 2, vsir_validate_integer_elementwise_operation}, - [VSIR_OP_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances}, - [VSIR_OP_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor}, - [VSIR_OP_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range}, -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 5d7fc6e1209..978af0a2d17 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -265,6 +265,7 @@ enum vkd3d_shader_error - VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE = 9024, - VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE = 9025, - VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT = 9026, -+ VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS = 9027, - - VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300, - -diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 0a5bd1122e3..9e9811bf922 100644 ---- a/libs/vkd3d/libs/vkd3d/state.c -+++ b/libs/vkd3d/libs/vkd3d/state.c -@@ -3232,17 +3232,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s - uint32_t mask; - HRESULT hr; - -- static const DWORD default_ps_code[] = -- { --#if 0 -- ps_4_0 -- ret --#endif -- 0x43425844, 0x19cbf606, 0x18f562b9, 0xdaeed4db, 0xc324aa46, 0x00000001, 0x00000060, 0x00000003, -- 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, -- 0x00000008, 0x00000000, 0x00000008, 0x52444853, 0x0000000c, 0x00000040, 0x00000003, 0x0100003e, -- }; -- static const D3D12_SHADER_BYTECODE default_ps = {default_ps_code, sizeof(default_ps_code)}; - static const struct - { - enum VkShaderStageFlagBits stage; -@@ -3401,11 +3390,10 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s - - if (!desc->ps.pShaderBytecode) - { -- if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count], -- VK_SHADER_STAGE_FRAGMENT_BIT, &default_ps, NULL))) -- goto fail; -- -- ++graphics->stage_count; -+ for (i = 0; i < rt_count; i++) -+ { -+ graphics->blend_attachments[i].colorWriteMask = 0; -+ } - } - } - --- -2.50.1 - diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch deleted file mode 100644 index bad42045..00000000 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch +++ /dev/null @@ -1,3953 +0,0 @@ -From 97f16d7d3743f07c6dd64999bf3ea0f227c0c2ce Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 22 Jul 2025 07:27:52 +1000 -Subject: [PATCH] Updated vkd3d to decc155cca45d7c4a60699990452b921a6e0fa65. - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 24 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 25 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 128 ++-- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 44 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 219 +++--- - libs/vkd3d/libs/vkd3d-shader/ir.c | 639 ++++++++++-------- - libs/vkd3d/libs/vkd3d-shader/msl.c | 40 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 60 +- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 75 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 16 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 109 ++- - 11 files changed, 806 insertions(+), 573 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index ae9278f68b1..7d10cf98f71 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -384,25 +384,25 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, - compiler->colours.error, type, compiler->colours.reset); - } - --static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) -+static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_data_type type) - { - static const char *const data_type_names[] = - { -- [VKD3D_DATA_FLOAT ] = "float", - [VKD3D_DATA_INT ] = "int", - [VKD3D_DATA_UINT ] = "uint", - [VKD3D_DATA_UNORM ] = "unorm", - [VKD3D_DATA_SNORM ] = "snorm", - [VKD3D_DATA_OPAQUE ] = "opaque", - [VKD3D_DATA_MIXED ] = "mixed", -- [VKD3D_DATA_DOUBLE ] = "double", - [VKD3D_DATA_CONTINUED] = "", - [VKD3D_DATA_UNUSED ] = "", - [VKD3D_DATA_UINT8 ] = "uint8", - [VKD3D_DATA_UINT64 ] = "uint64", - [VKD3D_DATA_BOOL ] = "bool", - [VKD3D_DATA_UINT16 ] = "uint16", -- [VKD3D_DATA_HALF ] = "half", -+ [VSIR_DATA_F16 ] = "half", -+ [VSIR_DATA_F32 ] = "float", -+ [VSIR_DATA_F64 ] = "double", - }; - - if (type < ARRAY_SIZE(data_type_names)) -@@ -412,7 +412,7 @@ static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum - compiler->colours.error, type, compiler->colours.reset); - } - --static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type) -+static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vsir_data_type *type) - { - int i; - -@@ -730,7 +730,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - case VSIR_DIMENSION_SCALAR: - switch (reg->data_type) - { -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - if (untyped) - shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], ""); - else -@@ -752,7 +752,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - case VSIR_DIMENSION_VEC4: - switch (reg->data_type) - { -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - if (untyped) - { - shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], ""); -@@ -800,7 +800,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - /* A double2 vector is treated as a float4 vector in enum vsir_dimension. */ - if (reg->dimension == VSIR_DIMENSION_SCALAR || reg->dimension == VSIR_DIMENSION_VEC4) - { -- if (reg->data_type == VKD3D_DATA_DOUBLE) -+ if (reg->data_type == VSIR_DATA_F64) - { - shader_print_double_literal(compiler, "", reg->u.immconst_f64[0], ""); - if (reg->dimension == VSIR_DIMENSION_VEC4) -@@ -1684,10 +1684,10 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, - shader_print_int_literal(compiler, ",", ins->texel_offset.w, ")"); - } - -- if (ins->resource_data_type[0] != VKD3D_DATA_FLOAT -- || ins->resource_data_type[1] != VKD3D_DATA_FLOAT -- || ins->resource_data_type[2] != VKD3D_DATA_FLOAT -- || ins->resource_data_type[3] != VKD3D_DATA_FLOAT) -+ if (ins->resource_data_type[0] != VSIR_DATA_F32 -+ || ins->resource_data_type[1] != VSIR_DATA_F32 -+ || ins->resource_data_type[2] != VSIR_DATA_F32 -+ || ins->resource_data_type[3] != VSIR_DATA_F32) - shader_dump_resource_data_type(compiler, ins->resource_data_type); - - for (i = 0; i < ins->dst_count; ++i) -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index eeb4deff61f..2dd9c731010 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -563,7 +563,7 @@ static void d3dbc_parse_register(struct vkd3d_shader_sm1_parser *d3dbc, - - reg_type = parse_register_type(d3dbc, param, &index_offset); - idx_count = idx_count_from_reg_type(reg_type); -- vsir_register_init(reg, reg_type, VKD3D_DATA_FLOAT, idx_count); -+ vsir_register_init(reg, reg_type, VSIR_DATA_F32, idx_count); - reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; - reg->non_uniform = false; - if (idx_count == 1) -@@ -1088,10 +1088,10 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, - { - semantic->resource_type = resource_type_table[resource_type]; - } -- semantic->resource_data_type[0] = VKD3D_DATA_FLOAT; -- semantic->resource_data_type[1] = VKD3D_DATA_FLOAT; -- semantic->resource_data_type[2] = VKD3D_DATA_FLOAT; -- semantic->resource_data_type[3] = VKD3D_DATA_FLOAT; -+ semantic->resource_data_type[0] = VSIR_DATA_F32; -+ semantic->resource_data_type[1] = VSIR_DATA_F32; -+ semantic->resource_data_type[2] = VSIR_DATA_F32; -+ semantic->resource_data_type[3] = VSIR_DATA_F32; - shader_sm1_parse_dst_param(sm1, dst_token, NULL, &semantic->resource.reg); - range = &semantic->resource.range; - range->space = 0; -@@ -1101,7 +1101,7 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, - } - - static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, -- struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vkd3d_data_type data_type) -+ struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vsir_data_type data_type) - { - unsigned int count = dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; - -@@ -1272,10 +1272,10 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - - ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; - ins->resource_stride = 0; -- ins->resource_data_type[0] = VKD3D_DATA_FLOAT; -- ins->resource_data_type[1] = VKD3D_DATA_FLOAT; -- ins->resource_data_type[2] = VKD3D_DATA_FLOAT; -- ins->resource_data_type[3] = VKD3D_DATA_FLOAT; -+ ins->resource_data_type[0] = VSIR_DATA_F32; -+ ins->resource_data_type[1] = VSIR_DATA_F32; -+ ins->resource_data_type[2] = VSIR_DATA_F32; -+ ins->resource_data_type[3] = VSIR_DATA_F32; - memset(&ins->texel_offset, 0, sizeof(ins->texel_offset)); - - p = *ptr; -@@ -1295,7 +1295,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - else if (ins->opcode == VSIR_OP_DEF) - { - shader_sm1_read_dst_param(sm1, &p, dst_param); -- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_FLOAT); -+ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VSIR_DATA_F32); - shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); - } - else if (ins->opcode == VSIR_OP_DEFB) -@@ -2147,6 +2147,9 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, - if ((result = vsir_allocate_temp_registers(program, message_context))) - return result; - -+ if ((result = vsir_update_dcl_temps(program, message_context))) -+ return result; -+ - d3dbc.program = program; - d3dbc.message_context = message_context; - switch (version->type) -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index db74a7bfbcc..f8f0d2543bd 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -882,9 +882,9 @@ struct sm6_descriptor_info - struct vkd3d_shader_register_range range; - enum vkd3d_shader_resource_type resource_type; - enum dxil_resource_kind kind; -- enum vkd3d_data_type resource_data_type; -+ enum vsir_data_type resource_data_type; - enum vkd3d_shader_register_type reg_type; -- enum vkd3d_data_type reg_data_type; -+ enum vsir_data_type reg_data_type; - }; - - struct sm6_parser -@@ -2467,13 +2467,13 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ - } - - static void register_init_with_id(struct vkd3d_shader_register *reg, -- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id) -+ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int id) - { - vsir_register_init(reg, reg_type, data_type, 1); - reg->idx[0].offset = id; - } - --static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type *type) -+static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) - { - if (type->class == TYPE_CLASS_INTEGER) - { -@@ -2499,14 +2499,14 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type - switch (type->u.width) - { - case 16: -- return VKD3D_DATA_HALF; -+ return VSIR_DATA_F16; - case 32: -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - case 64: -- return VKD3D_DATA_DOUBLE; -+ return VSIR_DATA_F64; - default: - FIXME("Unhandled width %u.\n", type->u.width); -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - } - } - -@@ -2562,8 +2562,8 @@ static void register_convert_to_minimum_precision(struct vkd3d_shader_register * - - switch (reg->data_type) - { -- case VKD3D_DATA_HALF: -- reg->data_type = VKD3D_DATA_FLOAT; -+ case VSIR_DATA_F16: -+ reg->data_type = VSIR_DATA_F32; - reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16; - if (reg->type == VKD3DSPR_IMMCONST) - { -@@ -2594,10 +2594,10 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str - struct sm6_parser *sm6) - { - const struct sm6_type *scalar_type; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - - scalar_type = sm6_type_get_scalar_type(value->type, 0); -- data_type = vkd3d_data_type_from_sm6_type(scalar_type); -+ data_type = vsir_data_type_from_dxil(scalar_type); - - switch (value->value_type) - { -@@ -3237,7 +3237,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - dst->u.data = icb; - - icb->register_idx = sm6->icb_count++; -- icb->data_type = vkd3d_data_type_from_sm6_type(elem_type); -+ icb->data_type = vsir_data_type_from_dxil(elem_type); - icb->element_count = type->u.array.count; - icb->component_count = 1; - icb->is_null = !operands; -@@ -3248,10 +3248,10 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - count = type->u.array.count; - switch (icb->data_type) - { -- case VKD3D_DATA_HALF: -+ case VSIR_DATA_F16: - for (i = 0; i < count; ++i) - icb->data[i] = half_to_float(operands[i]); -- icb->data_type = VKD3D_DATA_FLOAT; -+ icb->data_type = VSIR_DATA_F32; - break; - - case VKD3D_DATA_UINT16: -@@ -3260,13 +3260,13 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - icb->data_type = VKD3D_DATA_UINT; - break; - -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - case VKD3D_DATA_UINT: - for (i = 0; i < count; ++i) - icb->data[i] = operands[i]; - break; - -- case VKD3D_DATA_DOUBLE: -+ case VSIR_DATA_F64: - case VKD3D_DATA_UINT64: - data64 = (uint64_t *)icb->data; - for (i = 0; i < count; ++i) -@@ -3690,7 +3690,7 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru - unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init, - struct vkd3d_shader_instruction *ins, struct sm6_value *dst) - { -- enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); -+ enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type); - - if (ins) - vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_INDEXABLE_TEMP); -@@ -4068,8 +4068,8 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) - return VKD3D_OK; - } - --static void dst_param_io_init(struct vkd3d_shader_dst_param *param, -- const struct signature_element *e, enum vkd3d_shader_register_type reg_type) -+static void dst_param_io_init(struct vkd3d_shader_dst_param *param, const struct signature_element *e, -+ enum vkd3d_shader_register_type reg_type, enum vsir_dimension dimension) - { - enum vkd3d_shader_component_type component_type; - -@@ -4078,8 +4078,8 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, - param->shift = 0; - /* DXIL types do not have signedness. Load signed elements as unsigned. */ - component_type = e->component_type == VKD3D_SHADER_COMPONENT_INT ? VKD3D_SHADER_COMPONENT_UINT : e->component_type; -- vsir_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(component_type), 0); -- param->reg.dimension = VSIR_DIMENSION_VEC4; -+ vsir_register_init(¶m->reg, reg_type, vsir_data_type_from_component_type(component_type), 0); -+ param->reg.dimension = dimension; - } - - static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params, -@@ -4092,8 +4092,10 @@ static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_par - } - - static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( -- enum vkd3d_shader_sysval_semantic sysval_semantic, bool is_input) -+ enum vkd3d_shader_sysval_semantic sysval_semantic, bool is_input, enum vsir_dimension *dimension) - { -+ *dimension = VSIR_DIMENSION_VEC4; -+ - switch (sysval_semantic) - { - /* VSIR does not use an I/O register for SV_SampleIndex, but its -@@ -4104,10 +4106,13 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( - case VKD3D_SHADER_SV_COVERAGE: - return is_input ? VKD3DSPR_COVERAGE : VKD3DSPR_SAMPLEMASK; - case VKD3D_SHADER_SV_DEPTH: -+ *dimension = VSIR_DIMENSION_SCALAR; - return VKD3DSPR_DEPTHOUT; - case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: -+ *dimension = VSIR_DIMENSION_SCALAR; - return VKD3DSPR_DEPTHOUTGE; - case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: -+ *dimension = VSIR_DIMENSION_SCALAR; - return VKD3DSPR_DEPTHOUTLE; - default: - return VKD3DSPR_INVALID; -@@ -4147,18 +4152,21 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade - - for (i = 0; i < s->element_count; ++i) - { -+ enum vsir_dimension dimension; -+ - e = &s->elements[i]; - - param = ¶ms[i]; - - if (e->register_index == UINT_MAX -- && (io_reg_type = register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input)) != VKD3DSPR_NULL) -+ && (io_reg_type = register_type_from_dxil_semantic_kind( -+ e->sysval_semantic, is_input, &dimension)) != VKD3DSPR_NULL) - { -- dst_param_io_init(param, e, io_reg_type); -+ dst_param_io_init(param, e, io_reg_type, dimension); - continue; - } - -- dst_param_io_init(param, e, reg_type); -+ dst_param_io_init(param, e, reg_type, VSIR_DIMENSION_VEC4); - count = 0; - - if (is_control_point) -@@ -5169,7 +5177,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr - - type = sm6_type_get_scalar_type(dst->type, 0); - VKD3D_ASSERT(type); -- src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type); -+ src_param->reg.data_type = vsir_data_type_from_dxil(type); - if (data_type_is_64_bit(src_param->reg.data_type)) - src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); - else -@@ -5179,7 +5187,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr - } - - static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, -- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int component_count) -+ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int component_count) - { - struct vkd3d_shader_dst_param *dst_param; - struct vkd3d_shader_instruction *ins; -@@ -5194,8 +5202,8 @@ static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_s - } - } - --static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, -- struct vkd3d_shader_instruction *ins, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type) -+static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, -+ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, bool scalar) - { - struct vkd3d_shader_src_param *src_param; - -@@ -5205,6 +5213,8 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, - return; - sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, data_type, 1); - vsir_register_init(&src_param->reg, reg_type, data_type, 0); -+ if (!scalar) -+ src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param_init(src_param); - - instruction_dst_param_init_ssa_scalar(ins, sm6); -@@ -5213,7 +5223,7 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, - static void sm6_parser_emit_dx_coverage(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VKD3D_DATA_UINT); -+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VKD3D_DATA_UINT, false); - } - - static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6, -@@ -5333,8 +5343,8 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 3); -- vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 0); -+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, VKD3DSPR_TESSCOORD, VSIR_DATA_F32, 3); -+ vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VSIR_DATA_F32, 0); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param_init_scalar(src_param, component_idx); - -@@ -5477,11 +5487,9 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; - vsir_register_init(&src_param->reg, reg_type, VKD3D_DATA_UINT, 0); -+ src_param->reg.dimension = VSIR_DIMENSION_VEC4; - if (component_count > 1) -- { -- src_param->reg.dimension = VSIR_DIMENSION_VEC4; - component_idx = sm6_value_get_constant_uint(operands[0], sm6); -- } - src_param_init_scalar(src_param, component_idx); - - instruction_dst_param_init_ssa_scalar(ins, sm6); -@@ -5713,13 +5721,13 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri - static void sm6_parser_emit_dx_output_control_point_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT); -+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, true); - } - - static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VKD3D_DATA_UINT); -+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VKD3D_DATA_UINT, true); - } - - static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op) -@@ -5996,12 +6004,12 @@ static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_ - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- vsir_register_init(&src_param->reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&src_param->reg, VKD3DSPR_RASTERIZER, VSIR_DATA_F32, 0); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param_init(src_param); - - instruction_dst_param_init_ssa_scalar(ins, sm6); -- ins->dst->reg.data_type = VKD3D_DATA_FLOAT; -+ ins->dst->reg.data_type = VSIR_DATA_F32; - } - - static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -6030,7 +6038,7 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in - else - { - src_param_init_vector(&src_params[0], 2); -- vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VSIR_DATA_F32, 0); - src_params[0].reg.dimension = VSIR_DIMENSION_VEC4; - src_param_init_from_value(&src_params[1], operands[0], sm6); - } -@@ -6535,7 +6543,7 @@ static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intr - vkd3d_unreachable(); - } - -- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VKD3D_DATA_UINT); -+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VKD3D_DATA_UINT, true); - } - - struct sm6_dx_opcode_info -@@ -9031,7 +9039,7 @@ static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_k - } - } - --static const enum vkd3d_data_type data_type_table[] = -+static const enum vsir_data_type data_type_table[] = - { - [COMPONENT_TYPE_INVALID] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_I1] = VKD3D_DATA_UNUSED, -@@ -9041,30 +9049,30 @@ static const enum vkd3d_data_type data_type_table[] = - [COMPONENT_TYPE_U32] = VKD3D_DATA_UINT, - [COMPONENT_TYPE_I64] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_U64] = VKD3D_DATA_UNUSED, -- [COMPONENT_TYPE_F16] = VKD3D_DATA_FLOAT, -- [COMPONENT_TYPE_F32] = VKD3D_DATA_FLOAT, -- [COMPONENT_TYPE_F64] = VKD3D_DATA_DOUBLE, -+ [COMPONENT_TYPE_F16] = VSIR_DATA_F32, -+ [COMPONENT_TYPE_F32] = VSIR_DATA_F32, -+ [COMPONENT_TYPE_F64] = VSIR_DATA_F64, - [COMPONENT_TYPE_SNORMF16] = VKD3D_DATA_SNORM, - [COMPONENT_TYPE_UNORMF16] = VKD3D_DATA_UNORM, - [COMPONENT_TYPE_SNORMF32] = VKD3D_DATA_SNORM, - [COMPONENT_TYPE_UNORMF32] = VKD3D_DATA_UNORM, -- [COMPONENT_TYPE_SNORMF64] = VKD3D_DATA_DOUBLE, -- [COMPONENT_TYPE_UNORMF64] = VKD3D_DATA_DOUBLE, -+ [COMPONENT_TYPE_SNORMF64] = VSIR_DATA_F64, -+ [COMPONENT_TYPE_UNORMF64] = VSIR_DATA_F64, - [COMPONENT_TYPE_PACKEDS8X32] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_PACKEDU8X32] = VKD3D_DATA_UNUSED, - }; - --static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_component_type type, -+static enum vsir_data_type vsir_data_type_from_dxil_component_type(enum dxil_component_type type, - struct sm6_parser *sm6) - { -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - - if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VKD3D_DATA_UNUSED) - { - FIXME("Unhandled component type %u.\n", type); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, - "Resource descriptor component type %u is unhandled.", type); -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - } - - return data_type; -@@ -9072,7 +9080,7 @@ static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_c - - struct resource_additional_values - { -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - unsigned int byte_stride; - }; - -@@ -9113,7 +9121,7 @@ static bool resources_load_additional_values(struct resource_additional_values * - "An untyped resource has type %u.", value); - return false; - } -- info->data_type = vkd3d_data_type_from_dxil_component_type(value, sm6); -+ info->data_type = vsir_data_type_from_dxil_component_type(value, sm6); - break; - - case RESOURCE_TAG_ELEMENT_STRIDE: -@@ -9241,8 +9249,8 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc - } - - static void init_resource_declaration(struct vkd3d_shader_resource *resource, -- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id, -- const struct vkd3d_shader_register_range *range) -+ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, -+ unsigned int id, const struct vkd3d_shader_register_range *range) - { - struct vkd3d_shader_dst_param *param = &resource->reg; - -@@ -9413,7 +9421,7 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, - ins->declaration.cb.src.modifiers = VKD3DSPSM_NONE; - - reg = &ins->declaration.cb.src.reg; -- vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); -+ vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 3); - reg->idx[0].offset = d->id; - reg->idx[1].offset = d->range.first; - reg->idx[2].offset = d->range.last; -@@ -9421,8 +9429,8 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, - ins->declaration.cb.range = d->range; - - d->reg_type = VKD3DSPR_CONSTBUFFER; -- d->reg_data_type = VKD3D_DATA_FLOAT; -- d->resource_data_type = VKD3D_DATA_FLOAT; -+ d->reg_data_type = VSIR_DATA_F32; -+ d->resource_data_type = VSIR_DATA_F32; - - return VKD3D_OK; - } -@@ -9815,7 +9823,9 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const - - if ((is_register = e->register_index == UINT_MAX)) - { -- if (register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input) == VKD3DSPR_INVALID) -+ enum vsir_dimension dimension; -+ -+ if (register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input, &dimension) == VKD3DSPR_INVALID) - { - WARN("Unhandled I/O register semantic kind %u.\n", j); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE, -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index b3e3d10791d..bf407f0fc9c 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -328,12 +328,12 @@ static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_ca - } - - static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vkd3d_glsl_generator *gen, -- const char *src, enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type, unsigned int size) -+ const char *src, enum vsir_data_type dst_data_type, enum vsir_data_type src_data_type, unsigned int size) - { - if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) -- dst_data_type = VKD3D_DATA_FLOAT; -+ dst_data_type = VSIR_DATA_F32; - if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM) -- src_data_type = VKD3D_DATA_FLOAT; -+ src_data_type = VSIR_DATA_F32; - - if (dst_data_type == src_data_type) - { -@@ -341,7 +341,7 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk - return; - } - -- if (src_data_type == VKD3D_DATA_FLOAT) -+ if (src_data_type == VSIR_DATA_F32) - { - switch (dst_data_type) - { -@@ -360,7 +360,7 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk - { - switch (dst_data_type) - { -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - vkd3d_string_buffer_printf(dst, "uintBitsToFloat(%s)", src); - return; - case VKD3D_DATA_INT: -@@ -381,11 +381,11 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk - } - - static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, -- const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) -+ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vsir_data_type data_type) - { - const struct vkd3d_shader_register *reg = &vsir_src->reg; - struct vkd3d_string_buffer *register_name, *str; -- enum vkd3d_data_type src_data_type; -+ enum vsir_data_type src_data_type; - unsigned int size; - - register_name = vkd3d_string_buffer_get(&gen->string_buffers); -@@ -397,7 +397,7 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd - if (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_THREADID) - src_data_type = VKD3D_DATA_UINT; - else -- src_data_type = VKD3D_DATA_FLOAT; -+ src_data_type = VSIR_DATA_F32; - - shader_glsl_print_register_name(register_name, gen, reg); - -@@ -492,7 +492,7 @@ static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, stru - } - - static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_glsl_generator *gen, -- struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, va_list args) -+ struct glsl_dst *dst, enum vsir_data_type data_type, const char *format, va_list args) - { - struct vkd3d_string_buffer *buffer = gen->buffer; - uint32_t modifiers = dst->vsir->modifiers; -@@ -519,7 +519,7 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled destination register data type %#x.", data_type); - /* fall through */ -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - close = false; - break; - case VKD3D_DATA_INT: -@@ -550,7 +550,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( - } - - static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3d_glsl_generator *gen, -- struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, ...) -+ struct glsl_dst *dst, enum vsir_data_type data_type, const char *format, ...) - { - va_list args; - -@@ -797,7 +797,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ - const struct vkd3d_shader_descriptor_info1 *d; - enum vkd3d_shader_resource_type resource_type; - struct vkd3d_string_buffer *fetch; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - struct glsl_src coord; - struct glsl_dst dst; - uint32_t coord_mask; -@@ -826,7 +826,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ - resource_space = 0; - resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; - sample_count = 1; -- data_type = VKD3D_DATA_FLOAT; -+ data_type = VSIR_DATA_F32; - } - - if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) -@@ -912,7 +912,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk - enum vkd3d_shader_resource_type resource_type; - unsigned int component_idx, coord_size; - struct vkd3d_string_buffer *sample; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - struct glsl_dst dst; - - bias = ins->opcode == VSIR_OP_SAMPLE_B; -@@ -946,7 +946,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk - "Internal compiler error: Undeclared resource descriptor %u.", resource_id); - resource_space = 0; - resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -- data_type = VKD3D_DATA_FLOAT; -+ data_type = VSIR_DATA_F32; - } - - if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) -@@ -1061,7 +1061,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s - enum vkd3d_shader_resource_type resource_type; - unsigned int uav_id, uav_idx, uav_space; - struct vkd3d_string_buffer *load; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - struct glsl_src coord; - struct glsl_dst dst; - uint32_t coord_mask; -@@ -1084,7 +1084,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s - "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); - uav_space = 0; - resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -- data_type = VKD3D_DATA_FLOAT; -+ data_type = VSIR_DATA_F32; - } - - if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) -@@ -1121,7 +1121,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const - enum vkd3d_shader_resource_type resource_type; - unsigned int uav_id, uav_idx, uav_space; - struct vkd3d_string_buffer *image_data; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - struct glsl_src image_coord; - uint32_t coord_mask; - -@@ -1143,7 +1143,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const - "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); - uav_space = 0; - resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -- data_type = VKD3D_DATA_FLOAT; -+ data_type = VSIR_DATA_F32; - } - - if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) -@@ -1174,7 +1174,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled data type %#x.", data_type); - /* fall through */ -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: - vkd3d_string_buffer_printf(image_data, "vec4("); -@@ -1779,7 +1779,7 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge - "Internal compiler error: Unhandled data type %#x for UAV %u.", - uav->resource_data_type, uav->register_id); - /* fall through */ -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: - image_type_prefix = ""; -@@ -2001,7 +2001,7 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator - case VKD3D_DATA_INT: - sampler_type_prefix = "i"; - break; -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: - sampler_type_prefix = ""; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index afd6169514f..86198ce548f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -233,6 +233,20 @@ static bool divert_written_uniform_derefs_to_temp(struct hlsl_ctx *ctx, struct h - return true; - } - -+static void warn_on_field_semantic(struct hlsl_ctx *ctx, -+ const struct hlsl_struct_field *field, const struct hlsl_semantic *outer) -+{ -+ if (!field->semantic.name) -+ return; -+ -+ if (!ascii_strcasecmp(field->semantic.name, outer->name) && field->semantic.index == outer->index) -+ return; -+ -+ hlsl_warning(ctx, &field->loc, VKD3D_SHADER_WARNING_HLSL_OVERRIDDEN_SEMANTIC, -+ "Field semantic %s%u is overridden by outer semantic %s%u.\n", -+ field->semantic.name, field->semantic.index, outer->name, outer->index); -+} -+ - static void validate_field_semantic(struct hlsl_ctx *ctx, struct hlsl_struct_field *field) - { - if (!field->semantic.name && hlsl_is_numeric_type(hlsl_get_multiarray_element_type(field->type)) -@@ -288,10 +302,10 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls - - static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, -- uint32_t index, uint32_t stream_index, bool output, bool force_align, bool create, -- const struct vkd3d_shader_location *loc) -+ uint32_t stream_index, bool output, bool force_align, bool create, const struct vkd3d_shader_location *loc) - { - struct hlsl_semantic new_semantic; -+ uint32_t index = semantic->index; - struct hlsl_ir_var *ext_var; - const char *prefix; - char *new_name; -@@ -397,7 +411,7 @@ static uint32_t combine_field_storage_modifiers(uint32_t modifiers, uint32_t fie - - static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, -- uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) -+ uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align) - { - struct hlsl_type *type = lhs->node.data_type, *vector_type_src, *vector_type_dst; - struct vkd3d_shader_location *loc = &lhs->node.loc; -@@ -442,8 +456,9 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec - prim_type_src->modifiers = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK; - - if (!(input = add_semantic_var(ctx, func, var, prim_type_src, -- modifiers, semantic, semantic_index + i, 0, false, force_align, true, loc))) -+ modifiers, semantic, 0, false, force_align, true, loc))) - return; -+ ++semantic->index; - hlsl_init_simple_deref_from_var(&prim_deref, input); - - idx = hlsl_block_add_uint_constant(ctx, block, prim_index, &var->loc); -@@ -455,8 +470,9 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec - else - { - if (!(input = add_semantic_var(ctx, func, var, vector_type_src, -- modifiers, semantic, semantic_index + i, 0, false, force_align, true, loc))) -+ modifiers, semantic, 0, false, force_align, true, loc))) - return; -+ ++semantic->index; - - if (!(load = hlsl_new_var_load(ctx, input, &var->loc))) - return; -@@ -482,7 +498,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec - - static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, -- uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) -+ uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align) - { - struct vkd3d_shader_location *loc = &lhs->node.loc; - struct hlsl_type *type = lhs->node.data_type; -@@ -494,21 +510,31 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func - { - struct hlsl_ir_load *element_load; - struct hlsl_struct_field *field; -- uint32_t elem_semantic_index; - - for (i = 0; i < hlsl_type_element_count(type); ++i) - { - uint32_t element_modifiers; - -+ if (type->class == HLSL_CLASS_STRUCT) -+ loc = &type->e.record.fields[i].loc; -+ -+ c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); -+ -+ /* This redundant load is expected to be deleted later by DCE. */ -+ if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc))) -+ return; -+ hlsl_block_add_instr(block, &element_load->node); -+ - if (type->class == HLSL_CLASS_ARRAY) - { -- elem_semantic_index = semantic_index -- + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4; - element_modifiers = modifiers; - force_align = true; - - if (hlsl_type_is_primitive_array(type)) - prim_index = i; -+ -+ prepend_input_copy_recurse(ctx, func, block, prim_index, -+ element_load, element_modifiers, semantic, force_align); - } - else - { -@@ -518,28 +544,33 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func - hlsl_fixme(ctx, &field->loc, "Prepend uniform copies for resource components within structs."); - continue; - } -- validate_field_semantic(ctx, field); -- semantic = &field->semantic; -- elem_semantic_index = semantic->index; -- loc = &field->loc; - element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers); - force_align = (i == 0); -- } - -- c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); -+ if (semantic->name) -+ { -+ warn_on_field_semantic(ctx, field, semantic); -+ prepend_input_copy_recurse(ctx, func, block, prim_index, -+ element_load, element_modifiers, semantic, force_align); -+ } -+ else -+ { -+ struct hlsl_semantic semantic_copy; - -- /* This redundant load is expected to be deleted later by DCE. */ -- if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc))) -- return; -- hlsl_block_add_instr(block, &element_load->node); -+ validate_field_semantic(ctx, field); - -- prepend_input_copy_recurse(ctx, func, block, prim_index, element_load, -- element_modifiers, semantic, elem_semantic_index, force_align); -+ if (!(hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic))) -+ return; -+ prepend_input_copy_recurse(ctx, func, block, prim_index, -+ element_load, element_modifiers, &semantic_copy, force_align); -+ hlsl_cleanup_semantic(&semantic_copy); -+ } -+ } - } - } - else - { -- prepend_input_copy(ctx, func, block, prim_index, lhs, modifiers, semantic, semantic_index, force_align); -+ prepend_input_copy(ctx, func, block, prim_index, lhs, modifiers, semantic, force_align); - } - } - -@@ -547,6 +578,7 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func - * and copy the former to the latter, so that writes to input variables work. */ - static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var) - { -+ struct hlsl_semantic semantic_copy; - struct hlsl_ir_load *load; - struct hlsl_block block; - -@@ -557,15 +589,20 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function - return; - hlsl_block_add_instr(&block, &load->node); - -- prepend_input_copy_recurse(ctx, func, &block, 0, load, var->storage_modifiers, -- &var->semantic, var->semantic.index, false); -+ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) -+ { -+ hlsl_block_cleanup(&block); -+ return; -+ } -+ prepend_input_copy_recurse(ctx, func, &block, 0, load, var->storage_modifiers, &semantic_copy, false); -+ hlsl_cleanup_semantic(&semantic_copy); - - list_move_head(&func->body.instrs, &block.instrs); - } - - static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, -- struct hlsl_semantic *semantic, uint32_t semantic_index, uint32_t stream_index, bool force_align, bool create) -+ struct hlsl_semantic *semantic, uint32_t stream_index, bool force_align, bool create) - { - struct hlsl_type *type = rhs->node.data_type, *vector_type; - struct vkd3d_shader_location *loc = &rhs->node.loc; -@@ -594,9 +631,10 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_var *output; - struct hlsl_ir_node *load; - -- if (!(output = add_semantic_var(ctx, func, var, vector_type, -- modifiers, semantic, semantic_index + i, stream_index, true, force_align, create, loc))) -+ if (!(output = add_semantic_var(ctx, func, var, vector_type, modifiers, -+ semantic, stream_index, true, force_align, create, loc))) - return; -+ ++semantic->index; - - if (type->class == HLSL_CLASS_MATRIX) - { -@@ -615,8 +653,8 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - } - - static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, -- struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, -- struct hlsl_semantic *semantic, uint32_t semantic_index, uint32_t stream_index, bool force_align, bool create) -+ struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, -+ uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t stream_index, bool force_align, bool create) - { - struct vkd3d_shader_location *loc = &rhs->node.loc; - struct hlsl_ir_var *var = rhs->src.var; -@@ -627,47 +665,62 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * - { - for (i = 0; i < hlsl_type_element_count(type); ++i) - { -- uint32_t element_modifiers, elem_semantic_index; - const struct hlsl_type *element_type; - struct hlsl_ir_load *element_load; - struct hlsl_struct_field *field; -+ uint32_t element_modifiers; -+ -+ if (type->class == HLSL_CLASS_STRUCT) -+ loc = &type->e.record.fields[i].loc; -+ -+ c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); -+ if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc))) -+ return; -+ hlsl_block_add_instr(block, &element_load->node); - - if (type->class == HLSL_CLASS_ARRAY) - { -- elem_semantic_index = semantic_index -- + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4; - element_type = type->e.array.type; - element_modifiers = modifiers; - force_align = true; -+ -+ append_output_copy_recurse(ctx, block, func, element_type, element_load, -+ element_modifiers, semantic, stream_index, force_align, create); - } - else - { - field = &type->e.record.fields[i]; - if (hlsl_type_is_resource(field->type)) - continue; -- validate_field_semantic(ctx, field); -- semantic = &field->semantic; -- elem_semantic_index = semantic->index; -- loc = &field->loc; - element_type = field->type; - element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers); - force_align = (i == 0); -- } - -- c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); -+ if (semantic->name) -+ { -+ warn_on_field_semantic(ctx, field, semantic); - -- if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc))) -- return; -- hlsl_block_add_instr(block, &element_load->node); -+ append_output_copy_recurse(ctx, block, func, element_type, element_load, -+ element_modifiers, semantic, stream_index, force_align, create); -+ } -+ else -+ { -+ struct hlsl_semantic semantic_copy; -+ -+ validate_field_semantic(ctx, field); - -- append_output_copy_recurse(ctx, block, func, element_type, element_load, element_modifiers, semantic, -- elem_semantic_index, stream_index, force_align, create); -+ if (!hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic)) -+ continue; -+ append_output_copy_recurse(ctx, block, func, element_type, element_load, -+ element_modifiers, &semantic_copy, stream_index, force_align, create); -+ hlsl_cleanup_semantic(&semantic_copy); -+ } -+ } - } - } - else - { -- append_output_copy(ctx, block, func, rhs, modifiers, semantic, -- semantic_index, stream_index, force_align, create); -+ append_output_copy(ctx, block, func, rhs, modifiers, semantic, stream_index, force_align, create); - } - } - -@@ -676,6 +729,7 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * - * variables work. */ - static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var) - { -+ struct hlsl_semantic semantic_copy; - struct hlsl_ir_load *load; - - /* This redundant load is expected to be deleted later by DCE. */ -@@ -683,8 +737,11 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function - return; - hlsl_block_add_instr(&func->body, &load->node); - -- append_output_copy_recurse(ctx, &func->body, func, var->data_type, load, var->storage_modifiers, -- &var->semantic, var->semantic.index, 0, false, true); -+ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) -+ return; -+ append_output_copy_recurse(ctx, &func->body, func, var->data_type, -+ load, var->storage_modifiers, &semantic_copy, 0, false, true); -+ hlsl_cleanup_semantic(&semantic_copy); - } - - bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), -@@ -3375,6 +3432,7 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst - { - struct stream_append_ctx *append_ctx = context; - struct hlsl_ir_resource_store *store; -+ struct hlsl_semantic semantic_copy; - const struct hlsl_ir_node *rhs; - const struct hlsl_type *type; - struct hlsl_ir_var *var; -@@ -3405,9 +3463,12 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst - - hlsl_block_init(&block); - -+ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) -+ return false; - append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), -- var->storage_modifiers, &var->semantic, var->semantic.index, -- var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, false, !append_ctx->created[stream_index]); -+ var->storage_modifiers, &semantic_copy, var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, -+ false, !append_ctx->created[stream_index]); -+ hlsl_cleanup_semantic(&semantic_copy); - - append_ctx->created[stream_index] = true; - -@@ -8164,10 +8225,10 @@ static void generate_vsir_signature(struct hlsl_ctx *ctx, - } - } - --static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type) -+static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type) - { - if (hlsl_version_lt(ctx, 4, 0)) -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - - if (type->class == HLSL_CLASS_ARRAY) - return vsir_data_type_from_hlsl_type(ctx, type->e.array.type); -@@ -8178,11 +8239,11 @@ static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, - switch (type->e.numeric.type) - { - case HLSL_TYPE_DOUBLE: -- return VKD3D_DATA_DOUBLE; -+ return VSIR_DATA_F64; - case HLSL_TYPE_FLOAT: -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - case HLSL_TYPE_HALF: -- return VKD3D_DATA_HALF; -+ return VSIR_DATA_F16; - case HLSL_TYPE_INT: - return VKD3D_DATA_INT; - case HLSL_TYPE_UINT: -@@ -8195,7 +8256,7 @@ static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, - return VKD3D_DATA_UNUSED; - } - --static enum vkd3d_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx, -+static enum vsir_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx, - const struct hlsl_ir_node *instr) - { - return vsir_data_type_from_hlsl_type(ctx, instr->data_type); -@@ -8238,17 +8299,17 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr - ++instructions->count; - - dst_param = &ins->dst[0]; -- vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->dst[0].reg.idx[0].offset = constant_reg->index; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; - - src_param = &ins->src[0]; -- vsir_register_init(&src_param->reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&src_param->reg, VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); - src_param->reg.type = VKD3DSPR_IMMCONST; - src_param->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; - src_param->reg.non_uniform = false; -- src_param->reg.data_type = VKD3D_DATA_FLOAT; -+ src_param->reg.data_type = VSIR_DATA_F32; - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - for (x = 0; x < 4; ++x) - src_param->reg.u.immconst_f32[x] = constant_reg->value.f[x]; -@@ -8324,7 +8385,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, - semantic->resource_type = resource_type; - - dst_param = &semantic->resource.reg; -- vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1); - dst_param->reg.dimension = VSIR_DIMENSION_NONE; - dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index + i; - dst_param->write_mask = 0; -@@ -8394,7 +8455,7 @@ static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction( - - static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src, - struct hlsl_ctx *ctx, const struct hlsl_constant_value *value, -- enum vkd3d_data_type type, unsigned int width, unsigned int map_writemask) -+ enum vsir_data_type type, unsigned int width, unsigned int map_writemask) - { - unsigned int i, j; - -@@ -8699,7 +8760,7 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, - return; - - src_param = &ins->src[0]; -- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param->reg.idx[0].offset = constant->reg.id; - src_param->swizzle = generate_vsir_get_src_swizzle(constant->reg.writemask, instr->reg.writemask); -@@ -8789,13 +8850,13 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx - return; - - dst_param = &ins->dst[0]; -- vsir_register_init(&dst_param->reg, instr->reg.type, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&dst_param->reg, instr->reg.type, VSIR_DATA_F32, 1); - dst_param->reg.idx[0].offset = instr->reg.id; - dst_param->reg.dimension = VSIR_DIMENSION_VEC4; - dst_param->write_mask = 1u << i; - - src_param = &ins->src[0]; -- vsir_register_init(&src_param->reg, operand->reg.type, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&src_param->reg, operand->reg.type, VSIR_DATA_F32, 1); - src_param->reg.idx[0].offset = operand->reg.id; - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - c = vsir_swizzle_get_component(src_swizzle, i); -@@ -8825,13 +8886,13 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi - if (ctx->profile->major_version < 3) - { - src_param = &ins->src[1]; -- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param->reg.idx[0].offset = ctx->d3dsincosconst1.id; - src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; - - src_param = &ins->src[2]; -- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param->reg.idx[0].offset = ctx->d3dsincosconst2.id; - src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; -@@ -9156,12 +9217,12 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, - - if (type == VKD3DSPR_DEPTHOUT) - { -- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 0); - dst_param->reg.dimension = VSIR_DIMENSION_SCALAR; - } - else - { -- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 1); - dst_param->reg.idx[0].offset = register_index; - dst_param->reg.dimension = VSIR_DIMENSION_VEC4; - } -@@ -9184,7 +9245,7 @@ static void sm1_generate_vsir_instr_mova(struct hlsl_ctx *ctx, - return; - - dst_param = &ins->dst[0]; -- vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VSIR_DATA_F32, 0); - dst_param->write_mask = VKD3DSP_WRITEMASK_0; - - VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); -@@ -9204,7 +9265,7 @@ static struct vkd3d_shader_src_param *sm1_generate_vsir_new_address_src(struct h - } - - memset(idx_src, 0, sizeof(*idx_src)); -- vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VSIR_DATA_F32, 0); - idx_src->reg.dimension = VSIR_DIMENSION_VEC4; - idx_src->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); - return idx_src; -@@ -9283,7 +9344,7 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, - writemask = reg.writemask; - } - -- vsir_register_init(&src_param->reg, type, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&src_param->reg, type, VSIR_DATA_F32, 1); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param->reg.idx[0].offset = register_index; - src_param->reg.idx[0].rel_addr = src_rel_addr; -@@ -10132,18 +10193,18 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs - if (is_primitive) - { - VKD3D_ASSERT(has_idx); -- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 2); -+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 2); - dst_param->reg.idx[0].offset = var->data_type->e.array.elements_count; - dst_param->reg.idx[1].offset = idx; - } - else if (has_idx) - { -- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 1); - dst_param->reg.idx[0].offset = idx; - } - else - { -- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 0); - } - - if (shader_sm4_is_scalar_register(&dst_param->reg)) -@@ -10180,7 +10241,7 @@ static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx, - ins->declaration.indexable_temp.register_idx = idx; - ins->declaration.indexable_temp.register_size = size; - ins->declaration.indexable_temp.alignment = 0; -- ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT; -+ ins->declaration.indexable_temp.data_type = VSIR_DATA_F32; - ins->declaration.indexable_temp.component_count = comp_count; - ins->declaration.indexable_temp.has_function_scope = false; - } -@@ -10371,7 +10432,7 @@ static void sm4_generate_vsir_rcp_using_div(struct hlsl_ctx *ctx, - value.u[2].f = 1.0f; - value.u[3].f = 1.0f; - vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, -- VKD3D_DATA_FLOAT, instr->data_type->e.numeric.dimx, dst_param->write_mask); -+ VSIR_DATA_F32, instr->data_type->e.numeric.dimx, dst_param->write_mask); - - vsir_src_from_hlsl_node(&ins->src[1], ctx, operand, dst_param->write_mask); - } -@@ -12020,7 +12081,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, - ins->declaration.cb.size = cbuffer->size; - - src_param = &ins->declaration.cb.src; -- vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 0); -+ vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 0); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; - -@@ -12106,14 +12167,14 @@ static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const - } - } - --static enum vkd3d_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) -+static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) - { - const struct hlsl_type *format = type->e.resource.format; - - switch (format->e.numeric.type) - { - case HLSL_TYPE_DOUBLE: -- return VKD3D_DATA_DOUBLE; -+ return VSIR_DATA_F64; - - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: -@@ -12121,7 +12182,7 @@ static enum vkd3d_data_type sm4_generate_vsir_get_format_type(const struct hlsl_ - return VKD3D_DATA_UNORM; - if (format->modifiers & HLSL_MODIFIER_SNORM) - return VKD3D_DATA_SNORM; -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - - case HLSL_TYPE_INT: - return VKD3D_DATA_INT; -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index b060ccbb2bc..18cda0269af 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -555,7 +555,7 @@ static uint32_t vsir_combine_swizzles(uint32_t first, uint32_t second) - } - - void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, -- enum vkd3d_data_type data_type, unsigned int idx_count) -+ enum vsir_data_type data_type, unsigned int idx_count) - { - reg->type = reg_type; - reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; -@@ -581,7 +581,7 @@ static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shade - } - - void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, -- enum vkd3d_data_type data_type, unsigned int idx_count) -+ enum vsir_data_type data_type, unsigned int idx_count) - { - vsir_register_init(¶m->reg, reg_type, data_type, idx_count); - param->swizzle = 0; -@@ -597,7 +597,7 @@ static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32 - static void vsir_src_param_init_io(struct vkd3d_shader_src_param *src, - enum vkd3d_shader_register_type reg_type, const struct signature_element *e, unsigned int idx_count) - { -- vsir_src_param_init(src, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count); -+ vsir_src_param_init(src, reg_type, vsir_data_type_from_component_type(e->component_type), idx_count); - src->reg.dimension = VSIR_DIMENSION_VEC4; - src->swizzle = vsir_swizzle_from_writemask(e->mask); - } -@@ -609,13 +609,13 @@ void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned in - param->reg.idx[0].offset = label_id; - } - --static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type) -+static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vsir_data_type type) - { - vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1); - src->reg.idx[0].offset = idx; - } - --static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type) -+static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vsir_data_type type) - { - vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1); - src->reg.idx[0].offset = idx; -@@ -641,7 +641,7 @@ static void vsir_src_param_init_sampler(struct vkd3d_shader_src_param *src, unsi - } - - static void src_param_init_ssa(struct vkd3d_shader_src_param *src, unsigned int idx, -- enum vkd3d_data_type data_type, enum vsir_dimension dimension) -+ enum vsir_data_type data_type, enum vsir_dimension dimension) - { - vsir_src_param_init(src, VKD3DSPR_SSA, data_type, 1); - src->reg.idx[0].offset = idx; -@@ -653,8 +653,8 @@ static void src_param_init_ssa(struct vkd3d_shader_src_param *src, unsigned int - } - } - --static void src_param_init_ssa_scalar(struct vkd3d_shader_src_param *src, unsigned int idx, -- enum vkd3d_data_type data_type) -+static void src_param_init_ssa_scalar(struct vkd3d_shader_src_param *src, -+ unsigned int idx, enum vsir_data_type data_type) - { - src_param_init_ssa(src, idx, data_type, VSIR_DIMENSION_SCALAR); - } -@@ -666,12 +666,12 @@ static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned - - static void src_param_init_ssa_float(struct vkd3d_shader_src_param *src, unsigned int idx) - { -- src_param_init_ssa_scalar(src, idx, VKD3D_DATA_FLOAT); -+ src_param_init_ssa_scalar(src, idx, VSIR_DATA_F32); - } - - static void src_param_init_ssa_float4(struct vkd3d_shader_src_param *src, unsigned int idx) - { -- src_param_init_ssa(src, idx, VKD3D_DATA_FLOAT, VSIR_DIMENSION_VEC4); -+ src_param_init_ssa(src, idx, VSIR_DATA_F32, VSIR_DIMENSION_VEC4); - } - - static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx) -@@ -682,13 +682,13 @@ static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigne - - static void src_param_init_temp_float(struct vkd3d_shader_src_param *src, unsigned int idx) - { -- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); - src->reg.idx[0].offset = idx; - } - - static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsigned int idx) - { -- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); - src->reg.dimension = VSIR_DIMENSION_VEC4; - src->swizzle = VKD3D_SHADER_NO_SWIZZLE; - src->reg.idx[0].offset = idx; -@@ -701,7 +701,7 @@ static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigne - } - - void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, -- enum vkd3d_data_type data_type, unsigned int idx_count) -+ enum vsir_data_type data_type, unsigned int idx_count) - { - vsir_register_init(¶m->reg, reg_type, data_type, idx_count); - param->write_mask = VKD3DSP_WRITEMASK_0; -@@ -712,7 +712,7 @@ void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader - static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_register_type reg_type, - const struct signature_element *e, unsigned int idx_count) - { -- vsir_dst_param_init(dst, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count); -+ vsir_dst_param_init(dst, reg_type, vsir_data_type_from_component_type(e->component_type), idx_count); - dst->reg.dimension = VSIR_DIMENSION_VEC4; - dst->write_mask = e->mask; - } -@@ -725,7 +725,7 @@ void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst) - } - - static void dst_param_init_ssa(struct vkd3d_shader_dst_param *dst, unsigned int idx, -- enum vkd3d_data_type data_type, enum vsir_dimension dimension) -+ enum vsir_data_type data_type, enum vsir_dimension dimension) - { - vsir_dst_param_init(dst, VKD3DSPR_SSA, data_type, 1); - dst->reg.idx[0].offset = idx; -@@ -737,8 +737,8 @@ static void dst_param_init_ssa(struct vkd3d_shader_dst_param *dst, unsigned int - } - } - --static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *dst, unsigned int idx, -- enum vkd3d_data_type data_type) -+static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *dst, -+ unsigned int idx, enum vsir_data_type data_type) - { - dst_param_init_ssa(dst, idx, data_type, VSIR_DIMENSION_SCALAR); - } -@@ -750,12 +750,12 @@ static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned - - static void dst_param_init_ssa_float(struct vkd3d_shader_dst_param *dst, unsigned int idx) - { -- dst_param_init_ssa_scalar(dst, idx, VKD3D_DATA_FLOAT); -+ dst_param_init_ssa_scalar(dst, idx, VSIR_DATA_F32); - } - - static void dst_param_init_ssa_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx) - { -- dst_param_init_ssa(dst, idx, VKD3D_DATA_FLOAT, VSIR_DIMENSION_VEC4); -+ dst_param_init_ssa(dst, idx, VSIR_DATA_F32, VSIR_DIMENSION_VEC4); - } - - static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) -@@ -766,7 +766,7 @@ static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigne - - static void dst_param_init_temp_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx) - { -- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); - dst->reg.idx[0].offset = idx; - dst->reg.dimension = VSIR_DIMENSION_VEC4; - } -@@ -778,7 +778,7 @@ static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigne - } - - static void dst_param_init_output(struct vkd3d_shader_dst_param *dst, -- enum vkd3d_data_type data_type, uint32_t idx, uint32_t write_mask) -+ enum vsir_data_type data_type, uint32_t idx, uint32_t write_mask) - { - vsir_dst_param_init(dst, VKD3DSPR_OUTPUT, data_type, 1); - dst->reg.idx[0].offset = idx; -@@ -850,15 +850,15 @@ static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *i - vsir_instruction_init(ins, &location, VSIR_OP_NOP); - } - --static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type, -- enum vkd3d_shader_opcode *opcode, bool *requires_swap) -+static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, -+ enum vsir_data_type data_type, enum vkd3d_shader_opcode *opcode, bool *requires_swap) - { - switch (rel_op) - { - case VKD3D_SHADER_REL_OP_LT: - case VKD3D_SHADER_REL_OP_GT: - *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_GT); -- if (data_type == VKD3D_DATA_FLOAT) -+ if (data_type == VSIR_DATA_F32) - { - *opcode = VSIR_OP_LTO; - return true; -@@ -868,7 +868,7 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d - case VKD3D_SHADER_REL_OP_GE: - case VKD3D_SHADER_REL_OP_LE: - *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_LE); -- if (data_type == VKD3D_DATA_FLOAT) -+ if (data_type == VSIR_DATA_F32) - { - *opcode = VSIR_OP_GEO; - return true; -@@ -877,7 +877,7 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d - - case VKD3D_SHADER_REL_OP_EQ: - *requires_swap = false; -- if (data_type == VKD3D_DATA_FLOAT) -+ if (data_type == VSIR_DATA_F32) - { - *opcode = VSIR_OP_EQO; - return true; -@@ -886,7 +886,7 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d - - case VKD3D_SHADER_REL_OP_NE: - *requires_swap = false; -- if (data_type == VKD3D_DATA_FLOAT) -+ if (data_type == VSIR_DATA_F32) - { - *opcode = VSIR_OP_NEO; - return true; -@@ -928,7 +928,7 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - ins2 = &program->instructions.elements[i + 1]; - - ins->opcode = VSIR_OP_ROUND_NE; -- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = tmp_idx; - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - -@@ -940,7 +940,7 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - ins2->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins2->dst[0].write_mask = ins->dst[0].write_mask; - -- vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); - ins2->src[0].reg.idx[0].offset = tmp_idx; - ins2->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins2->src[0].swizzle = vsir_swizzle_from_writemask(ins2->dst[0].write_mask); -@@ -971,18 +971,16 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - } - - static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, -- struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx, -+ struct vsir_program_iterator *it, unsigned int *tmp_idx, - struct vkd3d_shader_message_context *message_context) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- size_t pos = ifc - instructions->elements; -- struct vkd3d_shader_instruction *ins; -+ struct vkd3d_shader_instruction *ifc, *ins; - enum vkd3d_shader_opcode opcode; - bool swap; - -- if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) -+ if (!vsir_program_iterator_insert_after(it, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ifc = &instructions->elements[pos]; -+ ifc = vsir_program_iterator_current(it); - - if (*tmp_idx == ~0u) - *tmp_idx = program->temp_count++; -@@ -996,7 +994,7 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - -- ins = &instructions->elements[pos + 1]; -+ ins = vsir_program_iterator_next(it); - if (!vsir_instruction_init_with_params(program, ins, &ifc->location, opcode, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1009,7 +1007,7 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, - ins->src[1] = ifc->src[!swap]; - - /* Create new if instruction using the previous result. */ -- ins = &instructions->elements[pos + 2]; -+ ins = vsir_program_iterator_next(it); - if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VSIR_OP_IF, 0, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; -@@ -1026,24 +1024,22 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, - } - - static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program, -- struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx) -+ struct vsir_program_iterator *it, unsigned int *tmp_idx) - { - const unsigned int components_read = 3 + (program->shader_version.major >= 2); -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- size_t pos = texkill - instructions->elements; -- struct vkd3d_shader_instruction *ins; -+ struct vkd3d_shader_instruction *ins, *texkill; - unsigned int j; - -- if (!shader_instruction_array_insert_at(instructions, pos + 1, components_read + 1)) -+ if (!vsir_program_iterator_insert_after(it, components_read + 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- texkill = &instructions->elements[pos]; -+ texkill = vsir_program_iterator_current(it); - - if (*tmp_idx == ~0u) - *tmp_idx = program->temp_count++; - - /* tmp = ins->src[0] < 0 */ - -- ins = &instructions->elements[pos + 1]; -+ ins = vsir_program_iterator_next(it); - if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_LTO, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1054,7 +1050,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - - ins->src[0].reg = texkill->src[0].reg; - ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; -- vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].reg.u.immconst_f32[0] = 0.0f; - ins->src[1].reg.u.immconst_f32[1] = 0.0f; -@@ -1067,7 +1063,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - - for (j = 1; j < components_read; ++j) - { -- ins = &instructions->elements[pos + 1 + j]; -+ ins = vsir_program_iterator_next(it); - if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_OR, 1, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1088,7 +1084,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - - /* discard_nz tmp.x */ - -- ins = &instructions->elements[pos + 1 + components_read]; -+ ins = vsir_program_iterator_next(it); - if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_DISCARD, 0, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; -@@ -1111,25 +1107,24 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - * not fused for "precise" operations." - * Windows drivers seem to conform with the latter, for SM 4-5 and SM 6. */ - static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *program, -- struct vkd3d_shader_instruction *mad, unsigned int *tmp_idx) -+ struct vsir_program_iterator *it, unsigned int *tmp_idx) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- struct vkd3d_shader_instruction *mul_ins, *add_ins; -- size_t pos = mad - instructions->elements; -+ struct vkd3d_shader_instruction *mad, *mul_ins, *add_ins; - struct vkd3d_shader_dst_param *mul_dst; - -+ mad = vsir_program_iterator_current(it); -+ - if (!(mad->flags & VKD3DSI_PRECISE_XYZW)) - return VKD3D_OK; - -- if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) -+ if (!vsir_program_iterator_insert_after(it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- mad = &instructions->elements[pos]; - - if (*tmp_idx == ~0u) - *tmp_idx = program->temp_count++; - -- mul_ins = &instructions->elements[pos]; -- add_ins = &instructions->elements[pos + 1]; -+ mul_ins = vsir_program_iterator_current(it); -+ add_ins = vsir_program_iterator_next(it); - - mul_ins->opcode = VSIR_OP_MUL; - mul_ins->src_count = 2; -@@ -1174,13 +1169,13 @@ static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program, - } - - static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, -- struct vkd3d_shader_instruction *udiv, struct vsir_transformation_context *ctx) -+ struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- size_t pos = udiv - instructions->elements; -- struct vkd3d_shader_instruction *ins, *mov; -+ struct vkd3d_shader_instruction *udiv, *ins, *mov; - unsigned int count = 2; - -+ udiv = vsir_program_iterator_current(it); -+ - if (udiv->dst_count != 2) - { - vkd3d_shader_error(ctx->message_context, &udiv->location, -@@ -1195,21 +1190,19 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - if (udiv->dst[1].reg.type != VKD3DSPR_NULL) - ++count; - -- if (!shader_instruction_array_insert_at(instructions, pos + 1, count)) -+ if (!vsir_program_iterator_insert_after(it, count)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- udiv = &instructions->elements[pos]; -- -- ins = &instructions->elements[pos + 1]; -+ udiv = vsir_program_iterator_current(it); - - /* Save the sources in a SSA in case a destination collides with a source. */ -- mov = ins++; -+ mov = vsir_program_iterator_next(it); - if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - mov->src[0] = udiv->src[0]; - dst_param_init_ssa(&mov->dst[0], program->ssa_count, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); - -- mov = ins++; -+ mov = vsir_program_iterator_next(it); - if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1218,6 +1211,8 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - - if (udiv->dst[0].reg.type != VKD3DSPR_NULL) - { -+ ins = vsir_program_iterator_next(it); -+ - if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_UDIV_SIMPLE, 1, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1228,12 +1223,12 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - src_param_init_ssa(&ins->src[1], program->ssa_count + 1, - udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); - ins->dst[0] = udiv->dst[0]; -- -- ++ins; - } - - if (udiv->dst[1].reg.type != VKD3DSPR_NULL) - { -+ ins = vsir_program_iterator_next(it); -+ - if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_UREM, 1, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1244,8 +1239,6 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - src_param_init_ssa(&ins->src[1], program->ssa_count + 1, - udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); - ins->dst[0] = udiv->dst[1]; -- -- ++ins; - } - - vkd3d_shader_instruction_make_nop(udiv); -@@ -1255,23 +1248,20 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - } - - static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program, -- struct vkd3d_shader_instruction *sincos) -+ struct vsir_program_iterator *it) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- size_t pos = sincos - instructions->elements; -- struct vkd3d_shader_instruction *ins, *mov; -+ struct vkd3d_shader_instruction *ins, *mov, *sincos; - unsigned int s, count; - -+ sincos = vsir_program_iterator_current(it); - count = 1 + vkd3d_popcount(sincos->dst[0].write_mask & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1)); - -- if (!shader_instruction_array_insert_at(instructions, pos + 1, count)) -+ if (!vsir_program_iterator_insert_after(it, count)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- sincos = &instructions->elements[pos]; -- -- ins = &instructions->elements[pos + 1]; -+ sincos = vsir_program_iterator_current(it); - - /* Save the source in a SSA in case a destination collides with the source. */ -- mov = ins++; -+ mov = vsir_program_iterator_next(it); - if (!(vsir_instruction_init_with_params(program, mov, &sincos->location, VSIR_OP_MOV, 1, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1285,6 +1275,8 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog - - if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_1) - { -+ ins = vsir_program_iterator_next(it); -+ - if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_SIN, 1, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1294,12 +1286,12 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog - - ins->dst[0] = *sincos->dst; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_1; -- -- ++ins; - } - - if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) - { -+ ins = vsir_program_iterator_next(it); -+ - if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_COS, 1, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1309,8 +1301,6 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog - - ins->dst[0] = *sincos->dst; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; -- -- ++ins; - } - - vkd3d_shader_instruction_make_nop(sincos); -@@ -1320,13 +1310,13 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog - } - - static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *program, -- struct vkd3d_shader_instruction *sincos, struct vsir_transformation_context *ctx) -+ struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- size_t pos = sincos - instructions->elements; -- struct vkd3d_shader_instruction *ins, *mov; -+ struct vkd3d_shader_instruction *ins, *mov, *sincos; - unsigned int count = 1; - -+ sincos = vsir_program_iterator_current(it); -+ - if (sincos->dst_count != 2) - { - vkd3d_shader_error(ctx->message_context, &sincos->location, -@@ -1341,14 +1331,12 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog - if (sincos->dst[1].reg.type != VKD3DSPR_NULL) - ++count; - -- if (!shader_instruction_array_insert_at(instructions, pos + 1, count)) -+ if (!vsir_program_iterator_insert_after(it, count)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- sincos = &instructions->elements[pos]; -- -- ins = &instructions->elements[pos + 1]; -+ sincos = vsir_program_iterator_current(it); - - /* Save the source in a SSA in case a destination collides with the source. */ -- mov = ins++; -+ mov = vsir_program_iterator_next(it); - if (!(vsir_instruction_init_with_params(program, mov, &sincos->location, VSIR_OP_MOV, 1, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1357,6 +1345,8 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog - - if (sincos->dst[0].reg.type != VKD3DSPR_NULL) - { -+ ins = vsir_program_iterator_next(it); -+ - if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_SIN, 1, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1365,12 +1355,12 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog - src_param_init_ssa(&ins->src[0], program->ssa_count, - sincos->src[0].reg.data_type, sincos->src[0].reg.dimension); - ins->dst[0] = sincos->dst[0]; -- -- ++ins; - } - - if (sincos->dst[1].reg.type != VKD3DSPR_NULL) - { -+ ins = vsir_program_iterator_next(it); -+ - if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_COS, 1, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1379,8 +1369,6 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog - src_param_init_ssa(&ins->src[0], program->ssa_count, - sincos->src[0].reg.data_type, sincos->src[0].reg.dimension); - ins->dst[0] = sincos->dst[1]; -- -- ++ins; - } - - vkd3d_shader_instruction_make_nop(sincos); -@@ -1390,30 +1378,33 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog - } - - static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, -- struct vkd3d_shader_instruction *tex, unsigned int *tmp_idx) -+ struct vsir_program_iterator *it, unsigned int *tmp_idx) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- struct vkd3d_shader_location *location = &tex->location; -- struct vkd3d_shader_instruction *div_ins, *tex_ins; -- size_t pos = tex - instructions->elements; -+ struct vkd3d_shader_instruction *div_ins, *tex, *tex_ins; -+ struct vsir_program_iterator it2; - unsigned int w_comp; - -+ tex = vsir_program_iterator_current(it); -+ - w_comp = vsir_swizzle_get_component(tex->src[0].swizzle, 3); - -- if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) -+ if (!vsir_program_iterator_insert_after(it, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- tex = &instructions->elements[pos]; -+ tex = vsir_program_iterator_current(it); - - if (*tmp_idx == ~0u) - *tmp_idx = program->temp_count++; - -- div_ins = &instructions->elements[pos + 1]; -- tex_ins = &instructions->elements[pos + 2]; -+ /* Do not increment `it', because we need to scan the generated instructions -+ * again to lower TEXLD. */ -+ it2 = *it; -+ div_ins = vsir_program_iterator_next(&it2); -+ tex_ins = vsir_program_iterator_next(&it2); - -- if (!vsir_instruction_init_with_params(program, div_ins, location, VSIR_OP_DIV, 1, 2)) -+ if (!vsir_instruction_init_with_params(program, div_ins, &tex->location, VSIR_OP_DIV, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VSIR_DATA_F32, 1); - div_ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - div_ins->dst[0].reg.idx[0].offset = *tmp_idx; - div_ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; -@@ -1423,7 +1414,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, - div_ins->src[1] = tex->src[0]; - div_ins->src[1].swizzle = vkd3d_shader_create_swizzle(w_comp, w_comp, w_comp, w_comp); - -- if (!vsir_instruction_init_with_params(program, tex_ins, location, VSIR_OP_TEXLD, 1, 2)) -+ if (!vsir_instruction_init_with_params(program, tex_ins, &tex->location, VSIR_OP_TEXLD, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - tex_ins->dst[0] = tex->dst[0]; -@@ -1579,29 +1570,28 @@ static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *prog - static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_message_context *message_context = ctx->message_context; -- unsigned int tmp_idx = ~0u, i; -+ struct vkd3d_shader_instruction *ins; -+ unsigned int tmp_idx = ~0u; - enum vkd3d_result ret; - -- for (i = 0; i < instructions->count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &instructions->elements[i]; -- - switch (ins->opcode) - { - case VSIR_OP_IFC: -- if ((ret = vsir_program_lower_ifc(program, ins, &tmp_idx, message_context)) < 0) -+ if ((ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context)) < 0) - return ret; - break; - - case VSIR_OP_TEXKILL: -- if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0) -+ if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0) - return ret; - break; - - case VSIR_OP_MAD: -- if ((ret = vsir_program_lower_precise_mad(program, ins, &tmp_idx)) < 0) -+ if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) - return ret; - break; - -@@ -1643,19 +1633,19 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - break; - - case VSIR_OP_UDIV: -- if ((ret = vsir_program_lower_udiv(program, ins, ctx)) < 0) -+ if ((ret = vsir_program_lower_udiv(program, &it, ctx)) < 0) - return ret; - break; - - case VSIR_OP_SINCOS: - if (ins->dst_count == 1) - { -- if ((ret = vsir_program_lower_sm1_sincos(program, ins)) < 0) -+ if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0) - return ret; - } - else - { -- if ((ret = vsir_program_lower_sm4_sincos(program, ins, ctx)) < 0) -+ if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) - return ret; - } - break; -@@ -1663,7 +1653,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - case VSIR_OP_TEXLD: - if (ins->flags == VKD3DSI_TEXLD_PROJECT) - { -- if ((ret = vsir_program_lower_texldp(program, ins, &tmp_idx)) < 0) -+ if ((ret = vsir_program_lower_texldp(program, &it, &tmp_idx)) < 0) - return ret; - } - else -@@ -1802,11 +1792,11 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra - ins = &program->instructions.elements[i]; - - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); -- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = 0; - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL & ~program->diffuse_written_mask; -- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); -+ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - for (i = 0; i < 4; ++i) - ins->src[0].reg.u.immconst_f32[i] = 1.0f; -@@ -2026,8 +2016,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program - e = &signature->elements[j]; - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, e->register_index, e->mask); -- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); -+ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask); -+ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ++ins; - } -@@ -6842,7 +6832,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].float_opcode, 1, 2); - src_param_init_temp_float(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); - src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], -- VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_FLOAT); -+ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VSIR_DATA_F32); - break; - - case VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32: -@@ -6875,7 +6865,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - - ++ins; - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = colour_signature_idx; - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->dst[0].write_mask = program->output_signature.elements[colour_signature_idx].mask; -@@ -6992,11 +6982,11 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DP4, 1, 2); - src_param_init_temp_float4(&ins->src[0], position_temp); -- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VKD3D_DATA_FLOAT); -+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VSIR_DATA_F32); - ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE; - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - -- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); - if (output_idx < 4) - ins->dst[0].reg.idx[0].offset = low_signature_idx; - else -@@ -7009,7 +6999,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog - } - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = position_signature_idx; - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->dst[0].write_mask = program->output_signature.elements[position_signature_idx].mask; -@@ -7162,9 +7152,9 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr - ins = &program->instructions.elements[pos]; - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; -- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VKD3D_DATA_FLOAT); -+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VSIR_DATA_F32); - - *ret_pos = pos + 1; - return VKD3D_OK; -@@ -7298,7 +7288,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - { - vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAX, 1, 2); - src_param_init_ssa_float(&ins->src[0], ssa_value); -- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VKD3D_DATA_FLOAT); -+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VSIR_DATA_F32); - if (max_parameter) - { - dst_param_init_ssa_float(&ins->dst[0], program->ssa_count); -@@ -7306,7 +7296,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - } - else - { -- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; - } - ++ins; -@@ -7317,8 +7307,8 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - { - vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MIN, 1, 2); - src_param_init_ssa_float(&ins->src[0], ssa_value); -- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VKD3D_DATA_FLOAT); -- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); -+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VSIR_DATA_F32); -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; - - ++i; -@@ -7495,7 +7485,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); - dst_param_init_temp_float4(&ins->dst[0], coord_temp); - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; -- vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0); -+ vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - ++ins; -@@ -7503,7 +7493,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); - dst_param_init_temp_float4(&ins->dst[0], coord_temp); - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; -- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); -+ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ++ins; - -@@ -7573,8 +7563,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); -- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VKD3D_DATA_FLOAT); -- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); -+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); -+ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); - ins->src[1].reg.idx[0].offset = fog_signature_idx; - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -@@ -7584,7 +7574,7 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp); -- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); -+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); - break; - - case VKD3D_SHADER_FOG_FRAGMENT_EXP: -@@ -7605,8 +7595,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); -- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); -- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); -+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); -+ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); - ins->src[1].reg.idx[0].offset = fog_signature_idx; - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -@@ -7638,8 +7628,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); -- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); -- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); -+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); -+ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); - ins->src[1].reg.idx[0].offset = fog_signature_idx; - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -@@ -7669,15 +7659,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_ADD, 1, 2); - dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); - src_param_init_temp_float4(&ins->src[0], colour_temp); -- src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT); -+ src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); - ins->src[1].modifiers = VKD3DSPSM_NEG; - - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MAD, 1, 3); -- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, colour_signature_idx, -+ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, - program->output_signature.elements[colour_signature_idx].mask); - src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); - src_param_init_ssa_float(&ins->src[1], ssa_factor); -- src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT); -+ src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); - - return VKD3D_OK; - } -@@ -7819,7 +7809,7 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr - - /* Write the fog output. */ - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, fog_signature_idx, 0x1); -+ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, fog_signature_idx, 0x1); - src_param_init_temp_float4(&ins->src[0], temp); - if (source == VKD3D_SHADER_FOG_SOURCE_Z) - ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); -@@ -7829,7 +7819,7 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr - - /* Write the position or specular output. */ - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -- dst_param_init_output(&ins->dst[0], vkd3d_data_type_from_component_type(e->component_type), -+ dst_param_init_output(&ins->dst[0], vsir_data_type_from_component_type(e->component_type), - source_signature_idx, e->mask); - src_param_init_temp_float4(&ins->src[0], temp); - ++ins; -@@ -8539,11 +8529,11 @@ static uint8_t get_available_writemask(const struct temp_allocator *allocator, - return writemask; - } - --static void temp_allocator_allocate(struct temp_allocator *allocator, struct liveness_tracker *tracker, -+static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liveness_tracker *tracker, - struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg, uint32_t base_id) - { - if (!liveness_reg->written) -- return; -+ return false; - - for (uint32_t id = base_id;; ++id) - { -@@ -8556,7 +8546,7 @@ static void temp_allocator_allocate(struct temp_allocator *allocator, struct liv - { - reg->temp_id = id; - reg->allocated_mask = liveness_reg->mask; -- return; -+ return true; - } - } - else -@@ -8569,7 +8559,7 @@ static void temp_allocator_allocate(struct temp_allocator *allocator, struct liv - { - reg->temp_id = id; - reg->allocated_mask = vsir_combine_write_masks(available_mask, liveness_reg->mask); -- return; -+ return true; - } - } - } -@@ -8591,6 +8581,7 @@ static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3 - return; - - src->reg.type = VKD3DSPR_TEMP; -+ src->reg.dimension = VSIR_DIMENSION_VEC4; - src->reg.idx[0].offset = reg->temp_id; - src->swizzle = vsir_combine_swizzles(vsir_swizzle_from_writemask(reg->allocated_mask), src->swizzle); - } -@@ -8678,6 +8669,7 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, - return; - - dst->reg.type = VKD3DSPR_TEMP; -+ dst->reg.dimension = VSIR_DIMENSION_VEC4; - dst->reg.idx[0].offset = reg->temp_id; - if (reg->allocated_mask != dst->write_mask) - { -@@ -8713,7 +8705,6 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - struct temp_allocator allocator = {0}; - struct temp_allocator_reg *regs; - struct liveness_tracker tracker; -- uint32_t temp_count = 0; - enum vkd3d_result ret; - - if (!program->ssa_count) -@@ -8733,12 +8724,16 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - for (unsigned int i = 0; i < program->ssa_count; ++i) - { - const struct liveness_tracker_reg *liveness_reg = &tracker.ssa_regs[i]; -+ const unsigned int prev_temp_count = program->temp_count; - struct temp_allocator_reg *reg = &allocator.ssa_regs[i]; - -- temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, program->temp_count); -- TRACE("Allocated r%u%s to sr%u (liveness %u-%u).\n", -- reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, -- liveness_reg->first_write, liveness_reg->last_access); -+ if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, prev_temp_count)) -+ { -+ TRACE("Allocated r%u%s to sr%u (liveness %u-%u).\n", -+ reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, -+ liveness_reg->first_write, liveness_reg->last_access); -+ program->temp_count = max(program->temp_count, reg->temp_id + 1); -+ } - ++allocator.allocated_ssa_count; - } - -@@ -8754,13 +8749,25 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - temp_allocator_set_dst(&allocator, &ins->dst[j], ins); - } - -- /* Rewrite dcl_temps to reflect the new temp count. -- * Note that dcl_temps appears once per phase, and should reflect only the -- * number of temps needed by that phase. -- * Therefore we iterate backwards through the shader, finding the maximum -- * register used by any instruction, update the dcl_temps at the beginning -- * of each phase, and then reset the temp count back to 0 for the next -- * phase (if any). */ -+ program->ssa_count = 0; -+ -+ vkd3d_free(regs); -+ liveness_tracker_cleanup(&tracker); -+ return allocator.result; -+} -+ -+/* Rewrite dcl_temps to reflect the new temp count. -+ * Note that dcl_temps appears once per phase, and should reflect only the -+ * number of temps needed by that phase. -+ * Therefore we iterate backwards through the shader, finding the maximum -+ * register used by any instruction, update the dcl_temps at the beginning -+ * of each phase, and then reset the temp count back to 0 for the next -+ * phase (if any). */ -+enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, -+ struct vkd3d_shader_message_context *message_context) -+{ -+ unsigned int temp_count = 0; -+ - for (int i = program->instructions.count - 1; i >= 0; --i) - { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -@@ -8771,6 +8778,7 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - temp_count = 0; - continue; - } -+ - if (temp_count && program->shader_version.major >= 4 - && (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE - || ins->opcode == VSIR_OP_HS_FORK_PHASE -@@ -8779,11 +8787,7 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - /* The phase didn't have a dcl_temps instruction, but we added - * temps here, so we need to insert one. */ - if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) -- { -- vkd3d_free(regs); -- liveness_tracker_cleanup(&tracker); - return VKD3D_ERROR_OUT_OF_MEMORY; -- } - - ins = &program->instructions.elements[i + 1]; - vsir_instruction_init(ins, &program->instructions.elements[i].location, VSIR_OP_DCL_TEMPS); -@@ -8792,15 +8796,16 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - continue; - } - -- /* No need to check sources. If we've produced an unwritten source then -- * that's a bug somewhere in this pass. */ -+ for (unsigned int j = 0; j < ins->src_count; ++j) -+ { -+ if (ins->src[j].reg.type == VKD3DSPR_TEMP) -+ temp_count = max(temp_count, ins->src[j].reg.idx[0].offset + 1); -+ } -+ - for (unsigned int j = 0; j < ins->dst_count; ++j) - { - if (ins->dst[j].reg.type == VKD3DSPR_TEMP) -- { - temp_count = max(temp_count, ins->dst[j].reg.idx[0].offset + 1); -- program->temp_count = max(program->temp_count, temp_count); -- } - } - } - -@@ -8809,22 +8814,14 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - struct vkd3d_shader_instruction *ins; - - if (!shader_instruction_array_insert_at(&program->instructions, 0, 1)) -- { -- vkd3d_free(regs); -- liveness_tracker_cleanup(&tracker); - return VKD3D_ERROR_OUT_OF_MEMORY; -- } - - ins = &program->instructions.elements[0]; - vsir_instruction_init(ins, &program->instructions.elements[1].location, VSIR_OP_DCL_TEMPS); - ins->declaration.count = temp_count; - } - -- program->ssa_count = 0; -- -- vkd3d_free(regs); -- liveness_tracker_cleanup(&tracker); -- return allocator.result; -+ return VKD3D_OK; - } - - struct validation_context -@@ -8848,7 +8845,7 @@ struct validation_context - struct validation_context_ssa_data - { - enum vsir_dimension dimension; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - size_t first_seen; - uint32_t write_mask; - uint32_t read_mask; -@@ -9542,6 +9539,24 @@ static void vsir_validate_src_param(struct validation_context *ctx, - static void vsir_validate_register(struct validation_context *ctx, - const struct vkd3d_shader_register *reg) - { -+ static const struct register_validation_data -+ { -+ bool valid; -+ unsigned int idx_count; -+ enum vsir_dimension dimension; -+ } -+ register_validation_data[] = -+ { -+ [VKD3DSPR_DEPTHOUT] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ [VKD3DSPR_THREADGROUPID] = {true, 0, VSIR_DIMENSION_VEC4}, -+ [VKD3DSPR_LOCALTHREADID] = {true, 0, VSIR_DIMENSION_VEC4}, -+ [VKD3DSPR_LOCALTHREADINDEX] = {true, 0, VSIR_DIMENSION_VEC4}, -+ [VKD3DSPR_COVERAGE] = {true, 0, VSIR_DIMENSION_VEC4}, -+ [VKD3DSPR_DEPTHOUTGE] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ [VKD3DSPR_DEPTHOUTLE] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ }; -+ -+ const struct register_validation_data *validation_data; - unsigned int i; - - if (reg->type >= VKD3DSPR_COUNT) -@@ -9552,7 +9567,7 @@ static void vsir_validate_register(struct validation_context *ctx, - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.", - reg->precision); - -- if (reg->data_type >= VKD3D_DATA_COUNT) -+ if (reg->data_type >= VSIR_DATA_TYPE_COUNT) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.", - reg->data_type); - -@@ -9607,10 +9622,6 @@ static void vsir_validate_register(struct validation_context *ctx, - vsir_validate_io_register(ctx, reg); - break; - -- case VKD3DSPR_DEPTHOUT: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- - case VKD3DSPR_MISCTYPE: - vsir_validate_misctype_register(ctx, reg); - break; -@@ -9683,22 +9694,6 @@ static void vsir_validate_register(struct validation_context *ctx, - vsir_validate_register_without_indices(ctx, reg); - break; - -- case VKD3DSPR_THREADGROUPID: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- -- case VKD3DSPR_LOCALTHREADID: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- -- case VKD3DSPR_LOCALTHREADINDEX: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- -- case VKD3DSPR_COVERAGE: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- - case VKD3DSPR_SAMPLEMASK: - vsir_validate_register_without_indices(ctx, reg); - break; -@@ -9707,14 +9702,6 @@ static void vsir_validate_register(struct validation_context *ctx, - vsir_validate_register_without_indices(ctx, reg); - break; - -- case VKD3DSPR_DEPTHOUTGE: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- -- case VKD3DSPR_DEPTHOUTLE: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- - case VKD3DSPR_OUTSTENCILREF: - vsir_validate_register_without_indices(ctx, reg); - break; -@@ -9734,6 +9721,24 @@ static void vsir_validate_register(struct validation_context *ctx, - default: - break; - } -+ -+ if (reg->type >= ARRAY_SIZE(register_validation_data)) -+ return; -+ -+ validation_data = ®ister_validation_data[reg->type]; -+ -+ if (!validation_data->valid) -+ return; -+ -+ if (reg->idx_count != validation_data->idx_count) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, -+ "Invalid index count %u for a register of type %#x, expected %u.", -+ reg->idx_count, reg->type, validation_data->idx_count); -+ -+ if (reg->dimension != validation_data->dimension) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, -+ "Invalid dimension %#x for a register of type %#x, expected %#x.", -+ reg->dimension, reg->type, validation_data->dimension); - } - - static void vsir_validate_io_dst_param(struct validation_context *ctx, -@@ -9783,9 +9788,9 @@ static void vsir_validate_dst_param(struct validation_context *ctx, - { - switch (dst->reg.data_type) - { -- case VKD3D_DATA_FLOAT: -- case VKD3D_DATA_DOUBLE: -- case VKD3D_DATA_HALF: -+ case VSIR_DATA_F16: -+ case VSIR_DATA_F32: -+ case VSIR_DATA_F64: - break; - - default: -@@ -9807,7 +9812,7 @@ static void vsir_validate_dst_param(struct validation_context *ctx, - case 13: - case 14: - case 15: -- if (dst->reg.data_type != VKD3D_DATA_FLOAT) -+ if (dst->reg.data_type != VSIR_DATA_F32) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for destination with shift.", dst->reg.data_type); - break; -@@ -9891,9 +9896,9 @@ static void vsir_validate_io_src_param(struct validation_context *ctx, - "Invalid register type %#x used as source parameter.", src->reg.type); - } - --#define F64_BIT (1u << VKD3D_DATA_DOUBLE) --#define F32_BIT (1u << VKD3D_DATA_FLOAT) --#define F16_BIT (1u << VKD3D_DATA_HALF) -+#define F64_BIT (1u << VSIR_DATA_F64) -+#define F32_BIT (1u << VSIR_DATA_F32) -+#define F16_BIT (1u << VSIR_DATA_F16) - - #define I32_BIT (1u << VKD3D_DATA_INT) - -@@ -10494,7 +10499,7 @@ static void vsir_validate_descriptors(struct validation_context *ctx) - "Descriptor %u has invalid resource type %#x for descriptor type %#x.", - i, descriptor->resource_type, descriptor->type); - -- if (descriptor->resource_data_type >= VKD3D_DATA_COUNT) -+ if (descriptor->resource_data_type >= VSIR_DATA_TYPE_COUNT) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Descriptor %u has invalid resource data type %#x.", i, descriptor->resource_data_type); - else if ((descriptor->resource_data_type == VKD3D_DATA_UNUSED) -@@ -10597,9 +10602,9 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, - } - - static void vsir_validate_elementwise_operation(struct validation_context *ctx, -- const struct vkd3d_shader_instruction *instruction, const bool types[VKD3D_DATA_COUNT]) -+ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) - { -- enum vkd3d_data_type dst_data_type; -+ enum vsir_data_type dst_data_type; - unsigned int i; - - if (instruction->dst_count < 1) -@@ -10607,7 +10612,7 @@ static void vsir_validate_elementwise_operation(struct validation_context *ctx, - - dst_data_type = instruction->dst[0].reg.data_type; - -- if (dst_data_type >= VKD3D_DATA_COUNT) -+ if (dst_data_type >= VSIR_DATA_TYPE_COUNT) - return; - - if (!types[dst_data_type]) -@@ -10629,9 +10634,9 @@ static void vsir_validate_elementwise_operation(struct validation_context *ctx, - static void vsir_validate_double_elementwise_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) - { -- static const bool types[VKD3D_DATA_COUNT] = -+ static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_DOUBLE] = true, -+ [VSIR_DATA_F64] = true, - }; - - vsir_validate_elementwise_operation(ctx, instruction, types); -@@ -10640,9 +10645,9 @@ static void vsir_validate_double_elementwise_operation(struct validation_context - static void vsir_validate_float_elementwise_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) - { -- static const bool types[VKD3D_DATA_COUNT] = -+ static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_FLOAT] = true, -+ [VSIR_DATA_F32] = true, - }; - - vsir_validate_elementwise_operation(ctx, instruction, types); -@@ -10651,7 +10656,7 @@ static void vsir_validate_float_elementwise_operation(struct validation_context - static void vsir_validate_integer_elementwise_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) - { -- static const bool types[VKD3D_DATA_COUNT] = -+ static const bool types[VSIR_DATA_TYPE_COUNT] = - { - [VKD3D_DATA_INT] = true, - [VKD3D_DATA_UINT] = true, -@@ -10664,7 +10669,7 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex - static void vsir_validate_logic_elementwise_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) - { -- static const bool types[VKD3D_DATA_COUNT] = -+ static const bool types[VSIR_DATA_TYPE_COUNT] = - { - [VKD3D_DATA_INT] = true, - [VKD3D_DATA_UINT] = true, -@@ -10676,9 +10681,9 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context - } - - static void vsir_validate_comparison_operation(struct validation_context *ctx, -- const struct vkd3d_shader_instruction *instruction, const bool types[VKD3D_DATA_COUNT]) -+ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) - { -- enum vkd3d_data_type dst_data_type, src_data_type; -+ enum vsir_data_type dst_data_type, src_data_type; - unsigned int i; - - if (instruction->dst_count < 1) -@@ -10696,7 +10701,7 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, - - src_data_type = instruction->src[0].reg.data_type; - -- if (src_data_type >= VKD3D_DATA_COUNT) -+ if (src_data_type >= VSIR_DATA_TYPE_COUNT) - return; - - if (!types[src_data_type]) -@@ -10718,9 +10723,9 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, - static void vsir_validate_double_comparison_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) - { -- static const bool types[VKD3D_DATA_COUNT] = -+ static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_DOUBLE] = true, -+ [VSIR_DATA_F64] = true, - }; - - vsir_validate_comparison_operation(ctx, instruction, types); -@@ -10729,9 +10734,10 @@ static void vsir_validate_double_comparison_operation(struct validation_context - static void vsir_validate_float_comparison_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) - { -- static const bool types[VKD3D_DATA_COUNT] = -+ static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_FLOAT] = true, -+ [VSIR_DATA_F32] = true, -+ [VSIR_DATA_F64] = true, - }; - - vsir_validate_comparison_operation(ctx, instruction, types); -@@ -10740,7 +10746,7 @@ static void vsir_validate_float_comparison_operation(struct validation_context * - static void vsir_validate_integer_comparison_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) - { -- static const bool types[VKD3D_DATA_COUNT] = -+ static const bool types[VSIR_DATA_TYPE_COUNT] = - { - [VKD3D_DATA_INT] = true, - [VKD3D_DATA_UINT] = true, -@@ -10750,6 +10756,32 @@ static void vsir_validate_integer_comparison_operation(struct validation_context - vsir_validate_comparison_operation(ctx, instruction, types); - } - -+static void vsir_validate_cast_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction, -+ const bool src_types[VSIR_DATA_TYPE_COUNT], const bool dst_types[VSIR_DATA_TYPE_COUNT]) -+{ -+ enum vsir_data_type dst_data_type, src_data_type; -+ -+ if (instruction->dst_count < 1 || instruction->src_count < 1) -+ return; -+ -+ dst_data_type = instruction->dst[0].reg.data_type; -+ src_data_type = instruction->src[0].reg.data_type; -+ -+ if (src_data_type >= VSIR_DATA_TYPE_COUNT || dst_data_type >= VSIR_DATA_TYPE_COUNT) -+ return; -+ -+ if (!src_types[src_data_type]) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid source data type %#x for cast operation \"%s\" (%#x).", -+ src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ -+ if (!dst_types[dst_data_type]) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid destination data type %#x for cast operation \"%s\" (%#x).", -+ dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+} -+ - static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) - { - size_t i; -@@ -11263,6 +11295,39 @@ static void vsir_validate_endswitch(struct validation_context *ctx, const struct - --ctx->depth; - } - -+static void vsir_validate_ftoi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool src_types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VSIR_DATA_F16] = true, -+ [VSIR_DATA_F32] = true, -+ [VSIR_DATA_F64] = true, -+ }; -+ static const bool dst_types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VKD3D_DATA_INT] = true, -+ [VKD3D_DATA_UINT] = true, -+ }; -+ -+ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); -+} -+ -+static void vsir_validate_ftou(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool src_types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VSIR_DATA_F16] = true, -+ [VSIR_DATA_F32] = true, -+ [VSIR_DATA_F64] = true, -+ }; -+ static const bool dst_types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VKD3D_DATA_UINT] = true, -+ }; -+ -+ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); -+} -+ - static void vsir_validate_if(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) - { - vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); -@@ -11275,6 +11340,38 @@ static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d - vsir_validator_push_block(ctx, VSIR_OP_IF); - } - -+static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool src_types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VKD3D_DATA_INT] = true, -+ [VKD3D_DATA_UINT] = true, -+ [VKD3D_DATA_UINT64] = true, -+ [VKD3D_DATA_BOOL] = true, -+ }; -+ static const bool dst_types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VSIR_DATA_F16] = true, -+ [VSIR_DATA_F32] = true, -+ [VSIR_DATA_F64] = true, -+ }; -+ -+ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); -+} -+ -+static void vsir_validate_itoi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VKD3D_DATA_INT] = true, -+ [VKD3D_DATA_UINT] = true, -+ [VKD3D_DATA_UINT64] = true, -+ [VKD3D_DATA_BOOL] = true, -+ }; -+ -+ vsir_validate_cast_operation(ctx, instruction, types, types); -+} -+ - static void vsir_validate_label(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) - { - vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS); -@@ -11443,6 +11540,25 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_ATAN] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_BRANCH] = {0, ~0u, vsir_validate_branch}, - [VSIR_OP_DADD] = {1, 2, vsir_validate_double_elementwise_operation}, -+ [VSIR_OP_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances}, -+ [VSIR_OP_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor}, -+ [VSIR_OP_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range}, -+ [VSIR_OP_DCL_INPUT] = {0, 0, vsir_validate_dcl_input}, -+ [VSIR_OP_DCL_INPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_input_primitive}, -+ [VSIR_OP_DCL_INPUT_PS] = {0, 0, vsir_validate_dcl_input_ps}, -+ [VSIR_OP_DCL_INPUT_PS_SGV] = {0, 0, vsir_validate_dcl_input_ps_sgv}, -+ [VSIR_OP_DCL_INPUT_PS_SIV] = {0, 0, vsir_validate_dcl_input_ps_siv}, -+ [VSIR_OP_DCL_INPUT_SGV] = {0, 0, vsir_validate_dcl_input_sgv}, -+ [VSIR_OP_DCL_INPUT_SIV] = {0, 0, vsir_validate_dcl_input_siv}, -+ [VSIR_OP_DCL_OUTPUT] = {0, 0, vsir_validate_dcl_output}, -+ [VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT] = {0, 0, vsir_validate_dcl_output_control_point_count}, -+ [VSIR_OP_DCL_OUTPUT_SIV] = {0, 0, vsir_validate_dcl_output_siv}, -+ [VSIR_OP_DCL_OUTPUT_TOPOLOGY] = {0, 0, vsir_validate_dcl_output_topology}, -+ [VSIR_OP_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps}, -+ [VSIR_OP_DCL_TESSELLATOR_DOMAIN] = {0, 0, vsir_validate_dcl_tessellator_domain}, -+ [VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_tessellator_output_primitive}, -+ [VSIR_OP_DCL_TESSELLATOR_PARTITIONING] = {0, 0, vsir_validate_dcl_tessellator_partitioning}, -+ [VSIR_OP_DCL_VERTICES_OUT] = {0, 0, vsir_validate_dcl_vertices_out}, - [VSIR_OP_DDIV] = {1, 2, vsir_validate_double_elementwise_operation}, - [VSIR_OP_DEQO] = {1, 2, vsir_validate_double_comparison_operation}, - [VSIR_OP_DFMA] = {1, 3, vsir_validate_double_elementwise_operation}, -@@ -11461,22 +11577,31 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_DSY] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_DSY_COARSE] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_DSY_FINE] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_ELSE] = {0, 0, vsir_validate_else}, -+ [VSIR_OP_ENDIF] = {0, 0, vsir_validate_endif}, -+ [VSIR_OP_ENDLOOP] = {0, 0, vsir_validate_endloop}, -+ [VSIR_OP_ENDREP] = {0, 0, vsir_validate_endrep}, -+ [VSIR_OP_ENDSWITCH] = {0, 0, vsir_validate_endswitch}, - [VSIR_OP_EQO] = {1, 2, vsir_validate_float_comparison_operation}, - [VSIR_OP_EQU] = {1, 2, vsir_validate_float_comparison_operation}, - [VSIR_OP_EXP] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_FRC] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_FREM] = {1, 2, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_FTOI] = {1, 1, vsir_validate_ftoi}, -+ [VSIR_OP_FTOU] = {1, 1, vsir_validate_ftou}, - [VSIR_OP_GEO] = {1, 2, vsir_validate_float_comparison_operation}, - [VSIR_OP_GEU] = {1, 2, vsir_validate_float_comparison_operation}, - [VSIR_OP_HCOS] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_HSIN] = {1, 1, vsir_validate_float_elementwise_operation}, -- [VSIR_OP_HTAN] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_HS_CONTROL_POINT_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, - [VSIR_OP_HS_DECLS] = {0, 0, vsir_validate_hull_shader_phase}, - [VSIR_OP_HS_FORK_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, - [VSIR_OP_HS_JOIN_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, -+ [VSIR_OP_HTAN] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_IADD] = {1, 2, vsir_validate_integer_elementwise_operation}, - [VSIR_OP_IEQ] = {1, 2, vsir_validate_integer_comparison_operation}, -+ [VSIR_OP_IF] = {0, 1, vsir_validate_if}, -+ [VSIR_OP_IFC] = {0, 2, vsir_validate_ifc}, - [VSIR_OP_IGE] = {1, 2, vsir_validate_integer_comparison_operation}, - [VSIR_OP_ILT] = {1, 2, vsir_validate_integer_comparison_operation}, - [VSIR_OP_IMAD] = {1, 3, vsir_validate_integer_elementwise_operation}, -@@ -11485,36 +11610,22 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_INE] = {1, 2, vsir_validate_integer_comparison_operation}, - [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation}, - [VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation}, - [VSIR_OP_ISHL] = {1, 2, vsir_validate_integer_elementwise_operation}, - [VSIR_OP_ISHR] = {1, 2, vsir_validate_integer_elementwise_operation}, -- [VSIR_OP_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances}, -- [VSIR_OP_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor}, -- [VSIR_OP_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range}, -- [VSIR_OP_DCL_INPUT] = {0, 0, vsir_validate_dcl_input}, -- [VSIR_OP_DCL_INPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_input_primitive}, -- [VSIR_OP_DCL_INPUT_PS] = {0, 0, vsir_validate_dcl_input_ps}, -- [VSIR_OP_DCL_INPUT_PS_SGV] = {0, 0, vsir_validate_dcl_input_ps_sgv}, -- [VSIR_OP_DCL_INPUT_PS_SIV] = {0, 0, vsir_validate_dcl_input_ps_siv}, -- [VSIR_OP_DCL_INPUT_SGV] = {0, 0, vsir_validate_dcl_input_sgv}, -- [VSIR_OP_DCL_INPUT_SIV] = {0, 0, vsir_validate_dcl_input_siv}, -- [VSIR_OP_DCL_OUTPUT] = {0, 0, vsir_validate_dcl_output}, -- [VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT] = {0, 0, vsir_validate_dcl_output_control_point_count}, -- [VSIR_OP_DCL_OUTPUT_SIV] = {0, 0, vsir_validate_dcl_output_siv}, -- [VSIR_OP_DCL_OUTPUT_TOPOLOGY] = {0, 0, vsir_validate_dcl_output_topology}, -- [VSIR_OP_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps}, -- [VSIR_OP_DCL_TESSELLATOR_DOMAIN] = {0, 0, vsir_validate_dcl_tessellator_domain}, -- [VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_tessellator_output_primitive}, -- [VSIR_OP_DCL_TESSELLATOR_PARTITIONING] = {0, 0, vsir_validate_dcl_tessellator_partitioning}, -- [VSIR_OP_DCL_VERTICES_OUT] = {0, 0, vsir_validate_dcl_vertices_out}, -- [VSIR_OP_ELSE] = {0, 0, vsir_validate_else}, -- [VSIR_OP_ENDIF] = {0, 0, vsir_validate_endif}, -- [VSIR_OP_ENDLOOP] = {0, 0, vsir_validate_endloop}, -- [VSIR_OP_ENDREP] = {0, 0, vsir_validate_endrep}, -- [VSIR_OP_ENDSWITCH] = {0, 0, vsir_validate_endswitch}, -- [VSIR_OP_IF] = {0, 1, vsir_validate_if}, -- [VSIR_OP_IFC] = {0, 2, vsir_validate_ifc}, -+ [VSIR_OP_ISINF] = {1, 1, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_ISNAN] = {1, 1, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_ITOF] = {1, 1, vsir_validate_itof}, -+ [VSIR_OP_ITOI] = {1, 1, vsir_validate_itoi}, - [VSIR_OP_LABEL] = {0, 1, vsir_validate_label}, -+ [VSIR_OP_LOG] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_LOOP] = {0, ~0u, vsir_validate_loop}, -+ [VSIR_OP_LTO] = {1, 2, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_LTU] = {1, 2, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_MAD] = {1, 3, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation}, - [VSIR_OP_NOP] = {0, 0, vsir_validate_nop}, - [VSIR_OP_PHI] = {1, ~0u, vsir_validate_phi}, - [VSIR_OP_REP] = {0, 1, vsir_validate_rep}, -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index 032b5504319..83cdf9feea0 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -133,11 +133,11 @@ static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int in - } - - static void msl_print_resource_datatype(struct msl_generator *gen, -- struct vkd3d_string_buffer *buffer, enum vkd3d_data_type data_type) -+ struct vkd3d_string_buffer *buffer, enum vsir_data_type data_type) - { - switch (data_type) - { -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: - vkd3d_string_buffer_printf(buffer, "float"); -@@ -157,12 +157,12 @@ static void msl_print_resource_datatype(struct msl_generator *gen, - } - - static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, -- struct msl_generator *gen, enum vkd3d_data_type data_type) -+ struct msl_generator *gen, enum vsir_data_type data_type) - { - vkd3d_string_buffer_printf(buffer, "."); - switch (data_type) - { -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - vkd3d_string_buffer_printf(buffer, "f"); - break; - case VKD3D_DATA_INT: -@@ -345,7 +345,7 @@ static void msl_print_sampler_name(struct vkd3d_string_buffer *buffer, unsigned - } - - static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, -- const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type, bool compare) -+ const struct msl_resource_type_info *resource_type_info, enum vsir_data_type resource_data_type, bool compare) - { - vkd3d_string_buffer_printf(buffer, "descriptors[%u].as<%s%s%s<", - binding, compare ? "depth" : "texture", resource_type_info->type_suffix, -@@ -355,7 +355,7 @@ static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_ge - } - - static void msl_print_uav_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, -- const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type) -+ const struct msl_resource_type_info *resource_type_info, enum vsir_data_type resource_data_type) - { - vkd3d_string_buffer_printf(buffer, "descriptors[%u].astype_suffix, -@@ -523,17 +523,17 @@ static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cach - } - - static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_generator *gen, const char *src, -- enum vkd3d_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) -+ enum vsir_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) - { - bool write_cast = false; - - if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) -- dst_data_type = VKD3D_DATA_FLOAT; -+ dst_data_type = VSIR_DATA_F32; - - switch (src_data_type) - { - case MSL_DATA_FLOAT: -- write_cast = dst_data_type != VKD3D_DATA_FLOAT; -+ write_cast = dst_data_type != VSIR_DATA_F32; - break; - - case MSL_DATA_UINT: -@@ -561,7 +561,7 @@ static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_genera - } - - static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, -- const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) -+ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vsir_data_type data_type) - { - const struct vkd3d_shader_register *reg = &vsir_src->reg; - struct vkd3d_string_buffer *register_name, *str; -@@ -947,7 +947,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - const struct vkd3d_shader_descriptor_binding *binding; - enum vkd3d_shader_resource_type resource_type; - struct vkd3d_string_buffer *read; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - unsigned int srv_binding; - uint32_t coord_mask; - struct msl_dst dst; -@@ -975,7 +975,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - "Internal compiler error: Undeclared resource descriptor %u.", resource_id); - resource_space = 0; - resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -- data_type = VKD3D_DATA_FLOAT; -+ data_type = VSIR_DATA_F32; - } - - if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBE -@@ -1047,7 +1047,7 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - enum vkd3d_shader_resource_type resource_type; - unsigned int srv_binding, sampler_binding; - struct vkd3d_string_buffer *sample; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - unsigned int component_idx; - uint32_t coord_mask; - struct msl_dst dst; -@@ -1086,7 +1086,7 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - "Internal compiler error: Undeclared resource descriptor %u.", resource_id); - resource_space = 0; - resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -- data_type = VKD3D_DATA_FLOAT; -+ data_type = VSIR_DATA_F32; - } - - if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER -@@ -1257,7 +1257,7 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - enum vkd3d_shader_resource_type resource_type; - unsigned int uav_id, uav_idx, uav_space; - struct vkd3d_string_buffer *image_data; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - unsigned int uav_binding; - uint32_t coord_mask; - -@@ -1280,7 +1280,7 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); - uav_space = 0; - resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -- data_type = VKD3D_DATA_FLOAT; -+ data_type = VSIR_DATA_F32; - } - - if (!(resource_type_info = msl_get_resource_type_info(resource_type))) -@@ -1319,7 +1319,7 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled data type %#x.", data_type); - /* fall through */ -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: - vkd3d_string_buffer_printf(image_data, "float4("); -@@ -1882,13 +1882,13 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) - switch (e->sysval_semantic) - { - case VKD3D_SHADER_SV_NONE: -- msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); -+ msl_print_register_datatype(buffer, gen, vsir_data_type_from_component_type(e->component_type)); - msl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i); - break; - - case VKD3D_SHADER_SV_POSITION: -- msl_print_register_datatype(buffer, gen, VKD3D_DATA_FLOAT); -+ msl_print_register_datatype(buffer, gen, VSIR_DATA_F32); - msl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, " = float4(input.position.xyz, 1.0f / input.position.w)"); - break; -@@ -1944,7 +1944,7 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) - vkd3d_string_buffer_printf(buffer, " output.shader_out_%u", i); - msl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, " = %s_out[%u]", gen->prefix, e->register_index); -- msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); -+ msl_print_register_datatype(buffer, gen, vsir_data_type_from_component_type(e->component_type)); - msl_print_write_mask(buffer, e->mask); - break; - case VKD3D_SHADER_SV_DEPTH: -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index c51a6a394c0..eb9a90e8b44 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -2568,7 +2568,7 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, - } - - static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, -- enum vkd3d_data_type data_type, unsigned int component_count) -+ enum vsir_data_type data_type, unsigned int component_count) - { - enum vkd3d_shader_component_type component_type; - -@@ -3012,7 +3012,7 @@ struct vkd3d_hull_shader_variables - - struct ssa_register_info - { -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - uint8_t write_mask; - uint32_t id; - }; -@@ -3985,7 +3985,7 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com - - static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compiler, - enum vkd3d_shader_parameter_name name, uint32_t spec_id, -- enum vkd3d_data_type type, unsigned int component_count) -+ enum vsir_data_type type, unsigned int component_count) - { - uint32_t scalar_type_id, vector_type_id, id, default_value, components[4]; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -@@ -4024,7 +4024,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile - - static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler, - enum vkd3d_shader_parameter_name name, uint32_t spec_id, -- enum vkd3d_data_type type, unsigned int component_count) -+ enum vsir_data_type type, unsigned int component_count) - { - unsigned int i; - -@@ -4038,7 +4038,7 @@ static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler - } - - static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compiler, -- const struct vkd3d_shader_parameter1 *parameter, enum vkd3d_data_type type, unsigned int component_count) -+ const struct vkd3d_shader_parameter1 *parameter, enum vsir_data_type type, unsigned int component_count) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - unsigned int index = parameter - compiler->program->parameters; -@@ -4054,18 +4054,18 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi - - static const struct - { -- enum vkd3d_data_type type; -+ enum vsir_data_type type; - unsigned int component_count; - } - parameter_data_type_map[] = - { -- [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VKD3D_DATA_FLOAT, 1}, -+ [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VSIR_DATA_F32, 1}, - [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VKD3D_DATA_UINT, 1}, -- [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VKD3D_DATA_FLOAT, 4}, -+ [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VSIR_DATA_F32, 4}, - }; - - static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *compiler, -- enum vkd3d_shader_parameter_name name, enum vkd3d_data_type type, unsigned int component_count) -+ enum vkd3d_shader_parameter_name name, enum vsir_data_type type, unsigned int component_count) - { - const struct vkd3d_shader_parameter1 *parameter; - -@@ -4479,7 +4479,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil - } - - static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, -- enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, -+ enum vkd3d_shader_conditional_op condition, enum vsir_data_type data_type, - unsigned int component_count, uint32_t val_id) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -@@ -4708,14 +4708,14 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil - - switch (icb->data_type) - { -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F32: - case VKD3D_DATA_INT: - case VKD3D_DATA_UINT: - for (i = 0; i < element_count; ++i) - elements[i] = spirv_compiler_get_constant(compiler, component_type, component_count, - &icb->data[component_count * i]); - break; -- case VKD3D_DATA_DOUBLE: -+ case VSIR_DATA_F64: - case VKD3D_DATA_UINT64: - { - uint64_t *data = (uint64_t *)icb->data; -@@ -4903,7 +4903,7 @@ static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *co - { - struct vkd3d_shader_src_param src_param = *src; - -- src_param.reg.data_type = vkd3d_data_type_from_component_type(component_type); -+ src_param.reg.data_type = vsir_data_type_from_component_type(component_type); - return spirv_compiler_emit_load_src(compiler, &src_param, write_mask); - } - -@@ -5029,7 +5029,7 @@ static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, zero_id, one_id; - -- if (reg->data_type == VKD3D_DATA_DOUBLE) -+ if (reg->data_type == VSIR_DATA_F64) - { - zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); - one_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count); -@@ -5083,7 +5083,7 @@ static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compil - /* XXX: The register data type could be fixed by the shader parser. For SM5 - * shaders the data types are stored in instructions modifiers. - */ -- typed_dst.reg.data_type = vkd3d_data_type_from_component_type(component_type); -+ typed_dst.reg.data_type = vsir_data_type_from_component_type(component_type); - spirv_compiler_emit_store_dst(compiler, &typed_dst, val_id); - } - -@@ -5511,7 +5511,7 @@ static uint32_t spirv_compiler_get_invocation_id(struct spirv_compiler *compiler - - VKD3D_ASSERT(compiler->shader_type == VKD3D_SHADER_TYPE_HULL); - -- vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0); -+ vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VSIR_DATA_F32, 0); - return spirv_compiler_get_register_id(compiler, &r); - } - -@@ -5800,7 +5800,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - { - struct vkd3d_shader_register dst_reg; - -- vsir_register_init(&dst_reg, reg_type, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(&dst_reg, reg_type, VSIR_DATA_F32, 1); - dst_reg.idx[0].offset = element_idx; - - type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count); -@@ -6502,7 +6502,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil - * scope is specified, e.g. DXIL alloca. */ - storage_class = temp->has_function_scope ? SpvStorageClassFunction : SpvStorageClassPrivate; - -- vsir_register_init(®, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(®, VKD3DSPR_IDXTEMP, VSIR_DATA_F32, 1); - reg.idx[0].offset = temp->register_idx; - - /* Alignment is supported only in the Kernel execution model and is an optimisation only. */ -@@ -6742,7 +6742,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, - struct vkd3d_symbol reg_symbol; - unsigned int size; - -- vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); -+ vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 3); - reg.idx[0].offset = descriptor->register_id; - reg.idx[1].offset = range->first; - reg.idx[2].offset = range->last; -@@ -6802,7 +6802,7 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi - vkd3d_spirv_build_op_name(builder, icb_id, "icb"); - - /* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */ -- vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 2); -+ vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VSIR_DATA_F32, 2); - reg.idx[0].offset = icb->register_idx; - vkd3d_symbol_make_register(®_symbol, ®); - vkd3d_symbol_set_register_info(®_symbol, icb_id, SpvStorageClassPrivate, -@@ -6821,7 +6821,7 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi - struct vkd3d_symbol reg_symbol; - uint32_t type_id, var_id; - -- vsir_register_init(®, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(®, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1); - reg.idx[0].offset = descriptor->register_id; - - vkd3d_symbol_make_sampler(®_symbol, ®); -@@ -7002,7 +7002,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - struct vkd3d_symbol resource_symbol; - struct vkd3d_shader_register reg; - -- vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_FLOAT, 1); -+ vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_F32, 1); - reg.idx[0].offset = descriptor->register_id; - - if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && sample_count == 1) -@@ -7592,11 +7592,11 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, - VKD3D_ASSERT(src->reg.data_type == VKD3D_DATA_BOOL && dst->reg.data_type != VKD3D_DATA_BOOL); - - val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); -- if (dst->reg.data_type == VKD3D_DATA_HALF || dst->reg.data_type == VKD3D_DATA_FLOAT) -+ if (dst->reg.data_type == VSIR_DATA_F16 || dst->reg.data_type == VSIR_DATA_F32) - { - val_id = spirv_compiler_emit_bool_to_float(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); - } -- else if (dst->reg.data_type == VKD3D_DATA_DOUBLE) -+ else if (dst->reg.data_type == VSIR_DATA_F64) - { - /* ITOD is not supported. Frontends which emit bool casts must use ITOF for double. */ - val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); -@@ -8051,7 +8051,7 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, - type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); - - src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); -- if (src->reg.data_type == VKD3D_DATA_DOUBLE) -+ if (src->reg.data_type == VSIR_DATA_F64) - div_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count); - else - div_id = spirv_compiler_get_constant_float_vector(compiler, 1.0f, component_count); -@@ -8101,7 +8101,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, - - component_count = vsir_write_mask_component_count(dst->write_mask); - -- if (src->reg.data_type == VKD3D_DATA_DOUBLE) -+ if (src->reg.data_type == VSIR_DATA_F64) - { - write_mask = vkd3d_write_mask_from_component_count(component_count); - int_min_id = spirv_compiler_get_constant_double_vector(compiler, -2147483648.0, component_count); -@@ -8157,7 +8157,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, - - component_count = vsir_write_mask_component_count(dst->write_mask); - -- if (src->reg.data_type == VKD3D_DATA_DOUBLE) -+ if (src->reg.data_type == VSIR_DATA_F64) - { - write_mask = vkd3d_write_mask_from_component_count(component_count); - zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); -@@ -10952,14 +10952,14 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) - - if (compiler->program->has_point_size) - { -- vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); -+ vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); - dst.reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; - spirv_compiler_emit_io_register(compiler, &dst); - } - - if (compiler->program->has_point_coord) - { -- vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0); -+ vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); - spirv_compiler_emit_io_register(compiler, &dst); - } - -@@ -10970,7 +10970,7 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) - if (bitmap_is_set(compiler->program->io_dcls, i) - || (compiler->program->shader_version.type == VKD3D_SHADER_TYPE_HULL && i == VKD3DSPR_OUTPOINTID)) - { -- vsir_dst_param_init(&dst, i, VKD3D_DATA_FLOAT, 0); -+ vsir_dst_param_init(&dst, i, VSIR_DATA_F32, 0); - spirv_compiler_emit_io_register(compiler, &dst); - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index c7eafbc79f3..26c41a902d2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -748,16 +748,16 @@ static const enum vkd3d_shader_resource_type resource_type_table[] = - /* VKD3D_SM4_RESOURCE_STRUCTURED_BUFFER */ VKD3D_SHADER_RESOURCE_BUFFER, - }; - --static const enum vkd3d_data_type data_type_table[] = -+static const enum vsir_data_type data_type_table[] = - { -- /* 0 */ VKD3D_DATA_FLOAT, -+ /* 0 */ VSIR_DATA_F32, - /* VKD3D_SM4_DATA_UNORM */ VKD3D_DATA_UNORM, - /* VKD3D_SM4_DATA_SNORM */ VKD3D_DATA_SNORM, - /* VKD3D_SM4_DATA_INT */ VKD3D_DATA_INT, - /* VKD3D_SM4_DATA_UINT */ VKD3D_DATA_UINT, -- /* VKD3D_SM4_DATA_FLOAT */ VKD3D_DATA_FLOAT, -+ /* VKD3D_SM4_DATA_FLOAT */ VSIR_DATA_F32, - /* VKD3D_SM4_DATA_MIXED */ VKD3D_DATA_MIXED, -- /* VKD3D_SM4_DATA_DOUBLE */ VKD3D_DATA_DOUBLE, -+ /* VKD3D_SM4_DATA_DOUBLE */ VSIR_DATA_F64, - /* VKD3D_SM4_DATA_CONTINUED */ VKD3D_DATA_CONTINUED, - /* VKD3D_SM4_DATA_UNUSED */ VKD3D_DATA_UNUSED, - }; -@@ -770,9 +770,9 @@ static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) - } - - static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, -- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param); -+ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_src_param *src_param); - static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, -- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param); -+ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_dst_param *dst_param); - - static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv, - const uint32_t **ptr, const uint32_t *end, unsigned int *register_space) -@@ -844,7 +844,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui - return; - } - icb->register_idx = 0; -- icb->data_type = VKD3D_DATA_FLOAT; -+ icb->data_type = VSIR_DATA_F32; - icb->component_count = VKD3D_VEC4_SIZE; - icb->element_count = icb_size / VKD3D_VEC4_SIZE; - icb->is_null = false; -@@ -873,7 +873,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u - enum vkd3d_sm4_resource_type resource_type; - const uint32_t *end = &tokens[token_count]; - enum vkd3d_sm4_data_type data_type; -- enum vkd3d_data_type reg_data_type; -+ enum vsir_data_type reg_data_type; - uint32_t components; - unsigned int i; - -@@ -907,7 +907,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u - if (!data_type || (data_type >= ARRAY_SIZE(data_type_table))) - { - FIXME("Unhandled data type %#x.\n", data_type); -- semantic->resource_data_type[i] = VKD3D_DATA_FLOAT; -+ semantic->resource_data_type[i] = VSIR_DATA_F32; - } - else - { -@@ -926,7 +926,7 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction - { - const uint32_t *end = &tokens[token_count]; - -- shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_FLOAT, &ins->declaration.cb.src); -+ shader_sm4_read_src_param(priv, &tokens, end, VSIR_DATA_F32, &ins->declaration.cb.src); - shader_sm4_set_descriptor_register_range(priv, &ins->declaration.cb.src.reg, &ins->declaration.cb.range); - if (opcode_token & VKD3D_SM4_INDEX_TYPE_MASK) - ins->flags |= VKD3DSI_INDEXED_DYNAMIC; -@@ -1142,14 +1142,14 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i - static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode, - uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { -- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, &ins->declaration.dst); -+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, &ins->declaration.dst); - } - - static void shader_sm4_read_declaration_register_semantic(struct vkd3d_shader_instruction *ins, uint32_t opcode, - uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { -- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, -- &ins->declaration.register_semantic.reg); -+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], -+ VSIR_DATA_F32, &ins->declaration.register_semantic.reg); - ins->declaration.register_semantic.sysval_semantic = *tokens; - } - -@@ -1159,7 +1159,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u - struct vkd3d_shader_dst_param *dst = &ins->declaration.dst; - - ins->flags = (opcode_token & VKD3D_SM4_INTERPOLATION_MODE_MASK) >> VKD3D_SM4_INTERPOLATION_MODE_SHIFT; -- if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst)) -+ if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) - { - struct signature_element *e = vsir_signature_find_element_for_reg( - &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); -@@ -1185,7 +1185,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in - struct vkd3d_shader_dst_param *dst = &ins->declaration.register_semantic.reg; - - ins->flags = (opcode_token & VKD3D_SM4_INTERPOLATION_MODE_MASK) >> VKD3D_SM4_INTERPOLATION_MODE_SHIFT; -- if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst)) -+ if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) - { - struct signature_element *e = vsir_signature_find_element_for_reg( - &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); -@@ -1212,7 +1212,7 @@ static void shader_sm4_read_dcl_indexable_temp(struct vkd3d_shader_instruction * - ins->declaration.indexable_temp.register_idx = *tokens++; - ins->declaration.indexable_temp.register_size = *tokens++; - ins->declaration.indexable_temp.alignment = 0; -- ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT; -+ ins->declaration.indexable_temp.data_type = VSIR_DATA_F32; - ins->declaration.indexable_temp.component_count = *tokens; - ins->declaration.indexable_temp.has_function_scope = false; - } -@@ -1339,7 +1339,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction * - static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins, uint32_t opcode, - uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { -- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg); -+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, &ins->declaration.tgsm_raw.reg); - ins->declaration.tgsm_raw.byte_count = *tokens; - if (ins->declaration.tgsm_raw.byte_count % 4) - FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count); -@@ -1349,8 +1349,8 @@ static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins, u - static void shader_sm5_read_dcl_tgsm_structured(struct vkd3d_shader_instruction *ins, uint32_t opcode, - uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { -- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, -- &ins->declaration.tgsm_structured.reg); -+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], -+ VSIR_DATA_F32, &ins->declaration.tgsm_structured.reg); - ins->declaration.tgsm_structured.byte_stride = *tokens++; - ins->declaration.tgsm_structured.structure_count = *tokens; - if (ins->declaration.tgsm_structured.byte_stride % 4) -@@ -1430,8 +1430,8 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) - unsigned int i; - - /* -- * d -> VKD3D_DATA_DOUBLE -- * f -> VKD3D_DATA_FLOAT -+ * d -> VSIR_DATA_F64 -+ * f -> VSIR_DATA_F32 - * i -> VKD3D_DATA_INT - * u -> VKD3D_DATA_UINT - * O -> VKD3D_DATA_OPAQUE -@@ -1985,14 +1985,14 @@ static enum vkd3d_sm4_stat_field get_stat_field_from_sm4_opcode( - return field_info->field; - } - --static enum vkd3d_data_type map_data_type(char t) -+static enum vsir_data_type map_data_type(char t) - { - switch (t) - { - case 'd': -- return VKD3D_DATA_DOUBLE; -+ return VSIR_DATA_F64; - case 'f': -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - case 'i': - return VKD3D_DATA_INT; - case 'u': -@@ -2003,7 +2003,7 @@ static enum vkd3d_data_type map_data_type(char t) - return VKD3D_DATA_UNUSED; - default: - ERR("Invalid data type '%c'.\n", t); -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - } - } - -@@ -2036,7 +2036,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const - } - - static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, const uint32_t *end, -- enum vkd3d_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier) -+ enum vsir_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier) - { - const struct vkd3d_sm4_register_type_info *register_type_info; - enum vkd3d_shader_register_type vsir_register_type; -@@ -2237,12 +2237,10 @@ bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg) - { - switch (reg->type) - { -- case VKD3DSPR_COVERAGE: - case VKD3DSPR_DEPTHOUT: - case VKD3DSPR_DEPTHOUTGE: - case VKD3DSPR_DEPTHOUTLE: - case VKD3DSPR_GSINSTID: -- case VKD3DSPR_LOCALTHREADINDEX: - case VKD3DSPR_OUTPOINTID: - case VKD3DSPR_PRIMID: - case VKD3DSPR_SAMPLEMASK: -@@ -2354,7 +2352,7 @@ static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_pa - } - - static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, -- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param) -+ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_src_param *src_param) - { - unsigned int dimension, mask; - uint32_t token; -@@ -2442,7 +2440,7 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons - } - - static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, -- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param) -+ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_dst_param *dst_param) - { - enum vkd3d_sm4_swizzle_type swizzle_type; - enum vkd3d_shader_src_modifier modifier; -@@ -2512,7 +2510,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons - break; - } - -- if (data_type == VKD3D_DATA_DOUBLE) -+ if (data_type == VSIR_DATA_F64) - dst_param->write_mask = vsir_write_mask_64_from_32(dst_param->write_mask); - /* Some scalar registers are declared with no write mask in shader bytecode. */ - if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg)) -@@ -2573,7 +2571,7 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d - if (!data_type || (data_type >= ARRAY_SIZE(data_type_table))) - { - FIXME("Unhandled data type %#x.\n", data_type); -- ins->resource_data_type[i] = VKD3D_DATA_FLOAT; -+ ins->resource_data_type[i] = VSIR_DATA_F32; - } - else - { -@@ -2683,10 +2681,10 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str - } - ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; - ins->resource_stride = 0; -- ins->resource_data_type[0] = VKD3D_DATA_FLOAT; -- ins->resource_data_type[1] = VKD3D_DATA_FLOAT; -- ins->resource_data_type[2] = VKD3D_DATA_FLOAT; -- ins->resource_data_type[3] = VKD3D_DATA_FLOAT; -+ ins->resource_data_type[0] = VSIR_DATA_F32; -+ ins->resource_data_type[1] = VSIR_DATA_F32; -+ ins->resource_data_type[2] = VSIR_DATA_F32; -+ ins->resource_data_type[3] = VSIR_DATA_F32; - memset(&ins->texel_offset, 0, sizeof(ins->texel_offset)); - - p = *ptr; -@@ -3838,7 +3836,7 @@ static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_s - write_sm4_instruction(tpf, &instr); - } - --static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_data_type) -+static uint32_t pack_resource_data_type(const enum vsir_data_type *resource_data_type) - { - unsigned int i, k, type = 0; - -@@ -4503,6 +4501,9 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struc - if ((ret = vsir_allocate_temp_registers(program, message_context))) - return ret; - -+ if ((ret = vsir_update_dcl_temps(program, message_context))) -+ return ret; -+ - tpf.program = program; - tpf.buffer = NULL; - tpf.stat = &stat; -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 4cda8493696..c60feec4aa2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -1084,7 +1084,7 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont - static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, - enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, - const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, -- enum vkd3d_data_type resource_data_type) -+ enum vsir_data_type resource_data_type) - { - struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; - struct vkd3d_shader_descriptor_info1 *d; -@@ -1145,7 +1145,7 @@ static void vkd3d_shader_scan_combined_sampler_declaration( - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, - &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED); - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, -- &semantic->resource.range, semantic->resource_type, VKD3D_DATA_FLOAT); -+ &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32); - } - - const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( -@@ -1235,7 +1235,7 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co - - static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, - const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, -- enum vkd3d_data_type resource_data_type, unsigned int sample_count, -+ enum vsir_data_type resource_data_type, unsigned int sample_count, - unsigned int structure_stride, bool raw, uint32_t flags) - { - struct vkd3d_shader_descriptor_info1 *d; -@@ -1522,7 +1522,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - return VKD3D_OK; - } - --static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vkd3d_data_type data_type) -+static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vsir_data_type data_type) - { - switch (data_type) - { -@@ -1534,16 +1534,16 @@ static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_t - return VKD3D_SHADER_RESOURCE_DATA_INT; - case VKD3D_DATA_UINT: - return VKD3D_SHADER_RESOURCE_DATA_UINT; -- case VKD3D_DATA_FLOAT: -- return VKD3D_SHADER_RESOURCE_DATA_FLOAT; - case VKD3D_DATA_MIXED: - return VKD3D_SHADER_RESOURCE_DATA_MIXED; -- case VKD3D_DATA_DOUBLE: -- return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; - case VKD3D_DATA_CONTINUED: - return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; - case VKD3D_DATA_UNUSED: - return VKD3D_SHADER_RESOURCE_DATA_NONE; -+ case VSIR_DATA_F32: -+ return VKD3D_SHADER_RESOURCE_DATA_FLOAT; -+ case VSIR_DATA_F64: -+ return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; - default: - ERR("Invalid resource data type %#x.\n", data_type); - return VKD3D_SHADER_RESOURCE_DATA_FLOAT; -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 978af0a2d17..f7bbadac3df 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -184,6 +184,7 @@ enum vkd3d_shader_error - VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305, - VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE = 5306, - VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER = 5307, -+ VKD3D_SHADER_WARNING_HLSL_OVERRIDDEN_SEMANTIC = 5308, - - VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, - VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND = 6001, -@@ -707,46 +708,47 @@ enum vkd3d_shader_register_precision - VKD3D_SHADER_REGISTER_PRECISION_INVALID = ~0u, - }; - --enum vkd3d_data_type -+enum vsir_data_type - { -- VKD3D_DATA_FLOAT, - VKD3D_DATA_INT, - VKD3D_DATA_UINT, - VKD3D_DATA_UNORM, - VKD3D_DATA_SNORM, - VKD3D_DATA_OPAQUE, - VKD3D_DATA_MIXED, -- VKD3D_DATA_DOUBLE, - VKD3D_DATA_CONTINUED, - VKD3D_DATA_UNUSED, - VKD3D_DATA_UINT8, - VKD3D_DATA_UINT64, - VKD3D_DATA_BOOL, - VKD3D_DATA_UINT16, -- VKD3D_DATA_HALF, - -- VKD3D_DATA_COUNT, -+ VSIR_DATA_F16, -+ VSIR_DATA_F32, -+ VSIR_DATA_F64, -+ -+ VSIR_DATA_TYPE_COUNT, - }; - --static inline bool data_type_is_integer(enum vkd3d_data_type data_type) -+static inline bool data_type_is_integer(enum vsir_data_type data_type) - { - return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT16 - || data_type == VKD3D_DATA_UINT || data_type == VKD3D_DATA_UINT64; - } - --static inline bool data_type_is_bool(enum vkd3d_data_type data_type) -+static inline bool data_type_is_bool(enum vsir_data_type data_type) - { - return data_type == VKD3D_DATA_BOOL; - } - --static inline bool data_type_is_floating_point(enum vkd3d_data_type data_type) -+static inline bool data_type_is_floating_point(enum vsir_data_type data_type) - { -- return data_type == VKD3D_DATA_HALF || data_type == VKD3D_DATA_FLOAT || data_type == VKD3D_DATA_DOUBLE; -+ return data_type == VSIR_DATA_F16 || data_type == VSIR_DATA_F32 || data_type == VSIR_DATA_F64; - } - --static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type) -+static inline bool data_type_is_64_bit(enum vsir_data_type data_type) - { -- return data_type == VKD3D_DATA_DOUBLE || data_type == VKD3D_DATA_UINT64; -+ return data_type == VSIR_DATA_F64 || data_type == VKD3D_DATA_UINT64; - } - - enum vsir_dimension -@@ -941,7 +943,7 @@ struct vkd3d_shader_version - struct vkd3d_shader_immediate_constant_buffer - { - unsigned int register_idx; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - /* total count is element_count * component_count */ - unsigned int element_count; - unsigned int component_count; -@@ -954,7 +956,7 @@ struct vkd3d_shader_indexable_temp - unsigned int register_idx; - unsigned int register_size; - unsigned int alignment; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - unsigned int component_count; - bool has_function_scope; - const struct vkd3d_shader_immediate_constant_buffer *initialiser; -@@ -973,7 +975,7 @@ struct vkd3d_shader_register - enum vkd3d_shader_register_type type; - enum vkd3d_shader_register_precision precision; - bool non_uniform; -- enum vkd3d_data_type data_type; -+ enum vsir_data_type data_type; - struct vkd3d_shader_register_index idx[3]; - unsigned int idx_count; - enum vsir_dimension dimension; -@@ -990,7 +992,7 @@ struct vkd3d_shader_register - }; - - void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, -- enum vkd3d_data_type data_type, unsigned int idx_count); -+ enum vsir_data_type data_type, unsigned int idx_count); - - static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_register *reg) - { -@@ -1023,9 +1025,9 @@ struct vkd3d_shader_src_param - }; - - void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, -- enum vkd3d_data_type data_type, unsigned int idx_count); -+ enum vsir_data_type data_type, unsigned int idx_count); - void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, -- enum vkd3d_data_type data_type, unsigned int idx_count); -+ enum vsir_data_type data_type, unsigned int idx_count); - void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst); - void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id); - -@@ -1071,7 +1073,7 @@ struct vkd3d_shader_semantic - unsigned int usage_idx; - enum vkd3d_shader_resource_type resource_type; - unsigned int sample_count; -- enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE]; -+ enum vsir_data_type resource_data_type[VKD3D_VEC4_SIZE]; - struct vkd3d_shader_resource resource; - }; - -@@ -1284,7 +1286,7 @@ struct vkd3d_shader_instruction - struct vkd3d_shader_texel_offset texel_offset; - enum vkd3d_shader_resource_type resource_type; - unsigned int resource_stride; -- enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE]; -+ enum vsir_data_type resource_data_type[VKD3D_VEC4_SIZE]; - bool coissue, structured, raw; - const struct vkd3d_shader_src_param *predicate; - union -@@ -1419,6 +1421,51 @@ bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_ - unsigned int dst, unsigned int src); - void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); - -+struct vsir_program_iterator -+{ -+ struct vkd3d_shader_instruction_array *array; -+ size_t idx; -+}; -+ -+static inline struct vsir_program_iterator vsir_program_iterator(struct vkd3d_shader_instruction_array *array) -+{ -+ return (struct vsir_program_iterator){ .array = array }; -+} -+ -+static inline struct vkd3d_shader_instruction *vsir_program_iterator_current( -+ struct vsir_program_iterator *iterator) -+{ -+ if (iterator->idx >= iterator->array->count) -+ return NULL; -+ -+ return &iterator->array->elements[iterator->idx]; -+} -+ -+static inline struct vkd3d_shader_instruction *vsir_program_iterator_head( -+ struct vsir_program_iterator *iterator) -+{ -+ iterator->idx = 0; -+ -+ return vsir_program_iterator_current(iterator); -+} -+ -+static inline struct vkd3d_shader_instruction *vsir_program_iterator_next( -+ struct vsir_program_iterator *iterator) -+{ -+ if (iterator->idx < iterator->array->count) -+ ++iterator->idx; -+ -+ return vsir_program_iterator_current(iterator); -+} -+ -+/* When insertion takes place, argument `it' is updated to point to the same -+ * instruction as before the insertion, but all other iterators and pointers -+ * to the same container are invalidated and cannot be used any more. */ -+static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterator *it, unsigned int count) -+{ -+ return shader_instruction_array_insert_at(it->array, it->idx + 1, count); -+} -+ - enum vkd3d_shader_config_flags - { - VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, -@@ -1445,7 +1492,7 @@ struct vkd3d_shader_descriptor_info1 - unsigned int register_index; - unsigned int register_id; - enum vkd3d_shader_resource_type resource_type; -- enum vkd3d_data_type resource_data_type; -+ enum vsir_data_type resource_data_type; - unsigned int flags; - unsigned int sample_count; - unsigned int buffer_size; -@@ -1511,6 +1558,8 @@ struct vsir_program - - enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context); -+enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, -+ struct vkd3d_shader_message_context *message_context); - void vsir_program_cleanup(struct vsir_program *program); - int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, -@@ -1739,23 +1788,22 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, - int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); - --static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( -- enum vkd3d_data_type data_type) -+static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) - { - switch (data_type) - { -- case VKD3D_DATA_HALF: /* Minimum precision. TODO: native 16-bit */ -- case VKD3D_DATA_FLOAT: -+ case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */ -+ case VSIR_DATA_F32: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: - return VKD3D_SHADER_COMPONENT_FLOAT; -+ case VSIR_DATA_F64: -+ return VKD3D_SHADER_COMPONENT_DOUBLE; - case VKD3D_DATA_UINT16: /* Minimum precision. TODO: native 16-bit */ - case VKD3D_DATA_UINT: - return VKD3D_SHADER_COMPONENT_UINT; - case VKD3D_DATA_INT: - return VKD3D_SHADER_COMPONENT_INT; -- case VKD3D_DATA_DOUBLE: -- return VKD3D_SHADER_COMPONENT_DOUBLE; - case VKD3D_DATA_UINT64: - return VKD3D_SHADER_COMPONENT_UINT64; - case VKD3D_DATA_BOOL: -@@ -1768,22 +1816,21 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty - } - } - --static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( -- enum vkd3d_shader_component_type component_type) -+static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_shader_component_type component_type) - { - switch (component_type) - { - case VKD3D_SHADER_COMPONENT_FLOAT: -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - case VKD3D_SHADER_COMPONENT_UINT: - return VKD3D_DATA_UINT; - case VKD3D_SHADER_COMPONENT_INT: - return VKD3D_DATA_INT; - case VKD3D_SHADER_COMPONENT_DOUBLE: -- return VKD3D_DATA_DOUBLE; -+ return VSIR_DATA_F64; - default: - FIXME("Unhandled component type %#x.\n", component_type); -- return VKD3D_DATA_FLOAT; -+ return VSIR_DATA_F32; - } - } - --- -2.50.1 - diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch deleted file mode 100644 index 1f504671..00000000 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch +++ /dev/null @@ -1,1701 +0,0 @@ -From dc5e92bd8bf82fa50d3d63e556b681862ddf47c7 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Wed, 23 Jul 2025 07:16:58 +1000 -Subject: [PATCH] Updated vkd3d to 68cd72c7fc7a364ecce87a19617acb382c70762f. - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 33 ++--- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 21 ++-- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 60 ++++----- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 54 ++++---- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 22 ++-- - libs/vkd3d/libs/vkd3d-shader/ir.c | 116 ++++++++---------- - libs/vkd3d/libs/vkd3d-shader/msl.c | 43 +++---- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 63 +++++----- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 44 ++++--- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 18 +-- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 46 ++++--- - 11 files changed, 260 insertions(+), 260 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 7d10cf98f71..5e3e7daab83 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -388,21 +388,21 @@ static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum - { - static const char *const data_type_names[] = - { -- [VKD3D_DATA_INT ] = "int", -- [VKD3D_DATA_UINT ] = "uint", - [VKD3D_DATA_UNORM ] = "unorm", - [VKD3D_DATA_SNORM ] = "snorm", - [VKD3D_DATA_OPAQUE ] = "opaque", - [VKD3D_DATA_MIXED ] = "mixed", - [VKD3D_DATA_CONTINUED] = "", - [VKD3D_DATA_UNUSED ] = "", -- [VKD3D_DATA_UINT8 ] = "uint8", -- [VKD3D_DATA_UINT64 ] = "uint64", - [VKD3D_DATA_BOOL ] = "bool", -- [VKD3D_DATA_UINT16 ] = "uint16", - [VSIR_DATA_F16 ] = "half", - [VSIR_DATA_F32 ] = "float", - [VSIR_DATA_F64 ] = "double", -+ [VSIR_DATA_I32 ] = "int", -+ [VSIR_DATA_U8 ] = "uint8", -+ [VSIR_DATA_U16 ] = "uint16", -+ [VSIR_DATA_U32 ] = "uint", -+ [VSIR_DATA_U64 ] = "uint64", - }; - - if (type < ARRAY_SIZE(data_type_names)) -@@ -736,10 +736,10 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - else - shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], ""); - break; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], ""); - break; -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_U32: - shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], ""); - break; - default: -@@ -768,13 +768,13 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], ""); - } - break; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], ""); - shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[1], ""); - shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[2], ""); - shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[3], ""); - break; -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_U32: - shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], ""); - shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[1], ""); - shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[2], ""); -@@ -806,7 +806,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - if (reg->dimension == VSIR_DIMENSION_VEC4) - shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], ""); - } -- else if (reg->data_type == VKD3D_DATA_UINT64) -+ else if (reg->data_type == VSIR_DATA_U64) - { - shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[0], ""); - if (reg->dimension == VSIR_DIMENSION_VEC4) -@@ -1951,8 +1951,7 @@ static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler, - } - } - --enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, -- const struct vkd3d_shader_compile_info *compile_info, -+enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, enum vsir_asm_flags flags) - { - const struct vkd3d_shader_version *shader_version = &program->shader_version; -@@ -1961,8 +1960,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, - { - .flags = flags, - }; -+ struct vkd3d_shader_instruction *ins; - enum vkd3d_result result = VKD3D_OK; - struct vkd3d_string_buffer *buffer; -+ struct vsir_program_iterator it; - unsigned int indent, i, j; - const char *indent_str; - -@@ -2042,10 +2043,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, - vkd3d_string_buffer_printf(buffer, "%s.text%s\n", compiler.colours.opcode, compiler.colours.reset); - - indent = 0; -- for (i = 0; i < program->instructions.count; ++i) -- { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - -+ it = vsir_program_iterator(&program->instructions); -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -+ { - switch (ins->opcode) - { - case VSIR_OP_ELSE: -@@ -2236,7 +2237,7 @@ static void trace_io_declarations(const struct vsir_program *program) - vkd3d_string_buffer_cleanup(&buffer); - } - --void vsir_program_trace(const struct vsir_program *program) -+void vsir_program_trace(struct vsir_program *program) - { - const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES - | VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS; -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 2dd9c731010..49e1a529369 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1301,13 +1301,13 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - else if (ins->opcode == VSIR_OP_DEFB) - { - shader_sm1_read_dst_param(sm1, &p, dst_param); -- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VKD3D_DATA_UINT); -+ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VSIR_DATA_U32); - shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); - } - else if (ins->opcode == VSIR_OP_DEFI) - { - shader_sm1_read_dst_param(sm1, &p, dst_param); -- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT); -+ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VSIR_DATA_I32); - shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); - } - else if (ins->opcode == VSIR_OP_TEXKILL) -@@ -1472,7 +1472,6 @@ static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1, - int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, - struct vkd3d_shader_message_context *message_context, struct vsir_program *program) - { -- struct vkd3d_shader_instruction_array *instructions; - struct vkd3d_shader_sm1_parser sm1 = {0}; - struct vkd3d_shader_instruction *ins; - unsigned int i; -@@ -1484,17 +1483,14 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c - return ret; - } - -- instructions = &program->instructions; - while (!shader_sm1_is_end(&sm1)) - { -- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) -+ if (!(ins = vsir_program_append(program))) - { -- ERR("Failed to allocate instructions.\n"); - vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); - vsir_program_cleanup(program); - return VKD3D_ERROR_OUT_OF_MEMORY; - } -- ins = &instructions->elements[instructions->count]; - shader_sm1_read_instruction(&sm1, ins); - - if (ins->opcode == VSIR_OP_INVALID) -@@ -1503,7 +1499,6 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c - vsir_program_cleanup(program); - return VKD3D_ERROR_INVALID_SHADER; - } -- ++instructions->count; - } - - for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) -@@ -2128,11 +2123,13 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc) - - static void d3dbc_write_program_instructions(struct d3dbc_compiler *d3dbc) - { -- struct vsir_program *program = d3dbc->program; -- unsigned int i; -+ struct vsir_program_iterator it = vsir_program_iterator(&d3dbc->program->instructions); -+ struct vkd3d_shader_instruction *ins; - -- for (i = 0; i < program->instructions.count; ++i) -- d3dbc_write_vsir_instruction(d3dbc, &program->instructions.elements[i]); -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -+ { -+ d3dbc_write_vsir_instruction(d3dbc, ins); -+ } - } - - int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index f8f0d2543bd..c3dd606f00f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -2482,16 +2482,16 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) - case 1: - return VKD3D_DATA_BOOL; - case 8: -- return VKD3D_DATA_UINT8; -+ return VSIR_DATA_U8; - case 16: -- return VKD3D_DATA_UINT16; -+ return VSIR_DATA_U16; - case 32: -- return VKD3D_DATA_UINT; -+ return VSIR_DATA_U32; - case 64: -- return VKD3D_DATA_UINT64; -+ return VSIR_DATA_U64; - default: - FIXME("Unhandled width %u.\n", type->u.width); -- return VKD3D_DATA_UINT; -+ return VSIR_DATA_U32; - } - } - else if (type->class == TYPE_CLASS_FLOAT) -@@ -2511,7 +2511,7 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) - } - - FIXME("Unhandled type %u.\n", type->class); -- return VKD3D_DATA_UINT; -+ return VSIR_DATA_U32; - } - - /* Based on the implementation in the OpenGL Mathematics library. */ -@@ -2572,8 +2572,8 @@ static void register_convert_to_minimum_precision(struct vkd3d_shader_register * - } - break; - -- case VKD3D_DATA_UINT16: -- reg->data_type = VKD3D_DATA_UINT; -+ case VSIR_DATA_U16: -+ reg->data_type = VSIR_DATA_U32; - reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16; - if (reg->type == VKD3DSPR_IMMCONST) - { -@@ -2668,7 +2668,7 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value * - - static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value) - { -- vsir_register_init(reg, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); -+ vsir_register_init(reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); - reg->u.immconst_u32[0] = value; - } - -@@ -2815,7 +2815,7 @@ static bool instruction_dst_param_init_uint_temp_vector(struct vkd3d_shader_inst - if (!(param = instruction_dst_params_alloc(ins, 1, sm6))) - return false; - -- vsir_dst_param_init(param, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_dst_param_init(param, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - param->write_mask = VKD3DSP_WRITEMASK_ALL; - param->reg.idx[0].offset = 0; - param->reg.dimension = VSIR_DIMENSION_VEC4; -@@ -3254,20 +3254,20 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - icb->data_type = VSIR_DATA_F32; - break; - -- case VKD3D_DATA_UINT16: -+ case VSIR_DATA_U16: - for (i = 0; i < count; ++i) - icb->data[i] = (int16_t)operands[i]; -- icb->data_type = VKD3D_DATA_UINT; -+ icb->data_type = VSIR_DATA_U32; - break; - - case VSIR_DATA_F32: -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_U32: - for (i = 0; i < count; ++i) - icb->data[i] = operands[i]; - break; - - case VSIR_DATA_F64: -- case VKD3D_DATA_UINT64: -+ case VSIR_DATA_U64: - data64 = (uint64_t *)icb->data; - for (i = 0; i < count; ++i) - data64[i] = operands[i]; -@@ -4104,6 +4104,7 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( - case VKD3D_SHADER_SV_SAMPLE_INDEX: - return VKD3DSPR_NULL; - case VKD3D_SHADER_SV_COVERAGE: -+ *dimension = is_input ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; - return is_input ? VKD3DSPR_COVERAGE : VKD3DSPR_SAMPLEMASK; - case VKD3D_SHADER_SV_DEPTH: - *dimension = VSIR_DIMENSION_SCALAR; -@@ -5223,7 +5224,7 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, struct - static void sm6_parser_emit_dx_coverage(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VKD3D_DATA_UINT, false); -+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VSIR_DATA_U32, false); - } - - static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6, -@@ -5300,8 +5301,7 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ - "Output stream index %u is invalid.", i); - } - -- /* VKD3D_DATA_UNUSED would be more reasonable, but TPF uses data type 0 here. */ -- register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, 0, i); -+ register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, VKD3D_DATA_UNUSED, i); - src_param_init(src_param); - - if (op == DX_EMIT_THEN_CUT_STREAM) -@@ -5482,11 +5482,11 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i - vkd3d_unreachable(); - } - -- sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, VKD3D_DATA_UINT, component_count); -+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, VSIR_DATA_U32, component_count); - vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- vsir_register_init(&src_param->reg, reg_type, VKD3D_DATA_UINT, 0); -+ vsir_register_init(&src_param->reg, reg_type, VSIR_DATA_U32, 0); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - if (component_count > 1) - component_idx = sm6_value_get_constant_uint(operands[0], sm6); -@@ -5721,13 +5721,13 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri - static void sm6_parser_emit_dx_output_control_point_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, true); -+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, true); - } - - static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VKD3D_DATA_UINT, true); -+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VSIR_DATA_U32, true); - } - - static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op) -@@ -5875,7 +5875,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ - if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) - return; - src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6); -- data.data_type = VKD3D_DATA_UINT; -+ data.data_type = VSIR_DATA_U32; - src_param_init_vector_from_reg(&src_params[operand_count - 1], &data); - - dst_param = instruction_dst_params_alloc(ins, 1, sm6); -@@ -6543,7 +6543,7 @@ static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intr - vkd3d_unreachable(); - } - -- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VKD3D_DATA_UINT, true); -+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VSIR_DATA_U32, true); - } - - struct sm6_dx_opcode_info -@@ -8441,9 +8441,9 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ - continue; - } - -- if (src_params[0].reg.data_type == VKD3D_DATA_UINT64) -+ if (src_params[0].reg.data_type == VSIR_DATA_U64) - { -- vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VKD3D_DATA_UINT64, 0); -+ vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VSIR_DATA_U64, 0); - src_params[count++].reg.u.immconst_u64[0] = switch_case->value; - } - else -@@ -8454,7 +8454,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, - "Truncating 64-bit switch case value %"PRIx64" to 32 bits.", switch_case->value); - } -- vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); -+ vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); - src_params[count++].reg.u.immconst_u32[0] = switch_case->value; - } - vsir_src_param_init_label(&src_params[count++], case_block->id); -@@ -9043,10 +9043,10 @@ static const enum vsir_data_type data_type_table[] = - { - [COMPONENT_TYPE_INVALID] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_I1] = VKD3D_DATA_UNUSED, -- [COMPONENT_TYPE_I16] = VKD3D_DATA_INT, -- [COMPONENT_TYPE_U16] = VKD3D_DATA_UINT, -- [COMPONENT_TYPE_I32] = VKD3D_DATA_INT, -- [COMPONENT_TYPE_U32] = VKD3D_DATA_UINT, -+ [COMPONENT_TYPE_I16] = VSIR_DATA_I32, -+ [COMPONENT_TYPE_U16] = VSIR_DATA_U32, -+ [COMPONENT_TYPE_I32] = VSIR_DATA_I32, -+ [COMPONENT_TYPE_U32] = VSIR_DATA_U32, - [COMPONENT_TYPE_I64] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_U64] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_F16] = VSIR_DATA_F32, -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index bf407f0fc9c..dc68e1792d9 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -345,10 +345,10 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk - { - switch (dst_data_type) - { -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - vkd3d_string_buffer_printf(dst, "floatBitsToInt(%s)", src); - return; -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_U32: - vkd3d_string_buffer_printf(dst, "floatBitsToUint(%s)", src); - return; - default: -@@ -356,14 +356,14 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk - } - } - -- if (src_data_type == VKD3D_DATA_UINT) -+ if (src_data_type == VSIR_DATA_U32) - { - switch (dst_data_type) - { - case VSIR_DATA_F32: - vkd3d_string_buffer_printf(dst, "uintBitsToFloat(%s)", src); - return; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - if (size == 1) - vkd3d_string_buffer_printf(dst, "int(%s)", src); - else -@@ -395,7 +395,7 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd - "Internal compiler error: Unhandled 'non-uniform' modifier."); - - if (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_THREADID) -- src_data_type = VKD3D_DATA_UINT; -+ src_data_type = VSIR_DATA_U32; - else - src_data_type = VSIR_DATA_F32; - -@@ -522,10 +522,10 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g - case VSIR_DATA_F32: - close = false; - break; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - vkd3d_string_buffer_printf(buffer, "intBitsToFloat("); - break; -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_U32: - vkd3d_string_buffer_printf(buffer, "uintBitsToFloat("); - break; - } -@@ -1164,12 +1164,12 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const - { - switch (data_type) - { -- case VKD3D_DATA_UINT: -- vkd3d_string_buffer_printf(image_data, "uvec4("); -- break; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - vkd3d_string_buffer_printf(image_data, "ivec4("); - break; -+ case VSIR_DATA_U32: -+ vkd3d_string_buffer_printf(image_data, "uvec4("); -+ break; - default: - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled data type %#x.", data_type); -@@ -1766,14 +1766,14 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge - - switch (uav->resource_data_type) - { -- case VKD3D_DATA_UINT: -- image_type_prefix = "u"; -- read_format = "r32ui"; -- break; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - image_type_prefix = "i"; - read_format = "r32i"; - break; -+ case VSIR_DATA_U32: -+ image_type_prefix = "u"; -+ read_format = "r32ui"; -+ break; - default: - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled data type %#x for UAV %u.", -@@ -1995,17 +1995,17 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator - - switch (srv->resource_data_type) - { -- case VKD3D_DATA_UINT: -- sampler_type_prefix = "u"; -- break; -- case VKD3D_DATA_INT: -- sampler_type_prefix = "i"; -- break; - case VSIR_DATA_F32: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: - sampler_type_prefix = ""; - break; -+ case VSIR_DATA_I32: -+ sampler_type_prefix = "i"; -+ break; -+ case VSIR_DATA_U32: -+ sampler_type_prefix = "u"; -+ break; - default: - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled data type %#x for combined resource/sampler " -@@ -2325,9 +2325,9 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) - - static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struct vkd3d_shader_code *out) - { -- const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions; - struct vkd3d_string_buffer *buffer = gen->buffer; -- unsigned int i; -+ struct vkd3d_shader_instruction *ins; -+ struct vsir_program_iterator it; - void *code; - - MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); -@@ -2342,9 +2342,11 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc - - ++gen->indent; - shader_glsl_shader_prologue(gen); -- for (i = 0; i < instructions->count; ++i) -+ -+ it = vsir_program_iterator(&gen->program->instructions); -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- vkd3d_glsl_handle_instruction(gen, &instructions->elements[i]); -+ vkd3d_glsl_handle_instruction(gen, ins); - } - - vkd3d_string_buffer_printf(buffer, "}\n"); -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 86198ce548f..7707412bf57 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -8245,11 +8245,11 @@ static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, c - case HLSL_TYPE_HALF: - return VSIR_DATA_F16; - case HLSL_TYPE_INT: -- return VKD3D_DATA_INT; -+ return VSIR_DATA_I32; - case HLSL_TYPE_UINT: - case HLSL_TYPE_BOOL: - case HLSL_TYPE_MIN16UINT: -- return VKD3D_DATA_UINT; -+ return VSIR_DATA_U32; - } - } - -@@ -10267,12 +10267,12 @@ static void sm4_generate_vsir_cast_from_bool(struct hlsl_ctx *ctx, struct vsir_p - - dst_param = &ins->dst[0]; - vsir_dst_from_hlsl_node(dst_param, ctx, instr); -- ins->dst[0].reg.data_type = VKD3D_DATA_UINT; -+ ins->dst[0].reg.data_type = VSIR_DATA_U32; - - vsir_src_from_hlsl_node(&ins->src[0], ctx, operand, dst_param->write_mask); - - value.u[0].u = bits; -- vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, VKD3D_DATA_UINT, 1, 0); -+ vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, VSIR_DATA_U32, 1, 0); - } - - static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, -@@ -10969,10 +10969,10 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr - - memset(&value, 0xff, sizeof(value)); - vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, -- VKD3D_DATA_UINT, type->e.numeric.dimx, dst_param->write_mask); -+ VSIR_DATA_U32, type->e.numeric.dimx, dst_param->write_mask); - memset(&value, 0x00, sizeof(value)); - vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, &value, -- VKD3D_DATA_UINT, type->e.numeric.dimx, dst_param->write_mask); -+ VSIR_DATA_U32, type->e.numeric.dimx, dst_param->write_mask); - } - else - { -@@ -11163,7 +11163,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, - { - if (sample_index->type == HLSL_IR_CONSTANT) - vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, -- &hlsl_ir_constant(sample_index)->value, VKD3D_DATA_INT, 1, 0); -+ &hlsl_ir_constant(sample_index)->value, VSIR_DATA_I32, 1, 0); - else if (version->major == 4 && version->minor == 0) - hlsl_error(ctx, &sample_index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expected literal sample index."); - else -@@ -11646,7 +11646,7 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, - - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_CASE, 0, 1))) - return; -- vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VKD3D_DATA_UINT, 1, VKD3DSP_WRITEMASK_ALL); -+ vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VSIR_DATA_U32, 1, VKD3DSP_WRITEMASK_ALL); - } - - sm4_generate_vsir_block(ctx, &cas->body, program); -@@ -12185,12 +12185,12 @@ static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_t - return VSIR_DATA_F32; - - case HLSL_TYPE_INT: -- return VKD3D_DATA_INT; -+ return VSIR_DATA_I32; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_MIN16UINT: - case HLSL_TYPE_UINT: -- return VKD3D_DATA_UINT; -+ return VSIR_DATA_U32; - } - - vkd3d_unreachable(); -@@ -12320,7 +12320,7 @@ static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, - return; - } - -- vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VKD3D_DATA_OPAQUE, 1); -+ vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VKD3D_DATA_UNUSED, 1); - ins->src[0].reg.dimension = VSIR_DIMENSION_NONE; - ins->src[0].reg.idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 18cda0269af..c322d9dde01 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -590,7 +590,7 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader - - static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value) - { -- vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); -+ vsir_src_param_init(src, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); - src->reg.u.immconst_u32[0] = value; - } - -@@ -696,7 +696,7 @@ static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsig - - static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx) - { -- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - src->reg.idx[0].offset = idx; - } - -@@ -773,7 +773,7 @@ static void dst_param_init_temp_float4(struct vkd3d_shader_dst_param *dst, unsig - - static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx) - { -- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - dst->reg.idx[0].offset = idx; - } - -@@ -913,7 +913,7 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - tmp_idx = program->temp_count++; - - ins->opcode = VSIR_OP_FTOU; -- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins->dst[0].reg.idx[0].offset = tmp_idx; - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - } -@@ -935,7 +935,7 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VSIR_OP_FTOU, 1, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins2->dst[0].reg.idx[0].offset = tmp_idx; - ins2->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins2->dst[0].write_mask = ins->dst[0].write_mask; -@@ -959,7 +959,7 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - if (tmp_idx == ~0u) - tmp_idx = program->temp_count++; - -- vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - rel->reg.idx[0].offset = tmp_idx; - rel->reg.dimension = VSIR_DIMENSION_VEC4; - } -@@ -998,7 +998,7 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, - if (!vsir_instruction_init_with_params(program, ins, &ifc->location, opcode, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->dst[0].reg.idx[0].offset = *tmp_idx; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; -@@ -1012,7 +1012,7 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, - return VKD3D_ERROR_OUT_OF_MEMORY; - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; - -- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[0].reg.idx[0].offset = *tmp_idx; - ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -@@ -1043,7 +1043,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_LTO, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->dst[0].reg.idx[0].offset = *tmp_idx; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; -@@ -1067,16 +1067,16 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_OR, 1, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->dst[0].reg.idx[0].offset = *tmp_idx; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; - -- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[0].reg.idx[0].offset = *tmp_idx; - ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -- vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].reg.idx[0].offset = *tmp_idx; - ins->src[1].swizzle = vkd3d_shader_create_swizzle(j, j, j, j); -@@ -1089,7 +1089,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - return VKD3D_ERROR_OUT_OF_MEMORY; - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; - -- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[0].reg.idx[0].offset = *tmp_idx; - ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -@@ -2301,7 +2301,7 @@ struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_ - if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1))) - return NULL; - -- vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, 0); -+ vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, 0); - rel_addr->swizzle = 0; - rel_addr->modifiers = 0; - -@@ -3862,7 +3862,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - for (j = 0; j < cf_info->u.switch_.cases_count; ++j) - { - unsigned int index = j * 2 + 3; -- vsir_src_param_init(&src_params[index], VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); -+ vsir_src_param_init(&src_params[index], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); - src_params[index].reg.u.immconst_u32[0] = cf_info->u.switch_.cases[j].value; - vsir_src_param_init_label(&src_params[index + 1], cf_info->u.switch_.cases[j].block_id); - } -@@ -6839,7 +6839,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].uint_opcode, 1, 2); - src_param_init_temp_uint(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); - src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], -- VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_UINT); -+ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VSIR_DATA_U32); - break; - - case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4: -@@ -9548,12 +9548,18 @@ static void vsir_validate_register(struct validation_context *ctx, - register_validation_data[] = - { - [VKD3DSPR_DEPTHOUT] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ [VKD3DSPR_PRIMID] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ [VKD3DSPR_OUTPOINTID] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ [VKD3DSPR_THREADID] = {true, 0, VSIR_DIMENSION_VEC4}, - [VKD3DSPR_THREADGROUPID] = {true, 0, VSIR_DIMENSION_VEC4}, - [VKD3DSPR_LOCALTHREADID] = {true, 0, VSIR_DIMENSION_VEC4}, - [VKD3DSPR_LOCALTHREADINDEX] = {true, 0, VSIR_DIMENSION_VEC4}, - [VKD3DSPR_COVERAGE] = {true, 0, VSIR_DIMENSION_VEC4}, -+ [VKD3DSPR_SAMPLEMASK] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ [VKD3DSPR_GSINSTID] = {true, 0, VSIR_DIMENSION_SCALAR}, - [VKD3DSPR_DEPTHOUTGE] = {true, 0, VSIR_DIMENSION_SCALAR}, - [VKD3DSPR_DEPTHOUTLE] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ [VKD3DSPR_OUTSTENCILREF] = {true, 0, VSIR_DIMENSION_SCALAR}, - }; - - const struct register_validation_data *validation_data; -@@ -9642,10 +9648,6 @@ static void vsir_validate_register(struct validation_context *ctx, - vsir_validate_constbuffer_register(ctx, reg); - break; - -- case VKD3DSPR_PRIMID: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- - case VKD3DSPR_NULL: - vsir_validate_register_without_indices(ctx, reg); - break; -@@ -9662,10 +9664,6 @@ static void vsir_validate_register(struct validation_context *ctx, - vsir_validate_uav_register(ctx, reg); - break; - -- case VKD3DSPR_OUTPOINTID: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- - case VKD3DSPR_FORKINSTID: - vsir_validate_register_without_indices(ctx, reg); - break; -@@ -9690,22 +9688,6 @@ static void vsir_validate_register(struct validation_context *ctx, - vsir_validate_register_without_indices(ctx, reg); - break; - -- case VKD3DSPR_THREADID: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- -- case VKD3DSPR_SAMPLEMASK: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- -- case VKD3DSPR_GSINSTID: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- -- case VKD3DSPR_OUTSTENCILREF: -- vsir_validate_register_without_indices(ctx, reg); -- break; -- - case VKD3DSPR_SSA: - vsir_validate_ssa_register(ctx, reg); - break; -@@ -9900,11 +9882,11 @@ static void vsir_validate_io_src_param(struct validation_context *ctx, - #define F32_BIT (1u << VSIR_DATA_F32) - #define F16_BIT (1u << VSIR_DATA_F16) - --#define I32_BIT (1u << VKD3D_DATA_INT) -+#define I32_BIT (1u << VSIR_DATA_I32) - --#define U64_BIT (1u << VKD3D_DATA_UINT64) --#define U32_BIT (1u << VKD3D_DATA_UINT) --#define U16_BIT (1u << VKD3D_DATA_UINT16) -+#define U64_BIT (1u << VSIR_DATA_U64) -+#define U32_BIT (1u << VSIR_DATA_U32) -+#define U16_BIT (1u << VSIR_DATA_U16) - - static void vsir_validate_src_param(struct validation_context *ctx, - const struct vkd3d_shader_src_param *src) -@@ -10658,9 +10640,9 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex - { - static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_INT] = true, -- [VKD3D_DATA_UINT] = true, -- [VKD3D_DATA_UINT64] = true, -+ [VSIR_DATA_I32] = true, -+ [VSIR_DATA_U32] = true, -+ [VSIR_DATA_U64] = true, - }; - - vsir_validate_elementwise_operation(ctx, instruction, types); -@@ -10671,10 +10653,10 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context - { - static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_INT] = true, -- [VKD3D_DATA_UINT] = true, -- [VKD3D_DATA_UINT64] = true, - [VKD3D_DATA_BOOL] = true, -+ [VSIR_DATA_I32] = true, -+ [VSIR_DATA_U32] = true, -+ [VSIR_DATA_U64] = true, - }; - - vsir_validate_elementwise_operation(ctx, instruction, types); -@@ -10691,7 +10673,7 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, - - dst_data_type = instruction->dst[0].reg.data_type; - -- if (dst_data_type != VKD3D_DATA_UINT && dst_data_type != VKD3D_DATA_BOOL) -+ if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VKD3D_DATA_BOOL) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for result of comparison operation \"%s\" (%#x).", - dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -@@ -10748,9 +10730,9 @@ static void vsir_validate_integer_comparison_operation(struct validation_context - { - static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_INT] = true, -- [VKD3D_DATA_UINT] = true, -- [VKD3D_DATA_UINT64] = true, -+ [VSIR_DATA_I32] = true, -+ [VSIR_DATA_U32] = true, -+ [VSIR_DATA_U64] = true, - }; - - vsir_validate_comparison_operation(ctx, instruction, types); -@@ -11305,8 +11287,8 @@ static void vsir_validate_ftoi(struct validation_context *ctx, const struct vkd3 - }; - static const bool dst_types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_INT] = true, -- [VKD3D_DATA_UINT] = true, -+ [VSIR_DATA_I32] = true, -+ [VSIR_DATA_U32] = true, - }; - - vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); -@@ -11322,7 +11304,7 @@ static void vsir_validate_ftou(struct validation_context *ctx, const struct vkd3 - }; - static const bool dst_types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_UINT] = true, -+ [VSIR_DATA_U32] = true, - }; - - vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); -@@ -11344,10 +11326,10 @@ static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3 - { - static const bool src_types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_INT] = true, -- [VKD3D_DATA_UINT] = true, -- [VKD3D_DATA_UINT64] = true, - [VKD3D_DATA_BOOL] = true, -+ [VSIR_DATA_I32] = true, -+ [VSIR_DATA_U32] = true, -+ [VSIR_DATA_U64] = true, - }; - static const bool dst_types[VSIR_DATA_TYPE_COUNT] = - { -@@ -11363,10 +11345,10 @@ static void vsir_validate_itoi(struct validation_context *ctx, const struct vkd3 - { - static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_INT] = true, -- [VKD3D_DATA_UINT] = true, -- [VKD3D_DATA_UINT64] = true, - [VKD3D_DATA_BOOL] = true, -+ [VSIR_DATA_I32] = true, -+ [VSIR_DATA_U32] = true, -+ [VSIR_DATA_U64] = true, - }; - - vsir_validate_cast_operation(ctx, instruction, types, types); -@@ -11626,10 +11608,18 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation}, - [VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation}, - [VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_NEO] = {1, 2, vsir_validate_float_comparison_operation}, -+ [VSIR_OP_NEU] = {1, 2, vsir_validate_float_comparison_operation}, - [VSIR_OP_NOP] = {0, 0, vsir_validate_nop}, -+ [VSIR_OP_NOT] = {1, 1, vsir_validate_logic_elementwise_operation}, -+ [VSIR_OP_OR] = {1, 2, vsir_validate_logic_elementwise_operation}, -+ [VSIR_OP_ORD] = {1, 2, vsir_validate_float_comparison_operation}, - [VSIR_OP_PHI] = {1, ~0u, vsir_validate_phi}, -+ [VSIR_OP_RCP] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_REP] = {0, 1, vsir_validate_rep}, - [VSIR_OP_RET] = {0, 0, vsir_validate_ret}, -+ [VSIR_OP_ROUND_NE] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_ROUND_NI] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch}, - [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, - }; -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index 83cdf9feea0..ccfce0f4591 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -142,10 +142,10 @@ static void msl_print_resource_datatype(struct msl_generator *gen, - case VKD3D_DATA_SNORM: - vkd3d_string_buffer_printf(buffer, "float"); - break; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - vkd3d_string_buffer_printf(buffer, "int"); - break; -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_U32: - vkd3d_string_buffer_printf(buffer, "uint"); - break; - default: -@@ -165,10 +165,10 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, - case VSIR_DATA_F32: - vkd3d_string_buffer_printf(buffer, "f"); - break; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - vkd3d_string_buffer_printf(buffer, "i"); - break; -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_U32: - vkd3d_string_buffer_printf(buffer, "u"); - break; - default: -@@ -537,7 +537,7 @@ static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_genera - break; - - case MSL_DATA_UINT: -- write_cast = dst_data_type != VKD3D_DATA_UINT; -+ write_cast = dst_data_type != VSIR_DATA_U32; - break; - - case MSL_DATA_UNION: -@@ -1012,19 +1012,19 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - vkd3d_string_buffer_printf(read, "as_type("); - msl_print_srv_name(read, gen, srv_binding, resource_type_info, data_type, false); - vkd3d_string_buffer_printf(read, ".read("); -- msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); -+ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VSIR_DATA_U32); - if (resource_type_info->array) - { - vkd3d_string_buffer_printf(read, ", "); -- msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT); -+ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VSIR_DATA_U32); - } - if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) - { - vkd3d_string_buffer_printf(read, ", "); - if (ins->opcode != VSIR_OP_LD2DMS) -- msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); -+ msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VSIR_DATA_U32); - else -- msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VKD3D_DATA_UINT); -+ msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32); - } - vkd3d_string_buffer_printf(read, "))"); - msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask); -@@ -1168,7 +1168,7 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - msl_dst_init(&dst, gen, ins, &ins->dst[0]); - sample = vkd3d_string_buffer_get(&gen->string_buffers); - -- if (ins->dst[0].reg.data_type == VKD3D_DATA_UINT) -+ if (ins->dst[0].reg.data_type == VSIR_DATA_U32) - vkd3d_string_buffer_printf(sample, "as_type("); - msl_print_srv_name(sample, gen, srv_binding, resource_type_info, data_type, compare); - if (gather && compare) -@@ -1238,7 +1238,7 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - vkd3d_string_buffer_printf(sample, ", component::%c", "xyzw"[component_idx]); - } - vkd3d_string_buffer_printf(sample, ")"); -- if (ins->dst[0].reg.data_type == VKD3D_DATA_UINT) -+ if (ins->dst[0].reg.data_type == VSIR_DATA_U32) - vkd3d_string_buffer_printf(sample, ")"); - if (!compare || gather) - msl_print_swizzle(sample, resource->swizzle, ins->dst[0].write_mask); -@@ -1309,10 +1309,10 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - { - switch (data_type) - { -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_U32: - vkd3d_string_buffer_printf(image_data, "uint4("); - break; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - vkd3d_string_buffer_printf(image_data, "int4("); - break; - default: -@@ -1333,7 +1333,7 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - msl_print_indent(gen->buffer, gen->indent); - msl_print_uav_name(gen->buffer, gen, uav_binding, resource_type_info, data_type); - vkd3d_string_buffer_printf(gen->buffer, ".write(%s, ", image_data->buffer); -- msl_print_src_with_type(gen->buffer, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); -+ msl_print_src_with_type(gen->buffer, gen, &ins->src[0], coord_mask, VSIR_DATA_U32); - vkd3d_string_buffer_printf(gen->buffer, ");\n"); - - vkd3d_string_buffer_release(&gen->string_buffers, image_data); -@@ -1894,19 +1894,19 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) - break; - - case VKD3D_SHADER_SV_VERTEX_ID: -- msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); -+ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); - msl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, " = uint4(vertex_id, 0u, 0u, 0u)"); - break; - - case VKD3D_SHADER_SV_IS_FRONT_FACE: -- msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); -+ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); - msl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, " = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)"); - break; - - case VKD3D_SHADER_SV_SAMPLE_INDEX: -- msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); -+ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); - msl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, " = uint4(input.sample_index, 0u, 0u, 0u)"); - break; -@@ -2028,8 +2028,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen) - - static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out) - { -- const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions; -- unsigned int i; -+ struct vkd3d_shader_instruction *ins; -+ struct vsir_program_iterator it; - - MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); - -@@ -2095,9 +2095,10 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader - vkd3d_string_buffer_printf(gen->buffer, "vkd3d_vec4 r[%u];\n\n", gen->program->temp_count); - } - -- for (i = 0; i < instructions->count; ++i) -+ it = vsir_program_iterator(&gen->program->instructions); -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- msl_handle_instruction(gen, &instructions->elements[i]); -+ msl_handle_instruction(gen, ins); - } - - --gen->indent; -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index eb9a90e8b44..d99c7ee27ff 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -3020,7 +3020,7 @@ struct ssa_register_info - struct spirv_compiler - { - struct vkd3d_spirv_builder spirv_builder; -- const struct vsir_program *program; -+ struct vsir_program *program; - - struct vkd3d_shader_message_context *message_context; - struct vkd3d_shader_location location; -@@ -3150,7 +3150,7 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) - vkd3d_free(compiler); - } - --static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *program, -+static struct spirv_compiler *spirv_compiler_create(struct vsir_program *program, - const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context, uint64_t config_flags) - { -@@ -4060,7 +4060,7 @@ static const struct - parameter_data_type_map[] = - { - [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VSIR_DATA_F32, 1}, -- [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VKD3D_DATA_UINT, 1}, -+ [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VSIR_DATA_U32, 1}, - [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VSIR_DATA_F32, 4}, - }; - -@@ -4491,7 +4491,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); - op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; - return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, -- data_type == VKD3D_DATA_UINT64 -+ data_type == VSIR_DATA_U64 - ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) - : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); - } -@@ -4660,8 +4660,8 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } -- val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, -- VKD3D_DATA_UINT, 1, val_id); -+ val_id = spirv_compiler_emit_int_to_bool(compiler, -+ VKD3D_SHADER_CONDITIONAL_OP_NZ, VSIR_DATA_U32, 1, val_id); - } - else - { -@@ -4709,14 +4709,14 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil - switch (icb->data_type) - { - case VSIR_DATA_F32: -- case VKD3D_DATA_INT: -- case VKD3D_DATA_UINT: -+ case VSIR_DATA_I32: -+ case VSIR_DATA_U32: - for (i = 0; i < element_count; ++i) - elements[i] = spirv_compiler_get_constant(compiler, component_type, component_count, - &icb->data[component_count * i]); - break; - case VSIR_DATA_F64: -- case VKD3D_DATA_UINT64: -+ case VSIR_DATA_U64: - { - uint64_t *data = (uint64_t *)icb->data; - for (i = 0; i < element_count; ++i) -@@ -4808,8 +4808,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } -- val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, -- VKD3D_DATA_UINT, component_count, val_id); -+ val_id = spirv_compiler_emit_int_to_bool(compiler, -+ VKD3D_SHADER_CONDITIONAL_OP_NZ, VSIR_DATA_U32, component_count, val_id); - } - else - { -@@ -5718,15 +5718,15 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - { - component_type = builtin->component_type; - input_component_count = builtin->component_count; -- component_idx = 0; - } - else - { - component_type = signature_element->component_type; - input_component_count = vsir_write_mask_component_count(signature_element->mask); -- component_idx = vsir_write_mask_get_component_idx(signature_element->mask); - } - -+ component_idx = vsir_write_mask_get_component_idx(write_mask); -+ - if (needs_private_io_variable(builtin)) - { - use_private_var = true; -@@ -5734,7 +5734,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - } - else - { -- component_idx = vsir_write_mask_get_component_idx(write_mask); - reg_write_mask = write_mask >> component_idx; - } - -@@ -5820,7 +5819,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - vkd3d_write_mask_from_component_count(input_component_count), - VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx); - -- spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask, val_id); -+ spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask >> component_idx, val_id); - } - } - -@@ -7601,11 +7600,11 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, - /* ITOD is not supported. Frontends which emit bool casts must use ITOF for double. */ - val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); - } -- else if (dst->reg.data_type == VKD3D_DATA_UINT16 || dst->reg.data_type == VKD3D_DATA_UINT) -+ else if (dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32) - { - val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); - } -- else if (dst->reg.data_type == VKD3D_DATA_UINT64) -+ else if (dst->reg.data_type == VSIR_DATA_U64) - { - val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); - } -@@ -7631,7 +7630,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil - SpvOp op = SpvOpMax; - bool check_zero; - -- if (src->reg.data_type == VKD3D_DATA_UINT64 && instruction->opcode == VSIR_OP_COUNTBITS) -+ if (src->reg.data_type == VSIR_DATA_U64 && instruction->opcode == VSIR_OP_COUNTBITS) - { - /* At least some drivers support this anyway, but if validation is enabled it will fail. */ - FIXME("Unsupported 64-bit source for bit count.\n"); -@@ -7701,7 +7700,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]); - -- if (dst[0].reg.data_type == VKD3D_DATA_UINT64) -+ if (dst[0].reg.data_type == VSIR_DATA_U64) - uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count); - else - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); -@@ -7816,7 +7815,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp - unsigned int i, component_count; - enum GLSLstd450 glsl_inst; - -- if (src[0].reg.data_type == VKD3D_DATA_UINT64 && (instruction->opcode == VSIR_OP_FIRSTBIT_HI -+ if (src[0].reg.data_type == VSIR_DATA_U64 && (instruction->opcode == VSIR_OP_FIRSTBIT_HI - || instruction->opcode == VSIR_OP_FIRSTBIT_LO || instruction->opcode == VSIR_OP_FIRSTBIT_SHI)) - { - /* At least some drivers support this anyway, but if validation is enabled it will fail. */ -@@ -8226,7 +8225,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - - component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -- size = (src[src_count - 1].reg.data_type == VKD3D_DATA_UINT64) ? 0x40 : 0x20; -+ size = (src[src_count - 1].reg.data_type == VSIR_DATA_U64) ? 0x40 : 0x20; - mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); - size_id = spirv_compiler_get_constant_uint(compiler, size); - -@@ -9424,7 +9423,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * - &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); - - data = &src[instruction->src_count - 1]; -- VKD3D_ASSERT(data->reg.data_type == VKD3D_DATA_UINT); -+ VKD3D_ASSERT(data->reg.data_type == VSIR_DATA_U32); - val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); - - component_count = vsir_write_mask_component_count(dst->write_mask); -@@ -9452,7 +9451,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * - type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); - - data = &src[instruction->src_count - 1]; -- VKD3D_ASSERT(data->reg.data_type == VKD3D_DATA_UINT); -+ VKD3D_ASSERT(data->reg.data_type == VSIR_DATA_U32); - val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); - - component_count = vsir_write_mask_component_count(dst->write_mask); -@@ -9495,7 +9494,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, - type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); - - data = src[instruction->src_count - 1]; -- data.reg.data_type = VKD3D_DATA_UINT; -+ data.reg.data_type = VSIR_DATA_U32; - val_id = spirv_compiler_emit_load_src(compiler, &data, dst->write_mask); - - component_count = vsir_write_mask_component_count(dst->write_mask); -@@ -9997,7 +9996,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co - if (src->reg.type == VKD3DSPR_RASTERIZER) - { - val_id = spirv_compiler_emit_shader_parameter(compiler, -- VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VKD3D_DATA_UINT, 1); -+ VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VSIR_DATA_U32, 1); - } - else - { -@@ -10317,7 +10316,7 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler - - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); -- direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VKD3D_DATA_UINT, 1); -+ direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VSIR_DATA_U32, 1); - val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); - direction_id = map_quad_read_across_direction(instruction->opcode); - direction_id = vkd3d_spirv_get_op_constant(builder, direction_type_id, direction_id); -@@ -11020,11 +11019,12 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; - const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- const struct vsir_program *program = compiler->program; -- struct vkd3d_shader_instruction_array instructions; -+ struct vsir_program *program = compiler->program; - enum vkd3d_shader_spirv_environment environment; -+ struct vkd3d_shader_instruction *ins; - enum vkd3d_result result = VKD3D_OK; - unsigned int i, max_element_count; -+ struct vsir_program_iterator it; - - max_element_count = max(program->output_signature.element_count, program->patch_constant_signature.element_count); - if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info)))) -@@ -11072,8 +11072,6 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - if (program->block_count && !spirv_compiler_init_blocks(compiler, program->block_count)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- instructions = program->instructions; -- - compiler->use_vocp = program->use_vocp; - compiler->block_names = program->block_names; - compiler->block_name_count = program->block_name_count; -@@ -11088,9 +11086,10 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) - spirv_compiler_emit_shader_signature_outputs(compiler); - -- for (i = 0; i < instructions.count && result >= 0; ++i) -+ it = vsir_program_iterator(&program->instructions); -+ for (ins = vsir_program_iterator_head(&it); ins && result >= 0; ins = vsir_program_iterator_next(&it)) - { -- result = spirv_compiler_handle_instruction(compiler, &instructions.elements[i]); -+ result = spirv_compiler_handle_instruction(compiler, ins); - } - - if (result < 0) -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 26c41a902d2..8acd7bc0db5 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -753,8 +753,8 @@ static const enum vsir_data_type data_type_table[] = - /* 0 */ VSIR_DATA_F32, - /* VKD3D_SM4_DATA_UNORM */ VKD3D_DATA_UNORM, - /* VKD3D_SM4_DATA_SNORM */ VKD3D_DATA_SNORM, -- /* VKD3D_SM4_DATA_INT */ VKD3D_DATA_INT, -- /* VKD3D_SM4_DATA_UINT */ VKD3D_DATA_UINT, -+ /* VKD3D_SM4_DATA_INT */ VSIR_DATA_I32, -+ /* VKD3D_SM4_DATA_UINT */ VSIR_DATA_U32, - /* VKD3D_SM4_DATA_FLOAT */ VSIR_DATA_F32, - /* VKD3D_SM4_DATA_MIXED */ VKD3D_DATA_MIXED, - /* VKD3D_SM4_DATA_DOUBLE */ VSIR_DATA_F64, -@@ -795,7 +795,7 @@ static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv, - static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, uint32_t opcode, - uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { -- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]); -+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_U32, &ins->src[0]); - ins->flags = (opcode_token & VKD3D_SM4_CONDITIONAL_NZ) ? - VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z; - } -@@ -803,7 +803,7 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, - static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode, - uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { -- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]); -+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_U32, &ins->src[0]); - if (ins->src[0].reg.type != VKD3DSPR_IMMCONST) - { - FIXME("Switch case value is not a 32-bit constant.\n"); -@@ -1432,8 +1432,8 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) - /* - * d -> VSIR_DATA_F64 - * f -> VSIR_DATA_F32 -- * i -> VKD3D_DATA_INT -- * u -> VKD3D_DATA_UINT -+ * i -> VSIR_DATA_I32 -+ * u -> VSIR_DATA_U32 - * O -> VKD3D_DATA_OPAQUE - * R -> VKD3D_DATA_RESOURCE - * S -> VKD3D_DATA_SAMPLER -@@ -1578,8 +1578,8 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) - {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VSIR_OP_HS_CONTROL_POINT_PHASE, "", ""}, - {VKD3D_SM5_OP_HS_FORK_PHASE, VSIR_OP_HS_FORK_PHASE, "", ""}, - {VKD3D_SM5_OP_HS_JOIN_PHASE, VSIR_OP_HS_JOIN_PHASE, "", ""}, -- {VKD3D_SM5_OP_EMIT_STREAM, VSIR_OP_EMIT_STREAM, "", "f"}, -- {VKD3D_SM5_OP_CUT_STREAM, VSIR_OP_CUT_STREAM, "", "f"}, -+ {VKD3D_SM5_OP_EMIT_STREAM, VSIR_OP_EMIT_STREAM, "", "*"}, -+ {VKD3D_SM5_OP_CUT_STREAM, VSIR_OP_CUT_STREAM, "", "*"}, - {VKD3D_SM5_OP_FCALL, VSIR_OP_FCALL, "", "O", - shader_sm5_read_fcall}, - {VKD3D_SM5_OP_BUFINFO, VSIR_OP_BUFINFO, "i", "*"}, -@@ -1602,7 +1602,7 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) - {VKD3D_SM5_OP_BFI, VSIR_OP_BFI, "u", "iiuu"}, - {VKD3D_SM5_OP_BFREV, VSIR_OP_BFREV, "u", "u"}, - {VKD3D_SM5_OP_SWAPC, VSIR_OP_SWAPC, "ff", "uff"}, -- {VKD3D_SM5_OP_DCL_STREAM, VSIR_OP_DCL_STREAM, "", "O"}, -+ {VKD3D_SM5_OP_DCL_STREAM, VSIR_OP_DCL_STREAM, "", "*"}, - {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VSIR_OP_DCL_FUNCTION_BODY, "", "", - shader_sm5_read_dcl_function_body}, - {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VSIR_OP_DCL_FUNCTION_TABLE, "", "", -@@ -1994,9 +1994,9 @@ static enum vsir_data_type map_data_type(char t) - case 'f': - return VSIR_DATA_F32; - case 'i': -- return VKD3D_DATA_INT; -+ return VSIR_DATA_I32; - case 'u': -- return VKD3D_DATA_UINT; -+ return VSIR_DATA_U32; - case 'O': - return VKD3D_DATA_OPAQUE; - case '*': -@@ -2024,7 +2024,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const - reg_idx->offset = *(*ptr)++; - else - reg_idx->offset = 0; -- shader_sm4_read_src_param(priv, ptr, end, VKD3D_DATA_INT, rel_addr); -+ shader_sm4_read_src_param(priv, ptr, end, VSIR_DATA_I32, rel_addr); - } - else - { -@@ -2896,7 +2896,6 @@ static void shader_sm4_validate_default_phase_index_ranges(struct vkd3d_shader_s - int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, - struct vkd3d_shader_message_context *message_context, struct vsir_program *program) - { -- struct vkd3d_shader_instruction_array *instructions; - struct vkd3d_shader_sm4_parser sm4 = {0}; - struct dxbc_shader_desc dxbc_desc = {0}; - struct vkd3d_shader_instruction *ins; -@@ -2956,17 +2955,14 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con - return VKD3D_ERROR_INVALID_SHADER; - } - -- instructions = &program->instructions; - while (sm4.ptr != sm4.end) - { -- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) -+ if (!(ins = vsir_program_append(program))) - { -- ERR("Failed to allocate instructions.\n"); - vkd3d_shader_parser_error(&sm4.p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); - vsir_program_cleanup(program); - return VKD3D_ERROR_OUT_OF_MEMORY; - } -- ins = &instructions->elements[instructions->count]; - shader_sm4_read_instruction(&sm4, ins); - - if (ins->opcode == VSIR_OP_INVALID) -@@ -2975,7 +2971,6 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con - vsir_program_cleanup(program); - return VKD3D_ERROR_OUT_OF_MEMORY; - } -- ++instructions->count; - } - if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL - && !sm4.has_control_point_phase && !sm4.p.failed) -@@ -4339,20 +4334,23 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ - } - } - --static void tpf_write_program(struct tpf_compiler *tpf, const struct vsir_program *program) -+static void tpf_write_program(struct tpf_compiler *tpf, struct vsir_program *program) - { -- unsigned int i; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vkd3d_shader_instruction *ins; - - if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE) - tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size); - -- for (i = 0; i < program->instructions.count; ++i) -- tpf_handle_instruction(tpf, &program->instructions.elements[i]); -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -+ { -+ tpf_handle_instruction(tpf, ins); -+ } - } - - static void tpf_write_shdr(struct tpf_compiler *tpf) - { -- const struct vsir_program *program = tpf->program; -+ struct vsir_program *program = tpf->program; - const struct vkd3d_shader_version *version; - struct vkd3d_bytecode_buffer buffer = {0}; - size_t token_count_position; -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index c60feec4aa2..9c615c116e9 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -1120,7 +1120,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc - struct vkd3d_shader_descriptor_info1 *d; - - if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, -- &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) -+ &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) - return; - d->buffer_size = cb->size; - } -@@ -1305,12 +1305,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - case VSIR_OP_DCL_RESOURCE_RAW: - case VSIR_OP_DCL_UAV_RAW: - vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, -- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, 0, true, instruction->flags); -+ VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32, 0, 0, true, instruction->flags); - break; - case VSIR_OP_DCL_RESOURCE_STRUCTURED: - case VSIR_OP_DCL_UAV_STRUCTURED: - vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, -- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, -+ VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32, 0, - instruction->declaration.structured_resource.byte_stride, false, instruction->flags); - break; - case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: -@@ -1530,10 +1530,6 @@ static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_t - return VKD3D_SHADER_RESOURCE_DATA_UNORM; - case VKD3D_DATA_SNORM: - return VKD3D_SHADER_RESOURCE_DATA_SNORM; -- case VKD3D_DATA_INT: -- return VKD3D_SHADER_RESOURCE_DATA_INT; -- case VKD3D_DATA_UINT: -- return VKD3D_SHADER_RESOURCE_DATA_UINT; - case VKD3D_DATA_MIXED: - return VKD3D_SHADER_RESOURCE_DATA_MIXED; - case VKD3D_DATA_CONTINUED: -@@ -1544,6 +1540,10 @@ static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_t - return VKD3D_SHADER_RESOURCE_DATA_FLOAT; - case VSIR_DATA_F64: - return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; -+ case VSIR_DATA_I32: -+ return VKD3D_SHADER_RESOURCE_DATA_INT; -+ case VSIR_DATA_U32: -+ return VKD3D_SHADER_RESOURCE_DATA_UINT; - default: - ERR("Invalid resource data type %#x.\n", data_type); - return VKD3D_SHADER_RESOURCE_DATA_FLOAT; -@@ -1647,8 +1647,8 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - - if (size) - { -- if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, -- &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) -+ if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, -+ ®, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) - d->buffer_size = size * 16; - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index f7bbadac3df..42f3c42033f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -710,30 +710,32 @@ enum vkd3d_shader_register_precision - - enum vsir_data_type - { -- VKD3D_DATA_INT, -- VKD3D_DATA_UINT, - VKD3D_DATA_UNORM, - VKD3D_DATA_SNORM, - VKD3D_DATA_OPAQUE, - VKD3D_DATA_MIXED, - VKD3D_DATA_CONTINUED, - VKD3D_DATA_UNUSED, -- VKD3D_DATA_UINT8, -- VKD3D_DATA_UINT64, - VKD3D_DATA_BOOL, -- VKD3D_DATA_UINT16, - - VSIR_DATA_F16, - VSIR_DATA_F32, - VSIR_DATA_F64, - -+ VSIR_DATA_I32, -+ -+ VSIR_DATA_U8, -+ VSIR_DATA_U16, -+ VSIR_DATA_U32, -+ VSIR_DATA_U64, -+ - VSIR_DATA_TYPE_COUNT, - }; - - static inline bool data_type_is_integer(enum vsir_data_type data_type) - { -- return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT16 -- || data_type == VKD3D_DATA_UINT || data_type == VKD3D_DATA_UINT64; -+ return data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 -+ || data_type == VSIR_DATA_U32 || data_type == VSIR_DATA_U64; - } - - static inline bool data_type_is_bool(enum vsir_data_type data_type) -@@ -748,7 +750,7 @@ static inline bool data_type_is_floating_point(enum vsir_data_type data_type) - - static inline bool data_type_is_64_bit(enum vsir_data_type data_type) - { -- return data_type == VSIR_DATA_F64 || data_type == VKD3D_DATA_UINT64; -+ return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_U64; - } - - enum vsir_dimension -@@ -1581,6 +1583,16 @@ bool vsir_instruction_init_with_params(struct vsir_program *program, - struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, - enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count); - -+static inline struct vkd3d_shader_instruction *vsir_program_append(struct vsir_program *program) -+{ -+ struct vkd3d_shader_instruction_array *array = &program->instructions; -+ -+ if (!shader_instruction_array_insert_at(array, array->count, 1)) -+ return NULL; -+ -+ return &array->elements[array->count - 1]; -+} -+ - static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params( - struct vsir_program *program, unsigned int count) - { -@@ -1608,7 +1620,7 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr - void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, - enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); - --void vsir_program_trace(const struct vsir_program *program); -+void vsir_program_trace(struct vsir_program *program); - - const char *shader_get_type_prefix(enum vkd3d_shader_type type); - -@@ -1633,7 +1645,7 @@ enum vsir_asm_flags - VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8, - }; - --enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, -+enum vkd3d_result d3d_asm_compile(struct vsir_program *program, - const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, enum vsir_asm_flags flags); - void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer); -@@ -1799,12 +1811,12 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty - return VKD3D_SHADER_COMPONENT_FLOAT; - case VSIR_DATA_F64: - return VKD3D_SHADER_COMPONENT_DOUBLE; -- case VKD3D_DATA_UINT16: /* Minimum precision. TODO: native 16-bit */ -- case VKD3D_DATA_UINT: -- return VKD3D_SHADER_COMPONENT_UINT; -- case VKD3D_DATA_INT: -+ case VSIR_DATA_I32: - return VKD3D_SHADER_COMPONENT_INT; -- case VKD3D_DATA_UINT64: -+ case VSIR_DATA_U16: /* Minimum precision. TODO: native 16-bit */ -+ case VSIR_DATA_U32: -+ return VKD3D_SHADER_COMPONENT_UINT; -+ case VSIR_DATA_U64: - return VKD3D_SHADER_COMPONENT_UINT64; - case VKD3D_DATA_BOOL: - return VKD3D_SHADER_COMPONENT_BOOL; -@@ -1823,9 +1835,9 @@ static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_ - case VKD3D_SHADER_COMPONENT_FLOAT: - return VSIR_DATA_F32; - case VKD3D_SHADER_COMPONENT_UINT: -- return VKD3D_DATA_UINT; -+ return VSIR_DATA_U32; - case VKD3D_SHADER_COMPONENT_INT: -- return VKD3D_DATA_INT; -+ return VSIR_DATA_I32; - case VKD3D_SHADER_COMPONENT_DOUBLE: - return VSIR_DATA_F64; - default: --- -2.50.1 - diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch deleted file mode 100644 index 1fe89e73..00000000 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch +++ /dev/null @@ -1,2302 +0,0 @@ -From d6c78db132503243a003082c10a9169e322b7641 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 24 Jul 2025 06:52:52 +1000 -Subject: [PATCH] Updated vkd3d to a4c25b81c59ae783a94c1b25714eb080231b86bd. - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 16 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 5 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 50 ++- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 16 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 16 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 9 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 287 ++++++++++-------- - libs/vkd3d/libs/vkd3d-shader/ir.c | 88 ++++-- - libs/vkd3d/libs/vkd3d-shader/msl.c | 10 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 60 ++-- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 41 +-- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 59 ++-- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 58 ++-- - 13 files changed, 384 insertions(+), 331 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 5e3e7daab83..c213007f2b4 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -388,13 +388,7 @@ static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum - { - static const char *const data_type_names[] = - { -- [VKD3D_DATA_UNORM ] = "unorm", -- [VKD3D_DATA_SNORM ] = "snorm", -- [VKD3D_DATA_OPAQUE ] = "opaque", -- [VKD3D_DATA_MIXED ] = "mixed", -- [VKD3D_DATA_CONTINUED] = "", -- [VKD3D_DATA_UNUSED ] = "", -- [VKD3D_DATA_BOOL ] = "bool", -+ [VSIR_DATA_BOOL ] = "bool", - [VSIR_DATA_F16 ] = "half", - [VSIR_DATA_F32 ] = "float", - [VSIR_DATA_F64 ] = "double", -@@ -403,6 +397,12 @@ static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum - [VSIR_DATA_U16 ] = "uint16", - [VSIR_DATA_U32 ] = "uint", - [VSIR_DATA_U64 ] = "uint64", -+ [VSIR_DATA_SNORM ] = "snorm", -+ [VSIR_DATA_UNORM ] = "unorm", -+ [VSIR_DATA_OPAQUE ] = "opaque", -+ [VSIR_DATA_MIXED ] = "mixed", -+ [VSIR_DATA_CONTINUED] = "", -+ [VSIR_DATA_UNUSED ] = "", - }; - - if (type < ARRAY_SIZE(data_type_names)) -@@ -957,7 +957,7 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, - return; - } - -- if (reg->data_type == VKD3D_DATA_UNUSED) -+ if (reg->data_type == VSIR_DATA_UNUSED) - return; - - if (reg->dimension < ARRAY_SIZE(dimensions)) -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 49e1a529369..dd13757bf59 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1685,7 +1685,7 @@ 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 parameter count %u for instruction \"%s\" (%#x); expected %u.", -+ "Invalid destination parameter count %zu 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; -@@ -1693,7 +1693,7 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ - if (ins->src_count != info->src_count) - { - vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT, -- "Invalid source parameter count %u for instruction \"%s\" (%#x); expected %u.", -+ "Invalid source parameter count %zu 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; -@@ -2018,6 +2018,7 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str - case VSIR_OP_SINCOS: - case VSIR_OP_SLT: - case VSIR_OP_TEXLD: -+ case VSIR_OP_TEXLDL: - case VSIR_OP_TEXLDD: - d3dbc_write_instruction(d3dbc, ins); - break; -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index c3dd606f00f..66e3c1ecd36 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -2480,7 +2480,7 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) - switch (type->u.width) - { - case 1: -- return VKD3D_DATA_BOOL; -+ return VSIR_DATA_BOOL; - case 8: - return VSIR_DATA_U8; - case 16: -@@ -4473,7 +4473,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ - dst_param_init(&dst_params[0]); - - dst_params[1].reg = reg; -- dst_params[1].reg.data_type = VKD3D_DATA_UNUSED; -+ dst_params[1].reg.data_type = VSIR_DATA_UNUSED; - dst_params[1].reg.idx[1].rel_addr = NULL; - dst_params[1].reg.idx[1].offset = ~0u; - dst_params[1].reg.idx_count = 1; -@@ -5301,7 +5301,7 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ - "Output stream index %u is invalid.", i); - } - -- register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, VKD3D_DATA_UNUSED, i); -+ register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, VSIR_DATA_UNUSED, i); - src_param_init(src_param); - - if (op == DX_EMIT_THEN_CUT_STREAM) -@@ -6009,7 +6009,7 @@ static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_ - src_param_init(src_param); - - instruction_dst_param_init_ssa_scalar(ins, sm6); -- ins->dst->reg.data_type = VSIR_DATA_F32; -+ ins->dst->reg.data_type = VSIR_DATA_U32; - } - - static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -9041,25 +9041,25 @@ static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_k - - static const enum vsir_data_type data_type_table[] = - { -- [COMPONENT_TYPE_INVALID] = VKD3D_DATA_UNUSED, -- [COMPONENT_TYPE_I1] = VKD3D_DATA_UNUSED, -+ [COMPONENT_TYPE_INVALID] = VSIR_DATA_UNUSED, -+ [COMPONENT_TYPE_I1] = VSIR_DATA_UNUSED, - [COMPONENT_TYPE_I16] = VSIR_DATA_I32, - [COMPONENT_TYPE_U16] = VSIR_DATA_U32, - [COMPONENT_TYPE_I32] = VSIR_DATA_I32, - [COMPONENT_TYPE_U32] = VSIR_DATA_U32, -- [COMPONENT_TYPE_I64] = VKD3D_DATA_UNUSED, -- [COMPONENT_TYPE_U64] = VKD3D_DATA_UNUSED, -+ [COMPONENT_TYPE_I64] = VSIR_DATA_UNUSED, -+ [COMPONENT_TYPE_U64] = VSIR_DATA_UNUSED, - [COMPONENT_TYPE_F16] = VSIR_DATA_F32, - [COMPONENT_TYPE_F32] = VSIR_DATA_F32, - [COMPONENT_TYPE_F64] = VSIR_DATA_F64, -- [COMPONENT_TYPE_SNORMF16] = VKD3D_DATA_SNORM, -- [COMPONENT_TYPE_UNORMF16] = VKD3D_DATA_UNORM, -- [COMPONENT_TYPE_SNORMF32] = VKD3D_DATA_SNORM, -- [COMPONENT_TYPE_UNORMF32] = VKD3D_DATA_UNORM, -+ [COMPONENT_TYPE_SNORMF16] = VSIR_DATA_SNORM, -+ [COMPONENT_TYPE_UNORMF16] = VSIR_DATA_UNORM, -+ [COMPONENT_TYPE_SNORMF32] = VSIR_DATA_SNORM, -+ [COMPONENT_TYPE_UNORMF32] = VSIR_DATA_UNORM, - [COMPONENT_TYPE_SNORMF64] = VSIR_DATA_F64, - [COMPONENT_TYPE_UNORMF64] = VSIR_DATA_F64, -- [COMPONENT_TYPE_PACKEDS8X32] = VKD3D_DATA_UNUSED, -- [COMPONENT_TYPE_PACKEDU8X32] = VKD3D_DATA_UNUSED, -+ [COMPONENT_TYPE_PACKEDS8X32] = VSIR_DATA_UNUSED, -+ [COMPONENT_TYPE_PACKEDU8X32] = VSIR_DATA_UNUSED, - }; - - static enum vsir_data_type vsir_data_type_from_dxil_component_type(enum dxil_component_type type, -@@ -9067,9 +9067,8 @@ static enum vsir_data_type vsir_data_type_from_dxil_component_type(enum dxil_com - { - enum vsir_data_type data_type; - -- if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VKD3D_DATA_UNUSED) -+ if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VSIR_DATA_UNUSED) - { -- FIXME("Unhandled component type %u.\n", type); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, - "Resource descriptor component type %u is unhandled.", type); - return VSIR_DATA_F32; -@@ -9089,7 +9088,7 @@ static bool resources_load_additional_values(struct resource_additional_values * - { - unsigned int i, operand_count, tag, value; - -- info->data_type = VKD3D_DATA_UNUSED; -+ info->data_type = VSIR_DATA_UNUSED; - info->byte_stride = 0; - - if (node->operand_count & 1) -@@ -9199,9 +9198,8 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc - - if (kind == RESOURCE_KIND_TYPEDBUFFER || resource_kind_is_texture(kind)) - { -- if (resource_values.data_type == VKD3D_DATA_UNUSED) -+ if (resource_values.data_type == VSIR_DATA_UNUSED) - { -- WARN("No data type defined.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, - "A typed resource has no data type."); - } -@@ -9303,9 +9301,9 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, - d->resource_type = ins->resource_type; - d->kind = kind; - d->reg_type = VKD3DSPR_RESOURCE; -- d->reg_data_type = VKD3D_DATA_UNUSED; -+ d->reg_data_type = VSIR_DATA_UNUSED; - d->resource_data_type = (ins->opcode == VSIR_OP_DCL) -- ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; -+ ? ins->declaration.semantic.resource_data_type[0] : VSIR_DATA_UNUSED; - - init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range); - -@@ -9377,9 +9375,9 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, - d->resource_type = ins->resource_type; - d->kind = values[0]; - d->reg_type = VKD3DSPR_UAV; -- d->reg_data_type = VKD3D_DATA_UNUSED; -+ d->reg_data_type = VSIR_DATA_UNUSED; - d->resource_data_type = (ins->opcode == VSIR_OP_DCL_UAV_TYPED) -- ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; -+ ? ins->declaration.semantic.resource_data_type[0] : VSIR_DATA_UNUSED; - - init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range); - -@@ -9483,7 +9481,7 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm - ins->declaration.sampler.src.modifiers = VKD3DSPSM_NONE; - - reg = &ins->declaration.sampler.src.reg; -- vsir_register_init(reg, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 3); -+ vsir_register_init(reg, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 3); - reg->idx[0].offset = d->id; - reg->idx[1].offset = d->range.first; - reg->idx[2].offset = d->range.last; -@@ -9493,8 +9491,8 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm - d->resource_type = ins->resource_type; - d->kind = RESOURCE_KIND_SAMPLER; - d->reg_type = VKD3DSPR_SAMPLER; -- d->reg_data_type = VKD3D_DATA_UNUSED; -- d->resource_data_type = VKD3D_DATA_UNUSED; -+ d->reg_data_type = VSIR_DATA_UNUSED; -+ d->resource_data_type = VSIR_DATA_UNUSED; - - return VKD3D_OK; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index dc68e1792d9..e57a4aa2731 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -330,9 +330,9 @@ static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_ca - static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vkd3d_glsl_generator *gen, - const char *src, enum vsir_data_type dst_data_type, enum vsir_data_type src_data_type, unsigned int size) - { -- if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) -+ if (dst_data_type == VSIR_DATA_UNORM || dst_data_type == VSIR_DATA_SNORM) - dst_data_type = VSIR_DATA_F32; -- if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM) -+ if (src_data_type == VSIR_DATA_UNORM || src_data_type == VSIR_DATA_SNORM) - src_data_type = VSIR_DATA_F32; - - if (dst_data_type == src_data_type) -@@ -1175,8 +1175,8 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const - "Internal compiler error: Unhandled data type %#x.", data_type); - /* fall through */ - case VSIR_DATA_F32: -- case VKD3D_DATA_UNORM: -- case VKD3D_DATA_SNORM: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: - vkd3d_string_buffer_printf(image_data, "vec4("); - break; - } -@@ -1780,8 +1780,8 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge - uav->resource_data_type, uav->register_id); - /* fall through */ - case VSIR_DATA_F32: -- case VKD3D_DATA_UNORM: -- case VKD3D_DATA_SNORM: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: - image_type_prefix = ""; - read_format = "r32f"; - break; -@@ -1996,8 +1996,8 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator - switch (srv->resource_data_type) - { - case VSIR_DATA_F32: -- case VKD3D_DATA_UNORM: -- case VKD3D_DATA_SNORM: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: - sampler_type_prefix = ""; - break; - case VSIR_DATA_I32: -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 678ed324919..e2c68d4afb5 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -2998,7 +2998,6 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, - decl->return_type = return_type; - decl->parameters = *parameters; - decl->loc = *loc; -- list_init(&decl->extern_vars); - - if (!hlsl_types_are_equal(return_type, ctx->builtin_types.Void)) - { -@@ -4066,20 +4065,23 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, - } - } - --void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func) -+void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func, -+ const char *description, const struct hlsl_block *processed_block) - { - struct vkd3d_string_buffer buffer; - size_t i; - - vkd3d_string_buffer_init(&buffer); -- vkd3d_string_buffer_printf(&buffer, "Dumping function %s.\n", func->func->name); -+ vkd3d_string_buffer_printf(&buffer, "Dumping %s \"%s\".\n", description, func->func->name); - vkd3d_string_buffer_printf(&buffer, "Function parameters:\n"); - for (i = 0; i < func->parameters.count; ++i) - { - dump_ir_var(ctx, &buffer, func->parameters.vars[i]); - vkd3d_string_buffer_printf(&buffer, "\n"); - } -- if (func->has_body) -+ if (processed_block) -+ dump_block(ctx, &buffer, processed_block); -+ else if (func->has_body) - dump_block(ctx, &buffer, &func->body); - - vkd3d_string_buffer_trace(&buffer); -@@ -5009,8 +5011,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) - vkd3d_free(ctx->constant_defs.regs); - } - --int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, -- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) -+int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) - { - enum vkd3d_shader_target_type target_type = compile_info->target_type; - const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; -@@ -5062,7 +5064,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d - if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- if ((ret = hlsl_lexer_compile(&ctx, hlsl)) == 2) -+ if ((ret = hlsl_lexer_compile(&ctx, &compile_info->source)) == 2) - { - hlsl_ctx_cleanup(&ctx); - return VKD3D_ERROR_OUT_OF_MEMORY; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 0dce2831c3e..47cc361a48a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -645,12 +645,6 @@ struct hlsl_ir_function_decl - * executed. Needed to deal with return statements in non-uniform control - * flow, since some backends can't handle them. */ - struct hlsl_ir_var *early_return_var; -- -- /* List of all the extern semantic variables; linked by the -- * hlsl_ir_var.extern_entry fields. This exists as a convenience because -- * it is often necessary to iterate all extern variables and these can be -- * declared in as function parameters, or as the function return value. */ -- struct list extern_vars; - }; - - struct hlsl_ir_call -@@ -1615,7 +1609,8 @@ struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl - void hlsl_block_cleanup(struct hlsl_block *block); - bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block); - --void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func); -+void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func, -+ const char *description, const struct hlsl_block *processed_block); - void hlsl_dump_ir_function_decl(struct hlsl_ctx *ctx, - struct vkd3d_string_buffer *buffer, const struct hlsl_ir_function_decl *f); - void hlsl_dump_var_default_values(const struct hlsl_ir_var *var); -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 7707412bf57..8bfa157a12b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -186,30 +186,34 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - { - struct hlsl_ir_node *store; - struct hlsl_ir_load *load; -- struct hlsl_ir_var *temp; -- char *new_name; - - uniform->is_uniform = 1; - list_add_tail(&ctx->extern_vars, &uniform->extern_entry); - -- if (!(new_name = hlsl_sprintf_alloc(ctx, "", uniform->name))) -- return; -- -- if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type, -- &uniform->loc, NULL, uniform->storage_modifiers, NULL))) -+ if (!uniform->temp_copy) - { -- vkd3d_free(new_name); -- return; -- } -- list_add_before(&uniform->scope_entry, &temp->scope_entry); -+ struct hlsl_ir_var *temp; -+ char *new_name; - -- uniform->temp_copy = temp; -+ if (!(new_name = hlsl_sprintf_alloc(ctx, "", uniform->name))) -+ return; -+ -+ if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type, -+ &uniform->loc, NULL, uniform->storage_modifiers, NULL))) -+ { -+ vkd3d_free(new_name); -+ return; -+ } -+ list_add_tail(&ctx->dummy_scope->vars, &temp->scope_entry); -+ -+ uniform->temp_copy = temp; -+ } - - if (!(load = hlsl_new_var_load(ctx, uniform, &uniform->loc))) - return; - list_add_head(&block->instrs, &load->node.entry); - -- if (!(store = hlsl_new_simple_store(ctx, temp, &load->node))) -+ if (!(store = hlsl_new_simple_store(ctx, uniform->temp_copy, &load->node))) - return; - list_add_after(&load->node.entry, &store->entry); - } -@@ -300,9 +304,9 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls - == base_type_get_semantic_equivalent(type2->e.numeric.type); - } - --static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, -- struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, -- uint32_t stream_index, bool output, bool force_align, bool create, const struct vkd3d_shader_location *loc) -+static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_ir_var *var, -+ struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t stream_index, bool output, -+ bool force_align, bool create, const struct vkd3d_shader_location *loc) - { - struct hlsl_semantic new_semantic; - uint32_t index = semantic->index; -@@ -323,7 +327,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir - if (!new_name) - return NULL; - -- LIST_FOR_EACH_ENTRY(ext_var, &func->extern_vars, struct hlsl_ir_var, extern_entry) -+ LIST_FOR_EACH_ENTRY(ext_var, semantic_vars, struct hlsl_ir_var, extern_entry) - { - if (!ascii_strcasecmp(ext_var->name, new_name)) - { -@@ -387,7 +391,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir - ext_var->is_param = var->is_param; - ext_var->force_align = force_align; - list_add_before(&var->scope_entry, &ext_var->scope_entry); -- list_add_tail(&func->extern_vars, &ext_var->extern_entry); -+ list_add_tail(semantic_vars, &ext_var->extern_entry); - - return ext_var; - } -@@ -409,7 +413,7 @@ static uint32_t combine_field_storage_modifiers(uint32_t modifiers, uint32_t fie - return field_modifiers; - } - --static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, -+static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *semantic_vars, - struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, - uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align) - { -@@ -455,7 +459,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec - return; - prim_type_src->modifiers = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK; - -- if (!(input = add_semantic_var(ctx, func, var, prim_type_src, -+ if (!(input = add_semantic_var(ctx, semantic_vars, var, prim_type_src, - modifiers, semantic, 0, false, force_align, true, loc))) - return; - ++semantic->index; -@@ -469,7 +473,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec - } - else - { -- if (!(input = add_semantic_var(ctx, func, var, vector_type_src, -+ if (!(input = add_semantic_var(ctx, semantic_vars, var, vector_type_src, - modifiers, semantic, 0, false, force_align, true, loc))) - return; - ++semantic->index; -@@ -496,7 +500,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec - } - } - --static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, -+static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct list *semantic_vars, - struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, - uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align) - { -@@ -533,7 +537,7 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func - if (hlsl_type_is_primitive_array(type)) - prim_index = i; - -- prepend_input_copy_recurse(ctx, func, block, prim_index, -+ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, - element_load, element_modifiers, semantic, force_align); - } - else -@@ -550,7 +554,7 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func - if (semantic->name) - { - warn_on_field_semantic(ctx, field, semantic); -- prepend_input_copy_recurse(ctx, func, block, prim_index, -+ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, - element_load, element_modifiers, semantic, force_align); - } - else -@@ -561,7 +565,7 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func - - if (!(hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic))) - return; -- prepend_input_copy_recurse(ctx, func, block, prim_index, -+ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, - element_load, element_modifiers, &semantic_copy, force_align); - hlsl_cleanup_semantic(&semantic_copy); - } -@@ -570,13 +574,14 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func - } - else - { -- prepend_input_copy(ctx, func, block, prim_index, lhs, modifiers, semantic, force_align); -+ prepend_input_copy(ctx, semantic_vars, block, prim_index, lhs, modifiers, semantic, force_align); - } - } - - /* Split inputs into two variables representing the semantic and temp registers, - * and copy the former to the latter, so that writes to input variables work. */ --static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var) -+static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *body, -+ struct list *semantic_vars, struct hlsl_ir_var *var) - { - struct hlsl_semantic semantic_copy; - struct hlsl_ir_load *load; -@@ -594,14 +599,14 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function - hlsl_block_cleanup(&block); - return; - } -- prepend_input_copy_recurse(ctx, func, &block, 0, load, var->storage_modifiers, &semantic_copy, false); -+ prepend_input_copy_recurse(ctx, semantic_vars, &block, 0, load, var->storage_modifiers, &semantic_copy, false); - hlsl_cleanup_semantic(&semantic_copy); - -- list_move_head(&func->body.instrs, &block.instrs); -+ list_move_head(&body->instrs, &block.instrs); - } - - static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, -- struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, -+ struct list *semantic_vars, struct hlsl_ir_load *rhs, uint32_t modifiers, - struct hlsl_semantic *semantic, uint32_t stream_index, bool force_align, bool create) - { - struct hlsl_type *type = rhs->node.data_type, *vector_type; -@@ -631,7 +636,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_var *output; - struct hlsl_ir_node *load; - -- if (!(output = add_semantic_var(ctx, func, var, vector_type, modifiers, -+ if (!(output = add_semantic_var(ctx, semantic_vars, var, vector_type, modifiers, - semantic, stream_index, true, force_align, create, loc))) - return; - ++semantic->index; -@@ -652,9 +657,9 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - } - } - --static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, -- struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, -- uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t stream_index, bool force_align, bool create) -+static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct list *semantic_vars, -+ const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, struct hlsl_semantic *semantic, -+ uint32_t stream_index, bool force_align, bool create) - { - struct vkd3d_shader_location *loc = &rhs->node.loc; - struct hlsl_ir_var *var = rhs->src.var; -@@ -684,7 +689,7 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * - element_modifiers = modifiers; - force_align = true; - -- append_output_copy_recurse(ctx, block, func, element_type, element_load, -+ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, - element_modifiers, semantic, stream_index, force_align, create); - } - else -@@ -700,7 +705,7 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * - { - warn_on_field_semantic(ctx, field, semantic); - -- append_output_copy_recurse(ctx, block, func, element_type, element_load, -+ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, - element_modifiers, semantic, stream_index, force_align, create); - } - else -@@ -711,7 +716,7 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * - - if (!hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic)) - continue; -- append_output_copy_recurse(ctx, block, func, element_type, element_load, -+ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, - element_modifiers, &semantic_copy, stream_index, force_align, create); - hlsl_cleanup_semantic(&semantic_copy); - } -@@ -720,14 +725,15 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * - } - else - { -- append_output_copy(ctx, block, func, rhs, modifiers, semantic, stream_index, force_align, create); -+ append_output_copy(ctx, block, semantic_vars, rhs, modifiers, semantic, stream_index, force_align, create); - } - } - - /* Split outputs into two variables representing the temp and semantic - * registers, and copy the former to the latter, so that reads from output - * variables work. */ --static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var) -+static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *body, -+ struct list *semantic_vars, struct hlsl_ir_var *var) - { - struct hlsl_semantic semantic_copy; - struct hlsl_ir_load *load; -@@ -735,11 +741,11 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function - /* This redundant load is expected to be deleted later by DCE. */ - if (!(load = hlsl_new_var_load(ctx, var, &var->loc))) - return; -- hlsl_block_add_instr(&func->body, &load->node); -+ hlsl_block_add_instr(body, &load->node); - - if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) - return; -- append_output_copy_recurse(ctx, &func->body, func, var->data_type, -+ append_output_copy_recurse(ctx, body, semantic_vars, var->data_type, - load, var->storage_modifiers, &semantic_copy, 0, false, true); - hlsl_cleanup_semantic(&semantic_copy); - } -@@ -3424,7 +3430,7 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - - struct stream_append_ctx - { -- struct hlsl_ir_function_decl *func; -+ struct list *semantic_vars; - bool created[VKD3D_MAX_STREAM_COUNT]; - }; - -@@ -3465,7 +3471,7 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst - - if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) - return false; -- append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), -+ append_output_copy_recurse(ctx, &block, append_ctx->semantic_vars, type->e.so.type, hlsl_ir_load(rhs), - var->storage_modifiers, &semantic_copy, var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, - false, !append_ctx->created[stream_index]); - hlsl_cleanup_semantic(&semantic_copy); -@@ -5292,7 +5298,7 @@ static void dump_function(struct rb_entry *entry, void *context) - LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) - { - if (decl->has_body) -- hlsl_dump_function(ctx, decl); -+ hlsl_dump_function(ctx, decl, "function", NULL); - } - } - -@@ -5309,7 +5315,7 @@ static bool mark_indexable_var(struct hlsl_ctx *ctx, struct hlsl_deref *deref, - return true; - } - --static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) -+static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_block *body) - { - struct hlsl_scope *scope; - struct hlsl_ir_var *var; -@@ -5320,7 +5326,7 @@ static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_de - var->indexable = false; - } - -- transform_derefs(ctx, mark_indexable_var, &entry_func->body); -+ transform_derefs(ctx, mark_indexable_var, body); - } - - static char get_regset_name(enum hlsl_regset regset) -@@ -5567,7 +5573,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop - } - } - --static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) -+static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_block *body) - { - struct hlsl_scope *scope; - struct hlsl_ir_var *var; -@@ -5575,7 +5581,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - if (ctx->result) - return; - -- index_instructions(&entry_func->body, 1); -+ index_instructions(body, 1); - - LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) - { -@@ -5583,7 +5589,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - var->first_write = var->last_read = 0; - } - -- compute_liveness_recurse(&entry_func->body, 0, 0); -+ compute_liveness_recurse(body, 0, 0); - } - - static void mark_vars_usage(struct hlsl_ctx *ctx) -@@ -6366,7 +6372,7 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl - } - } - --static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) -+static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *body) - { - struct register_allocator allocator_used = {0}; - struct register_allocator allocator = {0}; -@@ -6431,9 +6437,9 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi - } - } - -- allocate_const_registers_recurse(ctx, &entry_func->body, &allocator); -+ allocate_const_registers_recurse(ctx, body, &allocator); - -- allocate_sincos_const_registers(ctx, &entry_func->body, &allocator); -+ allocate_sincos_const_registers(ctx, body, &allocator); - - vkd3d_free(allocator.allocations); - } -@@ -6442,7 +6448,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi - * index to all (simultaneously live) variables or intermediate values. Agnostic - * as to how many registers are actually available for the current backend, and - * does not handle constants. */ --static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) -+static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) - { - struct register_allocator allocator = {0}; - struct hlsl_scope *scope; -@@ -6461,7 +6467,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun - /* ps_1_* outputs are special and go in temp register 0. */ - if (ctx->profile->major_version == 1 && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) - { -- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) -+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) - { - if (var->is_output_semantic) - { -@@ -6472,15 +6478,16 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun - } - } - -- allocate_temp_registers_recurse(ctx, &entry_func->body, &allocator); -+ allocate_temp_registers_recurse(ctx, body, &allocator); - vkd3d_free(allocator.allocations); - - if (allocator.indexable_count) -- TRACE("Declaration of function \"%s\" required %u temp registers, and %u indexable temps.\n", -- entry_func->func->name, allocator.reg_count, allocator.indexable_count); -+ TRACE("Declaration of %s function required %u temp registers, and %u indexable temps.\n", -+ ctx->is_patch_constant_func ? "patch constant" : "main", -+ allocator.reg_count, allocator.indexable_count); - else -- TRACE("Declaration of function \"%s\" required %u temp registers.\n", -- entry_func->func->name, allocator.reg_count); -+ TRACE("Declaration of %s function required %u temp registers.\n", -+ ctx->is_patch_constant_func ? "patch constant" : "main", allocator.reg_count); - - return allocator.reg_count; - } -@@ -6630,8 +6637,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var - } - } - --static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, -- uint32_t *output_reg_count) -+static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *semantic_vars, uint32_t *output_reg_count) - { - struct register_allocator input_allocator = {0}, output_allocators[VKD3D_MAX_STREAM_COUNT] = {{0}}; - struct register_allocator in_prim_allocator = {0}, patch_constant_out_patch_allocator = {0}; -@@ -6645,7 +6651,7 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun - for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) - output_allocators[i].prioritize_smaller_writemasks = true; - -- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) -+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) - { - if (var->is_input_semantic) - { -@@ -6986,7 +6992,7 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum - return NULL; - } - --static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, enum hlsl_regset regset) -+static void allocate_objects(struct hlsl_ctx *ctx, struct list *semantic_vars, enum hlsl_regset regset) - { - char regset_name = get_regset_name(regset); - uint32_t min_index = 0, id = 0; -@@ -6994,7 +7000,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - - if (regset == HLSL_REGSET_UAVS && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) - { -- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) -+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) - { - if (var->semantic.name && (!ascii_strcasecmp(var->semantic.name, "color") - || !ascii_strcasecmp(var->semantic.name, "sv_target"))) -@@ -7840,8 +7846,8 @@ static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx) - } - } - --static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, -- uint32_t output_reg_count) -+static void validate_max_output_size(struct hlsl_ctx *ctx, struct list *semantic_vars, -+ uint32_t output_reg_count, const struct vkd3d_shader_location *loc) - { - unsigned int max_output_size, comp_count = 0; - unsigned int *reg_comp_count; -@@ -7854,7 +7860,7 @@ static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_functi - if (!(reg_comp_count = hlsl_calloc(ctx, output_reg_count, sizeof(*reg_comp_count)))) - return; - -- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) -+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) - { - if (!var->is_output_semantic) - continue; -@@ -7869,7 +7875,7 @@ static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_functi - - max_output_size = ctx->max_vertex_count * comp_count; - if (max_output_size > 1024) -- hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, - "Max vertex count (%u) * output data component count (%u) = %u, which is greater than 1024.", - ctx->max_vertex_count, comp_count, max_output_size); - -@@ -8183,15 +8189,15 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog - } - } - --static void generate_vsir_signature(struct hlsl_ctx *ctx, -- struct vsir_program *program, struct hlsl_ir_function_decl *func) -+static void generate_vsir_signature(struct hlsl_ctx *ctx, struct vsir_program *program, -+ struct hlsl_ir_function_decl *func, struct list *semantic_vars) - { - bool is_domain = program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; - struct hlsl_ir_var *var; - - ctx->is_patch_constant_func = func == ctx->patch_constant_func; - -- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) -+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) - { - if (var->is_input_semantic) - { -@@ -8233,7 +8239,7 @@ static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, c - if (type->class == HLSL_CLASS_ARRAY) - return vsir_data_type_from_hlsl_type(ctx, type->e.array.type); - if (type->class == HLSL_CLASS_STRUCT) -- return VKD3D_DATA_MIXED; -+ return VSIR_DATA_MIXED; - if (type->class <= HLSL_CLASS_LAST_NUMERIC) - { - switch (type->e.numeric.type) -@@ -8253,7 +8259,7 @@ static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, c - } - } - -- return VKD3D_DATA_UNUSED; -+ return VSIR_DATA_UNUSED; - } - - static enum vsir_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx, -@@ -8782,7 +8788,7 @@ static void sm4_generate_vsir_rasterizer_sample_count(struct hlsl_ctx *ctx, - vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); - - src_param = &ins->src[0]; -- vsir_src_param_init(src_param, VKD3DSPR_RASTERIZER, VKD3D_DATA_UNUSED, 0); -+ vsir_src_param_init(src_param, VKD3DSPR_RASTERIZER, VSIR_DATA_UNUSED, 0); - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); - } -@@ -9397,6 +9403,10 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, - flags |= VKD3DSI_TEXLD_PROJECT; - break; - -+ case HLSL_RESOURCE_SAMPLE_LOD: -+ opcode = VSIR_OP_TEXLDL; -+ break; -+ - case HLSL_RESOURCE_SAMPLE_LOD_BIAS: - opcode = VSIR_OP_TEXLD; - flags |= VKD3DSI_TEXLD_BIAS; -@@ -9596,8 +9606,8 @@ static void sm1_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo - } - } - --static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, -- uint64_t config_flags, struct vsir_program *program) -+static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, -+ struct list *semantic_vars, struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) - { - struct vkd3d_shader_version version = {0}; - struct hlsl_block block; -@@ -9612,18 +9622,18 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - } - - program->ssa_count = 0; -- program->temp_count = allocate_temp_registers(ctx, entry_func); -+ program->temp_count = allocate_temp_registers(ctx, body, semantic_vars); - if (ctx->result) - return; - -- generate_vsir_signature(ctx, program, entry_func); -+ generate_vsir_signature(ctx, program, func, semantic_vars); - - hlsl_block_init(&block); - sm1_generate_vsir_constant_defs(ctx, program, &block); - sm1_generate_vsir_sampler_dcls(ctx, program, &block); -- list_move_head(&entry_func->body.instrs, &block.instrs); -+ list_move_head(&body->instrs, &block.instrs); - -- sm1_generate_vsir_block(ctx, &entry_func->body, program); -+ sm1_generate_vsir_block(ctx, body, program); - - program->ssa_count = ctx->ssa_count; - } -@@ -11738,8 +11748,9 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo - } - } - --static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, -- struct hlsl_ir_function_decl *func, uint64_t config_flags, struct vsir_program *program) -+static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *semantic_vars, -+ struct hlsl_ir_function_decl *func, struct hlsl_block *body, uint64_t config_flags, -+ struct vsir_program *program) - { - struct hlsl_block block = {0}; - struct hlsl_scope *scope; -@@ -11748,16 +11759,16 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, - - ctx->is_patch_constant_func = func == ctx->patch_constant_func; - -- compute_liveness(ctx, func); -- mark_indexable_vars(ctx, func); -- temp_count = allocate_temp_registers(ctx, func); -+ compute_liveness(ctx, body); -+ mark_indexable_vars(ctx, body); -+ temp_count = allocate_temp_registers(ctx, body, semantic_vars); - if (ctx->result) - return; - program->temp_count = max(program->temp_count, temp_count); - - hlsl_block_init(&block); - -- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) -+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) - { - if ((var->is_input_semantic && var->last_read) - || (var->is_output_semantic && var->first_write)) -@@ -11786,11 +11797,11 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, - } - } - -- list_move_head(&func->body.instrs, &block.instrs); -+ list_move_head(&body->instrs, &block.instrs); - - hlsl_block_cleanup(&block); - -- sm4_generate_vsir_block(ctx, &func->body, program); -+ sm4_generate_vsir_block(ctx, body, program); - - generate_vsir_add_program_instruction(ctx, program, &func->loc, VSIR_OP_RET, 0, 0); - } -@@ -12014,8 +12025,8 @@ static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vs - * STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */ - } - --static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, -- struct vsir_program *program, const struct hlsl_ir_function_decl *entry_func) -+static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, struct vsir_program *program, -+ const struct list *semantic_vars, const struct hlsl_ir_function_decl *entry_func) - { - const struct vkd3d_shader_version *version = &program->shader_version; - struct extern_resource *extern_resources; -@@ -12041,7 +12052,7 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, - - sm4_free_extern_resources(extern_resources, extern_resources_count); - -- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) -+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) - { - const struct hlsl_type *type = var->data_type; - -@@ -12123,7 +12134,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, - ins->flags |= VKD3DSI_SAMPLER_COMPARISON_MODE; - - src_param = &ins->declaration.sampler.src; -- vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 0); -+ vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 0); - - ins->declaration.sampler.range.first = array_first; - ins->declaration.sampler.range.last = array_last; -@@ -12179,9 +12190,9 @@ static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_t - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - if (format->modifiers & HLSL_MODIFIER_UNORM) -- return VKD3D_DATA_UNORM; -+ return VSIR_DATA_UNORM; - if (format->modifiers & HLSL_MODIFIER_SNORM) -- return VKD3D_DATA_SNORM; -+ return VSIR_DATA_SNORM; - return VSIR_DATA_F32; - - case HLSL_TYPE_INT: -@@ -12262,7 +12273,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, - else - vsir_resource = &ins->declaration.semantic.resource; - -- vsir_dst_param_init(&vsir_resource->reg, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 0); -+ vsir_dst_param_init(&vsir_resource->reg, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_UNUSED, 0); - - if (uav && component_type->e.resource.rasteriser_ordered) - ins->flags = VKD3DSUF_RASTERISER_ORDERED_VIEW; -@@ -12320,7 +12331,7 @@ static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, - return; - } - -- vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VKD3D_DATA_UNUSED, 1); -+ vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VSIR_DATA_UNUSED, 1); - ins->src[0].reg.dimension = VSIR_DIMENSION_NONE; - ins->src[0].reg.idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; - } -@@ -12329,7 +12340,8 @@ static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, - * vsir_program, so it can be used as input to tpf_compile() without relying - * on ctx and entry_func. */ - static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, -- uint64_t config_flags, struct vsir_program *program) -+ struct list *semantic_vars, struct hlsl_block *body, struct list *patch_semantic_vars, -+ struct hlsl_block *patch_body, uint64_t config_flags, struct vsir_program *program) - { - struct vkd3d_shader_version version = {0}; - struct extern_resource *extern_resources; -@@ -12346,9 +12358,9 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - return; - } - -- generate_vsir_signature(ctx, program, func); -+ generate_vsir_signature(ctx, program, func, semantic_vars); - if (version.type == VKD3D_SHADER_TYPE_HULL) -- generate_vsir_signature(ctx, program, ctx->patch_constant_func); -+ generate_vsir_signature(ctx, program, ctx->patch_constant_func, patch_semantic_vars); - - if (version.type == VKD3D_SHADER_TYPE_COMPUTE) - { -@@ -12415,16 +12427,17 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - if (version.type == VKD3D_SHADER_TYPE_HULL) - generate_vsir_add_program_instruction(ctx, program, - &ctx->patch_constant_func->loc, VSIR_OP_HS_CONTROL_POINT_PHASE, 0, 0); -- sm4_generate_vsir_add_function(ctx, func, config_flags, program); -+ sm4_generate_vsir_add_function(ctx, semantic_vars, func, body, config_flags, program); - if (version.type == VKD3D_SHADER_TYPE_HULL) - { - generate_vsir_add_program_instruction(ctx, program, - &ctx->patch_constant_func->loc, VSIR_OP_HS_FORK_PHASE, 0, 0); -- sm4_generate_vsir_add_function(ctx, ctx->patch_constant_func, config_flags, program); -+ sm4_generate_vsir_add_function(ctx, patch_semantic_vars, -+ ctx->patch_constant_func, patch_body, config_flags, program); - } - - generate_vsir_scan_required_features(ctx, program); -- generate_vsir_scan_global_flags(ctx, program, func); -+ generate_vsir_scan_global_flags(ctx, program, semantic_vars, func); - - program->ssa_count = ctx->ssa_count; - } -@@ -13565,15 +13578,14 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct - return true; - } - --static void process_entry_function(struct hlsl_ctx *ctx, -+static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *body, - const struct hlsl_block *global_uniform_block, struct hlsl_ir_function_decl *entry_func) - { -+ struct stream_append_ctx stream_append_ctx = { .semantic_vars = semantic_vars }; - const struct hlsl_ir_var *input_patch = NULL, *output_patch = NULL; - const struct hlsl_profile_info *profile = ctx->profile; - struct hlsl_block static_initializers, global_uniforms; -- struct hlsl_block *const body = &entry_func->body; - struct recursive_call_ctx recursive_call_ctx; -- struct stream_append_ctx stream_append_ctx; - uint32_t output_reg_count; - struct hlsl_ir_var *var; - unsigned int i; -@@ -13581,6 +13593,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, - - ctx->is_patch_constant_func = entry_func == ctx->patch_constant_func; - -+ hlsl_clone_block(ctx, body, &entry_func->body); -+ - if (!hlsl_clone_block(ctx, &static_initializers, &ctx->static_initializers)) - return; - list_move_head(&body->instrs, &static_initializers.instrs); -@@ -13624,7 +13638,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name); - -- append_output_var_copy(ctx, entry_func, entry_func->return_var); -+ append_output_var_copy(ctx, body, semantic_vars, entry_func->return_var); - } - - for (i = 0; i < entry_func->parameters.count; ++i) -@@ -13680,7 +13694,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - } - - validate_and_record_prim_type(ctx, var); -- prepend_input_var_copy(ctx, entry_func, var); -+ prepend_input_var_copy(ctx, body, semantic_vars, var); - } - else if (var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) - { -@@ -13716,7 +13730,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - continue; - } - -- prepend_input_var_copy(ctx, entry_func, var); -+ prepend_input_var_copy(ctx, body, semantic_vars, var); - } - if (var->storage_modifiers & HLSL_STORAGE_OUT) - { -@@ -13727,7 +13741,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Output parameters are not allowed in geometry shaders."); - else -- append_output_var_copy(ctx, entry_func, var); -+ append_output_var_copy(ctx, body, semantic_vars, var); - } - } - } -@@ -13776,8 +13790,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, - hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL); - } - -- compute_liveness(ctx, entry_func); -- transform_derefs(ctx, divert_written_uniform_derefs_to_temp, &entry_func->body); -+ compute_liveness(ctx, body); -+ transform_derefs(ctx, divert_written_uniform_derefs_to_temp, body); - - loop_unrolling_execute(ctx, body); - hlsl_run_const_passes(ctx, body); -@@ -13797,7 +13811,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - do - { - progress = vectorize_exprs(ctx, body); -- compute_liveness(ctx, entry_func); -+ compute_liveness(ctx, body); - progress |= hlsl_transform_ir(ctx, dce, body, NULL); - progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); - progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); -@@ -13810,7 +13824,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - hlsl_transform_ir(ctx, lower_combined_samples, body, NULL); - - do -- compute_liveness(ctx, entry_func); -+ compute_liveness(ctx, body); - while (hlsl_transform_ir(ctx, dce, body, NULL)); - - hlsl_transform_ir(ctx, track_components_usage, body, NULL); -@@ -13823,9 +13837,6 @@ static void process_entry_function(struct hlsl_ctx *ctx, - { - allocate_stream_outputs(ctx); - validate_and_record_stream_outputs(ctx); -- -- memset(&stream_append_ctx, 0, sizeof(stream_append_ctx)); -- stream_append_ctx.func = entry_func; - hlsl_transform_ir(ctx, lower_stream_appends, body, &stream_append_ctx); - } - -@@ -13866,7 +13877,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - hlsl_run_folding_passes(ctx, body); - - do -- compute_liveness(ctx, entry_func); -+ compute_liveness(ctx, body); - while (hlsl_transform_ir(ctx, dce, body, NULL)); - - /* TODO: move forward, remove when no longer needed */ -@@ -13875,27 +13886,28 @@ static void process_entry_function(struct hlsl_ctx *ctx, - transform_derefs(ctx, clean_constant_deref_offset_srcs, body); - - do -- compute_liveness(ctx, entry_func); -+ compute_liveness(ctx, body); - while (hlsl_transform_ir(ctx, dce, body, NULL)); - -- compute_liveness(ctx, entry_func); -+ compute_liveness(ctx, body); - mark_vars_usage(ctx); - - calculate_resource_register_counts(ctx); - - allocate_register_reservations(ctx, &ctx->extern_vars); -- allocate_register_reservations(ctx, &entry_func->extern_vars); -- allocate_semantic_registers(ctx, entry_func, &output_reg_count); -+ allocate_register_reservations(ctx, semantic_vars); -+ allocate_semantic_registers(ctx, semantic_vars, &output_reg_count); - - if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) -- validate_max_output_size(ctx, entry_func, output_reg_count); -+ validate_max_output_size(ctx, semantic_vars, output_reg_count, &entry_func->loc); - } - - int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) - { -+ struct hlsl_block global_uniform_block, body, patch_body; - const struct hlsl_profile_info *profile = ctx->profile; -- struct hlsl_block global_uniform_block; -+ struct list semantic_vars, patch_semantic_vars; - struct hlsl_ir_var *var; - - parse_entry_function_attributes(ctx, entry_func); -@@ -13914,6 +13926,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, - "Entry point \"%s\" is missing a [maxvertexcount] attribute.", entry_func->func->name); - -+ list_init(&ctx->extern_vars); -+ list_init(&semantic_vars); -+ list_init(&patch_semantic_vars); - hlsl_block_init(&global_uniform_block); - - LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) -@@ -13922,13 +13937,13 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - prepend_uniform_copy(ctx, &global_uniform_block, var); - } - -- process_entry_function(ctx, &global_uniform_block, entry_func); -+ process_entry_function(ctx, &semantic_vars, &body, &global_uniform_block, entry_func); - if (ctx->result) - return ctx->result; - - if (profile->type == VKD3D_SHADER_TYPE_HULL) - { -- process_entry_function(ctx, &global_uniform_block, ctx->patch_constant_func); -+ process_entry_function(ctx, &patch_semantic_vars, &patch_body, &global_uniform_block, ctx->patch_constant_func); - if (ctx->result) - return ctx->result; - } -@@ -13937,21 +13952,26 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - - if (profile->major_version < 4) - { -- mark_indexable_vars(ctx, entry_func); -- allocate_const_registers(ctx, entry_func); -+ mark_indexable_vars(ctx, &body); -+ allocate_const_registers(ctx, &body); - sort_uniforms_by_bind_count(ctx, HLSL_REGSET_SAMPLERS); -- allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS); -+ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS); - } - else - { - allocate_buffers(ctx); -- allocate_objects(ctx, entry_func, HLSL_REGSET_TEXTURES); -- allocate_objects(ctx, entry_func, HLSL_REGSET_UAVS); -- allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS); -+ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_TEXTURES); -+ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_UAVS); -+ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS); - } - - if (TRACE_ON()) -+ { - rb_for_each_entry(&ctx->functions, dump_function, ctx); -+ hlsl_dump_function(ctx, entry_func, "processed entry point", &body); -+ if (profile->type == VKD3D_SHADER_TYPE_HULL) -+ hlsl_dump_function(ctx, ctx->patch_constant_func, "processed patch-constant function", &patch_body); -+ } - - if (ctx->result) - return ctx->result; -@@ -13969,7 +13989,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - if (ctx->result) - return ctx->result; - -- sm1_generate_vsir(ctx, entry_func, config_flags, &program); -+ sm1_generate_vsir(ctx, entry_func, &semantic_vars, &body, config_flags, &program); - if (ctx->result) - { - vsir_program_cleanup(&program); -@@ -13996,7 +14016,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - if (ctx->result) - return ctx->result; - -- sm4_generate_vsir(ctx, entry_func, config_flags, &program); -+ sm4_generate_vsir(ctx, entry_func, &semantic_vars, &body, -+ &patch_semantic_vars, &patch_body, config_flags, &program); - if (ctx->result) - { - vsir_program_cleanup(&program); -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index c322d9dde01..92580a6a2df 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -604,7 +604,7 @@ static void vsir_src_param_init_io(struct vkd3d_shader_src_param *src, - - void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id) - { -- vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1); -+ vsir_src_param_init(param, VKD3DSPR_LABEL, VSIR_DATA_UNUSED, 1); - param->reg.dimension = VSIR_DIMENSION_NONE; - param->reg.idx[0].offset = label_id; - } -@@ -625,7 +625,7 @@ static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, ui - - static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx) - { -- vsir_src_param_init(src, VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 2); -+ vsir_src_param_init(src, VKD3DSPR_RESOURCE, VSIR_DATA_UNUSED, 2); - src->reg.idx[0].offset = id; - src->reg.idx[1].offset = idx; - src->reg.dimension = VSIR_DIMENSION_VEC4; -@@ -634,7 +634,7 @@ static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, uns - - static void vsir_src_param_init_sampler(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx) - { -- vsir_src_param_init(src, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 2); -+ vsir_src_param_init(src, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 2); - src->reg.idx[0].offset = id; - src->reg.idx[1].offset = idx; - src->reg.dimension = VSIR_DIMENSION_NONE; -@@ -661,7 +661,7 @@ static void src_param_init_ssa_scalar(struct vkd3d_shader_src_param *src, - - static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx) - { -- src_param_init_ssa_scalar(src, idx, VKD3D_DATA_BOOL); -+ src_param_init_ssa_scalar(src, idx, VSIR_DATA_BOOL); - } - - static void src_param_init_ssa_float(struct vkd3d_shader_src_param *src, unsigned int idx) -@@ -676,7 +676,7 @@ static void src_param_init_ssa_float4(struct vkd3d_shader_src_param *src, unsign - - static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx) - { -- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1); -+ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_BOOL, 1); - src->reg.idx[0].offset = idx; - } - -@@ -719,7 +719,7 @@ static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3 - - void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst) - { -- vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); -+ vsir_dst_param_init(dst, VKD3DSPR_NULL, VSIR_DATA_UNUSED, 0); - dst->reg.dimension = VSIR_DIMENSION_NONE; - dst->write_mask = 0; - } -@@ -745,7 +745,7 @@ static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *dst, - - static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) - { -- dst_param_init_ssa_scalar(dst, idx, VKD3D_DATA_BOOL); -+ dst_param_init_ssa_scalar(dst, idx, VSIR_DATA_BOOL); - } - - static void dst_param_init_ssa_float(struct vkd3d_shader_dst_param *dst, unsigned int idx) -@@ -760,7 +760,7 @@ static void dst_param_init_ssa_float4(struct vkd3d_shader_dst_param *dst, unsign - - static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) - { -- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1); -+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_BOOL, 1); - dst->reg.idx[0].offset = idx; - } - -@@ -792,6 +792,10 @@ void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vk - memset(ins, 0, sizeof(*ins)); - ins->location = *location; - ins->opcode = opcode; -+ ins->resource_data_type[0] = VSIR_DATA_F32; -+ ins->resource_data_type[1] = VSIR_DATA_F32; -+ ins->resource_data_type[2] = VSIR_DATA_F32; -+ ins->resource_data_type[3] = VSIR_DATA_F32; - } - - bool vsir_instruction_init_with_params(struct vsir_program *program, -@@ -1180,7 +1184,7 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - { - vkd3d_shader_error(ctx->message_context, &udiv->location, - VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, -- "Internal compiler error: invalid destination count %u for UDIV.", -+ "Internal compiler error: invalid destination count %zu for UDIV.", - udiv->dst_count); - return VKD3D_ERROR; - } -@@ -1321,7 +1325,7 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog - { - vkd3d_shader_error(ctx->message_context, &sincos->location, - VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, -- "Internal compiler error: invalid destination count %u for SINCOS.", -+ "Internal compiler error: invalid destination count %zu for SINCOS.", - sincos->dst_count); - return VKD3D_ERROR; - } -@@ -1497,6 +1501,34 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, - return VKD3D_OK; - } - -+static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, -+ struct vkd3d_shader_instruction *texldl) -+{ -+ unsigned int idx = texldl->src[1].reg.idx[0].offset; -+ enum vkd3d_shader_swizzle_component w; -+ struct vkd3d_shader_src_param *srcs; -+ -+ VKD3D_ASSERT(texldl->src[1].reg.idx_count == 1); -+ VKD3D_ASSERT(!texldl->src[1].reg.idx[0].rel_addr); -+ -+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 4))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ srcs[0] = texldl->src[0]; -+ vsir_src_param_init_resource(&srcs[1], idx, idx); -+ vsir_src_param_init_sampler(&srcs[2], idx, idx); -+ -+ texldl->opcode = VSIR_OP_SAMPLE_LOD; -+ texldl->src = srcs; -+ texldl->src_count = 4; -+ -+ w = vsir_swizzle_get_component(srcs[0].swizzle, 3); -+ srcs[3] = texldl->src[0]; -+ srcs[3].swizzle = vkd3d_shader_create_swizzle(w, w, w, w); -+ -+ return VKD3D_OK; -+} -+ - static enum vkd3d_result vsir_program_lower_dcl_input(struct vsir_program *program, - struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) - { -@@ -1668,6 +1700,11 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - return ret; - break; - -+ case VSIR_OP_TEXLDL: -+ if ((ret = vsir_program_lower_texldl(program, ins)) < 0) -+ return ret; -+ break; -+ - case VSIR_OP_TEXBEM: - case VSIR_OP_TEXBEML: - case VSIR_OP_TEXCOORD: -@@ -1675,7 +1712,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - case VSIR_OP_TEXDEPTH: - case VSIR_OP_TEXDP3: - case VSIR_OP_TEXDP3TEX: -- case VSIR_OP_TEXLDL: - case VSIR_OP_TEXM3x2PAD: - case VSIR_OP_TEXM3x2TEX: - case VSIR_OP_TEXM3x3DIFF: -@@ -9321,7 +9357,7 @@ static void vsir_validate_label_register(struct validation_context *ctx, - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, - "Invalid precision %#x for a LABEL register.", reg->precision); - -- if (reg->data_type != VKD3D_DATA_UNUSED) -+ if (reg->data_type != VSIR_DATA_UNUSED) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a LABEL register.", reg->data_type); - -@@ -9400,7 +9436,7 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, - "Invalid precision %#x for a SAMPLER register.", reg->precision); - -- if (reg->data_type != VKD3D_DATA_UNUSED) -+ if (reg->data_type != VSIR_DATA_UNUSED) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a SAMPLER register.", reg->data_type); - -@@ -9426,7 +9462,7 @@ static void vsir_validate_resource_register(struct validation_context *ctx, - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, - "Invalid precision %#x for a RESOURCE register.", reg->precision); - -- if (reg->data_type != VKD3D_DATA_UNUSED) -+ if (reg->data_type != VSIR_DATA_UNUSED) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a RESOURCE register.", reg->data_type); - -@@ -9452,7 +9488,7 @@ static void vsir_validate_uav_register(struct validation_context *ctx, - "Invalid precision %#x for a UAV register.", - reg->precision); - -- if (reg->data_type != VKD3D_DATA_UNUSED) -+ if (reg->data_type != VSIR_DATA_UNUSED) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a UAV register.", - reg->data_type); -@@ -9988,7 +10024,7 @@ static void vsir_validate_dst_count(struct validation_context *ctx, - { - if (instruction->dst_count != count) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, -- "Invalid destination parameter count %u for instruction \"%s\" (%#x); expected %u.", -+ "Invalid destination parameter count %zu for instruction \"%s\" (%#x); expected %u.", - instruction->dst_count, vsir_opcode_get_name(instruction->opcode, ""), - instruction->opcode, count); - } -@@ -9998,7 +10034,7 @@ static void vsir_validate_src_count(struct validation_context *ctx, - { - if (instruction->src_count != count) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, -- "Invalid source parameter count %u for instruction \"%s\" (%#x); expected %u.", -+ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected %u.", - instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), - instruction->opcode, count); - } -@@ -10009,7 +10045,7 @@ static bool vsir_validate_src_min_count(struct validation_context *ctx, - if (instruction->src_count < count) - { - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, -- "Invalid source parameter count %u for instruction \"%s\" (%#x); expected at least %u.", -+ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected at least %u.", - instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), - instruction->opcode, count); - return false; -@@ -10024,7 +10060,7 @@ static bool vsir_validate_src_max_count(struct validation_context *ctx, - if (instruction->src_count > count) - { - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, -- "Invalid source parameter count %u for instruction \"%s\" (%#x); expected at most %u.", -+ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected at most %u.", - instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), - instruction->opcode, count); - return false; -@@ -10484,7 +10520,7 @@ static void vsir_validate_descriptors(struct validation_context *ctx) - if (descriptor->resource_data_type >= VSIR_DATA_TYPE_COUNT) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Descriptor %u has invalid resource data type %#x.", i, descriptor->resource_data_type); -- else if ((descriptor->resource_data_type == VKD3D_DATA_UNUSED) -+ else if ((descriptor->resource_data_type == VSIR_DATA_UNUSED) - != (descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Descriptor %u has invalid resource data type %#x for descriptor type %#x.", -@@ -10653,7 +10689,7 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context - { - static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_BOOL] = true, -+ [VSIR_DATA_BOOL] = true, - [VSIR_DATA_I32] = true, - [VSIR_DATA_U32] = true, - [VSIR_DATA_U64] = true, -@@ -10673,7 +10709,7 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, - - dst_data_type = instruction->dst[0].reg.data_type; - -- if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VKD3D_DATA_BOOL) -+ if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VSIR_DATA_BOOL) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for result of comparison operation \"%s\" (%#x).", - dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -@@ -11326,7 +11362,7 @@ static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3 - { - static const bool src_types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_BOOL] = true, -+ [VSIR_DATA_BOOL] = true, - [VSIR_DATA_I32] = true, - [VSIR_DATA_U32] = true, - [VSIR_DATA_U64] = true, -@@ -11345,7 +11381,7 @@ static void vsir_validate_itoi(struct validation_context *ctx, const struct vkd3 - { - static const bool types[VSIR_DATA_TYPE_COUNT] = - { -- [VKD3D_DATA_BOOL] = true, -+ [VSIR_DATA_BOOL] = true, - [VSIR_DATA_I32] = true, - [VSIR_DATA_U32] = true, - [VSIR_DATA_U64] = true, -@@ -11389,7 +11425,7 @@ static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d - - if (instruction->src_count % 2 != 0) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, -- "Invalid source count %u for a PHI instruction, it must be an even number.", -+ "Invalid source count %zu for a PHI instruction, it must be an even number.", - instruction->src_count); - incoming_count = instruction->src_count / 2; - -@@ -11471,7 +11507,7 @@ static void vsir_validate_switch_monolithic(struct validation_context *ctx, - - if (instruction->src_count % 2 != 1) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, -- "Invalid source count %u for a monolithic SWITCH instruction, it must be an odd number.", -+ "Invalid source count %zu for a monolithic SWITCH instruction, it must be an odd number.", - instruction->src_count); - - if (!vsir_register_is_label(&instruction->src[1].reg)) -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index ccfce0f4591..d95b95f9738 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -138,8 +138,8 @@ static void msl_print_resource_datatype(struct msl_generator *gen, - switch (data_type) - { - case VSIR_DATA_F32: -- case VKD3D_DATA_UNORM: -- case VKD3D_DATA_SNORM: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: - vkd3d_string_buffer_printf(buffer, "float"); - break; - case VSIR_DATA_I32: -@@ -527,7 +527,7 @@ static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_genera - { - bool write_cast = false; - -- if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) -+ if (dst_data_type == VSIR_DATA_UNORM || dst_data_type == VSIR_DATA_SNORM) - dst_data_type = VSIR_DATA_F32; - - switch (src_data_type) -@@ -1320,8 +1320,8 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - "Internal compiler error: Unhandled data type %#x.", data_type); - /* fall through */ - case VSIR_DATA_F32: -- case VKD3D_DATA_UNORM: -- case VKD3D_DATA_SNORM: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: - vkd3d_string_buffer_printf(image_data, "float4("); - break; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index d99c7ee27ff..2e6d0c786d0 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -7588,7 +7588,7 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t val_id; - -- VKD3D_ASSERT(src->reg.data_type == VKD3D_DATA_BOOL && dst->reg.data_type != VKD3D_DATA_BOOL); -+ VKD3D_ASSERT(src->reg.data_type == VSIR_DATA_BOOL && dst->reg.data_type != VSIR_DATA_BOOL); - - val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); - if (dst->reg.data_type == VSIR_DATA_F16 || dst->reg.data_type == VSIR_DATA_F32) -@@ -7639,9 +7639,9 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil - return VKD3D_ERROR_INVALID_SHADER; - } - -- if (src->reg.data_type == VKD3D_DATA_BOOL) -+ if (src->reg.data_type == VSIR_DATA_BOOL) - { -- if (dst->reg.data_type == VKD3D_DATA_BOOL) -+ if (dst->reg.data_type == VSIR_DATA_BOOL) - { - /* VSIR supports logic ops AND/OR/XOR on bool values. */ - op = spirv_compiler_map_logical_instruction(instruction); -@@ -7955,7 +7955,7 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, - component_count = vsir_write_mask_component_count(dst->write_mask); - type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); - -- if (src[0].reg.data_type != VKD3D_DATA_BOOL) -+ if (src[0].reg.data_type != VSIR_DATA_BOOL) - { - if (instruction->opcode == VSIR_OP_CMP) - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, -@@ -8398,7 +8398,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co - result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - op, type_id, src0_id, src1_id); - -- if (dst->reg.data_type != VKD3D_DATA_BOOL) -+ if (dst->reg.data_type != VSIR_DATA_BOOL) - result_id = spirv_compiler_emit_bool_to_int(compiler, component_count, result_id, true); - spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, result_id); - } -@@ -8579,7 +8579,7 @@ static void spirv_compiler_emit_discard(struct spirv_compiler *compiler, - * a mismatch between the VSIR structure and the SPIR-V one, which would cause problems if - * structurisation is necessary. Therefore we emit it as a function call. */ - condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); -- if (src->reg.data_type != VKD3D_DATA_BOOL) -+ if (src->reg.data_type != VSIR_DATA_BOOL) - condition_id = spirv_compiler_emit_int_to_bool(compiler, - instruction->flags, src->reg.data_type, 1, condition_id); - else if (instruction->flags & VKD3D_SHADER_CONDITIONAL_OP_Z) -@@ -8652,7 +8652,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, - if (instruction->src_count == 3) - spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset); - else -- ERR("Invalid branch with %u sources.\n", instruction->src_count); -+ ERR("Invalid branch with %zu sources.\n", instruction->src_count); - } - vkd3d_spirv_build_op_branch(builder, spirv_compiler_get_label_id(compiler, src[0].reg.idx[0].offset)); - return; -@@ -8666,7 +8666,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, - } - - condition_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); -- if (src[0].reg.data_type != VKD3D_DATA_BOOL) -+ if (src[0].reg.data_type != VSIR_DATA_BOOL) - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id); - /* Emit the merge immediately before the branch instruction. */ -@@ -8674,7 +8674,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, - spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset, - (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0); - else -- ERR("Invalid branch with %u sources.\n", instruction->src_count); -+ ERR("Invalid branch with %zu sources.\n", instruction->src_count); - vkd3d_spirv_build_op_branch_conditional(builder, condition_id, - spirv_compiler_get_label_id(compiler, src[1].reg.idx[0].offset), - spirv_compiler_get_label_id(compiler, src[2].reg.idx[0].offset)); -@@ -9922,16 +9922,20 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, - static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) - { -+ enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_UINT; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_dst_param *dst = instruction->dst; - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, lod_id, val_id, miplevel_count_id; -- enum vkd3d_shader_component_type component_type; - uint32_t constituents[VKD3D_VEC4_SIZE]; - unsigned int i, size_component_count; - struct vkd3d_shader_image image; - bool supports_mipmaps; - -+ if (instruction->flags & ~VKD3DSI_RESINFO_UINT) -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled resinfo flags %#x.\n", instruction->flags & ~VKD3DSI_RESINFO_UINT); -+ - vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); - - spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); -@@ -9963,21 +9967,10 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_composite_construct(builder, - type_id, constituents, i + 2); - -- component_type = VKD3D_SHADER_COMPONENT_FLOAT; -- -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -- if (instruction->flags == VKD3DSI_RESINFO_UINT) -- { -- /* SSA registers must match the specified result type. */ -- if (!register_is_ssa(&dst->reg)) -- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -- else -- component_type = VKD3D_SHADER_COMPONENT_UINT; -- } -- else -+ if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) - { -- if (instruction->flags) -- FIXME("Unhandled flags %#x.\n", instruction->flags); -+ component_type = VKD3D_SHADER_COMPONENT_FLOAT; -+ type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); - } - val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, -@@ -10013,6 +10006,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co - static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) - { -+ enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_UINT; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_dst_param *dst = instruction->dst; - const struct vkd3d_shader_src_param *src = instruction->src; -@@ -10020,6 +10014,10 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, - uint32_t type_id, val_id; - unsigned int i; - -+ if (instruction->flags & ~VKD3DSI_SAMPLE_INFO_UINT) -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled sample info flags %#x.\n", instruction->flags & ~VKD3DSI_SAMPLE_INFO_UINT); -+ - val_id = spirv_compiler_emit_query_sample_count(compiler, src); - - constituents[0] = val_id; -@@ -10028,20 +10026,14 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -- if (instruction->flags == VKD3DSI_SAMPLE_INFO_UINT) -+ if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) - { -- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -- } -- else -- { -- if (instruction->flags) -- FIXME("Unhandled flags %#x.\n", instruction->flags); -+ component_type = VKD3D_SHADER_COMPONENT_FLOAT; -+ type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); - } -- - val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, -- VKD3D_SHADER_COMPONENT_FLOAT, src->swizzle, dst->write_mask); -+ component_type, src->swizzle, dst->write_mask); - - spirv_compiler_emit_store_dst(compiler, dst, val_id); - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 8acd7bc0db5..2175298a0db 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -751,15 +751,15 @@ static const enum vkd3d_shader_resource_type resource_type_table[] = - static const enum vsir_data_type data_type_table[] = - { - /* 0 */ VSIR_DATA_F32, -- /* VKD3D_SM4_DATA_UNORM */ VKD3D_DATA_UNORM, -- /* VKD3D_SM4_DATA_SNORM */ VKD3D_DATA_SNORM, -+ /* VKD3D_SM4_DATA_UNORM */ VSIR_DATA_UNORM, -+ /* VKD3D_SM4_DATA_SNORM */ VSIR_DATA_SNORM, - /* VKD3D_SM4_DATA_INT */ VSIR_DATA_I32, - /* VKD3D_SM4_DATA_UINT */ VSIR_DATA_U32, - /* VKD3D_SM4_DATA_FLOAT */ VSIR_DATA_F32, -- /* VKD3D_SM4_DATA_MIXED */ VKD3D_DATA_MIXED, -+ /* VKD3D_SM4_DATA_MIXED */ VSIR_DATA_MIXED, - /* VKD3D_SM4_DATA_DOUBLE */ VSIR_DATA_F64, -- /* VKD3D_SM4_DATA_CONTINUED */ VKD3D_DATA_CONTINUED, -- /* VKD3D_SM4_DATA_UNUSED */ VKD3D_DATA_UNUSED, -+ /* VKD3D_SM4_DATA_CONTINUED */ VSIR_DATA_CONTINUED, -+ /* VKD3D_SM4_DATA_UNUSED */ VSIR_DATA_UNUSED, - }; - - static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) -@@ -895,7 +895,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u - >> VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; - } - -- reg_data_type = VKD3D_DATA_UNUSED; -+ reg_data_type = VSIR_DATA_UNUSED; - shader_sm4_read_dst_param(priv, &tokens, end, reg_data_type, &semantic->resource.reg); - shader_sm4_set_descriptor_register_range(priv, &semantic->resource.reg.reg, &semantic->resource.range); - -@@ -957,7 +957,7 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins, ui - ins->flags = (opcode_token & VKD3D_SM4_SAMPLER_MODE_MASK) >> VKD3D_SM4_SAMPLER_MODE_SHIFT; - if (ins->flags & ~VKD3D_SM4_SAMPLER_COMPARISON) - FIXME("Unhandled sampler mode %#x.\n", ins->flags); -- shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &ins->declaration.sampler.src); -+ shader_sm4_read_src_param(priv, &tokens, end, VSIR_DATA_UNUSED, &ins->declaration.sampler.src); - shader_sm4_set_descriptor_register_range(priv, &ins->declaration.sampler.src.reg, &ins->declaration.sampler.range); - shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.range.space); - } -@@ -979,8 +979,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins - unsigned int *io_masks; - uint32_t write_mask; - -- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, -- &index_range->dst); -+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_OPAQUE, &index_range->dst); - index_range->register_count = *tokens; - - register_idx = index_range->dst.reg.idx[index_range->dst.reg.idx_count - 1].offset; -@@ -1228,7 +1227,7 @@ static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t - const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { - ins->src[0].reg.u.fp_body_idx = *tokens++; -- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &ins->src[0]); -+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_OPAQUE, &ins->src[0]); - } - - static void shader_sm5_read_dcl_function_body(struct vkd3d_shader_instruction *ins, uint32_t opcode, -@@ -1315,7 +1314,7 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins, ui - struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource; - const uint32_t *end = &tokens[token_count]; - -- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); -+ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); - shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); - ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT; - shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.range.space); -@@ -1327,7 +1326,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction * - struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource; - const uint32_t *end = &tokens[token_count]; - -- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); -+ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); - shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); - ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT; - resource->byte_stride = *tokens++; -@@ -1364,7 +1363,7 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct - struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource; - const uint32_t *end = &tokens[token_count]; - -- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); -+ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); - shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); - resource->byte_stride = *tokens++; - if (resource->byte_stride % 4) -@@ -1378,7 +1377,7 @@ static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *in - struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource; - const uint32_t *end = &tokens[token_count]; - -- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); -+ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); - shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); - shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.range.space); - } -@@ -1434,7 +1433,7 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) - * f -> VSIR_DATA_F32 - * i -> VSIR_DATA_I32 - * u -> VSIR_DATA_U32 -- * O -> VKD3D_DATA_OPAQUE -+ * O -> VSIR_DATA_OPAQUE - * R -> VKD3D_DATA_RESOURCE - * S -> VKD3D_DATA_SAMPLER - * U -> VKD3D_DATA_UAV -@@ -1998,9 +1997,9 @@ static enum vsir_data_type map_data_type(char t) - case 'u': - return VSIR_DATA_U32; - case 'O': -- return VKD3D_DATA_OPAQUE; -+ return VSIR_DATA_OPAQUE; - case '*': -- return VKD3D_DATA_UNUSED; -+ return VSIR_DATA_UNUSED; - default: - ERR("Invalid data type '%c'.\n", t); - return VSIR_DATA_F32; -@@ -2743,6 +2742,10 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str - } - } - -+ if ((ins->opcode == VSIR_OP_SAMPLE_INFO && ins->flags & VKD3DSI_SAMPLE_INFO_UINT) -+ || (ins->opcode == VSIR_OP_RESINFO && ins->flags & VKD3DSI_RESINFO_UINT)) -+ ins->dst[0].reg.data_type = VSIR_DATA_U32; -+ - return; - - fail: -@@ -4087,14 +4090,14 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_ - - if (ins->dst_count != dst_count) - { -- ERR("Invalid destination count %u for vsir instruction %#x (expected %u).\n", -+ ERR("Invalid destination count %zu for vsir instruction %#x (expected %u).\n", - ins->dst_count, ins->opcode, dst_count); - tpf->result = VKD3D_ERROR_INVALID_SHADER; - return; - } - if (ins->src_count != src_count) - { -- ERR("Invalid source count %u for vsir instruction %#x (expected %u).\n", -+ ERR("Invalid source count %zu for vsir instruction %#x (expected %u).\n", - ins->src_count, ins->opcode, src_count); - tpf->result = VKD3D_ERROR_INVALID_SHADER; - return; -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 9c615c116e9..a3c00af5d8b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -87,7 +87,7 @@ void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t siz - - static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int rc) - { -- unsigned int new_buffer_size = rc >= 0 ? buffer->content_size + rc + 1 : buffer->buffer_size * 2; -+ size_t new_buffer_size = rc >= 0 ? buffer->content_size + rc + 1 : buffer->buffer_size * 2; - - if (!vkd3d_array_reserve((void **)&buffer->buffer, &buffer->buffer_size, new_buffer_size, 1)) - { -@@ -100,7 +100,7 @@ static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int r - - int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args) - { -- unsigned int rem; -+ size_t rem; - va_list a; - int rc; - -@@ -135,7 +135,7 @@ int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *f - - int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f) - { -- unsigned int idx = buffer->content_size + 1; -+ size_t idx = buffer->content_size + 1; - int ret; - - if (!(ret = vkd3d_string_buffer_printf(buffer, "%.8e", f)) && isfinite(f)) -@@ -150,7 +150,7 @@ int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f) - - int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d) - { -- unsigned int idx = buffer->content_size + 1; -+ size_t idx = buffer->content_size + 1; - int ret; - - if (!(ret = vkd3d_string_buffer_printf(buffer, "%.16e", d)) && isfinite(d)) -@@ -1132,7 +1132,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte - struct vkd3d_shader_descriptor_info1 *d; - - if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, -- &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED))) -+ &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) - return; - - if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) -@@ -1143,7 +1143,7 @@ static void vkd3d_shader_scan_combined_sampler_declaration( - struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) - { - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, -- &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED); -+ &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, - &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32); - } -@@ -1526,16 +1526,6 @@ static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_t - { - switch (data_type) - { -- case VKD3D_DATA_UNORM: -- return VKD3D_SHADER_RESOURCE_DATA_UNORM; -- case VKD3D_DATA_SNORM: -- return VKD3D_SHADER_RESOURCE_DATA_SNORM; -- case VKD3D_DATA_MIXED: -- return VKD3D_SHADER_RESOURCE_DATA_MIXED; -- case VKD3D_DATA_CONTINUED: -- return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; -- case VKD3D_DATA_UNUSED: -- return VKD3D_SHADER_RESOURCE_DATA_NONE; - case VSIR_DATA_F32: - return VKD3D_SHADER_RESOURCE_DATA_FLOAT; - case VSIR_DATA_F64: -@@ -1544,6 +1534,16 @@ static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_t - return VKD3D_SHADER_RESOURCE_DATA_INT; - case VSIR_DATA_U32: - return VKD3D_SHADER_RESOURCE_DATA_UINT; -+ case VSIR_DATA_SNORM: -+ return VKD3D_SHADER_RESOURCE_DATA_SNORM; -+ case VSIR_DATA_UNORM: -+ return VKD3D_SHADER_RESOURCE_DATA_UNORM; -+ case VSIR_DATA_MIXED: -+ return VKD3D_SHADER_RESOURCE_DATA_MIXED; -+ case VSIR_DATA_CONTINUED: -+ return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; -+ case VSIR_DATA_UNUSED: -+ return VKD3D_SHADER_RESOURCE_DATA_NONE; - default: - ERR("Invalid resource data type %#x.\n", data_type); - return VKD3D_SHADER_RESOURCE_DATA_FLOAT; -@@ -1785,6 +1785,7 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, - const struct shader_dump_data *dump_data, struct vkd3d_shader_code *out, - struct vkd3d_shader_message_context *message_context) - { -+ struct vkd3d_shader_compile_info preprocessed_info; - struct vkd3d_shader_code preprocessed; - int ret; - -@@ -1793,7 +1794,9 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, - - vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC); - -- ret = hlsl_compile_shader(&preprocessed, compile_info, out, message_context); -+ preprocessed_info = *compile_info; -+ preprocessed_info.source = preprocessed; -+ ret = hlsl_compile_shader(&preprocessed_info, message_context, out); - - vkd3d_shader_free_shader_code(&preprocessed); - return ret; -@@ -2187,7 +2190,7 @@ static struct vkd3d_shader_param_node *shader_param_allocator_node_create( - } - - static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, -- unsigned int count, unsigned int stride) -+ size_t count, size_t stride) - { - allocator->count = max(count, MAX_REG_OUTPUT); - allocator->stride = stride; -@@ -2208,7 +2211,7 @@ static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator * - } - } - --void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count) -+void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) - { - void *params; - -@@ -2234,7 +2237,7 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, - return params; - } - --bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve) -+bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve) - { - memset(instructions, 0, sizeof(*instructions)); - /* Size the parameter initial allocations so they are large enough for most shaders. The -@@ -2245,7 +2248,7 @@ bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instru - return shader_instruction_array_reserve(instructions, reserve); - } - --bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve) -+bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve) - { - if (!vkd3d_array_reserve((void **)&instructions->elements, &instructions->capacity, reserve, - sizeof(*instructions->elements))) -@@ -2257,7 +2260,7 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins - } - - bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, -- unsigned int idx, unsigned int count) -+ size_t idx, size_t count) - { - VKD3D_ASSERT(idx <= instructions->count); - -@@ -2285,7 +2288,7 @@ bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *ins - - static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( - struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, -- unsigned int count); -+ size_t count); - - static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, - struct vkd3d_shader_instruction_array *instructions) -@@ -2306,10 +2309,10 @@ static bool shader_register_clone_relative_addresses(struct vkd3d_shader_registe - - static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( - struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_dst_param *params, -- unsigned int count) -+ size_t count) - { - struct vkd3d_shader_dst_param *dst_params; -- unsigned int i; -+ size_t i; - - if (!(dst_params = shader_dst_param_allocator_get(&instructions->dst_params, count))) - return NULL; -@@ -2326,10 +2329,10 @@ static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( - - static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( - struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, -- unsigned int count) -+ size_t count) - { - struct vkd3d_shader_src_param *src_params; -- unsigned int i; -+ size_t i; - - if (!(src_params = shader_src_param_allocator_get(&instructions->src_params, count))) - return NULL; -@@ -2347,7 +2350,7 @@ static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( - /* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the - * destination is in use. This seems like a reasonable requirement given how this is currently used. */ - bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, -- unsigned int dst, unsigned int src) -+ size_t dst, size_t src) - { - struct vkd3d_shader_instruction *ins = &instructions->elements[dst]; - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 42f3c42033f..a0d7faaa407 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -710,13 +710,7 @@ enum vkd3d_shader_register_precision - - enum vsir_data_type - { -- VKD3D_DATA_UNORM, -- VKD3D_DATA_SNORM, -- VKD3D_DATA_OPAQUE, -- VKD3D_DATA_MIXED, -- VKD3D_DATA_CONTINUED, -- VKD3D_DATA_UNUSED, -- VKD3D_DATA_BOOL, -+ VSIR_DATA_BOOL, - - VSIR_DATA_F16, - VSIR_DATA_F32, -@@ -729,6 +723,14 @@ enum vsir_data_type - VSIR_DATA_U32, - VSIR_DATA_U64, - -+ VSIR_DATA_SNORM, -+ VSIR_DATA_UNORM, -+ -+ VSIR_DATA_OPAQUE, -+ VSIR_DATA_MIXED, -+ VSIR_DATA_CONTINUED, -+ VSIR_DATA_UNUSED, -+ - VSIR_DATA_TYPE_COUNT, - }; - -@@ -740,7 +742,7 @@ static inline bool data_type_is_integer(enum vsir_data_type data_type) - - static inline bool data_type_is_bool(enum vsir_data_type data_type) - { -- return data_type == VKD3D_DATA_BOOL; -+ return data_type == VSIR_DATA_BOOL; - } - - static inline bool data_type_is_floating_point(enum vsir_data_type data_type) -@@ -1281,8 +1283,8 @@ struct vkd3d_shader_instruction - struct vkd3d_shader_location location; - enum vkd3d_shader_opcode opcode; - uint32_t flags; -- unsigned int dst_count; -- unsigned int src_count; -+ size_t dst_count; -+ size_t src_count; - struct vkd3d_shader_dst_param *dst; - struct vkd3d_shader_src_param *src; - struct vkd3d_shader_texel_offset texel_offset; -@@ -1377,22 +1379,22 @@ struct vkd3d_shader_param_allocator - { - struct vkd3d_shader_param_node *head; - struct vkd3d_shader_param_node *current; -- unsigned int count; -- unsigned int stride; -- unsigned int index; -+ size_t count; -+ size_t stride; -+ size_t index; - }; - --void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count); -+void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count); - - static inline struct vkd3d_shader_src_param *shader_src_param_allocator_get( -- struct vkd3d_shader_param_allocator *allocator, unsigned int count) -+ struct vkd3d_shader_param_allocator *allocator, size_t count) - { - VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_src_param)); - return shader_param_allocator_get(allocator, count); - } - - static inline struct vkd3d_shader_dst_param *shader_dst_param_allocator_get( -- struct vkd3d_shader_param_allocator *allocator, unsigned int count) -+ struct vkd3d_shader_param_allocator *allocator, size_t count) - { - VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_dst_param)); - return shader_param_allocator_get(allocator, count); -@@ -1413,14 +1415,14 @@ struct vkd3d_shader_instruction_array - struct vkd3d_shader_src_param *outpointid_param; - }; - --bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); --bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); -+bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve); -+bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve); - bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, -- unsigned int idx, unsigned int count); -+ size_t idx, size_t count); - bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, - struct vkd3d_shader_immediate_constant_buffer *icb); - bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, -- unsigned int dst, unsigned int src); -+ size_t dst, size_t src); - void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); - - struct vsir_program_iterator -@@ -1463,7 +1465,7 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_next( - /* When insertion takes place, argument `it' is updated to point to the same - * instruction as before the insertion, but all other iterators and pointers - * to the same container are invalidated and cannot be used any more. */ --static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterator *it, unsigned int count) -+static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterator *it, size_t count) - { - return shader_instruction_array_insert_at(it->array, it->idx + 1, count); - } -@@ -1797,17 +1799,19 @@ void vkd3d_compute_md5(const void *dxbc, size_t size, uint32_t checksum[4], enum - int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); - --int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, -- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); -+int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); - - static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) - { - switch (data_type) - { -+ case VSIR_DATA_BOOL: -+ return VKD3D_SHADER_COMPONENT_BOOL; - case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */ - case VSIR_DATA_F32: -- case VKD3D_DATA_UNORM: -- case VKD3D_DATA_SNORM: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: - return VKD3D_SHADER_COMPONENT_FLOAT; - case VSIR_DATA_F64: - return VKD3D_SHADER_COMPONENT_DOUBLE; -@@ -1818,12 +1822,10 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty - return VKD3D_SHADER_COMPONENT_UINT; - case VSIR_DATA_U64: - return VKD3D_SHADER_COMPONENT_UINT64; -- case VKD3D_DATA_BOOL: -- return VKD3D_SHADER_COMPONENT_BOOL; - default: - FIXME("Unhandled data type %#x.\n", data_type); - /* fall-through */ -- case VKD3D_DATA_MIXED: -+ case VSIR_DATA_MIXED: - return VKD3D_SHADER_COMPONENT_UINT; - } - } --- -2.50.1 - diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch deleted file mode 100644 index 5a4f8b9c..00000000 --- a/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f6b63c8ce9c20192debbe97b2e9673e382842b89 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 25 Jul 2025 07:41:13 +1000 -Subject: [PATCH] Updated vkd3d to b3e367b099cb65d79c5b0044134a02e7e9c285a5. - ---- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 2175298a0db..bdb2083e09a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -1434,9 +1434,7 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) - * i -> VSIR_DATA_I32 - * u -> VSIR_DATA_U32 - * O -> VSIR_DATA_OPAQUE -- * R -> VKD3D_DATA_RESOURCE -- * S -> VKD3D_DATA_SAMPLER -- * U -> VKD3D_DATA_UAV -+ * * -> VSIR_DATA_UNUSED - */ - static const struct vkd3d_sm4_opcode_info opcode_table[] = - { --- -2.50.1 - diff --git a/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch b/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch deleted file mode 100644 index 569a1d90..00000000 --- a/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch +++ /dev/null @@ -1,823 +0,0 @@ -From 962d21a69b8f5284ed0f4285b6ad303a324ea018 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 29 Jul 2025 18:36:33 +1000 -Subject: [PATCH] Updated vkd3d to f7866df201e491aa6033cc4618ab21cedd12a2e2. - ---- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 4 + - libs/vkd3d/libs/vkd3d-shader/fx.c | 36 ++++++- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 43 ++------- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 16 ++-- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 94 ++++++------------- - libs/vkd3d/libs/vkd3d-shader/ir.c | 86 ++++++++++++++++- - libs/vkd3d/libs/vkd3d-shader/msl.c | 74 +++++++++++---- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 23 ++++- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 22 ++++- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 6 +- - libs/vkd3d/libs/vkd3d/device.c | 7 +- - 11 files changed, 274 insertions(+), 137 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 66e3c1ecd36..19e9f54edda 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -6291,6 +6291,10 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in - return; - } - -+ /* DXIL doesn't know about signedness, but vsir expects the offset to be signed. */ -+ if (extended_offset) -+ offset.data_type = VSIR_DATA_I32; -+ - ins = state->ins; - if (op == DX_TEXTURE_GATHER) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c -index e5a792583b3..5b776108c95 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/fx.c -+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c -@@ -20,6 +20,8 @@ - - #include "hlsl.h" - -+#define TAG_FX20 0x46580200 -+ - static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uint32_t value) - { - return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value)); -@@ -4333,6 +4335,32 @@ static void fx_parse_fx_2_array_selector(struct fx_parser *parser) - } - } - -+static void fx_2_parse_code_blob(struct fx_parser *parser, const uint32_t *blob, uint32_t size) -+{ -+ uint32_t tag; -+ -+ if (size < sizeof(tag)) -+ return; -+ -+ tag = *blob; -+ -+ if (tag == TAG_FX20) -+ { -+ fx_2_parse_fxlvm_expression(parser, blob, size); -+ return; -+ } -+ -+ tag >>= 16; -+ if (tag == 0xfffe || tag == 0xffff) -+ { -+ fx_parse_shader_blob(parser, VKD3D_SHADER_SOURCE_D3D_BYTECODE, blob, size); -+ vkd3d_string_buffer_printf(&parser->buffer, "\n"); -+ return; -+ } -+ -+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Unrecognized code blob type, tag 0x%08x.", *blob); -+} -+ - static void fx_parse_fx_2_complex_state(struct fx_parser *parser) - { - struct -@@ -4374,7 +4402,7 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) - size = fx_parser_read_u32(parser); - data = fx_parser_get_ptr(parser, size); - vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size); -- fx_2_parse_fxlvm_expression(parser, data, size); -+ fx_2_parse_code_blob(parser, data, size); - fx_parser_skip(parser, align(size, 4)); - } - else -@@ -5164,6 +5192,12 @@ static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t - code.ptr = find_d3dbc_section(blob, count, TAG_FXLC, &count); - code.end = code.ptr + count; - -+ if (!code.ptr) -+ { -+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to locate expression code section."); -+ return; -+ } -+ - fx_parse_fxlvm_expression(parser, &code); - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index e2c68d4afb5..a089651eaf7 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -5016,9 +5016,12 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, - { - enum vkd3d_shader_target_type target_type = compile_info->target_type; - const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; -+ uint64_t config_flags = vkd3d_shader_init_config_flags(); - struct hlsl_ir_function_decl *decl, *entry_func = NULL; -+ struct vkd3d_shader_code reflection_data = {0}; - const struct hlsl_profile_info *profile; - struct hlsl_ir_function *func; -+ struct vsir_program program; - const char *entry_point; - struct hlsl_ctx ctx; - int ret; -@@ -5118,43 +5121,15 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, - return VKD3D_ERROR_INVALID_SHADER; - } - -- if (target_type == VKD3D_SHADER_TARGET_SPIRV_BINARY -- || target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT -- || target_type == VKD3D_SHADER_TARGET_GLSL -- || target_type == VKD3D_SHADER_TARGET_D3D_ASM) -+ if ((ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, &program, &reflection_data)) >= 0) - { -- uint64_t config_flags = vkd3d_shader_init_config_flags(); -- struct vkd3d_shader_compile_info info = *compile_info; -- struct vsir_program program; -- -- if (profile->major_version < 4) -- { -- if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0) -- goto done; -- info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE; -- ret = d3dbc_parse(&info, config_flags, message_context, &program); -- } -- else -- { -- if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0) -- goto done; -- info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; -- ret = tpf_parse(&info, config_flags, message_context, &program); -- } -- if (ret >= 0) -- { -- ret = vsir_program_compile(&program, config_flags, &info, out, message_context); -- vsir_program_cleanup(&program); -- } -- vkd3d_shader_free_shader_code(&info.source); -- } -- else -- { -- ret = hlsl_emit_bytecode(&ctx, entry_func, target_type, out); -+ vsir_program_trace(&program); -+ ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, message_context); -+ vkd3d_shader_free_shader_code(&reflection_data); -+ vsir_program_cleanup(&program); - } -- --done: - hlsl_ctx_cleanup(&ctx); -+ - return ret; - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 47cc361a48a..d899c33f8a2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -278,11 +278,12 @@ struct hlsl_struct_field - size_t name_bytecode_offset; - }; - --/* Information of the register(s) allocated for an instruction node or variable. -- * These values are initialized at the end of hlsl_emit_bytecode(), after the compilation passes, -- * just before writing the bytecode. -- * The type of register (register class) is implied from its use, so it is not stored in this -- * struct. */ -+/* Information about the register(s) allocated for an instruction node or -+ * variable. These values are initialised at the end of hlsl_emit_vsir(), -+ * after the compilation passes, as vsir starts being generated from HLSL IR. -+ * -+ * The type of register (register class) is implied by its usage, so it is not -+ * stored in this structure. */ - struct hlsl_reg - { - /* Register number of the first register allocated. */ -@@ -1625,9 +1626,10 @@ struct hlsl_state_block_entry *clone_stateblock_entry(struct hlsl_ctx *ctx, - - void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body); - void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body); --int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, -- enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); - int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out); -+int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, -+ struct hlsl_ir_function_decl *entry_func, struct vsir_program *program, -+ struct vkd3d_shader_code *reflection_data); - - bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len); - bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain); -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 8bfa157a12b..e3ca1b25eb9 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -9606,8 +9606,9 @@ static void sm1_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo - } - } - --static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, -- struct list *semantic_vars, struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) -+static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, -+ struct hlsl_ir_function_decl *func, struct list *semantic_vars, -+ struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) - { - struct vkd3d_shader_version version = {0}; - struct hlsl_block block; -@@ -9615,7 +9616,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - version.major = ctx->profile->major_version; - version.minor = ctx->profile->minor_version; - version.type = ctx->profile->type; -- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) -+ if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; -@@ -12339,7 +12340,8 @@ static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, - /* OBJECTIVE: Translate all the information from ctx and entry_func to the - * vsir_program, so it can be used as input to tpf_compile() without relying - * on ctx and entry_func. */ --static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, -+static void sm4_generate_vsir(struct hlsl_ctx *ctx, -+ const struct vkd3d_shader_compile_info *compile_info, struct hlsl_ir_function_decl *func, - struct list *semantic_vars, struct hlsl_block *body, struct list *patch_semantic_vars, - struct hlsl_block *patch_body, uint64_t config_flags, struct vsir_program *program) - { -@@ -12352,7 +12354,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - version.minor = ctx->profile->minor_version; - version.type = ctx->profile->type; - -- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) -+ if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; -@@ -13902,10 +13904,12 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v - validate_max_output_size(ctx, semantic_vars, output_reg_count, &entry_func->loc); - } - --int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, -- enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) -+int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, -+ struct hlsl_ir_function_decl *entry_func, struct vsir_program *program, -+ struct vkd3d_shader_code *reflection_data) - { - struct hlsl_block global_uniform_block, body, patch_body; -+ uint32_t config_flags = vkd3d_shader_init_config_flags(); - const struct hlsl_profile_info *profile = ctx->profile; - struct list semantic_vars, patch_semantic_vars; - struct hlsl_ir_var *var; -@@ -13976,65 +13980,29 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - if (ctx->result) - return ctx->result; - -- switch (target_type) -+ if (ctx->profile->major_version < 4) - { -- case VKD3D_SHADER_TARGET_D3D_BYTECODE: -- { -- uint32_t config_flags = vkd3d_shader_init_config_flags(); -- struct vkd3d_shader_code ctab = {0}; -- struct vsir_program program; -- int result; -- -- sm1_generate_ctab(ctx, &ctab); -- if (ctx->result) -- return ctx->result; -- -- sm1_generate_vsir(ctx, entry_func, &semantic_vars, &body, config_flags, &program); -- if (ctx->result) -- { -- vsir_program_cleanup(&program); -- vkd3d_shader_free_shader_code(&ctab); -- return ctx->result; -- } -- -- vsir_program_trace(&program); -- -- result = d3dbc_compile(&program, config_flags, NULL, &ctab, out, ctx->message_context); -- vsir_program_cleanup(&program); -- vkd3d_shader_free_shader_code(&ctab); -- return result; -- } -- -- case VKD3D_SHADER_TARGET_DXBC_TPF: -- { -- uint32_t config_flags = vkd3d_shader_init_config_flags(); -- struct vkd3d_shader_code rdef = {0}; -- struct vsir_program program; -- int result; -- -- sm4_generate_rdef(ctx, &rdef); -- if (ctx->result) -- return ctx->result; -- -- sm4_generate_vsir(ctx, entry_func, &semantic_vars, &body, -- &patch_semantic_vars, &patch_body, config_flags, &program); -- if (ctx->result) -- { -- vsir_program_cleanup(&program); -- vkd3d_shader_free_shader_code(&rdef); -- return ctx->result; -- } -+ sm1_generate_ctab(ctx, reflection_data); -+ if (ctx->result) -+ return ctx->result; - -- vsir_program_trace(&program); -+ sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program); -+ } -+ else -+ { -+ sm4_generate_rdef(ctx, reflection_data); -+ if (ctx->result) -+ return ctx->result; - -- result = tpf_compile(&program, config_flags, &rdef, out, ctx->message_context); -- vsir_program_cleanup(&program); -- vkd3d_shader_free_shader_code(&rdef); -- return result; -- } -+ sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, -+ &patch_semantic_vars, &patch_body, config_flags, program); -+ } - -- default: -- ERR("Unsupported shader target type %#x.\n", target_type); -- return VKD3D_ERROR_INVALID_ARGUMENT; -+ if (ctx->result) -+ { -+ vsir_program_cleanup(program); -+ vkd3d_shader_free_shader_code(reflection_data); - } -+ -+ return ctx->result; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 92580a6a2df..c3bcf9058e1 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -10800,6 +10800,38 @@ static void vsir_validate_cast_operation(struct validation_context *ctx, - dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - } - -+static void vsir_validate_shift_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ enum vsir_data_type data_type; -+ -+ static const bool types[] = -+ { -+ [VSIR_DATA_I32] = true, -+ [VSIR_DATA_U32] = true, -+ [VSIR_DATA_U64] = true, -+ }; -+ -+ data_type = instruction->dst[0].reg.data_type; -+ if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid destination data type %#x for shift operation \"%s\" (%#x).", -+ data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ -+ if (instruction->src[0].reg.data_type != data_type) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Data type %#x for source operand 0 doesn't match destination data type %#x " -+ "for shift operation \"%s\" (%#x).", -+ instruction->src[0].reg.data_type, data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ -+ data_type = instruction->src[1].reg.data_type; -+ if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid source operand 1 data type %#x for shift operation \"%s\" (%#x).", -+ data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+} -+ - static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) - { - size_t i; -@@ -11486,6 +11518,54 @@ static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d - ctx->inside_block = false; - } - -+static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; -+ -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid destination data type %#x for operation \"%s\" (%#x) with flags %#x.", dst_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode, instruction->flags); -+} -+ -+static void vsir_validate_sample_info(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; -+ -+ switch (dst_data_type) -+ { -+ case VSIR_DATA_F32: -+ case VSIR_DATA_U32: -+ if (!!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT) != (dst_data_type == VSIR_DATA_U32)) -+ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); -+ break; -+ -+ default: -+ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); -+ break; -+ } -+} -+ -+static void vsir_validate_resinfo(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; -+ -+ switch (dst_data_type) -+ { -+ case VSIR_DATA_F32: -+ case VSIR_DATA_U32: -+ if (!!(instruction->flags & VKD3DSI_RESINFO_UINT) != (dst_data_type == VSIR_DATA_U32)) -+ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); -+ break; -+ -+ default: -+ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); -+ break; -+ } -+} -+ - static void vsir_validate_switch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) - { - vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); -@@ -11629,8 +11709,8 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation}, - [VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation}, - [VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation}, -- [VSIR_OP_ISHL] = {1, 2, vsir_validate_integer_elementwise_operation}, -- [VSIR_OP_ISHR] = {1, 2, vsir_validate_integer_elementwise_operation}, -+ [VSIR_OP_ISHL] = {1, 2, vsir_validate_shift_operation}, -+ [VSIR_OP_ISHR] = {1, 2, vsir_validate_shift_operation}, - [VSIR_OP_ISINF] = {1, 1, vsir_validate_float_comparison_operation}, - [VSIR_OP_ISNAN] = {1, 1, vsir_validate_float_comparison_operation}, - [VSIR_OP_ITOF] = {1, 1, vsir_validate_itof}, -@@ -11653,9 +11733,11 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_PHI] = {1, ~0u, vsir_validate_phi}, - [VSIR_OP_RCP] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_REP] = {0, 1, vsir_validate_rep}, -+ [VSIR_OP_RESINFO] = {1, 2, vsir_validate_resinfo}, - [VSIR_OP_RET] = {0, 0, vsir_validate_ret}, - [VSIR_OP_ROUND_NE] = {1, 1, vsir_validate_float_elementwise_operation}, - [VSIR_OP_ROUND_NI] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_SAMPLE_INFO] = {1, 1, vsir_validate_sample_info}, - [VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch}, - [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, - }; -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index d95b95f9738..d07608bd26f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -18,6 +18,8 @@ - - #include "vkd3d_shader_private.h" - -+#define MAX_IO_REG_COUNT 32 -+ - enum msl_data_type - { - MSL_DATA_FLOAT, -@@ -481,7 +483,7 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu - "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; -+ return MSL_DATA_UNION; - - default: - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -946,10 +948,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - const struct vkd3d_shader_descriptor_info1 *descriptor; - const struct vkd3d_shader_descriptor_binding *binding; - enum vkd3d_shader_resource_type resource_type; -+ uint32_t coord_mask, write_mask_size; - struct vkd3d_string_buffer *read; - enum vsir_data_type data_type; - unsigned int srv_binding; -- uint32_t coord_mask; - struct msl_dst dst; - - if (vkd3d_shader_instruction_has_texel_offset(ins)) -@@ -1009,7 +1011,12 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - msl_dst_init(&dst, gen, ins, &ins->dst[0]); - read = vkd3d_string_buffer_get(&gen->string_buffers); - -- vkd3d_string_buffer_printf(read, "as_type("); -+ vkd3d_string_buffer_printf(read, "as_type<"); -+ msl_print_resource_datatype(gen, read, ins->dst[0].reg.data_type); -+ write_mask_size = vkd3d_popcount(ins->dst[0].write_mask); -+ if (write_mask_size != 1) -+ vkd3d_string_buffer_printf(read, "%u", write_mask_size); -+ vkd3d_string_buffer_printf(read, ">("); - msl_print_srv_name(read, gen, srv_binding, resource_type_info, data_type, false); - vkd3d_string_buffer_printf(read, ".read("); - msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VSIR_DATA_U32); -@@ -1026,8 +1033,9 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - else - msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32); - } -- vkd3d_string_buffer_printf(read, "))"); -+ vkd3d_string_buffer_printf(read, ")"); - msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask); -+ vkd3d_string_buffer_printf(read, ")"); - - msl_print_assignment(gen, &dst, "%s", read->buffer); - -@@ -1046,10 +1054,10 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - const struct vkd3d_shader_descriptor_info1 *d; - enum vkd3d_shader_resource_type resource_type; - unsigned int srv_binding, sampler_binding; -+ uint32_t coord_mask, write_mask_size; - struct vkd3d_string_buffer *sample; - enum vsir_data_type data_type; - unsigned int component_idx; -- uint32_t coord_mask; - struct msl_dst dst; - - bias = ins->opcode == VSIR_OP_SAMPLE_B; -@@ -1168,8 +1176,12 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - msl_dst_init(&dst, gen, ins, &ins->dst[0]); - sample = vkd3d_string_buffer_get(&gen->string_buffers); - -- if (ins->dst[0].reg.data_type == VSIR_DATA_U32) -- vkd3d_string_buffer_printf(sample, "as_type("); -+ vkd3d_string_buffer_printf(sample, "as_type<"); -+ msl_print_resource_datatype(gen, sample, ins->dst[0].reg.data_type); -+ write_mask_size = vkd3d_popcount(ins->dst[0].write_mask); -+ if (write_mask_size != 1) -+ vkd3d_string_buffer_printf(sample, "%u", write_mask_size); -+ vkd3d_string_buffer_printf(sample, ">("); - msl_print_srv_name(sample, gen, srv_binding, resource_type_info, data_type, compare); - if (gather && compare) - vkd3d_string_buffer_printf(sample, ".gather_compare("); -@@ -1238,10 +1250,9 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - vkd3d_string_buffer_printf(sample, ", component::%c", "xyzw"[component_idx]); - } - vkd3d_string_buffer_printf(sample, ")"); -- if (ins->dst[0].reg.data_type == VSIR_DATA_U32) -- vkd3d_string_buffer_printf(sample, ")"); - if (!compare || gather) - msl_print_swizzle(sample, resource->swizzle, ins->dst[0].write_mask); -+ vkd3d_string_buffer_printf(sample, ")"); - - msl_print_assignment(gen, &dst, "%s", sample->buffer); - -@@ -1402,8 +1413,9 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc - - static void msl_dcl_indexable_temp(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) - { -+ const char *type = ins->declaration.indexable_temp.component_count == 4 ? "vkd3d_vec4" : "vkd3d_scalar"; - msl_print_indent(gen->buffer, gen->indent); -- vkd3d_string_buffer_printf(gen->buffer, "vkd3d_vec4 x%u[%u];\n", -+ vkd3d_string_buffer_printf(gen->buffer, "%s x%u[%u];\n", type, - ins->declaration.indexable_temp.register_idx, - ins->declaration.indexable_temp.register_size); - } -@@ -1613,6 +1625,7 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) - const struct shader_signature *signature = &gen->program->input_signature; - enum vkd3d_shader_type type = gen->program->shader_version.type; - struct vkd3d_string_buffer *buffer = gen->buffer; -+ bool locations[MAX_IO_REG_COUNT] = {0}; - const struct signature_element *e; - unsigned int i; - -@@ -1625,6 +1638,18 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) - if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) - continue; - -+ if (e->target_location >= ARRAY_SIZE(locations)) -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled input target location %u.", e->target_location); -+ continue; -+ } -+ -+ if (locations[e->target_location]) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location); -+ locations[e->target_location] = true; -+ - switch (e->sysval_semantic) - { - case VKD3D_SHADER_SV_NONE: -@@ -1776,6 +1801,7 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) - const struct shader_signature *signature = &gen->program->output_signature; - enum vkd3d_shader_type type = gen->program->shader_version.type; - struct vkd3d_string_buffer *buffer = gen->buffer; -+ bool locations[MAX_IO_REG_COUNT] = {0}; - const struct signature_element *e; - unsigned int i; - -@@ -1789,17 +1815,22 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) - || e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) - continue; - -- if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) -+ if (e->target_location >= ARRAY_SIZE(locations)) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision); -+ "Internal compiler error: Unhandled input target location %u.", e->target_location); - continue; - } - -- if (e->interpolation_mode != VKD3DSIM_NONE) -+ if (locations[e->target_location]) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location); -+ locations[e->target_location] = true; -+ -+ if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); -+ "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision); - continue; - } - -@@ -1958,7 +1989,7 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) - } - - 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"); -+ vkd3d_string_buffer_printf(gen->buffer, " output.shader_out_mask = o_mask.u;\n"); - } - - static void msl_generate_entrypoint(struct msl_generator *gen) -@@ -2001,11 +2032,11 @@ static void msl_generate_entrypoint(struct msl_generator *gen) - vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix); - - /* TODO: declare #maximum_register + 1 */ -- 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_vec4 %s_in[%u];\n", gen->prefix, MAX_IO_REG_COUNT); -+ vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, MAX_IO_REG_COUNT); - 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, " vkd3d_scalar o_mask;\n"); - vkd3d_string_buffer_printf(gen->buffer, "\n"); - - msl_generate_entrypoint_prologue(gen); -@@ -2042,6 +2073,11 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)gen->program->global_flags); - -+ vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_scalar\n{\n"); -+ vkd3d_string_buffer_printf(gen->buffer, " uint u;\n"); -+ vkd3d_string_buffer_printf(gen->buffer, " int i;\n"); -+ vkd3d_string_buffer_printf(gen->buffer, " float f;\n};\n\n"); -+ - vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_vec4\n{\n"); - vkd3d_string_buffer_printf(gen->buffer, " uint4 u;\n"); - vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n"); -@@ -2082,7 +2118,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader - 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"); -+ vkd3d_string_buffer_printf(gen->buffer, ", thread vkd3d_scalar &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"); -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 2e6d0c786d0..8400db85084 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -982,6 +982,7 @@ struct vkd3d_spirv_builder - SpvExecutionModel execution_model; - - uint32_t current_id; -+ uint32_t source_name_id; - uint32_t main_function_id; - struct rb_tree declarations; - uint32_t type_sampler_id; -@@ -1568,10 +1569,15 @@ static uint32_t vkd3d_spirv_build_op_string(struct vkd3d_spirv_builder *builder, - static void vkd3d_spirv_build_op_source(struct vkd3d_spirv_builder *builder, const char *source_name) - { - struct vkd3d_spirv_stream *stream = &builder->debug_stream; -- uint32_t source_id; - -- source_id = vkd3d_spirv_build_op_string(builder, source_name ? source_name : ""); -- vkd3d_spirv_build_op3(stream, SpvOpSource, 0, 0, source_id); -+ builder->source_name_id = vkd3d_spirv_build_op_string(builder, source_name ? source_name : ""); -+ vkd3d_spirv_build_op3(stream, SpvOpSource, 0, 0, builder->source_name_id); -+} -+ -+static void vkd3d_spirv_build_op_line(struct vkd3d_spirv_builder *builder, const struct vkd3d_shader_location *location) -+{ -+ vkd3d_spirv_build_op3(&builder->function_stream, SpvOpLine, -+ builder->source_name_id, location->line, location->column); - } - - static void vkd3d_spirv_build_op_member_name(struct vkd3d_spirv_builder *builder, -@@ -10548,6 +10554,17 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - int ret = VKD3D_OK; - - compiler->location = instruction->location; -+ /* radeonsi from Mesa 20.3.5 seems to get confused by OpLine instructions -+ * before OpFunction, seemingly causing it to fail to find the entry -+ * point. As far as I can tell that's not prohibited, and the validation -+ * layers don't seem to mind either, but perhaps it's best avoided. -+ * Notably, radv from the same Mesa version doesn't mind either. -+ * -+ * This is an issue for hull shaders in particular, because we don't go -+ * through vkd3d_spirv_builder_begin_main_function() before getting here -+ * in that case. */ -+ if (!compiler->strip_debug && compiler->spirv_builder.function_stream.word_count) -+ vkd3d_spirv_build_op_line(&compiler->spirv_builder, &instruction->location); - - switch (instruction->opcode) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index a3c00af5d8b..a91846a46b9 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -1733,9 +1733,9 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char - return ret; - } - --int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, -- const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, -- struct vkd3d_shader_message_context *message_context) -+int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, -+ uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) - { - struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info; - struct vkd3d_shader_compile_info scan_info; -@@ -1746,9 +1746,23 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, - switch (compile_info->target_type) - { - case VKD3D_SHADER_TARGET_D3D_ASM: -+ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) -+ return ret; - ret = d3d_asm_compile(program, compile_info, out, VSIR_ASM_FLAG_NONE); - break; - -+ case VKD3D_SHADER_TARGET_D3D_BYTECODE: -+ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) -+ return ret; -+ ret = d3dbc_compile(program, config_flags, compile_info, reflection_data, out, message_context); -+ break; -+ -+ case VKD3D_SHADER_TARGET_DXBC_TPF: -+ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) -+ return ret; -+ ret = tpf_compile(program, config_flags, reflection_data, out, message_context); -+ break; -+ - case VKD3D_SHADER_TARGET_GLSL: - combined_sampler_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO; - combined_sampler_info.next = scan_info.next; -@@ -1843,7 +1857,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, - - if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) - { -- ret = vsir_program_compile(&program, config_flags, compile_info, out, &message_context); -+ ret = vsir_program_compile(&program, NULL, config_flags, compile_info, out, &message_context); - vsir_program_cleanup(&program); - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index a0d7faaa407..d1c2057b38e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1565,9 +1565,9 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context); - void vsir_program_cleanup(struct vsir_program *program); --int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, -- const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, -- struct vkd3d_shader_message_context *message_context); -+int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, -+ uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); - const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( - const struct vsir_program *program, enum vkd3d_shader_parameter_name name); - bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, -diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c -index b2636fd5585..67f84aafa29 100644 ---- a/libs/vkd3d/libs/vkd3d/device.c -+++ b/libs/vkd3d/libs/vkd3d/device.c -@@ -5193,7 +5193,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device - FIXME("iface %p, num_meta_commands %p, command_desc %p stub!\n", iface, - num_meta_commands, command_desc); - -- return E_NOTIMPL; -+ if (!num_meta_commands) -+ return E_INVALIDARG; -+ -+ *num_meta_commands = 0; -+ -+ return S_OK; - } - - static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device9 *iface, --- -2.50.1 - diff --git a/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch b/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch deleted file mode 100644 index e6225660..00000000 --- a/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch +++ /dev/null @@ -1,591 +0,0 @@ -From df589f34860797b7a53495423e20bdce4c698ce8 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Wed, 30 Jul 2025 08:46:04 +1000 -Subject: [PATCH] Updated vkd3d to bb2979aa4c3432bfd5b30ae23de8aaaa57e04c6a. - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 19 +++-- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 64 +++++++++------ - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 79 ++++++++----------- - libs/vkd3d/libs/vkd3d-shader/ir.c | 30 ++++--- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 16 ++-- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 1 - - .../libs/vkd3d-shader/vkd3d_shader_main.c | 17 ++-- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 9 +++ - 8 files changed, 136 insertions(+), 99 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index c213007f2b4..2ec9a74249b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -156,6 +156,8 @@ static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, - atomic_flags &= ~VKD3DARF_VOLATILE; - } - -+ atomic_flags &= ~VKD3DSI_PRECISE_XYZW; -+ - if (atomic_flags) - vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", atomic_flags); - } -@@ -183,6 +185,8 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint - sync_flags &= ~VKD3DSSF_THREAD_GROUP; - } - -+ sync_flags &= ~VKD3DSI_PRECISE_XYZW; -+ - if (sync_flags) - vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", sync_flags); - } -@@ -1332,7 +1336,7 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile - break; - - case VSIR_OP_RESINFO: -- switch (ins->flags) -+ switch (ins->flags & ~VKD3DSI_PRECISE_XYZW) - { - case VKD3DSI_NONE: - break; -@@ -1349,7 +1353,7 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile - break; - - case VSIR_OP_SAMPLE_INFO: -- switch (ins->flags) -+ switch (ins->flags & ~VKD3DSI_PRECISE_XYZW) - { - case VKD3DSI_NONE: - break; -@@ -1405,9 +1409,9 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile - case VSIR_OP_USHR: - if (ins->flags & VKD3DSI_SHIFT_UNMASKED) - vkd3d_string_buffer_printf(buffer, "_unmasked"); -- /* fall through */ -+ break; -+ - default: -- shader_dump_precise_flags(compiler, ins->flags); - break; - } - } -@@ -1664,9 +1668,14 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, - default: - shader_dump_instruction_flags(compiler, ins); - -+ if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE) -+ vkd3d_string_buffer_printf(buffer, "_indexable"); -+ -+ shader_dump_precise_flags(compiler, ins->flags); -+ - if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE) - { -- vkd3d_string_buffer_printf(buffer, "_indexable("); -+ vkd3d_string_buffer_printf(buffer, "("); - if (ins->raw) - vkd3d_string_buffer_printf(buffer, "raw_"); - if (ins->structured) -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index a089651eaf7..113ac760731 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -5011,19 +5011,12 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) - vkd3d_free(ctx->constant_defs.regs); - } - --int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, -- struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) -+static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context) - { - enum vkd3d_shader_target_type target_type = compile_info->target_type; - const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; -- uint64_t config_flags = vkd3d_shader_init_config_flags(); -- struct hlsl_ir_function_decl *decl, *entry_func = NULL; -- struct vkd3d_shader_code reflection_data = {0}; - const struct hlsl_profile_info *profile; -- struct hlsl_ir_function *func; -- struct vsir_program program; -- const char *entry_point; -- struct hlsl_ctx ctx; - int ret; - - if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) -@@ -5031,7 +5024,6 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, - ERR("No HLSL source info given.\n"); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -- entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; - - if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) - { -@@ -5064,37 +5056,65 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, - return VKD3D_ERROR_INVALID_ARGUMENT; - } - -- if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context)) -+ if (!hlsl_ctx_init(ctx, compile_info, profile, message_context)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- if ((ret = hlsl_lexer_compile(&ctx, &compile_info->source)) == 2) -+ if ((ret = hlsl_lexer_compile(ctx, &compile_info->source)) == 2) - { -- hlsl_ctx_cleanup(&ctx); -+ hlsl_ctx_cleanup(ctx); - return VKD3D_ERROR_OUT_OF_MEMORY; - } - -- if (ctx.result) -+ if (ctx->result) - { -- hlsl_ctx_cleanup(&ctx); -- return ctx.result; -+ hlsl_ctx_cleanup(ctx); -+ return ctx->result; - } - - /* If parsing failed without an error condition being recorded, we - * plausibly hit some unimplemented feature. */ - if (ret) - { -- hlsl_ctx_cleanup(&ctx); -+ hlsl_ctx_cleanup(ctx); - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - -- if (ctx.profile->type == VKD3D_SHADER_TYPE_EFFECT) -- { -- ret = hlsl_emit_effect_binary(&ctx, out); -+ return VKD3D_OK; -+} - -- hlsl_ctx_cleanup(&ctx); -+int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) -+{ -+ struct hlsl_ctx ctx; -+ int ret; -+ -+ if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0) - return ret; -- } - -+ ret = hlsl_emit_effect_binary(&ctx, out); -+ hlsl_ctx_cleanup(&ctx); -+ -+ return ret; -+} -+ -+int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) -+{ -+ const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; -+ uint64_t config_flags = vkd3d_shader_init_config_flags(); -+ struct hlsl_ir_function_decl *decl, *entry_func = NULL; -+ struct vkd3d_shader_code reflection_data = {0}; -+ struct hlsl_ir_function *func; -+ struct vsir_program program; -+ const char *entry_point; -+ struct hlsl_ctx ctx; -+ int ret; -+ -+ if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0) -+ return ret; -+ -+ hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO); -+ entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; - if ((func = hlsl_get_function(&ctx, entry_point))) - { - LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index e3ca1b25eb9..0b28aa6fe80 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -7549,6 +7549,8 @@ static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir - entry_func->early_depth_test = true; - else if (!strcmp(attr->name, "maxvertexcount") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY) - parse_maxvertexcount_attribute(ctx, attr); -+ else if (!strcmp(attr->name, "instance") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY) -+ hlsl_fixme(ctx, &entry_func->attrs[i]->loc, "Geometry shader instance count"); - else - hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, - "Ignoring unknown attribute \"%s\".", entry_func->attrs[i]->name); -@@ -9610,25 +9612,13 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co - struct hlsl_ir_function_decl *func, struct list *semantic_vars, - struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) - { -- struct vkd3d_shader_version version = {0}; - struct hlsl_block block; - -- version.major = ctx->profile->major_version; -- version.minor = ctx->profile->minor_version; -- version.type = ctx->profile->type; -- if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) -- { -- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; -- return; -- } -- - program->ssa_count = 0; - program->temp_count = allocate_temp_registers(ctx, body, semantic_vars); - if (ctx->result) - return; - -- generate_vsir_signature(ctx, program, func, semantic_vars); -- - hlsl_block_init(&block); - sm1_generate_vsir_constant_defs(ctx, program, &block); - sm1_generate_vsir_sampler_dcls(ctx, program, &block); -@@ -12345,32 +12335,18 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - struct list *semantic_vars, struct hlsl_block *body, struct list *patch_semantic_vars, - struct hlsl_block *patch_body, uint64_t config_flags, struct vsir_program *program) - { -- struct vkd3d_shader_version version = {0}; -+ const struct vkd3d_shader_version *version = &program->shader_version; - struct extern_resource *extern_resources; - unsigned int extern_resources_count; - const struct hlsl_buffer *cbuffer; - -- version.major = ctx->profile->major_version; -- version.minor = ctx->profile->minor_version; -- version.type = ctx->profile->type; -- -- if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) -- { -- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; -- return; -- } -- -- generate_vsir_signature(ctx, program, func, semantic_vars); -- if (version.type == VKD3D_SHADER_TYPE_HULL) -- generate_vsir_signature(ctx, program, ctx->patch_constant_func, patch_semantic_vars); -- -- if (version.type == VKD3D_SHADER_TYPE_COMPUTE) -+ if (version->type == VKD3D_SHADER_TYPE_COMPUTE) - { - program->thread_group_size.x = ctx->thread_count[0]; - program->thread_group_size.y = ctx->thread_count[1]; - program->thread_group_size.z = ctx->thread_count[2]; - } -- else if (version.type == VKD3D_SHADER_TYPE_HULL) -+ else if (version->type == VKD3D_SHADER_TYPE_HULL) - { - program->input_control_point_count = ctx->input_control_point_count == UINT_MAX - ? 1 : ctx->input_control_point_count; -@@ -12379,13 +12355,13 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - program->tess_partitioning = ctx->partitioning; - program->tess_output_primitive = ctx->output_primitive; - } -- else if (version.type == VKD3D_SHADER_TYPE_DOMAIN) -+ else if (version->type == VKD3D_SHADER_TYPE_DOMAIN) - { - program->input_control_point_count = ctx->input_control_point_count == UINT_MAX - ? 0 : ctx->input_control_point_count; - program->tess_domain = ctx->domain; - } -- else if (version.type == VKD3D_SHADER_TYPE_GEOMETRY) -+ else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY) - { - program->input_control_point_count = ctx->input_control_point_count; - program->input_primitive = ctx->input_primitive_type; -@@ -12413,7 +12389,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - } - sm4_free_extern_resources(extern_resources, extern_resources_count); - -- if (version.type == VKD3D_SHADER_TYPE_GEOMETRY && version.major >= 5) -+ if (version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) - { - const struct hlsl_ir_var *var; - -@@ -12426,11 +12402,11 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - - program->ssa_count = 0; - -- if (version.type == VKD3D_SHADER_TYPE_HULL) -+ if (version->type == VKD3D_SHADER_TYPE_HULL) - generate_vsir_add_program_instruction(ctx, program, - &ctx->patch_constant_func->loc, VSIR_OP_HS_CONTROL_POINT_PHASE, 0, 0); - sm4_generate_vsir_add_function(ctx, semantic_vars, func, body, config_flags, program); -- if (version.type == VKD3D_SHADER_TYPE_HULL) -+ if (version->type == VKD3D_SHADER_TYPE_HULL) - { - generate_vsir_add_program_instruction(ctx, program, - &ctx->patch_constant_func->loc, VSIR_OP_HS_FORK_PHASE, 0, 0); -@@ -13912,6 +13888,7 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info - uint32_t config_flags = vkd3d_shader_init_config_flags(); - const struct hlsl_profile_info *profile = ctx->profile; - struct list semantic_vars, patch_semantic_vars; -+ struct vkd3d_shader_version version = {0}; - struct hlsl_ir_var *var; - - parse_entry_function_attributes(ctx, entry_func); -@@ -13980,28 +13957,38 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info - if (ctx->result) - return ctx->result; - -- if (ctx->profile->major_version < 4) -+ version.major = ctx->profile->major_version; -+ version.minor = ctx->profile->minor_version; -+ version.type = ctx->profile->type; -+ if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) - { -- sm1_generate_ctab(ctx, reflection_data); -- if (ctx->result) -- return ctx->result; -- -- sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program); -+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; -+ return ctx->result; - } -+ -+ generate_vsir_signature(ctx, program, entry_func, &semantic_vars); -+ if (version.type == VKD3D_SHADER_TYPE_HULL) -+ generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars); -+ -+ if (version.major < 4) -+ sm1_generate_ctab(ctx, reflection_data); - else -- { - sm4_generate_rdef(ctx, reflection_data); -- if (ctx->result) -- return ctx->result; -+ if (ctx->result) -+ { -+ vsir_program_cleanup(program); -+ return ctx->result; -+ } - -+ if (version.major < 4) -+ sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program); -+ else - sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, - &patch_semantic_vars, &patch_body, config_flags, program); -- } -- - if (ctx->result) - { -- vsir_program_cleanup(program); - vkd3d_shader_free_shader_code(reflection_data); -+ vsir_program_cleanup(program); - } - - return ctx->result; -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index c3bcf9058e1..1098e4d3950 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -903,14 +903,13 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, - static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_instruction *ins, *ins2; - unsigned int tmp_idx = ~0u; -- unsigned int i, k, r; -+ unsigned int k, r; - -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &program->instructions.elements[i]; -- - if (ins->opcode == VSIR_OP_MOV && ins->dst[0].reg.type == VKD3DSPR_ADDR) - { - if (tmp_idx == ~0u) -@@ -926,16 +925,16 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - if (tmp_idx == ~0u) - tmp_idx = program->temp_count++; - -- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) -+ if (!vsir_program_iterator_insert_after(&it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = &program->instructions.elements[i]; -- ins2 = &program->instructions.elements[i + 1]; -+ ins = vsir_program_iterator_current(&it); - - ins->opcode = VSIR_OP_ROUND_NE; - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = tmp_idx; - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - -+ ins2 = vsir_program_iterator_next(&it); - if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VSIR_OP_FTOU, 1, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -1741,14 +1740,21 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - static const struct vkd3d_shader_location no_loc; -- if (program->instructions.count -- && program->instructions.elements[program->instructions.count - 1].opcode == VSIR_OP_RET) -+ struct vkd3d_shader_instruction *ins; -+ -+ ins = vsir_program_iterator_tail(&it); -+ -+ if (ins && ins->opcode == VSIR_OP_RET) - return VKD3D_OK; - -- if (!shader_instruction_array_insert_at(&program->instructions, program->instructions.count, 1)) -+ if (!vsir_program_iterator_insert_after(&it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- vsir_instruction_init(&program->instructions.elements[program->instructions.count - 1], &no_loc, VSIR_OP_RET); -+ -+ ins = vsir_program_iterator_next(&it); -+ vsir_instruction_init(ins, &no_loc, VSIR_OP_RET); -+ - return VKD3D_OK; - } - -@@ -9592,7 +9598,7 @@ static void vsir_validate_register(struct validation_context *ctx, - [VKD3DSPR_LOCALTHREADINDEX] = {true, 0, VSIR_DIMENSION_VEC4}, - [VKD3DSPR_COVERAGE] = {true, 0, VSIR_DIMENSION_VEC4}, - [VKD3DSPR_SAMPLEMASK] = {true, 0, VSIR_DIMENSION_SCALAR}, -- [VKD3DSPR_GSINSTID] = {true, 0, VSIR_DIMENSION_SCALAR}, -+ [VKD3DSPR_GSINSTID] = {true, 0, VSIR_DIMENSION_VEC4}, - [VKD3DSPR_DEPTHOUTGE] = {true, 0, VSIR_DIMENSION_SCALAR}, - [VKD3DSPR_DEPTHOUTLE] = {true, 0, VSIR_DIMENSION_SCALAR}, - [VKD3DSPR_OUTSTENCILREF] = {true, 0, VSIR_DIMENSION_SCALAR}, -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 8400db85084..4f50eadf714 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -9938,9 +9938,9 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - struct vkd3d_shader_image image; - bool supports_mipmaps; - -- if (instruction->flags & ~VKD3DSI_RESINFO_UINT) -- spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -- "Unhandled resinfo flags %#x.\n", instruction->flags & ~VKD3DSI_RESINFO_UINT); -+ if (instruction->flags & ~(VKD3DSI_RESINFO_UINT | VKD3DSI_PRECISE_XYZW)) -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unhandled resinfo flags %#x.\n", -+ instruction->flags & ~(VKD3DSI_RESINFO_UINT | VKD3DSI_PRECISE_XYZW)); - - vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); - -@@ -9978,6 +9978,8 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - component_type = VKD3D_SHADER_COMPONENT_FLOAT; - type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); -+ if (instruction->flags & VKD3DSI_PRECISE_XYZW) -+ vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); - } - val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, - component_type, src[1].swizzle, dst->write_mask); -@@ -10020,9 +10022,9 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, - uint32_t type_id, val_id; - unsigned int i; - -- if (instruction->flags & ~VKD3DSI_SAMPLE_INFO_UINT) -- spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -- "Unhandled sample info flags %#x.\n", instruction->flags & ~VKD3DSI_SAMPLE_INFO_UINT); -+ if (instruction->flags & ~(VKD3DSI_SAMPLE_INFO_UINT | VKD3DSI_PRECISE_XYZW)) -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unhandled sample info flags %#x.\n", -+ instruction->flags & ~(VKD3DSI_SAMPLE_INFO_UINT | VKD3DSI_PRECISE_XYZW)); - - val_id = spirv_compiler_emit_query_sample_count(compiler, src); - -@@ -10037,6 +10039,8 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, - component_type = VKD3D_SHADER_COMPONENT_FLOAT; - type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); -+ if (instruction->flags & VKD3DSI_PRECISE_XYZW) -+ vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); - } - val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, - component_type, src->swizzle, dst->write_mask); -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index bdb2083e09a..ed19faf945b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -2237,7 +2237,6 @@ bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg) - case VKD3DSPR_DEPTHOUT: - case VKD3DSPR_DEPTHOUTGE: - case VKD3DSPR_DEPTHOUTLE: -- case VKD3DSPR_GSINSTID: - case VKD3DSPR_OUTPOINTID: - case VKD3DSPR_PRIMID: - case VKD3DSPR_SAMPLEMASK: -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index a91846a46b9..2b73771d0a6 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -1598,12 +1598,13 @@ void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor - static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context, bool add_descriptor_info) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; - struct vkd3d_shader_scan_hull_shader_tessellation_info *tessellation_info; - struct vkd3d_shader_scan_descriptor_info *descriptor_info; - struct vkd3d_shader_scan_signature_info *signature_info; -- struct vkd3d_shader_instruction *instruction; - struct vkd3d_shader_scan_context context; -+ struct vkd3d_shader_instruction *ins; - int ret = VKD3D_OK; - unsigned int i; - -@@ -1631,10 +1632,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - if (TRACE_ON()) - vsir_program_trace(program); - -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- instruction = &program->instructions.elements[i]; -- if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0) -+ if ((ret = vkd3d_shader_scan_instruction(&context, ins)) < 0) - break; - } - -@@ -1810,7 +1810,10 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, - - preprocessed_info = *compile_info; - preprocessed_info.source = preprocessed; -- ret = hlsl_compile_shader(&preprocessed_info, message_context, out); -+ if (compile_info->target_type == VKD3D_SHADER_TARGET_FX) -+ ret = hlsl_compile_effect(&preprocessed_info, message_context, out); -+ else -+ ret = hlsl_compile_shader(&preprocessed_info, message_context, out); - - vkd3d_shader_free_shader_code(&preprocessed); - return ret; -@@ -2257,8 +2260,8 @@ bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instru - /* Size the parameter initial allocations so they are large enough for most shaders. The - * code path for chained allocations will be tested if a few shaders need to use it. */ - shader_param_allocator_init(&instructions->dst_params, reserve - reserve / 8u, -- sizeof(*instructions->elements->dst)); -- shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(*instructions->elements->src)); -+ sizeof(struct vkd3d_shader_dst_param)); -+ shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); - return shader_instruction_array_reserve(instructions, reserve); - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index d1c2057b38e..5bf3728a325 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1453,6 +1453,13 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_head( - return vsir_program_iterator_current(iterator); - } - -+static inline struct vkd3d_shader_instruction *vsir_program_iterator_tail(struct vsir_program_iterator *iterator) -+{ -+ iterator->idx = iterator->array->count - 1; -+ -+ return vsir_program_iterator_current(iterator); -+} -+ - static inline struct vkd3d_shader_instruction *vsir_program_iterator_next( - struct vsir_program_iterator *iterator) - { -@@ -1799,6 +1806,8 @@ void vkd3d_compute_md5(const void *dxbc, size_t size, uint32_t checksum[4], enum - int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); - -+int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); - int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); - --- -2.50.1 - diff --git a/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch b/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch deleted file mode 100644 index 7172a625..00000000 --- a/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 31ab77ada15b692f5b37d8ddf15f65c375860def Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 31 Jul 2025 09:06:17 +1000 -Subject: [PATCH] Updated vkd3d to 75cb4336ec1a0455c347db05b22dc0fd76dd8b5f. - ---- - libs/vkd3d/libs/vkd3d-shader/ir.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 1098e4d3950..4c324fef7cf 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -444,7 +444,14 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c - program->shader_version = *version; - program->cf_type = cf_type; - program->normalisation_level = normalisation_level; -- return shader_instruction_array_init(&program->instructions, reserve); -+ if (!shader_instruction_array_init(&program->instructions, reserve)) -+ { -+ if (program->free_parameters) -+ vkd3d_free((void *)program->parameters); -+ return false; -+ } -+ -+ return true; - } - - void vsir_program_cleanup(struct vsir_program *program) -@@ -8744,6 +8751,7 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, - enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context) - { -+ const unsigned int prev_temp_count = program->temp_count; - struct temp_allocator allocator = {0}; - struct temp_allocator_reg *regs; - struct liveness_tracker tracker; -@@ -8766,7 +8774,6 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - for (unsigned int i = 0; i < program->ssa_count; ++i) - { - const struct liveness_tracker_reg *liveness_reg = &tracker.ssa_regs[i]; -- const unsigned int prev_temp_count = program->temp_count; - struct temp_allocator_reg *reg = &allocator.ssa_regs[i]; - - if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, prev_temp_count)) --- -2.50.1 - diff --git a/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch b/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch deleted file mode 100644 index f186376b..00000000 --- a/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 6d9b7b4891f5ed2c30b6d383fe289637bcc2c6d9 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 1 Aug 2025 07:18:27 +1000 -Subject: [PATCH] Updated vkd3d to bd3d0f3495f6375901df9ca899accf8bc7a45345. - ---- - dlls/msado15/tests/msado15.c | 2 +- - .../include/private/vkd3d_shader_utils.h | 4 ---- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 1 + - libs/vkd3d/libs/vkd3d-shader/ir.c | 5 +---- - libs/vkd3d/libs/vkd3d/command.c | 21 +++++++++++++------ - libs/vkd3d/libs/vkd3d/state.c | 4 ++-- - 6 files changed, 20 insertions(+), 17 deletions(-) - -diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c -index 03eaab92b39..3f4b55d2916 100644 ---- a/dlls/msado15/tests/msado15.c -+++ b/dlls/msado15/tests/msado15.c -@@ -2023,8 +2023,8 @@ START_TEST(msado15) - setup_database(); - - test_Connection(); -- test_Connection_Open(); - test_ConnectionPoint(); -+ test_Connection_Open(); - test_ADORecordsetConstruction(FALSE); - test_ADORecordsetConstruction(TRUE); - test_Fields(); -diff --git a/libs/vkd3d/include/private/vkd3d_shader_utils.h b/libs/vkd3d/include/private/vkd3d_shader_utils.h -index 00052a89988..465734dfbff 100644 ---- a/libs/vkd3d/include/private/vkd3d_shader_utils.h -+++ b/libs/vkd3d/include/private/vkd3d_shader_utils.h -@@ -21,10 +21,6 @@ - - #include "vkd3d_shader.h" - --#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') --#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R') --#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X') -- - static inline enum vkd3d_result vkd3d_shader_parse_dxbc_source_type(const struct vkd3d_shader_code *dxbc, - enum vkd3d_shader_source_type *type, char **messages) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 19e9f54edda..02e72b28908 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -8905,6 +8905,7 @@ static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] = - [SEMANTIC_KIND_INSTANCEID] = VKD3D_SHADER_SV_INSTANCE_ID, - [SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION, - [SEMANTIC_KIND_RTARRAYINDEX] = VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX, -+ [SEMANTIC_KIND_VIEWPORTARRAYINDEX] = VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX, - [SEMANTIC_KIND_CLIPDISTANCE] = VKD3D_SHADER_SV_CLIP_DISTANCE, - [SEMANTIC_KIND_CULLDISTANCE] = VKD3D_SHADER_SV_CULL_DISTANCE, - [SEMANTIC_KIND_PRIMITIVEID] = VKD3D_SHADER_SV_PRIMITIVE_ID, -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 4c324fef7cf..76eb62cfd6f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -1752,14 +1752,11 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, - struct vkd3d_shader_instruction *ins; - - ins = vsir_program_iterator_tail(&it); -- - if (ins && ins->opcode == VSIR_OP_RET) - return VKD3D_OK; - -- if (!vsir_program_iterator_insert_after(&it, 1)) -+ if (!(ins = vsir_program_append(program))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- -- ins = vsir_program_iterator_next(&it); - vsir_instruction_init(ins, &no_loc, VSIR_OP_RET); - - return VKD3D_OK; -diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c -index e487ed0b9ad..074d8430585 100644 ---- a/libs/vkd3d/libs/vkd3d/command.c -+++ b/libs/vkd3d/libs/vkd3d/command.c -@@ -4221,13 +4221,21 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo - TRACE("iface %p, viewport_count %u, viewports %p.\n", iface, viewport_count, viewports); - - if (viewport_count > ARRAY_SIZE(vk_viewports)) -- { - FIXME("Viewport count %u > D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE.\n", viewport_count); -- viewport_count = ARRAY_SIZE(vk_viewports); -- } - -- for (i = 0; i < viewport_count; ++i) -+ for (i = 0; i < ARRAY_SIZE(vk_viewports); ++i) - { -+ if (i >= viewport_count) -+ { -+ vk_viewports[i].x = 0.0f; -+ vk_viewports[i].y = 0.0f; -+ vk_viewports[i].width = 1.0f; -+ vk_viewports[i].height = 1.0f; -+ vk_viewports[i].minDepth = 0.0f; -+ vk_viewports[i].maxDepth = 0.0f; -+ continue; -+ } -+ - vk_viewports[i].x = viewports[i].TopLeftX; - vk_viewports[i].y = viewports[i].TopLeftY + viewports[i].Height; - vk_viewports[i].width = viewports[i].Width; -@@ -4245,7 +4253,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo - } - - vk_procs = &list->device->vk_procs; -- VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports)); -+ VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, ARRAY_SIZE(vk_viewports), vk_viewports)); - } - - static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList6 *iface, -@@ -4264,6 +4272,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic - rect_count = ARRAY_SIZE(vk_rects); - } - -+ memset(vk_rects, 0, sizeof(vk_rects)); - for (i = 0; i < rect_count; ++i) - { - vk_rects[i].offset.x = rects[i].left; -@@ -4273,7 +4282,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic - } - - vk_procs = &list->device->vk_procs; -- VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects)); -+ VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, ARRAY_SIZE(vk_rects), vk_rects)); - } - - static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList6 *iface, -diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 9e9811bf922..413892789ba 100644 ---- a/libs/vkd3d/libs/vkd3d/state.c -+++ b/libs/vkd3d/libs/vkd3d/state.c -@@ -3971,9 +3971,9 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .pNext = NULL, - .flags = 0, -- .viewportCount = 1, -+ .viewportCount = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, - .pViewports = NULL, -- .scissorCount = 1, -+ .scissorCount = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, - .pScissors = NULL, - }; - static const VkDynamicState dynamic_states[] = --- -2.50.1 - diff --git a/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch b/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch deleted file mode 100644 index 6099e57d..00000000 --- a/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 1031928bdeb67d2a9f6af25ec7948dca4b24bd10 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 5 Aug 2025 13:30:41 +1000 -Subject: [PATCH] Updated vkd3d to 721859005f3edfb3d52bc0f810d1da4fe2e5174b. - ---- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 6 ++-- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 34 ++++++------------- - libs/vkd3d/libs/vkd3d-shader/ir.c | 7 ++-- - libs/vkd3d/libs/vkd3d-shader/msl.c | 3 ++ - .../libs/vkd3d-shader/vkd3d_shader_main.c | 3 ++ - 5 files changed, 26 insertions(+), 27 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 02e72b28908..c448e000cf9 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -3969,6 +3969,7 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm - - static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&sm6->p.program->instructions); - size_t i, count, base_value_idx = sm6->value_count; - const struct dxil_block *block = &sm6->root_block; - struct vkd3d_shader_instruction *ins; -@@ -4028,9 +4029,8 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) - } - - /* Resolve initialiser forward references. */ -- for (i = 0; i < sm6->p.program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &sm6->p.program->instructions.elements[i]; - if (ins->opcode == VSIR_OP_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser) - { - ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser( -@@ -4098,6 +4098,8 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( - - switch (sysval_semantic) - { -+ case VKD3D_SHADER_SV_PRIMITIVE_ID: -+ return VKD3DSPR_PRIMID; - /* VSIR does not use an I/O register for SV_SampleIndex, but its - * signature element has a register index of UINT_MAX and it is - * convenient to return a valid register type here to handle it. */ -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 0b28aa6fe80..5a11547e7a1 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -8282,7 +8282,6 @@ static uint32_t generate_vsir_get_src_swizzle(uint32_t src_writemask, uint32_t d - static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_program *program, - struct hlsl_block *block) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; - struct vkd3d_shader_dst_param *dst_param; - struct vkd3d_shader_src_param *src_param; - struct vkd3d_shader_instruction *ins; -@@ -8292,19 +8291,17 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr - { - const struct hlsl_constant_register *constant_reg = &ctx->constant_defs.regs[i]; - -- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) -+ if (!(ins = vsir_program_append(program))) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; - } -- -- ins = &instructions->elements[instructions->count]; - if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VSIR_OP_DEF, 1, 1)) - { -+ vsir_instruction_init(ins, &constant_reg->loc, VSIR_OP_NOP); - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; - } -- ++instructions->count; - - dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); -@@ -8328,7 +8325,6 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr - static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, - struct vsir_program *program, struct hlsl_block *block) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; - enum vkd3d_shader_resource_type resource_type; - struct vkd3d_shader_register_range *range; - struct vkd3d_shader_dst_param *dst_param; -@@ -8375,20 +8371,13 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, - break; - } - -- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) -- { -- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; -- return; -- } -- -- ins = &instructions->elements[instructions->count]; -- if (!vsir_instruction_init_with_params(program, ins, &var->loc, VSIR_OP_DCL, 0, 0)) -+ if (!(ins = vsir_program_append(program))) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; - } -- ++instructions->count; - -+ vsir_instruction_init(ins, &var->loc, VSIR_OP_DCL); - semantic = &ins->declaration.semantic; - semantic->resource_type = resource_type; - -@@ -8438,26 +8427,25 @@ static enum vkd3d_shader_register_type sm4_get_semantic_register_type(enum vkd3d - return VKD3DSPR_INPUT; - } - --static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction( -- struct hlsl_ctx *ctx, struct vsir_program *program, -- const struct vkd3d_shader_location *loc, enum vkd3d_shader_opcode opcode, -- unsigned int dst_count, unsigned int src_count) -+static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction(struct hlsl_ctx *ctx, -+ struct vsir_program *program, const struct vkd3d_shader_location *loc, -+ enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; - struct vkd3d_shader_instruction *ins; - -- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) -+ if (!(ins = vsir_program_append(program))) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return NULL; - } -- ins = &instructions->elements[instructions->count]; -+ - if (!vsir_instruction_init_with_params(program, ins, loc, opcode, dst_count, src_count)) - { -+ vsir_instruction_init(ins, loc, VSIR_OP_NOP); - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return NULL; - } -- ++instructions->count; -+ - return ins; - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 76eb62cfd6f..9d93936ac9e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -12064,8 +12064,11 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t - vsir_transform(&ctx, vsir_program_materialise_phi_ssas_to_temps); - vsir_transform(&ctx, vsir_program_lower_switch_to_selection_ladder); - vsir_transform(&ctx, vsir_program_structurize); -- vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); -- vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); -+ if (compile_info->target_type != VKD3D_SHADER_TARGET_MSL) -+ { -+ vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); -+ vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); -+ } - } - else - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index d07608bd26f..c6e048adb20 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -2196,6 +2196,9 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, - if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) - return ret; - -+ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0) -+ return ret; -+ - VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); - VKD3D_ASSERT(program->has_descriptor_info); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 2b73771d0a6..891a33d326f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -2119,6 +2119,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( - VKD3D_SHADER_TARGET_SPIRV_TEXT, - # endif - VKD3D_SHADER_TARGET_D3D_ASM, -+#ifdef VKD3D_SHADER_UNSUPPORTED_MSL -+ VKD3D_SHADER_TARGET_MSL, -+#endif - }; - - static const enum vkd3d_shader_target_type fx_types[] = --- -2.50.1 - diff --git a/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch b/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch deleted file mode 100644 index 4cab1f44..00000000 --- a/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch +++ /dev/null @@ -1,1199 +0,0 @@ -From 00ab2db3813cc8bcd0dc0edf90025365b9dac52f Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Wed, 6 Aug 2025 13:39:31 +1000 -Subject: [PATCH] Updated vkd3d to 4bb880f9ed09dab9a87a56bb065f087e92a0d62c. - ---- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 67 ++- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 8 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 + - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 69 ++- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 456 ++++++++++++++++++-- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 21 + - 6 files changed, 561 insertions(+), 61 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 113ac760731..3199072275b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -2062,7 +2062,7 @@ struct hlsl_ir_node *hlsl_block_add_load_component(struct hlsl_ctx *ctx, struct - return &load->node; - } - --static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, -+static struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, - const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) - { - struct hlsl_ir_resource_load *load; -@@ -2098,18 +2098,23 @@ static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, - load->sampling_dim = params->sampling_dim; - if (load->sampling_dim == HLSL_SAMPLER_DIM_GENERIC) - load->sampling_dim = hlsl_deref_get_type(ctx, &load->resource)->sampler_dim; -- return &load->node; -+ return load; - } - - struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) - { -- return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc)); -+ struct hlsl_ir_resource_load *load = hlsl_new_resource_load(ctx, params, loc); -+ -+ if (load && load->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ hlsl_src_from_node(&load->byte_offset, hlsl_block_add_uint_constant(ctx, block, 0, loc)); -+ -+ return append_new_instr(ctx, block, &load->node); - } - --static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type, -- const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, -- const struct vkd3d_shader_location *loc) -+static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, -+ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, -+ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) - { - struct hlsl_ir_resource_store *store; - -@@ -2117,6 +2122,7 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h - return NULL; - init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc); - store->store_type = type; -+ store->writemask = writemask; - - hlsl_copy_deref(ctx, &store->resource, resource); - hlsl_src_from_node(&store->coords, coords); -@@ -2126,9 +2132,9 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h - - void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, - enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, -- struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) -+ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) - { -- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc)); -+ append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc)); - } - - struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count, -@@ -2377,6 +2383,19 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index) - return false; - } - -+bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index) -+{ -+ if (index->val.node->type == HLSL_IR_LOAD) -+ { -+ struct hlsl_ir_load *load = hlsl_ir_load(index->val.node); -+ return load->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED; -+ } -+ -+ if (index->val.node->type == HLSL_IR_INDEX) -+ return hlsl_index_chain_has_tgsm_access(hlsl_ir_index(index->val.node)); -+ return false; -+} -+ - static struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, - struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) - { -@@ -2648,6 +2667,7 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, - vkd3d_free(dst); - return NULL; - } -+ clone_src(map, &dst->byte_offset, &src->byte_offset); - clone_src(map, &dst->coords, &src->coords); - clone_src(map, &dst->lod, &src->lod); - clone_src(map, &dst->ddx, &src->ddx); -@@ -2668,6 +2688,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, - return NULL; - init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc); - dst->store_type = src->store_type; -+ dst->writemask = src->writemask; - if (!clone_deref(ctx, map, &dst->resource, &src->resource)) - { - vkd3d_free(dst); -@@ -2985,6 +3006,17 @@ bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const - return ret; - } - -+struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) -+{ -+ struct clone_instr_map map = {0}; -+ struct hlsl_ir_node *ret; -+ -+ ret = clone_instr(ctx, &map, instr); -+ vkd3d_free(map.instrs); -+ -+ return ret; -+} -+ - struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, - struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, - const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) -@@ -3219,12 +3251,14 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl - return; - } - -- VKD3D_ASSERT(hlsl_is_numeric_type(type->e.resource.format)); -- VKD3D_ASSERT(type->e.resource.format->e.numeric.type < ARRAY_SIZE(base_types)); - if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) - { - vkd3d_string_buffer_printf(buffer, "Buffer<"); - } -+ else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ { -+ vkd3d_string_buffer_printf(buffer, "StructuredBuffer<"); -+ } - else - { - VKD3D_ASSERT(type->sampler_dim < ARRAY_SIZE(dimensions)); -@@ -3762,6 +3796,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru - dump_deref(buffer, &load->resource); - vkd3d_string_buffer_printf(buffer, ", sampler = "); - dump_deref(buffer, &load->sampler); -+ if (load->byte_offset.node) -+ { -+ vkd3d_string_buffer_printf(buffer, ", byte_offset = "); -+ dump_src(buffer, &load->byte_offset); -+ } - if (load->coords.node) - { - vkd3d_string_buffer_printf(buffer, ", coords = "); -@@ -3800,7 +3839,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru - vkd3d_string_buffer_printf(buffer, ")"); - } - --static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) -+static void dump_ir_resource_store(struct hlsl_ctx *ctx, -+ struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) - { - static const char *const type_names[] = - { -@@ -3812,6 +3852,8 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str - VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names)); - vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]); - dump_deref(buffer, &store->resource); -+ if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->resource))) -+ vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask)); - if (store->coords.node) - { - vkd3d_string_buffer_printf(buffer, ", coords = "); -@@ -4024,7 +4066,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, - break; - - case HLSL_IR_RESOURCE_STORE: -- dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr)); -+ dump_ir_resource_store(ctx, buffer, hlsl_ir_resource_store(instr)); - break; - - case HLSL_IR_STRING_CONSTANT: -@@ -4230,6 +4272,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) - { - hlsl_cleanup_deref(&load->sampler); - hlsl_cleanup_deref(&load->resource); -+ hlsl_src_remove(&load->byte_offset); - hlsl_src_remove(&load->coords); - hlsl_src_remove(&load->lod); - hlsl_src_remove(&load->ddx); -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index d899c33f8a2..c3002258aa2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -554,6 +554,7 @@ struct hlsl_ir_var - uint32_t is_param : 1; - uint32_t is_separated_resource : 1; - uint32_t is_synthetic : 1; -+ uint32_t is_tgsm : 1; - uint32_t has_explicit_bind_point : 1; - }; - -@@ -893,7 +894,7 @@ struct hlsl_ir_resource_load - struct hlsl_ir_node node; - enum hlsl_resource_load_type load_type; - struct hlsl_deref resource, sampler; -- struct hlsl_src coords, lod, ddx, ddy, cmp, sample_index, texel_offset; -+ struct hlsl_src byte_offset, coords, lod, ddx, ddy, cmp, sample_index, texel_offset; - enum hlsl_sampler_dim sampling_dim; - }; - -@@ -910,6 +911,7 @@ struct hlsl_ir_resource_store - enum hlsl_resource_store_type store_type; - struct hlsl_deref resource; - struct hlsl_src coords, value; -+ uint8_t writemask; - }; - - struct hlsl_ir_store -@@ -1586,7 +1588,7 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h - const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); - void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, - enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, -- struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); -+ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc); - struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc); - void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block, -@@ -1609,6 +1611,7 @@ struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc); - void hlsl_block_cleanup(struct hlsl_block *block); - bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block); -+struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr); - - void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func, - const char *description, const struct hlsl_block *processed_block); -@@ -1709,6 +1712,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls - bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index); - bool hlsl_index_is_resource_access(struct hlsl_ir_index *index); - bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); -+bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index); - - struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, - const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -index d9fd43b5e78..0cdebb8a657 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -@@ -158,6 +158,7 @@ static {return KW_STATIC; } - string {return KW_STRING; } - String {return KW_STRING; } - struct {return KW_STRUCT; } -+StructuredBuffer {return KW_STRUCTUREDBUFFER; } - switch {return KW_SWITCH; } - tbuffer {return KW_TBUFFER; } - (?i:technique) {return KW_TECHNIQUE; } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 40353abd81b..66582e884fe 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -2117,7 +2117,8 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc - VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); - VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count); - -- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc); -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, -+ &resource_deref, coords, rhs, writemask, &lhs->loc); - hlsl_cleanup_deref(&resource_deref); - } - else if (matrix_writemask) -@@ -2566,13 +2567,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) - "Ignoring the 'groupshared' modifier in a non-compute shader."); - } - -- if (modifiers & HLSL_STORAGE_GROUPSHARED) -- hlsl_fixme(ctx, &var->loc, "Group shared variables."); -- - /* Mark it as uniform. We need to do this here since synthetic - * variables also get put in the global scope, but shouldn't be - * considered uniforms, and we have no way of telling otherwise. */ -- if (!(modifiers & HLSL_STORAGE_STATIC)) -+ if (!(modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_GROUPSHARED))) - var->storage_modifiers |= HLSL_STORAGE_UNIFORM; - - if (stream_output) -@@ -5065,13 +5063,25 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op - - if (hlsl_deref_get_type(ctx, &dst_deref)->class != HLSL_CLASS_UAV) - { -- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements."); -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Interlocked targets must be UAV or groupshared elements."); - return false; - } - } -+ else if (lhs->type == HLSL_IR_INDEX && hlsl_index_chain_has_tgsm_access(hlsl_ir_index(lhs))) -+ { -+ hlsl_fixme(ctx, loc, "Interlocked operations on indexed groupshared elements."); -+ return false; -+ } -+ else if (lhs->type == HLSL_IR_LOAD && (hlsl_ir_load(lhs)->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED)) -+ { -+ hlsl_init_simple_deref_from_var(&dst_deref, hlsl_ir_load(lhs)->src.var); -+ coords = hlsl_block_add_uint_constant(ctx, params->instrs, 0, loc); -+ } - else - { -- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements."); -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Interlocked targets must be UAV or groupshared elements."); - return false; - } - -@@ -5637,6 +5647,7 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) - case HLSL_SAMPLER_DIM_CUBEARRAY: - case HLSL_SAMPLER_DIM_BUFFER: - case HLSL_SAMPLER_DIM_RAW_BUFFER: -+ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: - /* Offset parameters not supported for these types. */ - return 0; - default: -@@ -6302,6 +6313,7 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block - struct hlsl_ir_node *offset, *rhs; - struct hlsl_deref resource_deref; - unsigned int value_dim; -+ uint32_t writemask; - - if (params->args_count != 2) - { -@@ -6323,11 +6335,12 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block - hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); - rhs = add_implicit_conversion(ctx, block, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc); -+ writemask = vkd3d_write_mask_from_component_count(value_dim); - - if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) - return false; - -- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc); -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, writemask, loc); - hlsl_cleanup_deref(&resource_deref); - - return true; -@@ -6352,7 +6365,7 @@ static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *b - if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc))) - return false; - -- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc); -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, 0, loc); - hlsl_cleanup_deref(&so_deref); - - return true; -@@ -6373,7 +6386,7 @@ static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_bl - if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) - return false; - -- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc); -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, 0, loc); - hlsl_cleanup_deref(&so_deref); - - return true; -@@ -6554,19 +6567,25 @@ static bool add_object_property_access(struct hlsl_ctx *ctx, - return false; - } - --static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, -- const struct vkd3d_shader_location *loc) -+static void validate_texture_format_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, -+ struct hlsl_type *format, const struct vkd3d_shader_location *loc) - { -- if (format->class > HLSL_CLASS_VECTOR) -- { -- struct vkd3d_string_buffer *string; -+ struct vkd3d_string_buffer *string; - -- string = hlsl_type_to_string(ctx, format); -- if (string) -+ if (!(string = hlsl_type_to_string(ctx, format))) -+ return; -+ -+ if (dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ { -+ if (!type_contains_only_numerics(format)) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -- "Texture data type %s is not scalar or vector.", string->buffer); -- hlsl_release_string_buffer(ctx, string); -+ "SRV type %s is not numeric.", string->buffer); - } -+ else if (format->class > HLSL_CLASS_VECTOR) -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Texture data type %s is not scalar or vector.", string->buffer); -+ -+ hlsl_release_string_buffer(ctx, string); - } - - static bool check_continue(struct hlsl_ctx *ctx, const struct hlsl_scope *scope, const struct vkd3d_shader_location *loc) -@@ -6834,6 +6853,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, - %token KW_STATIC - %token KW_STRING - %token KW_STRUCT -+%token KW_STRUCTUREDBUFFER - %token KW_SWITCH - %token KW_TBUFFER - %token KW_TECHNIQUE -@@ -7921,6 +7941,10 @@ texture_type: - { - $$ = HLSL_SAMPLER_DIM_BUFFER; - } -+ | KW_STRUCTUREDBUFFER -+ { -+ $$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; -+ } - | KW_TEXTURE1D - { - $$ = HLSL_SAMPLER_DIM_1D; -@@ -8144,16 +8168,19 @@ type_no_void: - } - | texture_type - { -+ if ($1 == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Structured buffer type requires an explicit format."); - $$ = hlsl_new_texture_type(ctx, $1, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), 0); - } - | texture_type '<' resource_format '>' - { -- validate_texture_format_type(ctx, $3, &@3); -+ validate_texture_format_type(ctx, $1, $3, &@3); - $$ = hlsl_new_texture_type(ctx, $1, $3, 0); - } - | texture_ms_type '<' resource_format '>' - { -- validate_texture_format_type(ctx, $3, &@3); -+ validate_texture_format_type(ctx, $1, $3, &@3); - - $$ = hlsl_new_texture_type(ctx, $1, $3, 0); - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 5a11547e7a1..dbda72eb30f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -94,6 +94,134 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str - return base_offset; - } - -+static unsigned int base_type_get_byte_size(enum hlsl_base_type t) -+{ -+ switch (t) -+ { -+ case HLSL_TYPE_HALF: -+ case HLSL_TYPE_MIN16UINT: -+ case HLSL_TYPE_FLOAT: -+ case HLSL_TYPE_INT: -+ case HLSL_TYPE_UINT: -+ case HLSL_TYPE_BOOL: -+ return 4; -+ -+ case HLSL_TYPE_DOUBLE: -+ return 8; -+ } -+ -+ return 0; -+} -+ -+static unsigned int hlsl_type_get_packed_alignment(const struct hlsl_type *type) -+{ -+ unsigned int max_align, i; -+ -+ switch (type->class) -+ { -+ case HLSL_CLASS_SCALAR: -+ case HLSL_CLASS_VECTOR: -+ case HLSL_CLASS_MATRIX: -+ return base_type_get_byte_size(type->e.numeric.type); -+ -+ case HLSL_CLASS_ARRAY: -+ return hlsl_type_get_packed_alignment(type->e.array.type); -+ -+ case HLSL_CLASS_STRUCT: -+ for (i = 0, max_align = 0; i < type->e.record.field_count; ++i) -+ { -+ struct hlsl_struct_field *field = &type->e.record.fields[i]; -+ -+ max_align = max(max_align, hlsl_type_get_packed_alignment(field->type)); -+ } -+ -+ return max_align; -+ -+ default: -+ vkd3d_unreachable(); -+ } -+} -+ -+static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) -+{ -+ unsigned int size, i; -+ -+ switch (type->class) -+ { -+ case HLSL_CLASS_SCALAR: -+ case HLSL_CLASS_VECTOR: -+ return type->e.numeric.dimx * base_type_get_byte_size(type->e.numeric.type); -+ -+ case HLSL_CLASS_MATRIX: -+ return type->e.numeric.dimx * type->e.numeric.dimy * base_type_get_byte_size(type->e.numeric.type); -+ -+ case HLSL_CLASS_ARRAY: -+ return type->e.array.elements_count * hlsl_type_get_packed_size(type->e.array.type); -+ -+ case HLSL_CLASS_STRUCT: -+ for (i = 0, size = 0; i < type->e.record.field_count; ++i) -+ { -+ struct hlsl_struct_field *field = &type->e.record.fields[i]; -+ -+ size = align(size, hlsl_type_get_packed_alignment(field->type)) -+ + hlsl_type_get_packed_size(field->type); -+ } -+ size = align(size, hlsl_type_get_packed_alignment(type)); -+ -+ return size; -+ -+ default: -+ vkd3d_unreachable(); -+ } -+} -+ -+static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hlsl_ctx *ctx, -+ struct hlsl_block *block, struct hlsl_ir_node *prev_offset, struct hlsl_ir_node *idx, -+ struct hlsl_type *type, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_ir_node *idx_offset = NULL, *c; -+ unsigned int field_idx, offset, size, i; -+ -+ switch (type->class) -+ { -+ case HLSL_CLASS_VECTOR: -+ c = hlsl_block_add_uint_constant(ctx, block, base_type_get_byte_size(type->e.numeric.type), loc); -+ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); -+ break; -+ -+ case HLSL_CLASS_MATRIX: -+ size = base_type_get_byte_size(type->e.numeric.type) * hlsl_type_minor_size(type); -+ c = hlsl_block_add_uint_constant(ctx, block, size, loc); -+ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); -+ break; -+ -+ case HLSL_CLASS_ARRAY: -+ size = hlsl_type_get_packed_size(type->e.array.type); -+ c = hlsl_block_add_uint_constant(ctx, block, size, loc); -+ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); -+ break; -+ -+ case HLSL_CLASS_STRUCT: -+ field_idx = hlsl_ir_constant(idx)->value.u[0].u; -+ for (i = 0, offset = 0; i < field_idx; ++i) -+ { -+ struct hlsl_struct_field *field = &type->e.record.fields[i]; -+ -+ offset = align(offset, hlsl_type_get_packed_alignment(field->type)) -+ + hlsl_type_get_packed_size(field->type); -+ } -+ -+ offset = align(offset, hlsl_type_get_packed_alignment(type->e.record.fields[field_idx].type)); -+ idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); -+ break; -+ -+ default: -+ vkd3d_unreachable(); -+ } -+ -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, idx_offset, prev_offset); -+} -+ - /* TODO: remove when no longer needed, only used for replace_deref_path_with_offset() */ - static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct hlsl_deref *deref, unsigned int *offset_component, const struct vkd3d_shader_location *loc) -@@ -1308,6 +1436,73 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - return true; - } - -+ if (val->type == HLSL_IR_RESOURCE_LOAD) -+ { -+ struct hlsl_ir_resource_load *parent = hlsl_ir_resource_load(index->val.node); -+ -+ if (parent->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ { -+ if (hlsl_index_is_noncontiguous(index)) -+ { -+ /* For column major matrices, since we have to output a row, -+ * we need to emit dimx loads. */ -+ struct hlsl_ir_node *mat = index->val.node; -+ struct hlsl_deref row_deref; -+ -+ if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) -+ return false; -+ hlsl_init_simple_deref_from_var(&row_deref, var); -+ -+ for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i) -+ { -+ struct hlsl_type *type = parent->node.data_type; -+ struct hlsl_ir_node *c, *c_offset, *idx_offset; -+ struct hlsl_ir_resource_load *column_load; -+ -+ c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc); -+ c_offset = hlsl_block_add_packed_index_offset_append(ctx, -+ block, parent->byte_offset.node, c, type, &instr->loc); -+ type = hlsl_get_element_type_from_path_index(ctx, type, c); -+ -+ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, -+ block, c_offset, index->idx.node, type, &instr->loc); -+ type = hlsl_get_element_type_from_path_index(ctx, type, c_offset); -+ -+ column_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node)); -+ -+ hlsl_src_remove(&column_load->byte_offset); -+ hlsl_src_from_node(&column_load->byte_offset, idx_offset); -+ column_load->node.data_type = type; -+ -+ hlsl_block_add_instr(block, &column_load->node); -+ -+ hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node); -+ } -+ -+ hlsl_block_add_simple_load(ctx, block, var, &instr->loc); -+ } -+ else -+ { -+ struct hlsl_type *type = parent->node.data_type; -+ struct hlsl_ir_resource_load *appended_load; -+ struct hlsl_ir_node *idx_offset; -+ -+ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, block, -+ parent->byte_offset.node, index->idx.node, type, &instr->loc); -+ appended_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node)); -+ type = hlsl_get_element_type_from_path_index(ctx, type, index->idx.node); -+ -+ hlsl_src_remove(&appended_load->byte_offset); -+ hlsl_src_from_node(&appended_load->byte_offset, idx_offset); -+ appended_load->node.data_type = type; -+ -+ hlsl_block_add_instr(block, &appended_load->node); -+ } -+ -+ return true; -+ } -+ } -+ - if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc))) - return false; - hlsl_init_simple_deref_from_var(&var_deref, var); -@@ -1386,6 +1581,67 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s - return false; - } - -+/* Lowers loads from TGSMs to resource loads. */ -+static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+{ -+ struct hlsl_resource_load_params params = {.type = HLSL_RESOURCE_LOAD}; -+ const struct vkd3d_shader_location *loc = &instr->loc; -+ struct hlsl_ir_load *load; -+ struct hlsl_deref *deref; -+ -+ if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type)) -+ return false; -+ load = hlsl_ir_load(instr); -+ deref = &load->src; -+ -+ if (!deref->var->is_tgsm) -+ return false; -+ -+ if (deref->path_len) -+ { -+ hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM."); -+ return false; -+ } -+ -+ params.resource = hlsl_block_add_simple_load(ctx, block, deref->var, loc); -+ params.format = instr->data_type; -+ params.coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); -+ hlsl_block_add_resource_load(ctx, block, ¶ms, loc); -+ -+ return true; -+} -+ -+/* Lowers stores to TGSMs to resource stores. */ -+static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+{ -+ struct hlsl_ir_store *store; -+ struct hlsl_ir_node *coords; -+ struct hlsl_deref res_deref; -+ struct hlsl_deref *deref; -+ -+ if (instr->type != HLSL_IR_STORE) -+ return false; -+ store = hlsl_ir_store(instr); -+ deref = &store->lhs; -+ -+ if (!deref->var->is_tgsm) -+ return false; -+ -+ if (deref->path_len) -+ { -+ hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM."); -+ return false; -+ } -+ -+ hlsl_init_simple_deref_from_var(&res_deref, deref->var); -+ coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); -+ -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref, -+ coords, store->rhs.node, store->writemask, &instr->loc); -+ -+ return true; -+} -+ - /* Allocate a unique, ordered index to each instruction, which will be used for - * copy propagation and computing liveness ranges. - * Index 0 means unused, so start at 1. */ -@@ -3217,10 +3473,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - { - struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); - -- if (!load->resource.var->is_uniform) -+ if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm) - { - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, -- "Loaded resource must have a single uniform source."); -+ "Loaded resource must have a single uniform or groupshared source."); - } - else if (validate_component_index_range_from_deref(ctx, &load->resource) == DEREF_VALIDATION_NOT_CONSTANT) - { -@@ -3251,10 +3507,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - { - struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr); - -- if (!store->resource.var->is_uniform) -+ if (!store->resource.var->is_uniform && !store->resource.var->is_tgsm) - { - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, -- "Accessed resource must have a single uniform source."); -+ "Accessed resource must have a single uniform or groupshared source."); - } - else if (validate_component_index_range_from_deref(ctx, &store->resource) == DEREF_VALIDATION_NOT_CONSTANT) - { -@@ -3281,10 +3537,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - { - struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr); - -- if (!interlocked->dst.var->is_uniform) -+ if (!interlocked->dst.var->is_uniform && !interlocked->dst.var->is_tgsm) - { - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, -- "Accessed resource must have a single uniform source."); -+ "Accessed resource must have a single uniform or groupshared source."); - } - else if (validate_component_index_range_from_deref(ctx, &interlocked->dst) == DEREF_VALIDATION_NOT_CONSTANT) - { -@@ -3482,7 +3738,30 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst - hlsl_src_remove(&store->value); - - return true; -+} - -+static void split_resource_load(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, -+ struct hlsl_ir_resource_load *load, const unsigned int idx, struct hlsl_type *type) -+{ -+ struct hlsl_ir_resource_load *vector_load; -+ struct hlsl_ir_node *c, *idx_offset; -+ struct hlsl_block block; -+ -+ hlsl_block_init(&block); -+ -+ c = hlsl_block_add_uint_constant(ctx, &block, idx, &store->node.loc); -+ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, &block, -+ load->byte_offset.node, c, load->node.data_type, &store->node.loc); -+ -+ vector_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &load->node)); -+ hlsl_src_remove(&vector_load->byte_offset); -+ hlsl_src_from_node(&vector_load->byte_offset, idx_offset); -+ vector_load->node.data_type = type; -+ hlsl_block_add_instr(&block, &vector_load->node); -+ -+ hlsl_block_add_store_index(ctx, &block, &store->lhs, c, &vector_load->node, 0, &store->node.loc); -+ -+ list_move_before(&store->node.entry, &block.instrs); - } - - static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -3503,16 +3782,32 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - return false; - element_type = hlsl_get_vector_type(ctx, type->e.numeric.type, hlsl_type_minor_size(type)); - -- if (rhs->type != HLSL_IR_LOAD) -+ if (rhs->type != HLSL_IR_LOAD && rhs->type != HLSL_IR_RESOURCE_LOAD) - { - hlsl_fixme(ctx, &instr->loc, "Copying from unsupported node type."); - return false; - } - -- for (i = 0; i < hlsl_type_major_size(type); ++i) -+ if (rhs->type == HLSL_IR_RESOURCE_LOAD) - { -- if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) -- return false; -+ /* As we forbid non-scalar or vector types in non-structured resource -+ * loads, this is specific to structured buffer loads. */ -+ struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(rhs); -+ -+ VKD3D_ASSERT(hlsl_deref_get_type(ctx, &load->resource)->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER); -+ -+ for (i = 0; i < hlsl_type_major_size(type); ++i) -+ { -+ split_resource_load(ctx, store, load, i, element_type); -+ } -+ } -+ else -+ { -+ for (i = 0; i < hlsl_type_major_size(type); ++i) -+ { -+ if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) -+ return false; -+ } - } - - list_remove(&store->node.entry); -@@ -5486,6 +5781,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop - deref_mark_last_read(&load->sampler, last_read); - } - -+ if (load->byte_offset.node) -+ load->byte_offset.node->last_read = last_read; - if (load->coords.node) - load->coords.node->last_read = last_read; - if (load->texel_offset.node) -@@ -5867,6 +6164,9 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls - load = hlsl_ir_resource_load(instr); - var = load->resource.var; - -+ if (var->is_tgsm) -+ return false; -+ - regset = hlsl_deref_get_regset(ctx, &load->resource); - if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) - return false; -@@ -5935,7 +6235,7 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - { - struct hlsl_ir_load *load = hlsl_ir_load(instr); - -- if (!load->src.var->is_uniform) -+ if (!load->src.var->is_uniform && !load->src.var->is_tgsm) - return false; - - /* These will are handled by validate_static_object_references(). */ -@@ -6459,7 +6759,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block - { - LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) - { -- if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform)) -+ if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform || var->is_tgsm)) - memset(var->regs, 0, sizeof(var->regs)); - } - } -@@ -7109,6 +7409,27 @@ static void allocate_stream_outputs(struct hlsl_ctx *ctx) - } - } - -+static void allocate_tgsms(struct hlsl_ctx *ctx) -+{ -+ struct hlsl_ir_var *var; -+ struct hlsl_reg *reg; -+ uint32_t index = 0; -+ -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ if (!var->is_tgsm || !var->bind_count[HLSL_REGSET_NUMERIC]) -+ continue; -+ -+ reg = &var->regs[HLSL_REGSET_NUMERIC]; -+ reg->space = 0; -+ reg->index = index; -+ reg->id = index; -+ reg->allocated = true; -+ -+ ++index; -+ } -+} -+ - bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, - unsigned int *start, unsigned int *count) - { -@@ -8700,6 +9021,15 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p - *writemask = hlsl_reg.writemask; - } - } -+ else if (var->is_tgsm) -+ { -+ VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated); -+ reg->type = VKD3DSPR_GROUPSHAREDMEM; -+ reg->dimension = VSIR_DIMENSION_VEC4; -+ reg->idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; -+ reg->idx_count = 1; -+ *writemask = (1u << data_type->e.numeric.dimx) - 1; -+ } - else - { - return sm4_generate_vsir_numeric_reg_from_deref(ctx, program, reg, writemask, deref); -@@ -10906,6 +11236,8 @@ static bool sm4_generate_vsir_instr_store(struct hlsl_ctx *ctx, - struct vkd3d_shader_src_param *src_param; - struct vkd3d_shader_instruction *ins; - -+ VKD3D_ASSERT(!store->lhs.var->is_tgsm); -+ - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) - return false; - -@@ -10940,6 +11272,7 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr - struct vkd3d_shader_instruction *ins; - struct hlsl_constant_value value; - -+ VKD3D_ASSERT(!load->src.var->is_tgsm); - VKD3D_ASSERT(hlsl_is_numeric_type(type)); - if (type->e.numeric.type == HLSL_TYPE_BOOL && var_is_user_input(version, load->src.var)) - { -@@ -10984,8 +11317,8 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, - struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &store->resource); - struct hlsl_ir_node *coords = store->coords.node, *value = store->value.node; - struct hlsl_ir_node *instr = &store->node; -+ bool tgsm = store->resource.var->is_tgsm; - struct vkd3d_shader_instruction *ins; -- unsigned int writemask; - - if (store->store_type != HLSL_RESOURCE_STORE) - { -@@ -11012,9 +11345,9 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, - return true; - } - -- if (!store->resource.var->is_uniform) -+ if (!store->resource.var->is_uniform && !tgsm) - { -- hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable."); -+ hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform non-groupshared resource variable."); - return false; - } - -@@ -11024,14 +11357,19 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, - return false; - } - -- if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) -+ if (tgsm && !hlsl_is_numeric_type(resource_type)) -+ { -+ hlsl_fixme(ctx, &store->node.loc, "Store to structured TGSM."); -+ return false; -+ } -+ -+ if (tgsm || resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) - { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_RAW, 1, 2))) - return false; - -- writemask = vkd3d_write_mask_from_component_count(value->data_type->e.numeric.dimx); -- if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, -- &ins->dst[0], &store->resource, &instr->loc, writemask)) -+ if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, &ins->dst[0], -+ &store->resource, &instr->loc, store->writemask)) - return false; - } - else -@@ -11092,7 +11430,6 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, - const struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &load->resource); - bool uav = (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS); - const struct vkd3d_shader_version *version = &program->shader_version; -- bool raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER; - const struct hlsl_ir_node *sample_index = load->sample_index.node; - const struct hlsl_ir_node *texel_offset = load->texel_offset.node; - const struct hlsl_ir_node *coords = load->coords.node; -@@ -11100,16 +11437,33 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, - const struct hlsl_deref *resource = &load->resource; - const struct hlsl_ir_node *instr = &load->node; - enum hlsl_sampler_dim dim = load->sampling_dim; -+ bool tgsm = load->resource.var->is_tgsm; - struct vkd3d_shader_instruction *ins; - enum vkd3d_shader_opcode opcode; -- bool multisampled; -+ bool multisampled, raw; - - VKD3D_ASSERT(load->load_type == HLSL_RESOURCE_LOAD); - -+ if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ { -+ hlsl_fixme(ctx, &load->node.loc, "Structured buffer loads."); -+ return false; -+ } -+ - multisampled = resource_type->class == HLSL_CLASS_TEXTURE - && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS - || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); - -+ if (!tgsm) -+ { -+ raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER; -+ } -+ else if (!(raw = hlsl_is_numeric_type(resource_type))) -+ { -+ hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); -+ return false; -+ } -+ - if (uav) - opcode = VSIR_OP_LD_UAV_TYPED; - else if (raw) -@@ -11130,7 +11484,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, - - vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); - -- if (!uav) -+ if (!uav && !tgsm) - { - /* Mipmap level is in the last component in the IR, but needs to be in - * the W component in the instruction. */ -@@ -11401,7 +11755,7 @@ static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, - return false; - } - -- if (!load->resource.var->is_uniform) -+ if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm) - { - hlsl_fixme(ctx, &load->node.loc, "Load from non-uniform resource variable."); - return false; -@@ -11761,7 +12115,7 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se - { - LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) - { -- if (var->is_uniform || var->is_input_semantic || var->is_output_semantic) -+ if (var->is_uniform || var->is_tgsm || var->is_input_semantic || var->is_output_semantic) - continue; - if (!var->regs[HLSL_REGSET_NUMERIC].allocated) - continue; -@@ -12161,6 +12515,9 @@ static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_t - { - const struct hlsl_type *format = type->e.resource.format; - -+ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ return VSIR_DATA_MIXED; -+ - switch (format->e.numeric.type) - { - case HLSL_TYPE_DOUBLE: -@@ -12299,6 +12656,34 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, - } - } - -+static void sm4_generate_vsir_add_dcl_tgsm(struct hlsl_ctx *ctx, -+ struct vsir_program *program, const struct hlsl_ir_var *var) -+{ -+ struct vkd3d_shader_dst_param *dst_param; -+ struct vkd3d_shader_instruction *ins; -+ -+ if (!hlsl_is_numeric_type(var->data_type)) -+ { -+ hlsl_fixme(ctx, &var->loc, "Structured TGSM declaration."); -+ return; -+ } -+ -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VSIR_OP_DCL_TGSM_RAW, 0, 0))) -+ { -+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; -+ return; -+ } -+ -+ dst_param = &ins->declaration.tgsm_raw.reg; -+ -+ vsir_dst_param_init(dst_param, VKD3DSPR_GROUPSHAREDMEM, VSIR_DATA_F32, 1); -+ dst_param->reg.dimension = VSIR_DIMENSION_NONE; -+ dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; -+ -+ ins->declaration.tgsm_raw.byte_count = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * 4; -+ ins->declaration.tgsm_raw.zero_init = false; -+} -+ - static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, - struct vsir_program *program, const struct hlsl_ir_var *var) - { -@@ -12327,6 +12712,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - struct extern_resource *extern_resources; - unsigned int extern_resources_count; - const struct hlsl_buffer *cbuffer; -+ const struct hlsl_ir_var *var; - - if (version->type == VKD3D_SHADER_TYPE_COMPUTE) - { -@@ -12377,10 +12763,14 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - } - sm4_free_extern_resources(extern_resources, extern_resources_count); - -- if (version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { -- const struct hlsl_ir_var *var; -+ if (var->is_tgsm && var->regs[HLSL_REGSET_NUMERIC].allocated) -+ sm4_generate_vsir_add_dcl_tgsm(ctx, program, var); -+ } - -+ if (version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) -+ { - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (var->bind_count[HLSL_REGSET_STREAM_OUTPUTS]) -@@ -12489,6 +12879,9 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) - { - const struct hlsl_type *format = type->e.resource.format; - -+ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ return D3D_RETURN_TYPE_MIXED; -+ - switch (format->e.numeric.type) - { - case HLSL_TYPE_DOUBLE: -@@ -13594,6 +13987,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v - lower_ir(ctx, lower_matrix_swizzles, body); - lower_ir(ctx, lower_index_loads, body); - -+ lower_ir(ctx, lower_tgsm_loads, body); -+ lower_ir(ctx, lower_tgsm_stores, body); -+ - if (entry_func->return_var) - { - if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) -@@ -13903,7 +14299,14 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info - LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) - { - if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) -+ { - prepend_uniform_copy(ctx, &global_uniform_block, var); -+ } -+ else if (var->storage_modifiers & HLSL_STORAGE_GROUPSHARED) -+ { -+ var->is_tgsm = 1; -+ list_add_tail(&ctx->extern_vars, &var->extern_entry); -+ } - } - - process_entry_function(ctx, &semantic_vars, &body, &global_uniform_block, entry_func); -@@ -13932,6 +14335,7 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info - allocate_objects(ctx, &semantic_vars, HLSL_REGSET_TEXTURES); - allocate_objects(ctx, &semantic_vars, HLSL_REGSET_UAVS); - allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS); -+ allocate_tgsms(ctx); - } - - if (TRACE_ON()) -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index ed19faf945b..ea15c1a9ad5 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -3910,6 +3910,23 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s - write_sm4_instruction(tpf, &instr); - } - -+static void tpf_dcl_tgsm_raw(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) -+{ -+ const struct vkd3d_shader_tgsm_raw *tgsm = &ins->declaration.tgsm_raw; -+ struct sm4_instruction instr = -+ { -+ .opcode = VKD3D_SM5_OP_DCL_TGSM_RAW, -+ -+ .dsts[0] = tgsm->reg, -+ .dst_count = 1, -+ -+ .idx[0] = tgsm->byte_count, -+ .idx_count = 1, -+ }; -+ -+ write_sm4_instruction(tpf, &instr); -+} -+ - static void write_sm4_dcl_global_flags(const struct tpf_compiler *tpf, uint32_t flags) - { - struct sm4_instruction instr = -@@ -4199,6 +4216,10 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ - tpf_dcl_sampler(tpf, ins); - break; - -+ case VSIR_OP_DCL_TGSM_RAW: -+ tpf_dcl_tgsm_raw(tpf, ins); -+ break; -+ - case VSIR_OP_DCL: - case VSIR_OP_DCL_RESOURCE_RAW: - case VSIR_OP_DCL_UAV_RAW: --- -2.50.1 - diff --git a/patches/vkd3d-latest/0013-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch b/patches/vkd3d-latest/0013-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch deleted file mode 100644 index 5d4fbda7..00000000 --- a/patches/vkd3d-latest/0013-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch +++ /dev/null @@ -1,1950 +0,0 @@ -From baab59667d933fe15af4b456ea994d7aaf489d27 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 15 Aug 2025 07:48:03 +1000 -Subject: [PATCH] Updated vkd3d to 44fffee5e1331e1c7e10489d84723c3b9dad7e17. - ---- - libs/vkd3d/include/vkd3d_shader.h | 1 + - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 17 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 5 +- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 3 + - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 122 +++-- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 3 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 24 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 27 +- - libs/vkd3d/libs/vkd3d-shader/ir.c | 418 +++++++++++------- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 100 +++-- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 161 +++++-- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 51 ++- - 12 files changed, 607 insertions(+), 325 deletions(-) - -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index b50271ce9bb..0fd3c67b7e0 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -2966,6 +2966,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver - * - VKD3D_SHADER_SOURCE_DXBC_DXIL - * - VKD3D_SHADER_SOURCE_DXBC_TPF - * - VKD3D_SHADER_SOURCE_D3D_BYTECODE -+ * - VKD3D_SHADER_SOURCE_HLSL - * - * \param compile_info A chained structure containing scan parameters. - * \n -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 2ec9a74249b..6425a8f62d2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -1961,7 +1961,7 @@ static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler, - } - - enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, -- struct vkd3d_shader_code *out, enum vsir_asm_flags flags) -+ struct vkd3d_shader_code *out, enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context) - { - const struct vkd3d_shader_version *shader_version = &program->shader_version; - enum vkd3d_shader_compile_option_formatting_flags formatting; -@@ -2029,6 +2029,14 @@ enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd - if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) - compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES; - -+ if (compiler.flags & VSIR_ASM_FLAG_ALLOCATE_TEMPS) -+ { -+ if ((result = vsir_allocate_temp_registers(program, message_context)) < 0) -+ return result; -+ if ((result = vsir_update_dcl_temps(program, message_context))) -+ return result; -+ } -+ - buffer = &compiler.buffer; - vkd3d_string_buffer_init(buffer); - -@@ -2250,17 +2258,22 @@ void vsir_program_trace(struct vsir_program *program) - { - const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES - | VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS; -+ struct vkd3d_shader_message_context message_context; - struct vkd3d_shader_code code; - const char *p, *q, *end; - -+ vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_NONE); -+ - trace_signature(&program->input_signature, "Input"); - trace_signature(&program->output_signature, "Output"); - trace_signature(&program->patch_constant_signature, "Patch-constant"); - trace_io_declarations(program); - -- if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK) -+ if (d3d_asm_compile(program, NULL, &code, flags, &message_context) != VKD3D_OK) - return; - -+ vkd3d_shader_message_context_cleanup(&message_context); -+ - end = (const char *)code.code + code.size; - for (p = code.code; p < end; p = q) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index dd13757bf59..751e5578276 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1513,7 +1513,10 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c - return ret; - } - -- return VKD3D_OK; -+ if (program->normalisation_level >= VSIR_NORMALISED_SM4) -+ ret = vsir_program_lower_d3dbc(program, config_flags, compile_info, message_context); -+ -+ return ret; - } - - bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index e57a4aa2731..dfe0a40ddf0 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -2444,6 +2444,9 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, - if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) - return ret; - -+ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0) -+ return ret; -+ - VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); - VKD3D_ASSERT(program->has_descriptor_info); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 3199072275b..62335086e20 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -4897,8 +4897,9 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) - hlsl_release_string_buffer(ctx, name); - } - --static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, -- const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context) -+static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_files, -+ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, -+ struct vkd3d_shader_message_context *message_context) - { - unsigned int i; - -@@ -4908,15 +4909,12 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil - - ctx->message_context = message_context; - -- if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files)))) -- return false; -- if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : ""))) -- { -- vkd3d_free(ctx->source_files); -+ ctx->source_files = source_files; -+ if (!vkd3d_shader_source_list_append(source_files, -+ compile_info->source_name ? compile_info->source_name : "")) - return false; -- } -- ctx->source_files_count = 1; -- ctx->location.source_name = ctx->source_files[0]; -+ -+ ctx->location.source_name = source_files->sources[0]; - ctx->location.line = ctx->location.column = 1; - vkd3d_string_buffer_cache_init(&ctx->string_buffers); - -@@ -4924,8 +4922,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil - - if (!(ctx->dummy_scope = hlsl_new_scope(ctx, NULL))) - { -- vkd3d_free((void *)ctx->source_files[0]); -- vkd3d_free(ctx->source_files); -+ vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); - return false; - } - hlsl_push_scope(ctx); -@@ -5010,9 +5007,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) - struct hlsl_type *type, *next_type; - unsigned int i; - -- for (i = 0; i < ctx->source_files_count; ++i) -- vkd3d_free((void *)ctx->source_files[i]); -- vkd3d_free(ctx->source_files); - vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); - - rb_destroy(&ctx->functions, free_function_rb, NULL); -@@ -5054,26 +5048,13 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) - vkd3d_free(ctx->constant_defs.regs); - } - --static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, -+static int hlsl_ctx_parse(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_list, -+ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, - struct vkd3d_shader_message_context *message_context) - { - enum vkd3d_shader_target_type target_type = compile_info->target_type; -- const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; -- const struct hlsl_profile_info *profile; - int ret; - -- if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) -- { -- ERR("No HLSL source info given.\n"); -- return VKD3D_ERROR_INVALID_ARGUMENT; -- } -- -- if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) -- { -- FIXME("Unknown compilation target %s.\n", debugstr_a(hlsl_source_info->profile)); -- return VKD3D_ERROR_NOT_IMPLEMENTED; -- } -- - if (target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT) - { - vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, -@@ -5099,7 +5080,7 @@ static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil - return VKD3D_ERROR_INVALID_ARGUMENT; - } - -- if (!hlsl_ctx_init(ctx, compile_info, profile, message_context)) -+ if (!hlsl_ctx_init(ctx, source_list, compile_info, profile, message_context)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - if ((ret = hlsl_lexer_compile(ctx, &compile_info->source)) == 2) -@@ -5128,35 +5109,85 @@ static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil - int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) - { -+ const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; -+ struct vkd3d_shader_source_list source_list; -+ const struct hlsl_profile_info *profile; - struct hlsl_ctx ctx; - int ret; - -- if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0) -+ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) -+ { -+ WARN("No HLSL source info given.\n"); -+ return VKD3D_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) -+ { -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, -+ "Unknown target profile '%s'.", hlsl_source_info->profile); -+ return VKD3D_ERROR_NOT_IMPLEMENTED; -+ } -+ -+ vkd3d_shader_source_list_init(&source_list); -+ if ((ret = hlsl_ctx_parse(&ctx, &source_list, compile_info, profile, message_context)) < 0) -+ { -+ vkd3d_shader_source_list_cleanup(&source_list); - return ret; -+ } - - ret = hlsl_emit_effect_binary(&ctx, out); - hlsl_ctx_cleanup(&ctx); -+ vkd3d_shader_source_list_cleanup(&source_list); - - return ret; - } - --int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, -- struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) -+int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context, -+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data) - { - const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; -- uint64_t config_flags = vkd3d_shader_init_config_flags(); - struct hlsl_ir_function_decl *decl, *entry_func = NULL; -- struct vkd3d_shader_code reflection_data = {0}; -+ enum vsir_normalisation_level normalisation_level; -+ const struct hlsl_profile_info *profile; -+ struct vkd3d_shader_version version; - struct hlsl_ir_function *func; -- struct vsir_program program; - const char *entry_point; - struct hlsl_ctx ctx; - int ret; - -- if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0) -+ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) -+ { -+ WARN("No HLSL source info given.\n"); -+ return VKD3D_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) -+ { -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, -+ "Unknown target profile '%s'.", hlsl_source_info->profile); -+ return VKD3D_ERROR_NOT_IMPLEMENTED; -+ } -+ -+ version = (struct vkd3d_shader_version) -+ { -+ .type = profile->type, -+ .major = profile->major_version, -+ .minor = profile->minor_version, -+ }; -+ normalisation_level = VSIR_NORMALISED_SM4; -+ if (version.major < 4 && (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM -+ || compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE)) -+ normalisation_level = VSIR_NORMALISED_SM1; -+ if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, normalisation_level)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ if ((ret = hlsl_ctx_parse(&ctx, &program->source_files, compile_info, profile, message_context)) < 0) -+ { -+ vsir_program_cleanup(program); - return ret; -+ } - -- hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO); - entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; - if ((func = hlsl_get_function(&ctx, entry_point))) - { -@@ -5181,17 +5212,16 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, - hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, - "Entry point \"%s\" is not defined.", entry_point); - hlsl_ctx_cleanup(&ctx); -+ vsir_program_cleanup(program); - return VKD3D_ERROR_INVALID_SHADER; - } - -- if ((ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, &program, &reflection_data)) >= 0) -- { -- vsir_program_trace(&program); -- ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, message_context); -- vkd3d_shader_free_shader_code(&reflection_data); -- vsir_program_cleanup(&program); -- } -+ ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, program, reflection_data); - hlsl_ctx_cleanup(&ctx); -+ if (ret < 0) -+ vsir_program_cleanup(program); -+ else -+ vsir_program_trace(program); - - return ret; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index c3002258aa2..d67f820fe8b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -1093,8 +1093,7 @@ struct hlsl_ctx - { - const struct hlsl_profile_info *profile; - -- const char **source_files; -- unsigned int source_files_count; -+ struct vkd3d_shader_source_list *source_files; - /* Current location being read in the HLSL source, updated while parsing. */ - struct vkd3d_shader_location location; - /* Stores the logging messages and logging configuration. */ -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 66582e884fe..024d96c5663 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -7190,23 +7190,19 @@ declaration_statement_list: - preproc_directive: - PRE_LINE STRING - { -- const char **new_array = NULL; -- -- ctx->location.line = $1; - if (strcmp($2, ctx->location.source_name)) -- new_array = hlsl_realloc(ctx, ctx->source_files, -- sizeof(*ctx->source_files) * (ctx->source_files_count + 1)); -- -- if (new_array) -- { -- ctx->source_files = new_array; -- ctx->source_files[ctx->source_files_count++] = $2; -- ctx->location.source_name = $2; -- } -- else - { -- vkd3d_free($2); -+ if (!vkd3d_shader_source_list_append(ctx->source_files, $2)) -+ { -+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; -+ } -+ else -+ { -+ ctx->location.line = $1; -+ ctx->location.source_name = ctx->source_files->sources[ctx->source_files->count - 1]; -+ } - } -+ vkd3d_free($2); - } - - struct_declaration_without_vars: -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index dbda72eb30f..0b3dee4d2ce 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -9945,6 +9945,11 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co - sm1_generate_vsir_block(ctx, body, program); - - program->ssa_count = ctx->ssa_count; -+ -+ if (ctx->result) -+ return; -+ if (program->normalisation_level >= VSIR_NORMALISED_SM4) -+ ctx->result = vsir_program_lower_d3dbc(program, config_flags, compile_info, ctx->message_context); - } - - D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) -@@ -14272,7 +14277,6 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info - uint32_t config_flags = vkd3d_shader_init_config_flags(); - const struct hlsl_profile_info *profile = ctx->profile; - struct list semantic_vars, patch_semantic_vars; -- struct vkd3d_shader_version version = {0}; - struct hlsl_ir_var *var; - - parse_entry_function_attributes(ctx, entry_func); -@@ -14349,39 +14353,24 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info - if (ctx->result) - return ctx->result; - -- version.major = ctx->profile->major_version; -- version.minor = ctx->profile->minor_version; -- version.type = ctx->profile->type; -- if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) -- { -- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; -- return ctx->result; -- } -- - generate_vsir_signature(ctx, program, entry_func, &semantic_vars); -- if (version.type == VKD3D_SHADER_TYPE_HULL) -+ if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL) - generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars); - -- if (version.major < 4) -+ if (program->shader_version.major < 4) - sm1_generate_ctab(ctx, reflection_data); - else - sm4_generate_rdef(ctx, reflection_data); - if (ctx->result) -- { -- vsir_program_cleanup(program); - return ctx->result; -- } - -- if (version.major < 4) -+ if (program->shader_version.major < 4) - sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program); - else - sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, - &patch_semantic_vars, &patch_body, config_flags, program); - if (ctx->result) -- { - vkd3d_shader_free_shader_code(reflection_data); -- vsir_program_cleanup(program); -- } - - return ctx->result; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 9d93936ac9e..23e059a3490 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -451,6 +451,8 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c - return false; - } - -+ vkd3d_shader_source_list_init(&program->source_files); -+ - return true; - } - -@@ -463,6 +465,7 @@ void vsir_program_cleanup(struct vsir_program *program) - for (i = 0; i < program->block_name_count; ++i) - vkd3d_free((void *)program->block_names[i]); - vkd3d_free(program->block_names); -+ vkd3d_shader_source_list_cleanup(&program->source_files); - shader_instruction_array_destroy(&program->instructions); - shader_signature_cleanup(&program->input_signature); - shader_signature_cleanup(&program->output_signature); -@@ -1387,6 +1390,53 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog - return VKD3D_OK; - } - -+static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program, -+ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) -+{ -+ /* texcrd DST, t# -> mov DST, t# */ -+ -+ if (ins->src[0].modifiers) -+ { -+ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ "Aborting due to not yet implemented feature: texcrd source modifier."); -+ return VKD3D_ERROR_NOT_IMPLEMENTED; -+ } -+ -+ ins->opcode = VSIR_OP_MOV; -+ -+ return VKD3D_OK; -+} -+ -+static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program, -+ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) -+{ -+ unsigned int idx = ins->src[0].reg.idx[0].offset; -+ struct vkd3d_shader_src_param *srcs; -+ -+ /* texld DST, t# -> sample DST, t#, resource#, sampler# */ -+ -+ if (ins->src[0].modifiers) -+ { -+ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ "Aborting due to not yet implemented feature: texld source modifier."); -+ return VKD3D_ERROR_NOT_IMPLEMENTED; -+ } -+ -+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ /* Note we run before I/O normalization. */ -+ srcs[0] = ins->src[0]; -+ vsir_src_param_init_resource(&srcs[1], idx, idx); -+ vsir_src_param_init_sampler(&srcs[2], idx, idx); -+ -+ ins->opcode = VSIR_OP_SAMPLE; -+ ins->src = srcs; -+ ins->src_count = 3; -+ -+ return VKD3D_OK; -+} -+ - static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, - struct vsir_program_iterator *it, unsigned int *tmp_idx) - { -@@ -1605,6 +1655,45 @@ static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *prog - return VKD3D_OK; - } - -+static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_program *program, -+ struct vsir_transformation_context *ctx) -+{ -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vkd3d_shader_message_context *message_context = ctx->message_context; -+ struct vkd3d_shader_instruction *ins; -+ unsigned int tmp_idx = ~0u; -+ -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -+ { -+ enum vkd3d_result ret; -+ -+ switch (ins->opcode) -+ { -+ case VSIR_OP_TEXCRD: -+ ret = vsir_program_lower_texcrd(program, ins, message_context); -+ break; -+ -+ case VSIR_OP_TEXLD: -+ if (program->shader_version.major == 1) -+ ret = vsir_program_lower_texld_sm1(program, ins, message_context); -+ else if (ins->flags == VKD3DSI_TEXLD_PROJECT) -+ ret = vsir_program_lower_texldp(program, &it, &tmp_idx); -+ else -+ ret = vsir_program_lower_texld(program, ins, message_context); -+ break; -+ -+ default: -+ ret = VKD3D_OK; -+ break; -+ } -+ -+ if (ret < 0) -+ return ret; -+ } -+ -+ return VKD3D_OK; -+} -+ - static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -@@ -1688,19 +1777,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - } - break; - -- case VSIR_OP_TEXLD: -- if (ins->flags == VKD3DSI_TEXLD_PROJECT) -- { -- if ((ret = vsir_program_lower_texldp(program, &it, &tmp_idx)) < 0) -- return ret; -- } -- else -- { -- if ((ret = vsir_program_lower_texld(program, ins, message_context)) < 0) -- return ret; -- } -- break; -- - case VSIR_OP_TEXLDD: - if ((ret = vsir_program_lower_texldd(program, ins)) < 0) - return ret; -@@ -1714,7 +1790,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - case VSIR_OP_TEXBEM: - case VSIR_OP_TEXBEML: - case VSIR_OP_TEXCOORD: -- case VSIR_OP_TEXCRD: - case VSIR_OP_TEXDEPTH: - case VSIR_OP_TEXDP3: - case VSIR_OP_TEXDP3TEX: -@@ -1762,6 +1837,39 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, - return VKD3D_OK; - } - -+/* ps_1_* outputs color in r0. Add an instruction to copy that to oC0. -+ * We don't need to modify the signature since it already contains COLOR. */ -+static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program *program, -+ struct vsir_transformation_context *ctx) -+{ -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vkd3d_shader_instruction *ins; -+ struct vkd3d_shader_location loc; -+ -+ if (!(ins = vsir_program_iterator_tail(&it))) -+ return VKD3D_OK; -+ loc = ins->location; -+ -+ if (!(ins = vsir_program_append(program))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1)) -+ { -+ vsir_instruction_init(ins, &loc, VSIR_OP_NOP); -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ } -+ -+ src_param_init_temp_float4(&ins->src[0], 0); -+ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; -+ /* Note we run before I/O normalization. */ -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_COLOROUT, VSIR_DATA_F32, 1); -+ ins->dst[0].reg.idx[0].offset = 0; -+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; -+ ins->dst[0].modifiers = VKD3DSPDM_SATURATE; -+ -+ return VKD3D_OK; -+} -+ - static struct signature_element *add_signature_element(struct shader_signature *signature, - const char *semantic_name, uint32_t semantic_index, uint32_t mask, uint32_t register_index, - enum vkd3d_shader_interpolation_mode interpolation_mode) -@@ -1814,6 +1922,7 @@ static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *pr - static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - static const struct vkd3d_shader_location no_loc; - struct vkd3d_shader_instruction *ins; - unsigned int i; -@@ -1825,17 +1934,16 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra - /* Write the instruction after all LABEL, DCL, and NOP instructions. - * We need to skip NOP instructions because they might result from removed - * DCLs, and there could still be DCLs after NOPs. */ -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &program->instructions.elements[i]; -- - if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) - break; - } - -- if (!shader_instruction_array_insert_at(&program->instructions, i, 1)) -+ vsir_program_iterator_prev(&it); -+ if (!vsir_program_iterator_insert_after(&it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = &program->instructions.elements[i]; -+ ins = vsir_program_iterator_next(&it); - - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1); -@@ -1936,6 +2044,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program - struct vsir_transformation_context *ctx) - { - const struct vkd3d_shader_location location = {.source_name = ctx->compile_info->source_name}; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_message_context *message_context = ctx->message_context; - const struct vkd3d_shader_compile_info *compile_info = ctx->compile_info; - bool allows_subset_masks = target_allows_subset_masks(compile_info); -@@ -1945,6 +2054,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program - struct signature_element *new_elements, *e; - unsigned int uninit_varying_count = 0; - unsigned int subset_varying_count = 0; -+ struct vkd3d_shader_instruction *ins; - unsigned int new_register_count = 0; - unsigned int i; - -@@ -2044,18 +2154,18 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program - } - - /* Write each uninitialized varying before each ret. */ -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - struct vkd3d_shader_location loc; - - if (ins->opcode != VSIR_OP_RET) - continue; - - loc = ins->location; -- if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count)) -+ vsir_program_iterator_prev(&it); -+ if (!vsir_program_iterator_insert_after(&it, uninit_varying_count)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = &program->instructions.elements[i]; -+ ins = vsir_program_iterator_next(&it); - - for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) - { -@@ -2065,10 +2175,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program - dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask); - vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; -- ++ins; -+ ins = vsir_program_iterator_next(&it); - } -- -- i += uninit_varying_count; - } - - /* Vulkan (without KHR_maintenance4) disallows any mismatching masks, -@@ -2079,10 +2187,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program - if (!subset_varying_count || allows_subset_masks) - return VKD3D_OK; - -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - for (unsigned int j = 0; j < ins->dst_count; ++j) - remove_unread_output_components(signature, ins, &ins->dst[j]); - } -@@ -2121,10 +2227,9 @@ struct shader_phase_location_array - unsigned int count; - }; - --static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, -- unsigned int index, struct shader_phase_location_array *locations) -+static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index, -+ struct vkd3d_shader_instruction *ins, struct shader_phase_location_array *locations) - { -- struct vkd3d_shader_instruction *ins = &normaliser->program->instructions.elements[index]; - struct shader_phase_location *loc; - bool b; - -@@ -2289,15 +2394,19 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali - static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct shader_phase_location_array locations; - struct hull_flattener flattener = {program}; -+ struct vkd3d_shader_instruction *ins; - enum vkd3d_result result = VKD3D_OK; - unsigned int i; - - flattener.phase = VSIR_OP_INVALID; -- for (i = 0, locations.count = 0; i < instructions->count; ++i) -- flattener_eliminate_phase_related_dcls(&flattener, i, &locations); -+ locations.count = 0; -+ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) -+ { -+ flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations); -+ } - bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID); - bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID); - -@@ -2315,10 +2424,9 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro - - if (flattener.phase != VSIR_OP_INVALID) - { -- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) -+ if (!(ins = vsir_program_append(program))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- vsir_instruction_init(&instructions->elements[instructions->count++], -- &flattener.last_ret_location, VSIR_OP_RET); -+ vsir_instruction_init(ins, &flattener.last_ret_location, VSIR_OP_RET); - } - - return result; -@@ -2436,11 +2544,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p - static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io( - struct vsir_program *program, struct vsir_transformation_context *ctx) - { -- struct vkd3d_shader_instruction_array *instructions; - struct control_point_normaliser normaliser; - unsigned int input_control_point_count; - struct vkd3d_shader_location location; - struct vkd3d_shader_instruction *ins; -+ struct vsir_program_iterator it; - enum vkd3d_result ret; - unsigned int i, j; - -@@ -2458,13 +2566,11 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i - return VKD3D_ERROR_OUT_OF_MEMORY; - } - normaliser.instructions = program->instructions; -- instructions = &normaliser.instructions; -+ it = vsir_program_iterator(&normaliser.instructions); - normaliser.phase = VSIR_OP_INVALID; - -- for (i = 0; i < normaliser.instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &instructions->elements[i]; -- - switch (ins->opcode) - { - case VSIR_OP_HS_CONTROL_POINT_PHASE: -@@ -2484,10 +2590,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i - normaliser.phase = VSIR_OP_INVALID; - input_control_point_count = 1; - -- for (i = 0; i < instructions->count; ++i) -+ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) - { -- ins = &instructions->elements[i]; -- - switch (ins->opcode) - { - case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: -@@ -2531,7 +2635,6 @@ struct io_normaliser - { - struct vkd3d_shader_message_context *message_context; - enum vkd3d_result result; -- struct vkd3d_shader_instruction_array instructions; - enum vkd3d_shader_type shader_type; - uint8_t major; - struct shader_signature *input_signature; -@@ -3147,10 +3250,10 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi - static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -- struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK, program->instructions}; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK}; - struct vkd3d_shader_instruction *ins; - enum vkd3d_result ret; -- unsigned int i; - - VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_HULL_CONTROL_POINT_IO); - -@@ -3161,10 +3264,8 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program - normaliser.output_signature = &program->output_signature; - normaliser.patch_constant_signature = &program->patch_constant_signature; - -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &program->instructions.elements[i]; -- - switch (ins->opcode) - { - case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: -@@ -3190,16 +3291,14 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program - normaliser.output_range_map, false)) < 0 - || (ret = shader_signature_merge(&normaliser, &program->patch_constant_signature, - normaliser.pc_range_map, true)) < 0) -- { -- program->instructions = normaliser.instructions; - return ret; -- } - - normaliser.phase = VSIR_OP_INVALID; -- for (i = 0; i < normaliser.instructions.count; ++i) -- shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser); -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -+ { -+ shader_instruction_normalise_io_params(ins, &normaliser); -+ } - -- program->instructions = normaliser.instructions; - program->use_vocp = normaliser.use_vocp; - program->normalisation_level = VSIR_NORMALISED_SM6; - return normaliser.result; -@@ -3288,13 +3387,13 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par - static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct flat_constants_normaliser normaliser = {0}; -- unsigned int i, j; -+ struct vkd3d_shader_instruction *ins; -+ unsigned int i; - -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - if (ins->opcode == VSIR_OP_DEF || ins->opcode == VSIR_OP_DEFI || ins->opcode == VSIR_OP_DEFB) - { - struct flat_constant_def *def; -@@ -3309,15 +3408,19 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr - def = &normaliser.defs[normaliser.def_count++]; - - get_flat_constant_register_type(&ins->dst[0].reg, &def->set, &def->index, NULL); -- for (j = 0; j < 4; ++j) -- def->value[j] = ins->src[0].reg.u.immconst_u32[j]; -+ for (i = 0; i < 4; ++i) -+ { -+ def->value[i] = ins->src[0].reg.u.immconst_u32[i]; -+ } - - vkd3d_shader_instruction_make_nop(ins); - } - else - { -- for (j = 0; j < ins->src_count; ++j) -- shader_register_normalise_flat_constants(&ins->src[j], &normaliser); -+ for (i = 0; i < ins->src_count; ++i) -+ { -+ shader_register_normalise_flat_constants(&ins->src[i], &normaliser); -+ } - } - } - -@@ -3328,13 +3431,13 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr - static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -- size_t i, depth = 0; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vkd3d_shader_instruction *ins; - bool dead = false; -+ size_t depth = 0; - -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - switch (ins->opcode) - { - case VSIR_OP_IF: -@@ -3707,10 +3810,11 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - struct vkd3d_shader_message_context *message_context) - { - struct vkd3d_shader_instruction_array *instructions; -+ const struct vkd3d_shader_instruction *instruction; - struct vsir_program *program = flattener->program; - bool is_hull_shader, after_declarations_section; - struct vkd3d_shader_instruction *dst_ins; -- size_t i; -+ struct vsir_program_iterator it; - - instructions = &program->instructions; - is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL; -@@ -3719,10 +3823,10 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - if (!cf_flattener_require_space(flattener, instructions->count + 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- for (i = 0; i < instructions->count; ++i) -+ it = vsir_program_iterator(instructions); -+ for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it)) - { - unsigned int loop_header_block_id, loop_body_block_id, continue_block_id, merge_block_id, true_block_id; -- const struct vkd3d_shader_instruction *instruction = &instructions->elements[i]; - const struct vkd3d_shader_src_param *src = instruction->src; - struct cf_flattener_info *cf_info; - -@@ -4321,10 +4425,12 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl - static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -- size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count; - struct ssas_to_temps_block_info *info, *block_info = NULL; - struct vkd3d_shader_instruction *instructions = NULL; - struct ssas_to_temps_alloc alloc = {0}; -+ struct vkd3d_shader_instruction *ins; - unsigned int current_label = 0; - - VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); -@@ -4338,9 +4444,10 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ - if (!ssas_to_temps_alloc_init(&alloc, program->ssa_count, program->temp_count)) - goto fail; - -- for (i = 0, phi_count = 0, incoming_count = 0; i < program->instructions.count; ++i) -+ phi_count = 0; -+ incoming_count = 0; -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - unsigned int j, temp_idx; - - /* Only phi src/dst SSA values need be converted here. Structurisation may -@@ -4383,9 +4490,9 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ - if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count)) - goto fail; - -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *mov_ins, *ins = &program->instructions.elements[i]; -+ struct vkd3d_shader_instruction *mov_ins; - size_t j; - - for (j = 0; j < ins->dst_count; ++j) -@@ -6826,14 +6933,12 @@ static enum vkd3d_result vsir_program_apply_flat_interpolation(struct vsir_progr - } - - static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *program, -- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func, -+ struct vsir_program_iterator *it, enum vkd3d_shader_comparison_func compare_func, - const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx, -- uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context) -+ uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- const struct vkd3d_shader_location loc = ret->location; -+ struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; - static const struct vkd3d_shader_location no_loc; -- size_t pos = ret - instructions->elements; - struct vkd3d_shader_instruction *ins; - - static const struct -@@ -6854,23 +6959,23 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - - if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER) - { -- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) -+ vsir_program_iterator_prev(it); -+ if (!vsir_program_iterator_insert_after(it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -- ins = &program->instructions.elements[pos]; -+ ins = vsir_program_iterator_next(it); - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; - src_param_init_const_uint(&ins->src[0], 0); -+ vsir_program_iterator_next(it); - -- *ret_pos = pos + 1; - return VKD3D_OK; - } - -- if (!shader_instruction_array_insert_at(&program->instructions, pos, 3)) -+ vsir_program_iterator_prev(it); -+ if (!vsir_program_iterator_insert_after(it, 3)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -- ins = &program->instructions.elements[pos]; -+ ins = vsir_program_iterator_next(it); - - switch (ref->data_type) - { -@@ -6902,14 +7007,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - ins->src[opcodes[compare_func].swap ? 1 : 0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); - -- ++ins; -+ ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; - src_param_init_ssa_bool(&ins->src[0], program->ssa_count); - - ++program->ssa_count; - -- ++ins; -+ ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = colour_signature_idx; -@@ -6919,20 +7024,21 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - -- *ret_pos = pos + 3; -+ vsir_program_iterator_next(it); -+ - return VKD3D_OK; - } - - static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_message_context *message_context = ctx->message_context; - const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL; - uint32_t colour_signature_idx, colour_temp = ~0u; - static const struct vkd3d_shader_location no_loc; - enum vkd3d_shader_comparison_func compare_func; - struct vkd3d_shader_instruction *ins; -- size_t new_pos; - int ret; - - if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) -@@ -6969,19 +7075,16 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro - if (compare_func != VKD3D_SHADER_COMPARISON_FUNC_NEVER) - colour_temp = program->temp_count++; - -- for (size_t i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &program->instructions.elements[i]; -- - if (vsir_instruction_is_dcl(ins)) - continue; - - if (ins->opcode == VSIR_OP_RET) - { -- if ((ret = insert_alpha_test_before_ret(program, ins, compare_func, -- ref, colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) -+ if ((ret = insert_alpha_test_before_ret(program, &it, compare_func, -+ ref, colour_signature_idx, colour_temp, message_context)) < 0) - return ret; -- i = new_pos; - continue; - } - -@@ -7007,19 +7110,17 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro - } - - static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *program, -- const struct vkd3d_shader_instruction *ret, uint32_t mask, uint32_t position_signature_idx, -- uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos) -+ struct vsir_program_iterator *it, uint32_t mask, uint32_t position_signature_idx, -+ uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- const struct vkd3d_shader_location loc = ret->location; -- size_t pos = ret - instructions->elements; -+ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; - struct vkd3d_shader_instruction *ins; - unsigned int output_idx = 0; - -- if (!shader_instruction_array_insert_at(&program->instructions, pos, vkd3d_popcount(mask) + 1)) -+ vsir_program_iterator_prev(it); -+ if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -- ins = &program->instructions.elements[pos]; -+ ins = vsir_program_iterator_next(it); - - for (unsigned int i = 0; i < 8; ++i) - { -@@ -7041,7 +7142,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog - ins->dst[0].write_mask = (1u << (output_idx % 4)); - ++output_idx; - -- ++ins; -+ ins = vsir_program_iterator_next(it); - } - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -@@ -7052,14 +7153,15 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog - src_param_init_temp_float(&ins->src[0], position_temp); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; -+ ins = vsir_program_iterator_next(it); - -- *ret_pos = pos + vkd3d_popcount(mask) + 1; - return VKD3D_OK; - } - - static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct shader_signature *signature = &program->output_signature; - unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; - const struct vkd3d_shader_parameter1 *mask_parameter = NULL; -@@ -7068,7 +7170,6 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr - struct signature_element *clip_element; - struct vkd3d_shader_instruction *ins; - unsigned int plane_count; -- size_t new_pos; - int ret; - - if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX) -@@ -7144,19 +7245,16 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr - - position_temp = program->temp_count++; - -- for (size_t i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &program->instructions.elements[i]; -- - if (vsir_instruction_is_dcl(ins)) - continue; - - if (ins->opcode == VSIR_OP_RET) - { -- if ((ret = insert_clip_planes_before_ret(program, ins, mask, position_signature_idx, -- position_temp, low_signature_idx, high_signature_idx, &new_pos)) < 0) -+ if ((ret = insert_clip_planes_before_ret(program, &it, mask, position_signature_idx, -+ position_temp, low_signature_idx, high_signature_idx)) < 0) - return ret; -- i = new_pos; - continue; - } - -@@ -7185,32 +7283,32 @@ static bool is_pre_rasterization_shader(enum vkd3d_shader_type type) - } - - static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *program, -- const struct vkd3d_shader_instruction *ret, size_t *ret_pos) -+ struct vsir_program_iterator *it) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- const struct vkd3d_shader_location loc = ret->location; -- size_t pos = ret - instructions->elements; -+ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; - struct vkd3d_shader_instruction *ins; - -- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) -+ vsir_program_iterator_prev(it); -+ if (!vsir_program_iterator_insert_after(it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -- ins = &program->instructions.elements[pos]; -+ ins = vsir_program_iterator_next(it); - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VSIR_DATA_F32); -+ ins = vsir_program_iterator_next(it); - -- *ret_pos = pos + 1; - return VKD3D_OK; - } - - static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - const struct vkd3d_shader_parameter1 *size_parameter = NULL; - static const struct vkd3d_shader_location no_loc; -+ struct vkd3d_shader_instruction *ins; - - if (program->has_point_size) - return VKD3D_OK; -@@ -7239,18 +7337,14 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro - program->has_point_size = true; - - /* Append a point size write before each ret. */ -- for (size_t i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - if (ins->opcode == VSIR_OP_RET) - { -- size_t new_pos; - int ret; - -- if ((ret = insert_point_size_before_ret(program, ins, &new_pos)) < 0) -+ if ((ret = insert_point_size_before_ret(program, &it)) < 0) - return ret; -- i = new_pos; - } - } - -@@ -7261,7 +7355,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - struct vsir_transformation_context *ctx) - { - const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - static const struct vkd3d_shader_location no_loc; -+ struct vkd3d_shader_instruction *ins; - - if (!program->has_point_size) - return VKD3D_OK; -@@ -7298,9 +7394,8 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - - /* Replace writes to the point size by inserting a clamp before each write. */ - -- for (size_t i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - const struct vkd3d_shader_location *loc; - unsigned int ssa_value; - bool clamp = false; -@@ -7324,11 +7419,11 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - if (!clamp) - continue; - -- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter)) -+ if (!vsir_program_iterator_insert_after(&it, !!min_parameter + !!max_parameter)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = &program->instructions.elements[i + 1]; - -- loc = &program->instructions.elements[i].location; -+ loc = &vsir_program_iterator_current(&it)->location; -+ ins = vsir_program_iterator_next(&it); - - if (min_parameter) - { -@@ -7345,8 +7440,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; - } -- ++ins; -- ++i; -+ ins = vsir_program_iterator_next(&it); - } - - if (max_parameter) -@@ -7356,8 +7450,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VSIR_DATA_F32); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; -- -- ++i; -+ ins = vsir_program_iterator_next(&it); - } - } - -@@ -7435,12 +7528,13 @@ static bool replace_texcoord_with_point_coord(struct vsir_program *program, - static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2; - const struct vkd3d_shader_parameter1 *sprite_parameter = NULL; - static const struct vkd3d_shader_location no_loc; - struct vkd3d_shader_instruction *ins; - bool used_texcoord = false; - unsigned int coord_temp; -- size_t i, insert_pos; -+ size_t i; - - if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) - return VKD3D_OK; -@@ -7481,21 +7575,16 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - /* Construct the new temp after all LABEL, DCL, and NOP instructions. - * We need to skip NOP instructions because they might result from removed - * DCLs, and there could still be DCLs after NOPs. */ -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &program->instructions.elements[i]; -- - if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) - break; - } - -- insert_pos = i; -- -+ it2 = it; - /* Replace each texcoord read with a read from the point coord. */ -- for (; i < program->instructions.count; ++i) -+ for (; ins; ins = vsir_program_iterator_next(&it2)) - { -- ins = &program->instructions.elements[i]; -- - if (vsir_instruction_is_dcl(ins)) - continue; - -@@ -7524,9 +7613,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - - if (used_texcoord) - { -- if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2)) -+ vsir_program_iterator_prev(&it); -+ if (!vsir_program_iterator_insert_after(&it, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = &program->instructions.elements[insert_pos]; -+ ins = vsir_program_iterator_next(&it); - - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); - dst_param_init_temp_float4(&ins->dst[0], coord_temp); -@@ -7534,14 +7624,14 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; -- ++ins; -+ ins = vsir_program_iterator_next(&it); - - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); - dst_param_init_temp_float4(&ins->dst[0], coord_temp); - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; - vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); - ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; -- ++ins; -+ vsir_program_iterator_next(&it); - - program->has_point_coord = true; - } -@@ -12045,6 +12135,28 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin - return ctx.result; - } - -+enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, -+ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) -+{ -+ struct vsir_transformation_context ctx = -+ { -+ .result = VKD3D_OK, -+ .program = program, -+ .config_flags = config_flags, -+ .compile_info = compile_info, -+ .message_context = message_context, -+ }; -+ -+ vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); -+ if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) -+ vsir_transform(&ctx, vsir_program_normalise_ps1_output); -+ -+ if (TRACE_ON()) -+ vsir_program_trace(program); -+ -+ return ctx.result; -+} -+ - enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 4f50eadf714..a4990d982bc 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -5676,6 +5676,48 @@ static unsigned int shader_signature_next_location(const struct shader_signature - return max_row; - } - -+static const struct vkd3d_symbol *spirv_compiler_emit_io_register(struct spirv_compiler *compiler, -+ const struct vkd3d_shader_dst_param *dst) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ const struct vkd3d_shader_register *reg = &dst->reg; -+ const struct vkd3d_spirv_builtin *builtin; -+ struct vkd3d_symbol reg_symbol; -+ SpvStorageClass storage_class; -+ uint32_t write_mask, id; -+ struct rb_entry *entry; -+ -+ VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); -+ VKD3D_ASSERT(reg->idx_count < 2); -+ -+ if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) -+ { -+ builtin = &vkd3d_output_point_size_builtin; -+ storage_class = SpvStorageClassOutput; -+ } -+ else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) -+ { -+ FIXME("Unhandled register %#x.\n", reg->type); -+ return NULL; -+ } -+ -+ /* vPrim may be declared in multiple hull shader phases. */ -+ vkd3d_symbol_make_register(®_symbol, reg); -+ if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) -+ return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); -+ -+ id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); -+ spirv_compiler_emit_register_execution_mode(compiler, reg->type); -+ spirv_compiler_emit_register_debug_name(builder, id, reg); -+ -+ write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); -+ vkd3d_symbol_set_register_info(®_symbol, id, -+ storage_class, builtin->component_type, write_mask); -+ reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; -+ -+ return spirv_compiler_put_symbol(compiler, ®_symbol); -+} -+ - static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - enum vkd3d_shader_register_type reg_type, unsigned int element_idx) - { -@@ -5684,6 +5726,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - const struct signature_element *signature_element; - const struct shader_signature *shader_signature; - enum vkd3d_shader_component_type component_type; -+ enum vkd3d_shader_register_type sysval_reg_type; - const struct vkd3d_spirv_builtin *builtin; - enum vkd3d_shader_sysval_semantic sysval; - uint32_t write_mask, reg_write_mask; -@@ -5708,6 +5751,22 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - if (!signature_element->used_mask) - return; - -+ sysval_reg_type = vsir_register_type_from_sysval_input(signature_element->sysval_semantic); -+ if (sysval_reg_type != VKD3DSPR_INPUT) -+ { -+ struct vkd3d_shader_dst_param dst; -+ const struct vkd3d_symbol *symbol; -+ -+ vsir_dst_param_init(&dst, sysval_reg_type, VSIR_DATA_F32, 0); -+ symbol = spirv_compiler_emit_io_register(compiler, &dst); -+ -+ vkd3d_symbol_make_io(®_symbol, reg_type, element_idx); -+ reg_symbol.id = symbol->id; -+ reg_symbol.info.reg = symbol->info.reg; -+ spirv_compiler_put_symbol(compiler, ®_symbol); -+ return; -+ } -+ - builtin = get_spirv_builtin_for_sysval(compiler, sysval); - - array_sizes[0] = signature_element->register_count; -@@ -5829,47 +5888,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - } - } - --static void spirv_compiler_emit_io_register(struct spirv_compiler *compiler, -- const struct vkd3d_shader_dst_param *dst) --{ -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- const struct vkd3d_shader_register *reg = &dst->reg; -- const struct vkd3d_spirv_builtin *builtin; -- struct vkd3d_symbol reg_symbol; -- SpvStorageClass storage_class; -- uint32_t write_mask, id; -- struct rb_entry *entry; -- -- VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); -- VKD3D_ASSERT(reg->idx_count < 2); -- -- if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) -- { -- builtin = &vkd3d_output_point_size_builtin; -- storage_class = SpvStorageClassOutput; -- } -- else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) -- { -- FIXME("Unhandled register %#x.\n", reg->type); -- return; -- } -- -- /* vPrim may be declared in multiple hull shader phases. */ -- vkd3d_symbol_make_register(®_symbol, reg); -- if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) -- return; -- -- id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); -- -- write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); -- vkd3d_symbol_set_register_info(®_symbol, id, -- storage_class, builtin->component_type, write_mask); -- reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; -- spirv_compiler_put_symbol(compiler, ®_symbol); -- spirv_compiler_emit_register_execution_mode(compiler, reg->type); -- spirv_compiler_emit_register_debug_name(builder, id, reg); --} -- - static unsigned int get_shader_output_swizzle(const struct spirv_compiler *compiler, - unsigned int register_idx) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 891a33d326f..d1992c9d446 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -57,6 +57,39 @@ uint32_t vkd3d_parse_integer(const char *s) - return ret; - } - -+bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source) -+{ -+ char *s; -+ -+ if (!(s = vkd3d_strdup(source))) -+ return false; -+ -+ if (!vkd3d_array_reserve((void **)&l->sources, &l->capacity, l->count + 1, sizeof(*l->sources))) -+ { -+ vkd3d_free(s); -+ return false; -+ } -+ l->sources[l->count++] = s; -+ -+ return true; -+} -+ -+void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l) -+{ -+ size_t i; -+ -+ for (i = 0; i < l->count; ++i) -+ { -+ vkd3d_free((void *)l->sources[i]); -+ } -+ vkd3d_free(l->sources); -+} -+ -+void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l) -+{ -+ memset(l, 0, sizeof(*l)); -+} -+ - void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) - { - buffer->buffer_size = 16; -@@ -767,12 +800,28 @@ static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_ - } - - static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, -- struct vkd3d_shader_message_context *message_context, struct vsir_program *program) -+ const struct shader_dump_data *dump_data, struct vkd3d_shader_message_context *message_context, -+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data) - { -+ struct vkd3d_shader_compile_info preprocessed_info; -+ struct vkd3d_shader_code preprocessed; - enum vkd3d_result ret; - - switch (compile_info->source_type) - { -+ case VKD3D_SHADER_SOURCE_HLSL: -+ if ((ret = preproc_lexer_parse(compile_info, &preprocessed, message_context)) >= 0) -+ { -+ vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC); -+ -+ preprocessed_info = *compile_info; -+ preprocessed_info.source = preprocessed; -+ ret = hlsl_parse(&preprocessed_info, message_context, program, reflection_data); -+ -+ vkd3d_shader_free_shader_code(&preprocessed); -+ } -+ break; -+ - case VKD3D_SHADER_SOURCE_D3D_BYTECODE: - ret = d3dbc_parse(compile_info, config_flags, message_context, program); - break; -@@ -803,13 +852,19 @@ static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *comp - - if (TRACE_ON()) - vsir_program_trace(program); -- -- vsir_program_cleanup(program); -- return ret; -+ goto fail; - } - -- if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE) -- ret = vsir_program_transform_early(program, config_flags, compile_info, message_context); -+ if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE -+ && (ret = vsir_program_transform_early(program, config_flags, compile_info, message_context)) < 0) -+ goto fail; -+ -+ return ret; -+ -+fail: -+ vkd3d_shader_free_shader_code(reflection_data); -+ vsir_program_cleanup(program); -+ - return ret; - } - -@@ -1233,6 +1288,40 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co - s->sampler_index = sampler_idx; - } - -+static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context, -+ const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler) -+{ -+ unsigned int resource_idx = resource->idx[0].offset; -+ unsigned int sampler_idx = sampler->idx[0].offset; -+ -+ vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler); -+ -+ if (!context->scan_descriptor_info) -+ return; -+ -+ /* Sample instructions lowered from 1.x texture instructions have no -+ * DCL, so we need to add the resource if it didn't already exist. -+ * Such descriptors have a fixed count, type, etc. */ -+ -+ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx)) -+ { -+ struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx}; -+ -+ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource, -+ &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32); -+ } -+ -+ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx)) -+ { -+ struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; -+ -+ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource, -+ &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); -+ } -+} -+ - static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, - const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, - enum vsir_data_type resource_data_type, unsigned int sample_count, -@@ -1436,13 +1525,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - if (context->cf_info_count) - context->cf_info[context->cf_info_count - 1].inside_block = false; - break; -- case VSIR_OP_TEXLD: -- if (context->version->major == 1) -- sampler_reg = &instruction->dst[0].reg; -- else -- sampler_reg = &instruction->src[1].reg; -- vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg); -- break; - case VSIR_OP_TEX: - case VSIR_OP_TEXBEM: - case VSIR_OP_TEXBEML: -@@ -1459,7 +1541,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - break; - case VSIR_OP_GATHER4: - case VSIR_OP_GATHER4_C: -- case VSIR_OP_SAMPLE: - case VSIR_OP_SAMPLE_B: - case VSIR_OP_SAMPLE_C: - case VSIR_OP_SAMPLE_C_LZ: -@@ -1467,6 +1548,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - case VSIR_OP_SAMPLE_LOD: - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg); - break; -+ case VSIR_OP_SAMPLE: -+ vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg); -+ break; - case VSIR_OP_GATHER4_PO: - case VSIR_OP_GATHER4_PO_C: - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg); -@@ -1691,7 +1775,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages) - { - struct vkd3d_shader_message_context message_context; -+ struct vkd3d_shader_code reflection_data = {0}; - struct shader_dump_data dump_data; -+ struct vsir_program program; - int ret; - - TRACE("compile_info %p, messages %p.\n", compile_info, messages); -@@ -1709,21 +1795,12 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char - fill_shader_dump_data(compile_info, &dump_data); - vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); - -- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) -- { -- FIXME("HLSL support not implemented.\n"); -- ret = VKD3D_ERROR_NOT_IMPLEMENTED; -- } -- else -+ if (!(ret = vsir_parse(compile_info, vkd3d_shader_init_config_flags(), -+ &dump_data, &message_context, &program, &reflection_data))) - { -- uint64_t config_flags = vkd3d_shader_init_config_flags(); -- struct vsir_program program; -- -- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) -- { -- ret = vsir_program_scan(&program, compile_info, &message_context, false); -- vsir_program_cleanup(&program); -- } -+ ret = vsir_program_scan(&program, compile_info, &message_context, false); -+ vkd3d_shader_free_shader_code(&reflection_data); -+ vsir_program_cleanup(&program); - } - - vkd3d_shader_message_context_trace_messages(&message_context); -@@ -1733,12 +1810,13 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char - return ret; - } - --int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, -+static int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, - uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) - { - struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info; - struct vkd3d_shader_compile_info scan_info; -+ enum vsir_asm_flags asm_flags; - int ret; - - scan_info = *compile_info; -@@ -1748,7 +1826,11 @@ int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader - case VKD3D_SHADER_TARGET_D3D_ASM: - if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) - return ret; -- ret = d3d_asm_compile(program, compile_info, out, VSIR_ASM_FLAG_NONE); -+ asm_flags = VSIR_ASM_FLAG_NONE; -+ if (program->shader_version.major < 6 && compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF -+ && compile_info->source_type != VKD3D_SHADER_SOURCE_D3D_BYTECODE) -+ asm_flags |= VSIR_ASM_FLAG_ALLOCATE_TEMPS; -+ ret = d3d_asm_compile(program, compile_info, out, asm_flags, message_context); - break; - - case VKD3D_SHADER_TARGET_D3D_BYTECODE: -@@ -1795,7 +1877,7 @@ int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader - return ret; - } - --static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, -+static int fx_compile(const struct vkd3d_shader_compile_info *compile_info, - const struct shader_dump_data *dump_data, struct vkd3d_shader_code *out, - struct vkd3d_shader_message_context *message_context) - { -@@ -1810,10 +1892,7 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, - - preprocessed_info = *compile_info; - preprocessed_info.source = preprocessed; -- if (compile_info->target_type == VKD3D_SHADER_TARGET_FX) -- ret = hlsl_compile_effect(&preprocessed_info, message_context, out); -- else -- ret = hlsl_compile_shader(&preprocessed_info, message_context, out); -+ ret = hlsl_compile_effect(&preprocessed_info, message_context, out); - - vkd3d_shader_free_shader_code(&preprocessed); - return ret; -@@ -1841,9 +1920,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, - fill_shader_dump_data(compile_info, &dump_data); - vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); - -- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) -+ if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL -+ && compile_info->target_type == VKD3D_SHADER_TARGET_FX) - { -- ret = compile_hlsl(compile_info, &dump_data, out, &message_context); -+ ret = fx_compile(compile_info, &dump_data, out, &message_context); - } - else if (compile_info->source_type == VKD3D_SHADER_SOURCE_FX) - { -@@ -1856,11 +1936,14 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, - else - { - uint64_t config_flags = vkd3d_shader_init_config_flags(); -+ struct vkd3d_shader_code reflection_data = {0}; - struct vsir_program program; - -- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) -+ if (!(ret = vsir_parse(compile_info, config_flags, &dump_data, -+ &message_context, &program, &reflection_data))) - { -- ret = vsir_program_compile(&program, NULL, config_flags, compile_info, out, &message_context); -+ ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, &message_context); -+ vkd3d_shader_free_shader_code(&reflection_data); - vsir_program_cleanup(&program); - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 5bf3728a325..e758c16b3d4 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -937,6 +937,16 @@ enum vkd3d_shader_type - - struct vkd3d_shader_message_context; - -+struct vkd3d_shader_source_list -+{ -+ const char **sources; -+ size_t capacity, count; -+}; -+ -+bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source); -+void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l); -+void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l); -+ - struct vkd3d_shader_version - { - enum vkd3d_shader_type type; -@@ -1013,6 +1023,20 @@ static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_registe - } - } - -+static inline enum vkd3d_shader_register_type vsir_register_type_from_sysval_input( -+ enum vkd3d_shader_sysval_semantic sysval) -+{ -+ switch (sysval) -+ { -+ case VKD3D_SHADER_SV_PRIMITIVE_ID: -+ return VKD3DSPR_PRIMID; -+ case VKD3D_SHADER_SV_COVERAGE: -+ return VKD3DSPR_COVERAGE; -+ default: -+ return VKD3DSPR_INPUT; -+ } -+} -+ - struct vkd3d_shader_dst_param - { - struct vkd3d_shader_register reg; -@@ -1463,12 +1487,21 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_tail(struct - static inline struct vkd3d_shader_instruction *vsir_program_iterator_next( - struct vsir_program_iterator *iterator) - { -- if (iterator->idx < iterator->array->count) -+ if (iterator->idx < iterator->array->count || iterator->idx == SIZE_MAX) - ++iterator->idx; - - return vsir_program_iterator_current(iterator); - } - -+static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev( -+ struct vsir_program_iterator *iterator) -+{ -+ if (iterator->idx != SIZE_MAX) -+ --iterator->idx; -+ -+ return vsir_program_iterator_current(iterator); -+} -+ - /* When insertion takes place, argument `it' is updated to point to the same - * instruction as before the insertion, but all other iterators and pointers - * to the same container are invalidated and cannot be used any more. */ -@@ -1563,6 +1596,7 @@ struct vsir_program - - struct vsir_features features; - -+ struct vkd3d_shader_source_list source_files; - const char **block_names; - size_t block_name_count; - }; -@@ -1572,14 +1606,13 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context); - void vsir_program_cleanup(struct vsir_program *program); --int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, -- uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, -- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); - const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( - const struct vsir_program *program, enum vkd3d_shader_parameter_name name); - bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, - const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type, - enum vsir_normalisation_level normalisation_level); -+enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, -+ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context); - enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context); - enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags, -@@ -1652,11 +1685,12 @@ enum vsir_asm_flags - VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2, - VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4, - VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8, -+ VSIR_ASM_FLAG_ALLOCATE_TEMPS = 0x10, - }; - - enum vkd3d_result d3d_asm_compile(struct vsir_program *program, -- const struct vkd3d_shader_compile_info *compile_info, -- struct vkd3d_shader_code *out, enum vsir_asm_flags flags); -+ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, -+ enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context); - void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer); - struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list); - void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer); -@@ -1808,8 +1842,9 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, - - int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); --int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, -- struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); -+int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context, -+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data); - - static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) - { --- -2.50.1 -