diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch index 48324079..a803d6fe 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch @@ -1,41 +1,17 @@ -From 900a91b2b7e2260fe4eefb78e1db3dffa2360d23 Mon Sep 17 00:00:00 2001 +From 7c1151365e7c94a832b7134ba700102a6073ba2a 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 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 | 7 + - libs/vkd3d/libs/vkd3d-common/blob.c | 1 + - 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 | 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 | 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 | 36 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 13 +- - 31 files changed, 10162 insertions(+), 5992 deletions(-) + dlls/msado15/tests/msado15.c | 2 +- + libs/vkd3d/include/private/vkd3d_common.h | 2 +- + libs/vkd3d/include/private/vkd3d_version.h | 2 +- + libs/vkd3d/libs/vkd3d-common/blob.c | 1 + + libs/vkd3d/libs/vkd3d-shader/preproc.l | 1 + + libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c | 2 ++ + libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 2 ++ + 7 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 03eaab92b39..3f4b55d2916 100644 @@ -52,18 +28,10 @@ index 03eaab92b39..3f4b55d2916 100644 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 +index 08341304eea..0501e6a06c2 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h -@@ -66,6 +66,7 @@ - - #define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') - #define TAG_CLI4 VKD3D_MAKE_TAG('C', 'L', 'I', '4') -+#define TAG_CLIT VKD3D_MAKE_TAG('C', 'L', 'I', 'T') - #define TAG_CTAB VKD3D_MAKE_TAG('C', 'T', 'A', 'B') - #define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C') - #define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') -@@ -278,7 +279,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) +@@ -279,7 +279,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) { #ifdef _MSC_VER return __popcnt(v); @@ -72,21 +40,6 @@ 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 @@ -94,38 +47,6 @@ index 0edc4428022..687751d6a5f 100644 @@ -1 +1 @@ -#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..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 - * Input is a raw FX section without container. \since 1.14 - */ - VKD3D_SHADER_SOURCE_FX, -+ /** -+ * A D3DX texture shader. This is the format used for the 'tx_1_0' HLSL -+ * target profile. \since 1.17 -+ */ -+ VKD3D_SHADER_SOURCE_TX, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SOURCE_TYPE), - }; -@@ -2761,6 +2766,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported - * - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_DXBC_TPF - * - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_FX - * - VKD3D_SHADER_SOURCE_FX to VKD3D_SHADER_TARGET_D3D_ASM -+ * - VKD3D_SHADER_SOURCE_TX to VKD3D_SHADER_TARGET_D3D_ASM - * - * 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 @@ -138,21444 +59,8 @@ index f60ef7db769..c2c6ad67804 100644 #define CONST_VTABLE #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..6425a8f62d2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -27,333 +27,6 @@ - #include - #include - --static const char * const shader_opcode_names[] = --{ -- [VKD3DSIH_ABS ] = "abs", -- [VKD3DSIH_ACOS ] = "acos", -- [VKD3DSIH_ADD ] = "add", -- [VKD3DSIH_AND ] = "and", -- [VKD3DSIH_ASIN ] = "asin", -- [VKD3DSIH_ATAN ] = "atan", -- [VKD3DSIH_ATOMIC_AND ] = "atomic_and", -- [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", -- [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", -- [VKD3DSIH_ATOMIC_IMAX ] = "atomic_imax", -- [VKD3DSIH_ATOMIC_IMIN ] = "atomic_imin", -- [VKD3DSIH_ATOMIC_OR ] = "atomic_or", -- [VKD3DSIH_ATOMIC_UMAX ] = "atomic_umax", -- [VKD3DSIH_ATOMIC_UMIN ] = "atomic_umin", -- [VKD3DSIH_ATOMIC_XOR ] = "atomic_xor", -- [VKD3DSIH_BEM ] = "bem", -- [VKD3DSIH_BFI ] = "bfi", -- [VKD3DSIH_BFREV ] = "bfrev", -- [VKD3DSIH_BRANCH ] = "branch", -- [VKD3DSIH_BREAK ] = "break", -- [VKD3DSIH_BREAKC ] = "break", -- [VKD3DSIH_BREAKP ] = "breakp", -- [VKD3DSIH_BUFINFO ] = "bufinfo", -- [VKD3DSIH_CALL ] = "call", -- [VKD3DSIH_CALLNZ ] = "callnz", -- [VKD3DSIH_CASE ] = "case", -- [VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped", -- [VKD3DSIH_CMP ] = "cmp", -- [VKD3DSIH_CND ] = "cnd", -- [VKD3DSIH_CONTINUE ] = "continue", -- [VKD3DSIH_CONTINUEP ] = "continuec", -- [VKD3DSIH_COUNTBITS ] = "countbits", -- [VKD3DSIH_CRS ] = "crs", -- [VKD3DSIH_CUT ] = "cut", -- [VKD3DSIH_CUT_STREAM ] = "cut_stream", -- [VKD3DSIH_DADD ] = "dadd", -- [VKD3DSIH_DCL ] = "dcl", -- [VKD3DSIH_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer", -- [VKD3DSIH_DCL_FUNCTION_BODY ] = "dcl_function_body", -- [VKD3DSIH_DCL_FUNCTION_TABLE ] = "dcl_function_table", -- [VKD3DSIH_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags", -- [VKD3DSIH_DCL_GS_INSTANCES ] = "dcl_gs_instances", -- [VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count", -- [VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count", -- [VKD3DSIH_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor", -- [VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer", -- [VKD3DSIH_DCL_INDEX_RANGE ] = "dcl_index_range", -- [VKD3DSIH_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp", -- [VKD3DSIH_DCL_INPUT ] = "dcl_input", -- [VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count", -- [VKD3DSIH_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive", -- [VKD3DSIH_DCL_INPUT_PS ] = "dcl_input_ps", -- [VKD3DSIH_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv", -- [VKD3DSIH_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv", -- [VKD3DSIH_DCL_INPUT_SGV ] = "dcl_input_sgv", -- [VKD3DSIH_DCL_INPUT_SIV ] = "dcl_input_siv", -- [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface", -- [VKD3DSIH_DCL_OUTPUT ] = "dcl_output", -- [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", -- [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv", -- [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", -- [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw", -- [VKD3DSIH_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured", -- [VKD3DSIH_DCL_SAMPLER ] = "dcl_sampler", -- [VKD3DSIH_DCL_STREAM ] = "dcl_stream", -- [VKD3DSIH_DCL_TEMPS ] = "dcl_temps", -- [VKD3DSIH_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain", -- [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive", -- [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning", -- [VKD3DSIH_DCL_TGSM_RAW ] = "dcl_tgsm_raw", -- [VKD3DSIH_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured", -- [VKD3DSIH_DCL_THREAD_GROUP ] = "dcl_thread_group", -- [VKD3DSIH_DCL_UAV_RAW ] = "dcl_uav_raw", -- [VKD3DSIH_DCL_UAV_STRUCTURED ] = "dcl_uav_structured", -- [VKD3DSIH_DCL_UAV_TYPED ] = "dcl_uav_typed", -- [VKD3DSIH_DCL_VERTICES_OUT ] = "dcl_maxout", -- [VKD3DSIH_DDIV ] = "ddiv", -- [VKD3DSIH_DEF ] = "def", -- [VKD3DSIH_DEFAULT ] = "default", -- [VKD3DSIH_DEFB ] = "defb", -- [VKD3DSIH_DEFI ] = "defi", -- [VKD3DSIH_DEQO ] = "deq", -- [VKD3DSIH_DFMA ] = "dfma", -- [VKD3DSIH_DGEO ] = "dge", -- [VKD3DSIH_DISCARD ] = "discard", -- [VKD3DSIH_DIV ] = "div", -- [VKD3DSIH_DLT ] = "dlt", -- [VKD3DSIH_DMAX ] = "dmax", -- [VKD3DSIH_DMIN ] = "dmin", -- [VKD3DSIH_DMOV ] = "dmov", -- [VKD3DSIH_DMOVC ] = "dmovc", -- [VKD3DSIH_DMUL ] = "dmul", -- [VKD3DSIH_DNE ] = "dne", -- [VKD3DSIH_DP2 ] = "dp2", -- [VKD3DSIH_DP2ADD ] = "dp2add", -- [VKD3DSIH_DP3 ] = "dp3", -- [VKD3DSIH_DP4 ] = "dp4", -- [VKD3DSIH_DRCP ] = "drcp", -- [VKD3DSIH_DST ] = "dst", -- [VKD3DSIH_DSX ] = "dsx", -- [VKD3DSIH_DSX_COARSE ] = "deriv_rtx_coarse", -- [VKD3DSIH_DSX_FINE ] = "deriv_rtx_fine", -- [VKD3DSIH_DSY ] = "dsy", -- [VKD3DSIH_DSY_COARSE ] = "deriv_rty_coarse", -- [VKD3DSIH_DSY_FINE ] = "deriv_rty_fine", -- [VKD3DSIH_DTOF ] = "dtof", -- [VKD3DSIH_DTOI ] = "dtoi", -- [VKD3DSIH_DTOU ] = "dtou", -- [VKD3DSIH_ELSE ] = "else", -- [VKD3DSIH_EMIT ] = "emit", -- [VKD3DSIH_EMIT_STREAM ] = "emit_stream", -- [VKD3DSIH_ENDIF ] = "endif", -- [VKD3DSIH_ENDLOOP ] = "endloop", -- [VKD3DSIH_ENDREP ] = "endrep", -- [VKD3DSIH_ENDSWITCH ] = "endswitch", -- [VKD3DSIH_EQO ] = "eq", -- [VKD3DSIH_EQU ] = "eq_unord", -- [VKD3DSIH_EVAL_CENTROID ] = "eval_centroid", -- [VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index", -- [VKD3DSIH_EXP ] = "exp", -- [VKD3DSIH_EXPP ] = "expp", -- [VKD3DSIH_F16TOF32 ] = "f16tof32", -- [VKD3DSIH_F32TOF16 ] = "f32tof16", -- [VKD3DSIH_FCALL ] = "fcall", -- [VKD3DSIH_FIRSTBIT_HI ] = "firstbit_hi", -- [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo", -- [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi", -- [VKD3DSIH_FRC ] = "frc", -- [VKD3DSIH_FREM ] = "frem", -- [VKD3DSIH_FTOD ] = "ftod", -- [VKD3DSIH_FTOI ] = "ftoi", -- [VKD3DSIH_FTOU ] = "ftou", -- [VKD3DSIH_GATHER4 ] = "gather4", -- [VKD3DSIH_GATHER4_C ] = "gather4_c", -- [VKD3DSIH_GATHER4_C_S ] = "gather4_c_s", -- [VKD3DSIH_GATHER4_PO ] = "gather4_po", -- [VKD3DSIH_GATHER4_PO_C ] = "gather4_po_c", -- [VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s", -- [VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s", -- [VKD3DSIH_GATHER4_S ] = "gather4_s", -- [VKD3DSIH_GEO ] = "ge", -- [VKD3DSIH_GEU ] = "ge_unord", -- [VKD3DSIH_HCOS ] = "hcos", -- [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", -- [VKD3DSIH_HS_DECLS ] = "hs_decls", -- [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", -- [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", -- [VKD3DSIH_HSIN ] = "hsin", -- [VKD3DSIH_HTAN ] = "htan", -- [VKD3DSIH_IADD ] = "iadd", -- [VKD3DSIH_IBFE ] = "ibfe", -- [VKD3DSIH_IDIV ] = "idiv", -- [VKD3DSIH_IEQ ] = "ieq", -- [VKD3DSIH_IF ] = "if", -- [VKD3DSIH_IFC ] = "if", -- [VKD3DSIH_IGE ] = "ige", -- [VKD3DSIH_ILT ] = "ilt", -- [VKD3DSIH_IMAD ] = "imad", -- [VKD3DSIH_IMAX ] = "imax", -- [VKD3DSIH_IMIN ] = "imin", -- [VKD3DSIH_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc", -- [VKD3DSIH_IMM_ATOMIC_AND ] = "imm_atomic_and", -- [VKD3DSIH_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch", -- [VKD3DSIH_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume", -- [VKD3DSIH_IMM_ATOMIC_EXCH ] = "imm_atomic_exch", -- [VKD3DSIH_IMM_ATOMIC_IADD ] = "imm_atomic_iadd", -- [VKD3DSIH_IMM_ATOMIC_IMAX ] = "imm_atomic_imax", -- [VKD3DSIH_IMM_ATOMIC_IMIN ] = "imm_atomic_imin", -- [VKD3DSIH_IMM_ATOMIC_OR ] = "imm_atomic_or", -- [VKD3DSIH_IMM_ATOMIC_UMAX ] = "imm_atomic_umax", -- [VKD3DSIH_IMM_ATOMIC_UMIN ] = "imm_atomic_umin", -- [VKD3DSIH_IMM_ATOMIC_XOR ] = "imm_atomic_xor", -- [VKD3DSIH_IMUL ] = "imul", -- [VKD3DSIH_INE ] = "ine", -- [VKD3DSIH_INEG ] = "ineg", -- [VKD3DSIH_ISFINITE ] = "isfinite", -- [VKD3DSIH_ISHL ] = "ishl", -- [VKD3DSIH_ISHR ] = "ishr", -- [VKD3DSIH_ISINF ] = "isinf", -- [VKD3DSIH_ISNAN ] = "isnan", -- [VKD3DSIH_ITOD ] = "itod", -- [VKD3DSIH_ITOF ] = "itof", -- [VKD3DSIH_ITOI ] = "itoi", -- [VKD3DSIH_LABEL ] = "label", -- [VKD3DSIH_LD ] = "ld", -- [VKD3DSIH_LD2DMS ] = "ld2dms", -- [VKD3DSIH_LD2DMS_S ] = "ld2dms_s", -- [VKD3DSIH_LD_RAW ] = "ld_raw", -- [VKD3DSIH_LD_RAW_S ] = "ld_raw_s", -- [VKD3DSIH_LD_S ] = "ld_s", -- [VKD3DSIH_LD_STRUCTURED ] = "ld_structured", -- [VKD3DSIH_LD_STRUCTURED_S ] = "ld_structured_s", -- [VKD3DSIH_LD_UAV_TYPED ] = "ld_uav_typed", -- [VKD3DSIH_LD_UAV_TYPED_S ] = "ld_uav_typed_s", -- [VKD3DSIH_LIT ] = "lit", -- [VKD3DSIH_LOD ] = "lod", -- [VKD3DSIH_LOG ] = "log", -- [VKD3DSIH_LOGP ] = "logp", -- [VKD3DSIH_LOOP ] = "loop", -- [VKD3DSIH_LRP ] = "lrp", -- [VKD3DSIH_LTO ] = "lt", -- [VKD3DSIH_LTU ] = "lt_unord", -- [VKD3DSIH_M3x2 ] = "m3x2", -- [VKD3DSIH_M3x3 ] = "m3x3", -- [VKD3DSIH_M3x4 ] = "m3x4", -- [VKD3DSIH_M4x3 ] = "m4x3", -- [VKD3DSIH_M4x4 ] = "m4x4", -- [VKD3DSIH_MAD ] = "mad", -- [VKD3DSIH_MAX ] = "max", -- [VKD3DSIH_MIN ] = "min", -- [VKD3DSIH_MOV ] = "mov", -- [VKD3DSIH_MOVA ] = "mova", -- [VKD3DSIH_MOVC ] = "movc", -- [VKD3DSIH_MSAD ] = "msad", -- [VKD3DSIH_MUL ] = "mul", -- [VKD3DSIH_NEO ] = "ne_ord", -- [VKD3DSIH_NEU ] = "ne", -- [VKD3DSIH_NOP ] = "nop", -- [VKD3DSIH_NOT ] = "not", -- [VKD3DSIH_NRM ] = "nrm", -- [VKD3DSIH_OR ] = "or", -- [VKD3DSIH_ORD ] = "ord", -- [VKD3DSIH_PHASE ] = "phase", -- [VKD3DSIH_PHI ] = "phi", -- [VKD3DSIH_POW ] = "pow", -- [VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d", -- [VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x", -- [VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", -- [VKD3DSIH_QUAD_READ_LANE_AT ] = "quad_read_lane_at", -- [VKD3DSIH_RCP ] = "rcp", -- [VKD3DSIH_REP ] = "rep", -- [VKD3DSIH_RESINFO ] = "resinfo", -- [VKD3DSIH_RET ] = "ret", -- [VKD3DSIH_RETP ] = "retp", -- [VKD3DSIH_ROUND_NE ] = "round_ne", -- [VKD3DSIH_ROUND_NI ] = "round_ni", -- [VKD3DSIH_ROUND_PI ] = "round_pi", -- [VKD3DSIH_ROUND_Z ] = "round_z", -- [VKD3DSIH_RSQ ] = "rsq", -- [VKD3DSIH_SAMPLE ] = "sample", -- [VKD3DSIH_SAMPLE_B ] = "sample_b", -- [VKD3DSIH_SAMPLE_B_CL_S ] = "sample_b_cl_s", -- [VKD3DSIH_SAMPLE_C ] = "sample_c", -- [VKD3DSIH_SAMPLE_C_CL_S ] = "sample_c_cl_s", -- [VKD3DSIH_SAMPLE_C_LZ ] = "sample_c_lz", -- [VKD3DSIH_SAMPLE_C_LZ_S ] = "sample_c_lz_s", -- [VKD3DSIH_SAMPLE_CL_S ] = "sample_cl_s", -- [VKD3DSIH_SAMPLE_GRAD ] = "sample_d", -- [VKD3DSIH_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s", -- [VKD3DSIH_SAMPLE_INFO ] = "sample_info", -- [VKD3DSIH_SAMPLE_LOD ] = "sample_l", -- [VKD3DSIH_SAMPLE_LOD_S ] = "sample_l_s", -- [VKD3DSIH_SAMPLE_POS ] = "sample_pos", -- [VKD3DSIH_SETP ] = "setp", -- [VKD3DSIH_SGE ] = "sge", -- [VKD3DSIH_SGN ] = "sgn", -- [VKD3DSIH_SINCOS ] = "sincos", -- [VKD3DSIH_SLT ] = "slt", -- [VKD3DSIH_SQRT ] = "sqrt", -- [VKD3DSIH_STORE_RAW ] = "store_raw", -- [VKD3DSIH_STORE_STRUCTURED ] = "store_structured", -- [VKD3DSIH_STORE_UAV_TYPED ] = "store_uav_typed", -- [VKD3DSIH_SUB ] = "sub", -- [VKD3DSIH_SWAPC ] = "swapc", -- [VKD3DSIH_SWITCH ] = "switch", -- [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch", -- [VKD3DSIH_SYNC ] = "sync", -- [VKD3DSIH_TAN ] = "tan", -- [VKD3DSIH_TEX ] = "texld", -- [VKD3DSIH_TEXBEM ] = "texbem", -- [VKD3DSIH_TEXBEML ] = "texbeml", -- [VKD3DSIH_TEXCOORD ] = "texcrd", -- [VKD3DSIH_TEXDEPTH ] = "texdepth", -- [VKD3DSIH_TEXDP3 ] = "texdp3", -- [VKD3DSIH_TEXDP3TEX ] = "texdp3tex", -- [VKD3DSIH_TEXKILL ] = "texkill", -- [VKD3DSIH_TEXLDD ] = "texldd", -- [VKD3DSIH_TEXLDL ] = "texldl", -- [VKD3DSIH_TEXM3x2DEPTH ] = "texm3x2depth", -- [VKD3DSIH_TEXM3x2PAD ] = "texm3x2pad", -- [VKD3DSIH_TEXM3x2TEX ] = "texm3x2tex", -- [VKD3DSIH_TEXM3x3 ] = "texm3x3", -- [VKD3DSIH_TEXM3x3DIFF ] = "texm3x3diff", -- [VKD3DSIH_TEXM3x3PAD ] = "texm3x3pad", -- [VKD3DSIH_TEXM3x3SPEC ] = "texm3x3spec", -- [VKD3DSIH_TEXM3x3TEX ] = "texm3x3tex", -- [VKD3DSIH_TEXM3x3VSPEC ] = "texm3x3vspec", -- [VKD3DSIH_TEXREG2AR ] = "texreg2ar", -- [VKD3DSIH_TEXREG2GB ] = "texreg2gb", -- [VKD3DSIH_TEXREG2RGB ] = "texreg2rgb", -- [VKD3DSIH_UBFE ] = "ubfe", -- [VKD3DSIH_UDIV ] = "udiv", -- [VKD3DSIH_UGE ] = "uge", -- [VKD3DSIH_ULT ] = "ult", -- [VKD3DSIH_UMAX ] = "umax", -- [VKD3DSIH_UMIN ] = "umin", -- [VKD3DSIH_UMUL ] = "umul", -- [VKD3DSIH_UNO ] = "uno", -- [VKD3DSIH_USHR ] = "ushr", -- [VKD3DSIH_UTOD ] = "utod", -- [VKD3DSIH_UTOF ] = "utof", -- [VKD3DSIH_UTOU ] = "utou", -- [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", -- [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", -- [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", -- [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", -- [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", -- [VKD3DSIH_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count", -- [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true", -- [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true", -- [VKD3DSIH_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane", -- [VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add", -- [VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax", -- [VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin", -- [VKD3DSIH_WAVE_OP_MAX ] = "wave_op_max", -- [VKD3DSIH_WAVE_OP_MIN ] = "wave_op_min", -- [VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul", -- [VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax", -- [VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin", -- [VKD3DSIH_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count", -- [VKD3DSIH_WAVE_READ_LANE_AT ] = "wave_read_lane_at", -- [VKD3DSIH_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first", -- [VKD3DSIH_XOR ] = "xor", --}; -- - static const char * const shader_register_names[] = - { - [VKD3DSPR_ADDR ] = "a", -@@ -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) - { -+ /* Note that we need to handle INT_MIN here as well. */ - if (i < 0) -- vkd3d_string_buffer_printf(&compiler->buffer, "%s-%s%d%s%s", -- prefix, compiler->colours.literal, -i, compiler->colours.reset, suffix); -+ vkd3d_string_buffer_printf(&compiler->buffer, "%s-%s%u%s%s", -+ prefix, compiler->colours.literal, -(unsigned int)i, compiler->colours.reset, suffix); - else - vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%d%s%s", - prefix, compiler->colours.literal, i, compiler->colours.reset, suffix); -@@ -1041,8 +719,8 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - - switch (compiler->current->opcode) - { -- case VKD3DSIH_MOV: -- case VKD3DSIH_MOVC: -+ case VSIR_OP_MOV: -+ case VSIR_OP_MOVC: - untyped = true; - break; - -@@ -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) - { -- case VKD3DSIH_BREAKP: -- case VKD3DSIH_CONTINUEP: -- case VKD3DSIH_DISCARD: -- case VKD3DSIH_IF: -- case VKD3DSIH_RETP: -+ case VSIR_OP_BREAKP: -+ case VSIR_OP_CONTINUEP: -+ case VSIR_OP_DISCARD: -+ case VSIR_OP_IF: -+ case VSIR_OP_RETP: - switch (ins->flags) - { - case VKD3D_SHADER_CONDITIONAL_OP_NZ: -@@ -1629,8 +1307,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile - } - break; - -- case VKD3DSIH_IFC: -- case VKD3DSIH_BREAKC: -+ case VSIR_OP_IFC: -+ case VSIR_OP_BREAKC: - switch (ins->flags) - { - case VKD3D_SHADER_REL_OP_GT: -@@ -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 & ~VKD3DSI_PRECISE_XYZW) - { - case VKD3DSI_NONE: - 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 & ~VKD3DSI_PRECISE_XYZW) - { - case VKD3DSI_NONE: - break; -@@ -1688,24 +1366,24 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile - } - break; - -- case VKD3DSIH_IMM_ATOMIC_CMP_EXCH: -- case VKD3DSIH_IMM_ATOMIC_IADD: -- case VKD3DSIH_IMM_ATOMIC_AND: -- case VKD3DSIH_IMM_ATOMIC_IMAX: -- case VKD3DSIH_IMM_ATOMIC_IMIN: -- case VKD3DSIH_IMM_ATOMIC_OR: -- case VKD3DSIH_IMM_ATOMIC_UMAX: -- case VKD3DSIH_IMM_ATOMIC_UMIN: -- case VKD3DSIH_IMM_ATOMIC_EXCH: -- case VKD3DSIH_IMM_ATOMIC_XOR: -+ case VSIR_OP_IMM_ATOMIC_CMP_EXCH: -+ case VSIR_OP_IMM_ATOMIC_IADD: -+ case VSIR_OP_IMM_ATOMIC_AND: -+ case VSIR_OP_IMM_ATOMIC_IMAX: -+ case VSIR_OP_IMM_ATOMIC_IMIN: -+ case VSIR_OP_IMM_ATOMIC_OR: -+ case VSIR_OP_IMM_ATOMIC_UMAX: -+ case VSIR_OP_IMM_ATOMIC_UMIN: -+ case VSIR_OP_IMM_ATOMIC_EXCH: -+ case VSIR_OP_IMM_ATOMIC_XOR: - shader_dump_atomic_op_flags(compiler, ins->flags); - break; - -- case VKD3DSIH_SYNC: -+ case VSIR_OP_SYNC: - shader_dump_sync_flags(compiler, ins->flags); - break; - -- case VKD3DSIH_TEX: -+ case VSIR_OP_TEXLD: - if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0)) - { - if (ins->flags & VKD3DSI_TEXLD_PROJECT) -@@ -1715,25 +1393,25 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile - } - break; - -- case VKD3DSIH_WAVE_OP_ADD: -- case VKD3DSIH_WAVE_OP_IMAX: -- case VKD3DSIH_WAVE_OP_IMIN: -- case VKD3DSIH_WAVE_OP_MAX: -- case VKD3DSIH_WAVE_OP_MIN: -- case VKD3DSIH_WAVE_OP_MUL: -- case VKD3DSIH_WAVE_OP_UMAX: -- case VKD3DSIH_WAVE_OP_UMIN: -+ case VSIR_OP_WAVE_OP_ADD: -+ case VSIR_OP_WAVE_OP_IMAX: -+ case VSIR_OP_WAVE_OP_IMIN: -+ case VSIR_OP_WAVE_OP_MAX: -+ case VSIR_OP_WAVE_OP_MIN: -+ case VSIR_OP_WAVE_OP_MUL: -+ case VSIR_OP_WAVE_OP_UMAX: -+ case VSIR_OP_WAVE_OP_UMIN: - vkd3d_string_buffer_printf(&compiler->buffer, (ins->flags & VKD3DSI_WAVE_PREFIX) ? "_prefix" : "_active"); - break; - -- case VKD3DSIH_ISHL: -- case VKD3DSIH_ISHR: -- case VKD3DSIH_USHR: -+ case VSIR_OP_ISHL: -+ case VSIR_OP_ISHR: -+ 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; - } - } -@@ -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, -- shader_opcode_names[opcode], compiler->colours.reset); -+ vsir_opcode_get_name(opcode, ""), compiler->colours.reset); - } - - static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler, -@@ -1799,8 +1477,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, - - switch (ins->opcode) - { -- case VKD3DSIH_DCL: -- case VKD3DSIH_DCL_UAV_TYPED: -+ case VSIR_OP_DCL: -+ case VSIR_OP_DCL_UAV_TYPED: - 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 +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; - -- case VKD3DSIH_DCL_CONSTANT_BUFFER: -+ case VSIR_OP_DCL_CONSTANT_BUFFER: - 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 +1498,33 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, - shader_dump_register_space(compiler, ins->declaration.cb.range.space); - break; - -- case VKD3DSIH_DCL_FUNCTION_BODY: -+ case VSIR_OP_DCL_FUNCTION_BODY: - vkd3d_string_buffer_printf(buffer, " fb%u", ins->declaration.index); - break; - -- case VKD3DSIH_DCL_FUNCTION_TABLE: -+ case VSIR_OP_DCL_FUNCTION_TABLE: - vkd3d_string_buffer_printf(buffer, " ft%u = {...}", ins->declaration.index); - break; - -- case VKD3DSIH_DCL_GLOBAL_FLAGS: -+ case VSIR_OP_DCL_GLOBAL_FLAGS: - vkd3d_string_buffer_printf(buffer, " "); - shader_dump_global_flags(compiler, ins->declaration.global_flags); - break; - -- case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: -+ case VSIR_OP_DCL_HS_MAX_TESSFACTOR: - shader_print_float_literal(compiler, " ", ins->declaration.max_tessellation_factor, ""); - break; - -- case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER: -+ case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: - shader_dump_icb(compiler, ins->declaration.icb); - break; - -- case VKD3DSIH_DCL_INDEX_RANGE: -+ case VSIR_OP_DCL_INDEX_RANGE: - shader_print_dst_param(compiler, " ", &ins->declaration.index_range.dst, true, ""); - shader_print_uint_literal(compiler, " ", ins->declaration.index_range.register_count, ""); - break; - -- case VKD3DSIH_DCL_INDEXABLE_TEMP: -+ case VSIR_OP_DCL_INDEXABLE_TEMP: - 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 +1535,113 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, - shader_dump_icb(compiler, ins->declaration.indexable_temp.initialiser); - break; - -- case VKD3DSIH_DCL_INPUT_PS: -+ case VSIR_OP_DCL_INPUT_PS: - shader_print_interpolation_mode(compiler, " ", ins->flags, ""); - shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, ""); - break; - -- case VKD3DSIH_DCL_INPUT_PS_SGV: -- case VKD3DSIH_DCL_INPUT_SGV: -- case VKD3DSIH_DCL_INPUT_SIV: -- case VKD3DSIH_DCL_OUTPUT_SIV: -+ case VSIR_OP_DCL_INPUT_PS_SGV: -+ case VSIR_OP_DCL_INPUT_SGV: -+ case VSIR_OP_DCL_INPUT_SIV: -+ case VSIR_OP_DCL_OUTPUT_SGV: -+ case VSIR_OP_DCL_OUTPUT_SIV: - shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, ""); - shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, ""); - break; - -- case VKD3DSIH_DCL_INPUT_PS_SIV: -+ case VSIR_OP_DCL_INPUT_PS_SIV: - shader_print_interpolation_mode(compiler, " ", ins->flags, ""); - shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, ""); - shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, ""); - break; - -- case VKD3DSIH_DCL_INPUT: -- case VKD3DSIH_DCL_OUTPUT: -+ case VSIR_OP_DCL_INPUT: -+ case VSIR_OP_DCL_OUTPUT: - shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, ""); - break; - -- case VKD3DSIH_DCL_INPUT_PRIMITIVE: -- case VKD3DSIH_DCL_OUTPUT_TOPOLOGY: -+ case VSIR_OP_DCL_INPUT_PRIMITIVE: -+ case VSIR_OP_DCL_OUTPUT_TOPOLOGY: - shader_print_primitive_type(compiler, " ", &ins->declaration.primitive_type, ""); - break; - -- case VKD3DSIH_DCL_INTERFACE: -+ case VSIR_OP_DCL_INTERFACE: - vkd3d_string_buffer_printf(buffer, " fp%u", ins->declaration.fp.index); - shader_print_subscript(compiler, ins->declaration.fp.array_size, NULL); - shader_print_subscript(compiler, ins->declaration.fp.body_count, NULL); - vkd3d_string_buffer_printf(buffer, " = {...}"); - break; - -- case VKD3DSIH_DCL_RESOURCE_RAW: -+ case VSIR_OP_DCL_RESOURCE_RAW: - shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, ""); - shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space); - break; - -- case VKD3DSIH_DCL_RESOURCE_STRUCTURED: -+ case VSIR_OP_DCL_RESOURCE_STRUCTURED: - shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, ""); - shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, ""); - shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space); - break; - -- case VKD3DSIH_DCL_SAMPLER: -+ case VSIR_OP_DCL_SAMPLER: - shader_print_register(compiler, " ", &ins->declaration.sampler.src.reg, true, - ins->flags == VKD3DSI_SAMPLER_COMPARISON_MODE ? ", comparisonMode" : ""); - shader_dump_register_space(compiler, ins->declaration.sampler.range.space); - break; - -- case VKD3DSIH_DCL_TEMPS: -- case VKD3DSIH_DCL_GS_INSTANCES: -- case VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT: -- case VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: -- case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: -- case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT: -- case VKD3DSIH_DCL_VERTICES_OUT: -+ case VSIR_OP_DCL_TEMPS: -+ case VSIR_OP_DCL_GS_INSTANCES: -+ case VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT: -+ case VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: -+ case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: -+ case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: -+ case VSIR_OP_DCL_VERTICES_OUT: - shader_print_uint_literal(compiler, " ", ins->declaration.count, ""); - break; - -- case VKD3DSIH_DCL_TESSELLATOR_DOMAIN: -+ case VSIR_OP_DCL_TESSELLATOR_DOMAIN: - shader_print_tessellator_domain(compiler, " ", ins->declaration.tessellator_domain, ""); - break; - -- case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: -+ case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: - shader_print_tessellator_output_primitive(compiler, " ", ins->declaration.tessellator_output_primitive, ""); - break; - -- case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING: -+ case VSIR_OP_DCL_TESSELLATOR_PARTITIONING: - shader_print_tessellator_partitioning(compiler, " ", ins->declaration.tessellator_partitioning, ""); - break; - -- case VKD3DSIH_DCL_TGSM_RAW: -+ case VSIR_OP_DCL_TGSM_RAW: - shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_raw.reg, true, ""); - shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_raw.byte_count, ""); - break; - -- case VKD3DSIH_DCL_TGSM_STRUCTURED: -+ case VSIR_OP_DCL_TGSM_STRUCTURED: - shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_structured.reg, true, ""); - shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.byte_stride, ""); - shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.structure_count, ""); - break; - -- case VKD3DSIH_DCL_THREAD_GROUP: -+ case VSIR_OP_DCL_THREAD_GROUP: - shader_print_uint_literal(compiler, " ", ins->declaration.thread_group_size.x, ""); - shader_print_uint_literal(compiler, ", ", ins->declaration.thread_group_size.y, ""); - shader_print_uint_literal(compiler, ", ", ins->declaration.thread_group_size.z, ""); - break; - -- case VKD3DSIH_DCL_UAV_RAW: -+ case VSIR_OP_DCL_UAV_RAW: - shader_dump_uav_flags(compiler, ins->flags); - shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, ""); - shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space); - break; - -- case VKD3DSIH_DCL_UAV_STRUCTURED: -+ case VSIR_OP_DCL_UAV_STRUCTURED: - shader_dump_uav_flags(compiler, ins->flags); - shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, ""); - shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, ""); - shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space); - break; - -- case VKD3DSIH_DEF: -+ case VSIR_OP_DEF: - 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 +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; - -- case VKD3DSIH_DEFI: -+ case VSIR_OP_DEFI: - 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 +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; - -- case VKD3DSIH_DEFB: -+ case VSIR_OP_DEFB: - 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], ""); -@@ -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: -- case VKD3DSIH_ENDIF: -- case VKD3DSIH_ENDLOOP: -- case VKD3DSIH_ENDSWITCH: -+ case VSIR_OP_ELSE: -+ case VSIR_OP_ENDIF: -+ case VSIR_OP_ENDLOOP: -+ case VSIR_OP_ENDSWITCH: - if (indent) - --indent; - break; - -- case VKD3DSIH_LABEL: -- case VKD3DSIH_HS_DECLS: -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_LABEL: -+ case VSIR_OP_HS_DECLS: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - indent = 0; - break; - -@@ -2402,12 +2095,12 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, - - switch (ins->opcode) - { -- case VKD3DSIH_ELSE: -- case VKD3DSIH_IF: -- case VKD3DSIH_IFC: -- case VKD3DSIH_LOOP: -- case VKD3DSIH_SWITCH: -- case VKD3DSIH_LABEL: -+ case VSIR_OP_ELSE: -+ case VSIR_OP_IF: -+ case VSIR_OP_IFC: -+ case VSIR_OP_LOOP: -+ case VSIR_OP_SWITCH: -+ case VSIR_OP_LABEL: - ++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..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 - static const struct vkd3d_sm1_opcode_info vs_opcode_table[] = - { - /* Arithmetic */ -- {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP}, -- {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV}, -- {VKD3D_SM1_OP_MOVA, 1, 1, VKD3DSIH_MOVA, {2, 0}}, -- {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD}, -- {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB}, -- {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD}, -- {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL}, -- {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP}, -- {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ}, -- {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3}, -- {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4}, -- {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN}, -- {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX}, -- {VKD3D_SM1_OP_SLT, 1, 2, VKD3DSIH_SLT}, -- {VKD3D_SM1_OP_SGE, 1, 2, VKD3DSIH_SGE}, -- {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS, {2, 0}}, -- {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP}, -- {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG}, -- {VKD3D_SM1_OP_EXPP, 1, 1, VKD3DSIH_EXPP}, -- {VKD3D_SM1_OP_LOGP, 1, 1, VKD3DSIH_LOGP}, -- {VKD3D_SM1_OP_LIT, 1, 1, VKD3DSIH_LIT}, -- {VKD3D_SM1_OP_DST, 1, 2, VKD3DSIH_DST}, -- {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP, {2, 0}}, -- {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC}, -- {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW, {2, 0}}, -- {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS, {2, 0}}, -- {VKD3D_SM1_OP_SGN, 1, 3, VKD3DSIH_SGN, {2, 0}, {2, 1}}, -- {VKD3D_SM1_OP_SGN, 1, 1, VKD3DSIH_SGN, {3, 0}}, -- {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM, {2, 0}}, -- {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, {2, 1}}, -- {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}}, -+ {VKD3D_SM1_OP_NOP, 0, 0, VSIR_OP_NOP}, -+ {VKD3D_SM1_OP_MOV, 1, 1, VSIR_OP_MOV}, -+ {VKD3D_SM1_OP_MOVA, 1, 1, VSIR_OP_MOVA, {2, 0}}, -+ {VKD3D_SM1_OP_ADD, 1, 2, VSIR_OP_ADD}, -+ {VKD3D_SM1_OP_SUB, 1, 2, VSIR_OP_SUB}, -+ {VKD3D_SM1_OP_MAD, 1, 3, VSIR_OP_MAD}, -+ {VKD3D_SM1_OP_MUL, 1, 2, VSIR_OP_MUL}, -+ {VKD3D_SM1_OP_RCP, 1, 1, VSIR_OP_RCP}, -+ {VKD3D_SM1_OP_RSQ, 1, 1, VSIR_OP_RSQ}, -+ {VKD3D_SM1_OP_DP3, 1, 2, VSIR_OP_DP3}, -+ {VKD3D_SM1_OP_DP4, 1, 2, VSIR_OP_DP4}, -+ {VKD3D_SM1_OP_MIN, 1, 2, VSIR_OP_MIN}, -+ {VKD3D_SM1_OP_MAX, 1, 2, VSIR_OP_MAX}, -+ {VKD3D_SM1_OP_SLT, 1, 2, VSIR_OP_SLT}, -+ {VKD3D_SM1_OP_SGE, 1, 2, VSIR_OP_SGE}, -+ {VKD3D_SM1_OP_ABS, 1, 1, VSIR_OP_ABS, {2, 0}}, -+ {VKD3D_SM1_OP_EXP, 1, 1, VSIR_OP_EXP}, -+ {VKD3D_SM1_OP_LOG, 1, 1, VSIR_OP_LOG}, -+ {VKD3D_SM1_OP_EXPP, 1, 1, VSIR_OP_EXPP}, -+ {VKD3D_SM1_OP_LOGP, 1, 1, VSIR_OP_LOGP}, -+ {VKD3D_SM1_OP_LIT, 1, 1, VSIR_OP_LIT}, -+ {VKD3D_SM1_OP_DST, 1, 2, VSIR_OP_DST}, -+ {VKD3D_SM1_OP_LRP, 1, 3, VSIR_OP_LRP, {2, 0}}, -+ {VKD3D_SM1_OP_FRC, 1, 1, VSIR_OP_FRC}, -+ {VKD3D_SM1_OP_POW, 1, 2, VSIR_OP_POW, {2, 0}}, -+ {VKD3D_SM1_OP_CRS, 1, 2, VSIR_OP_CRS, {2, 0}}, -+ {VKD3D_SM1_OP_SGN, 1, 3, VSIR_OP_SGN, {2, 0}, {2, 1}}, -+ {VKD3D_SM1_OP_SGN, 1, 1, VSIR_OP_SGN, {3, 0}}, -+ {VKD3D_SM1_OP_NRM, 1, 1, VSIR_OP_NRM, {2, 0}}, -+ {VKD3D_SM1_OP_SINCOS, 1, 3, VSIR_OP_SINCOS, {2, 0}, {2, 1}}, -+ {VKD3D_SM1_OP_SINCOS, 1, 1, VSIR_OP_SINCOS, {3, 0}}, - /* Matrix */ -- {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4}, -- {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3}, -- {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4}, -- {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3}, -- {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2}, -+ {VKD3D_SM1_OP_M4x4, 1, 2, VSIR_OP_M4x4}, -+ {VKD3D_SM1_OP_M4x3, 1, 2, VSIR_OP_M4x3}, -+ {VKD3D_SM1_OP_M3x4, 1, 2, VSIR_OP_M3x4}, -+ {VKD3D_SM1_OP_M3x3, 1, 2, VSIR_OP_M3x3}, -+ {VKD3D_SM1_OP_M3x2, 1, 2, VSIR_OP_M3x2}, - /* Declarations */ -- {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL}, -+ {VKD3D_SM1_OP_DCL, 0, 0, VSIR_OP_DCL}, - /* Constant definitions */ -- {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF}, -- {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB, {2, 0}}, -- {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI, {2, 0}}, -+ {VKD3D_SM1_OP_DEF, 1, 1, VSIR_OP_DEF}, -+ {VKD3D_SM1_OP_DEFB, 1, 1, VSIR_OP_DEFB, {2, 0}}, -+ {VKD3D_SM1_OP_DEFI, 1, 1, VSIR_OP_DEFI, {2, 0}}, - /* Control flow */ -- {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 0}}, -- {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 0}}, -- {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 0}}, -- {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}}, -- {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 0}}, -- {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 0}}, -- {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}}, -- {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}}, -- {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP, {2, 1}}, -- {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 0}}, -- {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 0}}, -- {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {2, 0}}, -- {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 0}}, -- {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {2, 0}}, -- {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 0}}, -- -- {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP, {2, 1}}, -- {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}}, -- {0, 0, 0, VKD3DSIH_INVALID}, -+ {VKD3D_SM1_OP_REP, 0, 1, VSIR_OP_REP, {2, 0}}, -+ {VKD3D_SM1_OP_ENDREP, 0, 0, VSIR_OP_ENDREP, {2, 0}}, -+ {VKD3D_SM1_OP_IF, 0, 1, VSIR_OP_IF, {2, 0}}, -+ {VKD3D_SM1_OP_IFC, 0, 2, VSIR_OP_IFC, {2, 1}}, -+ {VKD3D_SM1_OP_ELSE, 0, 0, VSIR_OP_ELSE, {2, 0}}, -+ {VKD3D_SM1_OP_ENDIF, 0, 0, VSIR_OP_ENDIF, {2, 0}}, -+ {VKD3D_SM1_OP_BREAK, 0, 0, VSIR_OP_BREAK, {2, 1}}, -+ {VKD3D_SM1_OP_BREAKC, 0, 2, VSIR_OP_BREAKC, {2, 1}}, -+ {VKD3D_SM1_OP_BREAKP, 0, 1, VSIR_OP_BREAKP, {2, 1}}, -+ {VKD3D_SM1_OP_CALL, 0, 1, VSIR_OP_CALL, {2, 0}}, -+ {VKD3D_SM1_OP_CALLNZ, 0, 2, VSIR_OP_CALLNZ, {2, 0}}, -+ {VKD3D_SM1_OP_LOOP, 0, 2, VSIR_OP_LOOP, {2, 0}}, -+ {VKD3D_SM1_OP_RET, 0, 0, VSIR_OP_RET, {2, 0}}, -+ {VKD3D_SM1_OP_ENDLOOP, 0, 0, VSIR_OP_ENDLOOP, {2, 0}}, -+ {VKD3D_SM1_OP_LABEL, 0, 1, VSIR_OP_LABEL, {2, 0}}, -+ -+ {VKD3D_SM1_OP_SETP, 1, 2, VSIR_OP_SETP, {2, 1}}, -+ {VKD3D_SM1_OP_TEXLDL, 1, 2, VSIR_OP_TEXLDL, {3, 0}}, -+ {0, 0, 0, VSIR_OP_INVALID}, - }; - - static const struct vkd3d_sm1_opcode_info ps_opcode_table[] = - { - /* Arithmetic */ -- {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP}, -- {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV}, -- {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD}, -- {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB}, -- {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD}, -- {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL}, -- {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP, {2, 0}}, -- {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ, {2, 0}}, -- {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3}, -- {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4, {1, 2}}, -- {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN, {2, 0}}, -- {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX, {2, 0}}, -- {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS, {2, 0}}, -- {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP, {2, 0}}, -- {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG, {2, 0}}, -- {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP}, -- {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC, {2, 0}}, -- {VKD3D_SM1_OP_CND, 1, 3, VKD3DSIH_CND, {1, 0}, {1, 4}}, -- {VKD3D_SM1_OP_CMP, 1, 3, VKD3DSIH_CMP, {1, 2}}, -- {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW, {2, 0}}, -- {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS, {2, 0}}, -- {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM, {2, 0}}, -- {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, {2, 1}}, -- {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}}, -- {VKD3D_SM1_OP_DP2ADD, 1, 3, VKD3DSIH_DP2ADD, {2, 0}}, -+ {VKD3D_SM1_OP_NOP, 0, 0, VSIR_OP_NOP}, -+ {VKD3D_SM1_OP_MOV, 1, 1, VSIR_OP_MOV}, -+ {VKD3D_SM1_OP_ADD, 1, 2, VSIR_OP_ADD}, -+ {VKD3D_SM1_OP_SUB, 1, 2, VSIR_OP_SUB}, -+ {VKD3D_SM1_OP_MAD, 1, 3, VSIR_OP_MAD}, -+ {VKD3D_SM1_OP_MUL, 1, 2, VSIR_OP_MUL}, -+ {VKD3D_SM1_OP_RCP, 1, 1, VSIR_OP_RCP, {2, 0}}, -+ {VKD3D_SM1_OP_RSQ, 1, 1, VSIR_OP_RSQ, {2, 0}}, -+ {VKD3D_SM1_OP_DP3, 1, 2, VSIR_OP_DP3}, -+ {VKD3D_SM1_OP_DP4, 1, 2, VSIR_OP_DP4, {1, 2}}, -+ {VKD3D_SM1_OP_MIN, 1, 2, VSIR_OP_MIN, {2, 0}}, -+ {VKD3D_SM1_OP_MAX, 1, 2, VSIR_OP_MAX, {2, 0}}, -+ {VKD3D_SM1_OP_ABS, 1, 1, VSIR_OP_ABS, {2, 0}}, -+ {VKD3D_SM1_OP_EXP, 1, 1, VSIR_OP_EXP, {2, 0}}, -+ {VKD3D_SM1_OP_LOG, 1, 1, VSIR_OP_LOG, {2, 0}}, -+ {VKD3D_SM1_OP_LRP, 1, 3, VSIR_OP_LRP}, -+ {VKD3D_SM1_OP_FRC, 1, 1, VSIR_OP_FRC, {2, 0}}, -+ {VKD3D_SM1_OP_CND, 1, 3, VSIR_OP_CND, {1, 0}, {1, 4}}, -+ {VKD3D_SM1_OP_CMP, 1, 3, VSIR_OP_CMP, {1, 2}}, -+ {VKD3D_SM1_OP_POW, 1, 2, VSIR_OP_POW, {2, 0}}, -+ {VKD3D_SM1_OP_CRS, 1, 2, VSIR_OP_CRS, {2, 0}}, -+ {VKD3D_SM1_OP_NRM, 1, 1, VSIR_OP_NRM, {2, 0}}, -+ {VKD3D_SM1_OP_SINCOS, 1, 3, VSIR_OP_SINCOS, {2, 0}, {2, 1}}, -+ {VKD3D_SM1_OP_SINCOS, 1, 1, VSIR_OP_SINCOS, {3, 0}}, -+ {VKD3D_SM1_OP_DP2ADD, 1, 3, VSIR_OP_DP2ADD, {2, 0}}, - /* Matrix */ -- {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4, {2, 0}}, -- {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3, {2, 0}}, -- {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4, {2, 0}}, -- {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3, {2, 0}}, -- {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2, {2, 0}}, -+ {VKD3D_SM1_OP_M4x4, 1, 2, VSIR_OP_M4x4, {2, 0}}, -+ {VKD3D_SM1_OP_M4x3, 1, 2, VSIR_OP_M4x3, {2, 0}}, -+ {VKD3D_SM1_OP_M3x4, 1, 2, VSIR_OP_M3x4, {2, 0}}, -+ {VKD3D_SM1_OP_M3x3, 1, 2, VSIR_OP_M3x3, {2, 0}}, -+ {VKD3D_SM1_OP_M3x2, 1, 2, VSIR_OP_M3x2, {2, 0}}, - /* Declarations */ -- {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL, {2, 0}}, -+ {VKD3D_SM1_OP_DCL, 0, 0, VSIR_OP_DCL, {2, 0}}, - /* Constant definitions */ -- {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF}, -- {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB, {2, 0}}, -- {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI, {2, 1}}, -+ {VKD3D_SM1_OP_DEF, 1, 1, VSIR_OP_DEF}, -+ {VKD3D_SM1_OP_DEFB, 1, 1, VSIR_OP_DEFB, {2, 0}}, -+ {VKD3D_SM1_OP_DEFI, 1, 1, VSIR_OP_DEFI, {2, 1}}, - /* Control flow */ -- {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 1}}, -- {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 1}}, -- {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 1}}, -- {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}}, -- {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 1}}, -- {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 1}}, -- {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}}, -- {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}}, -- {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP, {2, 1}}, -- {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 1}}, -- {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 1}}, -- {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {3, 0}}, -- {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 1}}, -- {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {3, 0}}, -- {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 1}}, -+ {VKD3D_SM1_OP_REP, 0, 1, VSIR_OP_REP, {2, 1}}, -+ {VKD3D_SM1_OP_ENDREP, 0, 0, VSIR_OP_ENDREP, {2, 1}}, -+ {VKD3D_SM1_OP_IF, 0, 1, VSIR_OP_IF, {2, 1}}, -+ {VKD3D_SM1_OP_IFC, 0, 2, VSIR_OP_IFC, {2, 1}}, -+ {VKD3D_SM1_OP_ELSE, 0, 0, VSIR_OP_ELSE, {2, 1}}, -+ {VKD3D_SM1_OP_ENDIF, 0, 0, VSIR_OP_ENDIF, {2, 1}}, -+ {VKD3D_SM1_OP_BREAK, 0, 0, VSIR_OP_BREAK, {2, 1}}, -+ {VKD3D_SM1_OP_BREAKC, 0, 2, VSIR_OP_BREAKC, {2, 1}}, -+ {VKD3D_SM1_OP_BREAKP, 0, 1, VSIR_OP_BREAKP, {2, 1}}, -+ {VKD3D_SM1_OP_CALL, 0, 1, VSIR_OP_CALL, {2, 1}}, -+ {VKD3D_SM1_OP_CALLNZ, 0, 2, VSIR_OP_CALLNZ, {2, 1}}, -+ {VKD3D_SM1_OP_LOOP, 0, 2, VSIR_OP_LOOP, {3, 0}}, -+ {VKD3D_SM1_OP_RET, 0, 0, VSIR_OP_RET, {2, 1}}, -+ {VKD3D_SM1_OP_ENDLOOP, 0, 0, VSIR_OP_ENDLOOP, {3, 0}}, -+ {VKD3D_SM1_OP_LABEL, 0, 1, VSIR_OP_LABEL, {2, 1}}, - /* Texture */ -- {VKD3D_SM1_OP_TEXCOORD, 1, 0, VKD3DSIH_TEXCOORD, {0, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXCOORD, 1, 1, VKD3DSIH_TEXCOORD, {1, 4}, {1, 4}}, -- {VKD3D_SM1_OP_TEXKILL, 1, 0, VKD3DSIH_TEXKILL, {1, 0}}, -- {VKD3D_SM1_OP_TEX, 1, 0, VKD3DSIH_TEX, {0, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEX, 1, 1, VKD3DSIH_TEX, {1, 4}, {1, 4}}, -- {VKD3D_SM1_OP_TEX, 1, 2, VKD3DSIH_TEX, {2, 0}}, -- {VKD3D_SM1_OP_TEXBEM, 1, 1, VKD3DSIH_TEXBEM, {0, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXBEML, 1, 1, VKD3DSIH_TEXBEML, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VKD3DSIH_TEXREG2AR, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VKD3DSIH_TEXREG2GB, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VKD3DSIH_TEXREG2RGB, {1, 2}, {1, 3}}, -- {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VKD3DSIH_TEXM3x2PAD, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VKD3DSIH_TEXM3x2TEX, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VKD3DSIH_TEXM3x3PAD, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VKD3DSIH_TEXM3x3DIFF, {0, 0}, {0, 0}}, -- {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VKD3DSIH_TEXM3x3SPEC, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VKD3DSIH_TEXM3x3VSPEC, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VKD3DSIH_TEXM3x3TEX, {1, 0}, {1, 3}}, -- {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VKD3DSIH_TEXDP3TEX, {1, 2}, {1, 3}}, -- {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VKD3DSIH_TEXM3x2DEPTH, {1, 3}, {1, 3}}, -- {VKD3D_SM1_OP_TEXDP3, 1, 1, VKD3DSIH_TEXDP3, {1, 2}, {1, 3}}, -- {VKD3D_SM1_OP_TEXM3x3, 1, 1, VKD3DSIH_TEXM3x3, {1, 2}, {1, 3}}, -- {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VKD3DSIH_TEXDEPTH, {1, 4}, {1, 4}}, -- {VKD3D_SM1_OP_BEM, 1, 2, VKD3DSIH_BEM, {1, 4}, {1, 4}}, -- {VKD3D_SM1_OP_DSX, 1, 1, VKD3DSIH_DSX, {2, 1}}, -- {VKD3D_SM1_OP_DSY, 1, 1, VKD3DSIH_DSY, {2, 1}}, -- {VKD3D_SM1_OP_TEXLDD, 1, 4, VKD3DSIH_TEXLDD, {2, 1}}, -- {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP, {2, 1}}, -- {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}}, -- {VKD3D_SM1_OP_PHASE, 0, 0, VKD3DSIH_PHASE, {1, 4}, {1, 4}}, -- {0, 0, 0, VKD3DSIH_INVALID}, -+ {VKD3D_SM1_OP_TEXCOORD, 1, 0, VSIR_OP_TEXCOORD, {0, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXCOORD, 1, 1, VSIR_OP_TEXCRD, {1, 4}, {1, 4}}, -+ {VKD3D_SM1_OP_TEXKILL, 1, 0, VSIR_OP_TEXKILL, {1, 0}}, -+ {VKD3D_SM1_OP_TEX, 1, 0, VSIR_OP_TEX, {0, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEX, 1, 1, VSIR_OP_TEXLD, {1, 4}, {1, 4}}, -+ {VKD3D_SM1_OP_TEX, 1, 2, VSIR_OP_TEXLD, {2, 0}}, -+ {VKD3D_SM1_OP_TEXBEM, 1, 1, VSIR_OP_TEXBEM, {0, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXBEML, 1, 1, VSIR_OP_TEXBEML, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VSIR_OP_TEXREG2AR, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VSIR_OP_TEXREG2GB, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VSIR_OP_TEXREG2RGB, {1, 2}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VSIR_OP_TEXM3x2PAD, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VSIR_OP_TEXM3x2TEX, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VSIR_OP_TEXM3x3PAD, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VSIR_OP_TEXM3x3DIFF, {0, 0}, {0, 0}}, -+ {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VSIR_OP_TEXM3x3SPEC, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VSIR_OP_TEXM3x3VSPEC, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VSIR_OP_TEXM3x3TEX, {1, 0}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VSIR_OP_TEXDP3TEX, {1, 2}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VSIR_OP_TEXM3x2DEPTH, {1, 3}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXDP3, 1, 1, VSIR_OP_TEXDP3, {1, 2}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXM3x3, 1, 1, VSIR_OP_TEXM3x3, {1, 2}, {1, 3}}, -+ {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VSIR_OP_TEXDEPTH, {1, 4}, {1, 4}}, -+ {VKD3D_SM1_OP_BEM, 1, 2, VSIR_OP_BEM, {1, 4}, {1, 4}}, -+ {VKD3D_SM1_OP_DSX, 1, 1, VSIR_OP_DSX, {2, 1}}, -+ {VKD3D_SM1_OP_DSY, 1, 1, VSIR_OP_DSY, {2, 1}}, -+ {VKD3D_SM1_OP_TEXLDD, 1, 4, VSIR_OP_TEXLDD, {2, 1}}, -+ {VKD3D_SM1_OP_SETP, 1, 2, VSIR_OP_SETP, {2, 1}}, -+ {VKD3D_SM1_OP_TEXLDL, 1, 2, VSIR_OP_TEXLDL, {3, 0}}, -+ {VKD3D_SM1_OP_PHASE, 0, 0, VSIR_OP_PHASE, {1, 4}, {1, 4}}, -+ {0, 0, 0, VSIR_OP_INVALID}, - }; - - static const struct -@@ -475,7 +475,7 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info( - for (;;) - { - info = &sm1->opcode_table[i++]; -- if (info->vkd3d_opcode == VKD3DSIH_INVALID) -+ if (info->vkd3d_opcode == VSIR_OP_INVALID) - 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 - * shader_sm1_read_semantic(). */ -- if (opcode_info->vkd3d_opcode == VKD3DSIH_DCL) -+ if (opcode_info->vkd3d_opcode == VSIR_OP_DCL) - { - *ptr += 2; - } -@@ -1002,7 +1002,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co - * four tokens for that source. See shader_sm1_read_immconst(). - * Technically shader model 1 doesn't have integer registers or DEFI; we - * handle it here anyway because it's easy. */ -- else if (opcode_info->vkd3d_opcode == VKD3DSIH_DEF || opcode_info->vkd3d_opcode == VKD3DSIH_DEFI) -+ else if (opcode_info->vkd3d_opcode == VSIR_OP_DEF || opcode_info->vkd3d_opcode == VSIR_OP_DEFI) - { - *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) - { -- if ((ins->opcode == VKD3DSIH_BREAKP || ins->opcode == VKD3DSIH_IF) && ins->flags) -+ if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags) - { - vkd3d_shader_parser_warning(&sm1->p, VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS, - "Ignoring unexpected instruction flags %#x.", ins->flags); -@@ -1242,7 +1242,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - goto fail; - } - -- if (opcode_info->vkd3d_opcode == VKD3DSIH_TEXKILL) -+ if (opcode_info->vkd3d_opcode == VSIR_OP_TEXKILL) - { - 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; - } - -- if (ins->opcode == VKD3DSIH_DCL) -+ if (ins->opcode == VSIR_OP_DCL) - { - shader_sm1_read_semantic(sm1, &p, &ins->declaration.semantic); - } -- else if (ins->opcode == VKD3DSIH_DEF) -+ 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 == 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, 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, VSIR_DATA_I32); - shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); - } -- else if (ins->opcode == VKD3DSIH_TEXKILL) -+ else if (ins->opcode == VSIR_OP_TEXKILL) - { - /* TEXKILL, uniquely, encodes its argument as a destination, when it is - * semantically a source. Since we have multiple passes which operate -@@ -1360,7 +1360,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - return; - - fail: -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - *ptr = sm1->end; - } - -@@ -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) -+ if (ins->opcode == VSIR_OP_INVALID) - { - WARN("Encountered unrecognized or invalid instruction.\n"); - vsir_program_cleanup(program); - 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++]; -- if (info->vkd3d_opcode == VKD3DSIH_INVALID) -+ if (info->vkd3d_opcode == VSIR_OP_INVALID) - return NULL; - - if (vkd3d_opcode == info->vkd3d_opcode -@@ -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, -- "Opcode %#x not supported for shader profile.", ins->opcode); -+ "Instruction \"%s\" (%#x) is not supported for the current target.", -+ vsir_opcode_get_name(ins->opcode, ""), ins->opcode); - d3dbc->failed = true; - return NULL; - } -@@ -1689,16 +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 %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; - } - if (ins->src_count != info->src_count) - { - vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT, -- "Invalid source count %u for vsir instruction %#x (expected %u).", -- ins->src_count, ins->opcode, info->src_count); -+ "Invalid source parameter count %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 +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; - -- if (ins->opcode != VKD3DSIH_MOV) -+ if (ins->opcode != VSIR_OP_MOV) - return false; - if (dst->modifiers != VKD3DSPDM_NONE) - return false; -@@ -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; -+ size_t size, token_position; - unsigned int i; - uint32_t token; - -@@ -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); - -- if (version->major > 1) -- token |= (ins->dst_count + ins->src_count) << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; -- put_u32(buffer, token); -+ token_position = put_u32(buffer, 0); - - for (i = 0; i < ins->dst_count; ++i) - { -@@ -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); - } -+ -+ if (version->major > 1) -+ { -+ size = (bytecode_get_size(buffer) - token_position) / sizeof(uint32_t); -+ token |= ((size - 1) << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT); -+ } -+ -+ set_u32(buffer, token_position, token); - }; - - static void d3dbc_write_texkill(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) -@@ -1982,55 +1988,56 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str - - switch (ins->opcode) - { -- case VKD3DSIH_DEF: -+ case VSIR_OP_DEF: - d3dbc_write_vsir_def(d3dbc, ins); - break; - -- case VKD3DSIH_DCL: -+ case VSIR_OP_DCL: - d3dbc_write_vsir_dcl(d3dbc, ins); - break; - -- case VKD3DSIH_TEXKILL: -+ case VSIR_OP_TEXKILL: - d3dbc_write_texkill(d3dbc, ins); - break; - -- case VKD3DSIH_ABS: -- case VKD3DSIH_ADD: -- case VKD3DSIH_CMP: -- case VKD3DSIH_DP2ADD: -- case VKD3DSIH_DP3: -- case VKD3DSIH_DP4: -- case VKD3DSIH_DSX: -- case VKD3DSIH_DSY: -- case VKD3DSIH_ELSE: -- case VKD3DSIH_ENDIF: -- case VKD3DSIH_FRC: -- case VKD3DSIH_IFC: -- case VKD3DSIH_MAD: -- case VKD3DSIH_MAX: -- case VKD3DSIH_MIN: -- case VKD3DSIH_MOV: -- case VKD3DSIH_MOVA: -- case VKD3DSIH_MUL: -- case VKD3DSIH_SINCOS: -- case VKD3DSIH_SLT: -- case VKD3DSIH_TEX: -- case VKD3DSIH_TEXLDD: -+ case VSIR_OP_ABS: -+ case VSIR_OP_ADD: -+ case VSIR_OP_CMP: -+ case VSIR_OP_DP2ADD: -+ case VSIR_OP_DP3: -+ case VSIR_OP_DP4: -+ case VSIR_OP_DSX: -+ case VSIR_OP_DSY: -+ case VSIR_OP_ELSE: -+ case VSIR_OP_ENDIF: -+ case VSIR_OP_FRC: -+ case VSIR_OP_IFC: -+ case VSIR_OP_MAD: -+ case VSIR_OP_MAX: -+ case VSIR_OP_MIN: -+ case VSIR_OP_MOV: -+ case VSIR_OP_MOVA: -+ case VSIR_OP_MUL: -+ 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; - -- case VKD3DSIH_EXP: -- case VKD3DSIH_LOG: -- case VKD3DSIH_RCP: -- case VKD3DSIH_RSQ: -+ case VSIR_OP_EXP: -+ case VSIR_OP_LOG: -+ case VSIR_OP_RCP: -+ case VSIR_OP_RSQ: - writemask = ins->dst->write_mask; - if (writemask != VKD3DSP_WRITEMASK_0 && writemask != VKD3DSP_WRITEMASK_1 - && writemask != VKD3DSP_WRITEMASK_2 && writemask != VKD3DSP_WRITEMASK_3) - { - vkd3d_shader_error(d3dbc->message_context, &ins->location, - VKD3D_SHADER_ERROR_D3DBC_INVALID_WRITEMASK, -- "writemask %#x for vsir instruction with opcode %#x is not single component.", -- writemask, ins->opcode); -+ "Writemask %#x for instruction \"%s\" (%#x) is not single component.", -+ writemask, vsir_opcode_get_name(ins->opcode, ""), ins->opcode); - d3dbc->failed = true; - } - d3dbc_write_instruction(d3dbc, ins); -@@ -2038,7 +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, -- "vsir instruction with opcode %#x.", ins->opcode); -+ "Internal compiler error: Unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(ins->opcode, ""), ins->opcode); - d3dbc->failed = true; - break; - } -@@ -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; -+ if (!vkd3d_shader_ver_ge(version, 3, 0)) -+ { -+ if (reg.reg.idx[0].offset > SM1_RASTOUT_REGISTER_OFFSET) -+ reg.reg.idx[0].offset -= SM1_RASTOUT_REGISTER_OFFSET; -+ else if (reg.reg.idx[0].offset > SM1_COLOR_REGISTER_OFFSET) -+ reg.reg.idx[0].offset -= SM1_COLOR_REGISTER_OFFSET; -+ } - } - - token = VKD3D_SM1_OP_DCL; -@@ -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 +2170,7 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, - } - - put_u32(buffer, sm1_version(version->type, version->major, version->minor)); -- d3dbc_write_comment(&d3dbc, VKD3D_MAKE_TAG('C','T','A','B'), ctab); -+ d3dbc_write_comment(&d3dbc, TAG_CTAB, ctab); - d3dbc_write_semantic_dcls(&d3dbc); - d3dbc_write_program_instructions(&d3dbc); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c -index 9e3a57132a1..45a45c3ad4a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c -@@ -388,7 +388,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s - { - WARN("Invalid data size %#zx.\n", section->data.size); - vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, -- "Section size %zu is smaller than the minimum signature header size.\n", section->data.size); -+ "Section size %zu is smaller than the minimum signature header size.", section->data.size); - return VKD3D_ERROR_INVALID_ARGUMENT; - } - -@@ -402,7 +402,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s - { - WARN("Invalid header size %#x.\n", header_size); - vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, -- "Signature header size %#x is invalid.\n", header_size); -+ "Signature header size %#x is invalid.", header_size); - return VKD3D_ERROR_INVALID_ARGUMENT; - } - skip_dword_unknown(&ptr, i - 2); -@@ -438,7 +438,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s - || !(e[i].semantic_name = vkd3d_strdup(name))) - { - vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_STRING_REFERENCE, -- "Element %u has invalid semantic name reference %#zx (data size %#zx).\n", -+ "Element %u has invalid semantic name reference %#zx (data size %#zx).", - i, name_offset, section->data.size); - fail = true; - } -@@ -447,7 +447,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s - if ((e[i].component_type = read_u32(&ptr)) > VKD3D_SHADER_COMPONENT_FLOAT) - { - vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_COMPONENT_TYPE, -- "Element %u has invalid component type %#x.\n", i, e[i].component_type); -+ "Element %u has invalid component type %#x.", i, e[i].component_type); - fail = true; - } - e[i].register_index = read_u32(&ptr); -@@ -531,7 +531,7 @@ static int shdr_parse_features(const struct vkd3d_shader_dxbc_section_desc *sect - { - WARN("Invalid data size %#zx.\n", section->data.size); - vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE, -- "SFI0 section size %zu is too small to contain flags.\n", section->data.size); -+ "SFI0 section size %zu is too small to contain flags.", section->data.size); - return VKD3D_ERROR_INVALID_ARGUMENT; - } - flags = read_u64(&ptr); -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -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 - - enum sm6_value_type - { -+ VALUE_TYPE_INVALID, - VALUE_TYPE_FUNCTION, -- VALUE_TYPE_REG, - VALUE_TYPE_DATA, - VALUE_TYPE_HANDLE, - VALUE_TYPE_SSA, - VALUE_TYPE_ICB, - VALUE_TYPE_IDXTEMP, - VALUE_TYPE_GROUPSHAREDMEM, -+ VALUE_TYPE_CONSTANT, - VALUE_TYPE_UNDEFINED, -- VALUE_TYPE_INVALID, -+}; -+ -+struct sm6_index -+{ -+ const struct sm6_value *index; -+ bool is_in_bounds; - }; - - struct sm6_function_data -@@ -678,16 +684,24 @@ struct sm6_icb_data - { - unsigned int data_id; - unsigned int id; -+ struct sm6_index index; - }; - - struct sm6_idxtemp_data - { - unsigned int id; -+ struct sm6_index index; - }; - - struct sm6_groupsharedmem_data - { - unsigned int id; -+ struct sm6_index index; -+}; -+ -+struct sm6_constant_data -+{ -+ union vsir_immediate_constant immconst; - }; - - struct sm6_value -@@ -696,6 +710,7 @@ struct sm6_value - enum sm6_value_type value_type; - unsigned int structure_stride; - bool is_back_ref; -+ bool non_uniform; - union - { - struct sm6_function_data function; -@@ -705,8 +720,8 @@ struct sm6_value - struct sm6_icb_data icb; - struct sm6_idxtemp_data idxtemp; - struct sm6_groupsharedmem_data groupsharedmem; -+ struct sm6_constant_data constant; - } u; -- struct vkd3d_shader_register reg; - }; - - struct dxil_record -@@ -731,7 +746,7 @@ struct incoming_value - - struct sm6_phi - { -- struct vkd3d_shader_register reg; -+ struct sm6_value value; - 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"); - } - --static inline const struct sm6_type *sm6_type_get_element_type(const struct sm6_type *type) --{ -- return (type->class == TYPE_CLASS_ARRAY || type->class == TYPE_CLASS_VECTOR) ? type->u.array.elem_type : type; --} -- - static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type *type, - enum bitcode_address_space addr_space, struct sm6_parser *sm6) - { -@@ -2214,38 +2224,14 @@ static const char *sm6_parser_get_global_symbol_name(const struct sm6_parser *sm - return NULL; - } - --static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg) --{ -- if (!register_is_constant(reg) || (!data_type_is_integer(reg->data_type) && !data_type_is_bool(reg->data_type))) -- return UINT_MAX; -- -- if (reg->dimension == VSIR_DIMENSION_VEC4) -- WARN("Returning vec4.x.\n"); -- -- if (reg->type == VKD3DSPR_IMMCONST64) -- { -- if (reg->u.immconst_u64[0] > UINT_MAX) -- FIXME("Truncating 64-bit value.\n"); -- return reg->u.immconst_u64[0]; -- } -- -- return reg->u.immconst_u32[0]; --} -- --static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg) -+static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) - { -- if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type)) -- return UINT64_MAX; -- -- if (reg->dimension == VSIR_DIMENSION_VEC4) -- WARN("Returning vec4.x.\n"); -- -- return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_u64[0] : reg->u.immconst_u32[0]; -+ return value->value_type == VALUE_TYPE_FUNCTION; - } - --static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) -+static bool sm6_value_is_invalid(const struct sm6_value *value) - { -- return value->value_type == VALUE_TYPE_FUNCTION; -+ return value->value_type == VALUE_TYPE_INVALID; - } - - static inline bool sm6_value_is_dx_intrinsic_dcl(const struct sm6_value *fn) -@@ -2264,11 +2250,11 @@ static inline bool sm6_value_is_register(const struct sm6_value *value) - { - switch (value->value_type) - { -- case VALUE_TYPE_REG: - case VALUE_TYPE_SSA: - case VALUE_TYPE_ICB: - case VALUE_TYPE_IDXTEMP: - case VALUE_TYPE_GROUPSHAREDMEM: -+ case VALUE_TYPE_CONSTANT: - case VALUE_TYPE_UNDEFINED: - case VALUE_TYPE_INVALID: - return true; -@@ -2285,18 +2271,41 @@ static bool sm6_value_is_handle(const struct sm6_value *value) - - static inline bool sm6_value_is_constant(const struct sm6_value *value) - { -- return sm6_value_is_register(value) && register_is_constant(&value->reg); -+ return value->value_type == VALUE_TYPE_CONSTANT; - } - - static bool sm6_value_is_constant_zero(const struct sm6_value *value) - { -- /* Constant vectors do not occur. */ -- return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->reg); -+ if (value->value_type != VALUE_TYPE_CONSTANT) -+ return false; -+ -+ switch (value->type->class) -+ { -+ case TYPE_CLASS_INTEGER: -+ case TYPE_CLASS_FLOAT: -+ break; -+ -+ default: -+ return false; -+ } -+ -+ if (value->type->u.width == 64) -+ return value->u.constant.immconst.immconst_u64[0] == 0; -+ else -+ return value->u.constant.immconst.immconst_u32[0] == 0; - } - - static inline bool sm6_value_is_undef(const struct sm6_value *value) - { -- return sm6_value_is_register(value) && value->reg.type == VKD3DSPR_UNDEF; -+ switch (value->value_type) -+ { -+ case VALUE_TYPE_UNDEFINED: -+ case VALUE_TYPE_INVALID: -+ return true; -+ -+ default: -+ return false; -+ } - } - - static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count) -@@ -2315,26 +2324,98 @@ static bool sm6_value_is_data(const struct sm6_value *value) - - static bool sm6_value_is_ssa(const struct sm6_value *value) - { -- return sm6_value_is_register(value) && register_is_ssa(&value->reg); -+ return value->value_type == VALUE_TYPE_SSA; - } - - static bool sm6_value_is_numeric_array(const struct sm6_value *value) - { -- return sm6_value_is_register(value) && register_is_numeric_array(&value->reg); -+ switch (value->value_type) -+ { -+ case VALUE_TYPE_ICB: -+ case VALUE_TYPE_IDXTEMP: -+ case VALUE_TYPE_GROUPSHAREDMEM: -+ return true; -+ -+ default: -+ return false; -+ } - } - --static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) -+static unsigned int sm6_value_get_constant_uint(const struct sm6_value *value, struct sm6_parser *sm6) - { - if (!sm6_value_is_constant(value)) -+ { -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, -+ "Invalid non-constant value."); - return UINT_MAX; -- return register_get_uint_value(&value->reg); -+ } -+ -+ if (value->type->class != TYPE_CLASS_INTEGER) -+ { -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, -+ "Invalid non-integer constant value."); -+ return UINT_MAX; -+ } -+ -+ if (value->type->u.width == 64) -+ { -+ uint64_t val = value->u.constant.immconst.immconst_u64[0]; -+ if (val > UINT_MAX) -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, -+ "Invalid 64-bit constant %"PRIu64" will be truncated do %u.", val, (unsigned int)val); -+ return val; -+ } -+ -+ return value->u.constant.immconst.immconst_u32[0]; - } - --static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value) -+static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value, struct sm6_parser *sm6) - { - if (!sm6_value_is_constant(value)) -+ { -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, -+ "Invalid non-constant value."); - return UINT64_MAX; -- return register_get_uint64_value(&value->reg); -+ } -+ -+ if (value->type->class != TYPE_CLASS_INTEGER) -+ { -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, -+ "Invalid non-integer constant value."); -+ return UINT64_MAX; -+ } -+ -+ if (value->type->u.width == 64) -+ return value->u.constant.immconst.immconst_u64[0]; -+ else -+ return value->u.constant.immconst.immconst_u32[0]; -+} -+ -+static float sm6_value_get_constant_float(const struct sm6_value *value, struct sm6_parser *sm6) -+{ -+ if (!sm6_value_is_constant(value)) -+ { -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, -+ "Invalid non-constant value."); -+ return 0.0f; -+ } -+ -+ if (value->type->class != TYPE_CLASS_FLOAT) -+ { -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, -+ "Invalid non-floating-point constant value."); -+ return 0.0f; -+ } -+ -+ if (value->type->u.width == 64) -+ { -+ double val = value->u.constant.immconst.immconst_f64[0]; -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, -+ "Invalid double constant %lf will be truncated do float %f.", val, (float)val); -+ return val; -+ } -+ -+ return value->u.constant.immconst.immconst_f32[0]; - } - - static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) -@@ -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) -+/* Based on the implementation in the OpenGL Mathematics library. */ -+static uint32_t half_to_float(uint16_t value) - { -- enum vkd3d_data_type data_type; -+ uint32_t s = (value & 0x8000u) << 16; -+ uint32_t e = (value >> 10) & 0x1fu; -+ uint32_t m = value & 0x3ffu; - -- data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(value->type, 0)); -+ if (!e) -+ { -+ if (!m) -+ { -+ /* Plus or minus zero */ -+ return s; -+ } -+ else -+ { -+ /* Denormalized number -- renormalize it */ -+ while (!(m & 0x400u)) -+ { -+ m <<= 1; -+ --e; -+ } - -- switch (value->value_type) -+ ++e; -+ m &= ~0x400u; -+ } -+ } -+ 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); -+ } -+ -+ /* Normalized number */ -+ e += 127u - 15u; -+ m <<= 13; -+ -+ /* Assemble s, e and m. */ -+ return s | (e << 23) | m; -+} -+ -+static void register_convert_to_minimum_precision(struct vkd3d_shader_register *reg) -+{ -+ unsigned int i; -+ -+ switch (reg->data_type) -+ { -+ case VSIR_DATA_F16: -+ reg->data_type = VSIR_DATA_F32; -+ reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16; -+ if (reg->type == VKD3DSPR_IMMCONST) -+ { -+ for (i = 0; i < VSIR_DIMENSION_VEC4; ++i) -+ reg->u.immconst_u32[i] = half_to_float(reg->u.immconst_u32[i]); -+ } -+ break; -+ -+ 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; -+ } -+} -+ -+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 vsir_data_type data_type; -+ -+ scalar_type = sm6_type_get_scalar_type(value->type, 0); -+ data_type = vsir_data_type_from_dxil(scalar_type); -+ -+ switch (value->value_type) -+ { - case VALUE_TYPE_SSA: - register_init_with_id(reg, VKD3DSPR_SSA, data_type, value->u.ssa.id); - reg->dimension = sm6_type_is_scalar(value->type) ? VSIR_DIMENSION_SCALAR : VSIR_DIMENSION_VEC4; - break; - - case VALUE_TYPE_ICB: -- register_init_with_id(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, value->u.icb.id); -+ vsir_register_init(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, 2); -+ reg->idx[0].offset = value->u.icb.id; -+ register_index_address_init(®->idx[1], value->u.icb.index.index, sm6); -+ reg->idx[1].is_in_bounds = value->u.icb.index.is_in_bounds; - break; - - case VALUE_TYPE_IDXTEMP: -- register_init_with_id(reg, VKD3DSPR_IDXTEMP, data_type, value->u.idxtemp.id); -+ vsir_register_init(reg, VKD3DSPR_IDXTEMP, data_type, 2); -+ reg->idx[0].offset = value->u.idxtemp.id; -+ register_index_address_init(®->idx[1], value->u.idxtemp.index.index, sm6); -+ reg->idx[1].is_in_bounds = value->u.idxtemp.index.is_in_bounds; - break; - - case VALUE_TYPE_GROUPSHAREDMEM: -- register_init_with_id(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, value->u.groupsharedmem.id); -+ vsir_register_init(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, 2); -+ reg->idx[0].offset = value->u.groupsharedmem.id; -+ register_index_address_init(®->idx[1], value->u.groupsharedmem.index.index, sm6); -+ reg->idx[1].is_in_bounds = value->u.groupsharedmem.index.is_in_bounds; -+ break; -+ -+ case VALUE_TYPE_CONSTANT: -+ vsir_register_init(reg, scalar_type->u.width == 64 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST, -+ data_type, 0); -+ reg->u = value->u.constant.immconst; - break; - - case VALUE_TYPE_UNDEFINED: -@@ -2472,15 +2643,18 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str - case VALUE_TYPE_DATA: - vkd3d_unreachable(); - } -+ -+ register_convert_to_minimum_precision(reg); -+ reg->non_uniform = value->non_uniform; - } - - static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *value) - { - unsigned int id; - -- if (register_is_ssa(&value->reg) && value->reg.idx[0].offset) -+ if (value->value_type == VALUE_TYPE_SSA && value->u.ssa.id) - { -- id = value->reg.idx[0].offset; -+ id = value->u.ssa.id; - TRACE("Using forward-allocated id %u.\n", id); - } - else -@@ -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; -- sm6_register_from_value(&value->reg, 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; - } - -@@ -2547,10 +2720,11 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned - param->modifiers = VKD3DSPSM_NONE; - } - --static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src) -+static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src, -+ struct sm6_parser *sm6) - { - src_param_init(param); -- sm6_register_from_value(¶m->reg, src); -+ sm6_register_from_value(¶m->reg, src, sm6); - } - - static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param, -@@ -2570,12 +2744,12 @@ static void src_param_make_constant_uint(struct vkd3d_shader_src_param *param, u - static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, - struct sm6_parser *sm6) - { -- if (sm6_value_is_constant(address)) -+ if (address && sm6_value_is_constant(address)) - { -- idx->offset = sm6_value_get_constant_uint(address); -+ idx->offset = sm6_value_get_constant_uint(address, sm6); - idx->rel_addr = NULL; - } -- else if (sm6_value_is_undef(address)) -+ else if (!address || sm6_value_is_undef(address)) - { - idx->offset = 0; - idx->rel_addr = NULL; -@@ -2584,7 +2758,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, - { - struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1); - if (rel_addr) -- src_param_init_from_value(rel_addr, address); -+ src_param_init_from_value(rel_addr, address, sm6); - idx->offset = 0; - idx->rel_addr = rel_addr; - } -@@ -2619,7 +2793,7 @@ static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio - - dst_param_init(param); - sm6_parser_init_ssa_value(sm6, dst); -- sm6_register_from_value(¶m->reg, dst); -+ sm6_register_from_value(¶m->reg, dst, sm6); - return true; - } - -@@ -2631,22 +2805,20 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio - - dst_param_init_vector(param, component_count); - sm6_parser_init_ssa_value(sm6, dst); -- sm6_register_from_value(¶m->reg, dst); -+ sm6_register_from_value(¶m->reg, dst, sm6); - } - --static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) -+static bool instruction_dst_param_init_uint_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) - { -- struct sm6_value *dst = sm6_parser_get_current_value(sm6); - struct vkd3d_shader_dst_param *param; - - if (!(param = instruction_dst_params_alloc(ins, 1, sm6))) - 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, VSIR_DATA_U32, 1); - param->write_mask = VKD3DSP_WRITEMASK_ALL; - param->reg.idx[0].offset = 0; - param->reg.dimension = VSIR_DIMENSION_VEC4; -- dst->reg = param->reg; - - return true; - } -@@ -2928,7 +3100,6 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru - value->type = fwd_type; - value->value_type = VALUE_TYPE_SSA; - value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6); -- sm6_register_from_value(&value->reg, value); - } - } - -@@ -3017,53 +3188,13 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) - return value << 63; - } - --static float bitcast_uint_to_float(unsigned int value) --{ -- union -- { -- uint32_t uint32_value; -- float float_value; -- } u; -- -- u.uint32_value = value; -- return u.float_value; --} -- --static inline double bitcast_uint64_to_double(uint64_t value) --{ -- union -- { -- uint64_t uint64_value; -- double double_value; -- } u; -- -- u.uint64_value = value; -- return u.double_value; --} -- --static float register_get_float_value(const struct vkd3d_shader_register *reg) --{ -- if (!register_is_constant(reg) || !data_type_is_floating_point(reg->data_type)) -- return 0.0; -- -- if (reg->dimension == VSIR_DIMENSION_VEC4) -- WARN("Returning vec4.x.\n"); -- -- if (reg->type == VKD3DSPR_IMMCONST64) -- { -- WARN("Truncating double to float.\n"); -- return bitcast_uint64_to_double(reg->u.immconst_u64[0]); -- } -- -- return bitcast_uint_to_float(reg->u.immconst_u32[0]); --} -- - static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, - const uint64_t *operands, struct sm6_parser *sm6) - { - struct vkd3d_shader_immediate_constant_buffer *icb; - const struct sm6_type *elem_type; - unsigned int i, size, count; -+ uint64_t *data64; - - 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; - - count = type->u.array.count; -- if (size > sizeof(icb->data[0])) -+ switch (icb->data_type) - { -- uint64_t *data = (uint64_t *)icb->data; -- for (i = 0; i < count; ++i) -- data[i] = operands[i]; -- } -- else -- { -- for (i = 0; i < count; ++i) -- icb->data[i] = operands[i]; -+ case VSIR_DATA_F16: -+ for (i = 0; i < count; ++i) -+ icb->data[i] = half_to_float(operands[i]); -+ icb->data_type = VSIR_DATA_F32; -+ break; -+ -+ case VSIR_DATA_U16: -+ for (i = 0; i < count; ++i) -+ icb->data[i] = (int16_t)operands[i]; -+ icb->data_type = VSIR_DATA_U32; -+ break; -+ -+ case VSIR_DATA_F32: -+ case VSIR_DATA_U32: -+ for (i = 0; i < count; ++i) -+ icb->data[i] = operands[i]; -+ break; -+ -+ case VSIR_DATA_F64: -+ case VSIR_DATA_U64: -+ data64 = (uint64_t *)icb->data; -+ for (i = 0; i < count; ++i) -+ data64[i] = operands[i]; -+ break; -+ -+ default: -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Invalid array of type %u.", icb->data_type); -+ return VKD3D_ERROR_INVALID_SHADER; - } - - return VKD3D_OK; - } - -+static struct sm6_index *sm6_get_value_index(struct sm6_parser *sm6, struct sm6_value *value) -+{ -+ switch (value->value_type) -+ { -+ case VALUE_TYPE_ICB: -+ return &value->u.icb.index; -+ -+ case VALUE_TYPE_IDXTEMP: -+ return &value->u.idxtemp.index; -+ -+ case VALUE_TYPE_GROUPSHAREDMEM: -+ return &value->u.groupsharedmem.index; -+ -+ default: -+ WARN("Cannot index into value of type %#x.\n", value->value_type); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Cannot index into value of type %#x.", value->value_type); -+ return NULL; -+ } -+} -+ - static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, const struct dxil_record *record, - struct sm6_value *dst) - { - const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type; -- struct vkd3d_shader_register reg; - struct sm6_value *operands[3]; - unsigned int i, j, offset; -+ struct sm6_index *index; - uint64_t value; - - i = 0; -@@ -3178,9 +3351,13 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c - } - } - -- sm6_register_from_value(®, operands[0]); -+ *dst = *operands[0]; -+ index = sm6_get_value_index(sm6, dst); - -- if (reg.idx_count > 1) -+ if (!index) -+ return VKD3D_ERROR_INVALID_SHADER; -+ -+ if (index->index) - { - WARN("Unsupported stacked GEP.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -3203,8 +3380,6 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c - return VKD3D_ERROR_INVALID_SHADER; - } - -- dst->structure_stride = operands[0]->structure_stride; -- - ptr_type = operands[0]->type; - if (!sm6_type_is_pointer(ptr_type)) - { -@@ -3225,7 +3400,7 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c - "Explicit pointee type for constexpr GEP does not match the element type."); - } - -- offset = sm6_value_get_constant_uint(operands[2]); -+ offset = sm6_value_get_constant_uint(operands[2], sm6); - if (!(gep_type = sm6_type_get_element_type_at_index(pointee_type, offset))) - { - WARN("Failed to get element type.\n"); -@@ -3241,20 +3416,17 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c - "Module does not define a pointer type for a constexpr GEP result."); - return VKD3D_ERROR_INVALID_SHADER; - } -- dst->reg = reg; -- dst->reg.idx[1].offset = offset; -- dst->reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; -- dst->reg.idx_count = 2; -+ -+ index->index = operands[2]; -+ index->is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; - - return VKD3D_OK; - } - - static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block) - { -- enum vkd3d_shader_register_type reg_type = VKD3DSPR_INVALID; -- const struct sm6_type *type, *elem_type, *ptr_type; -+ const struct sm6_type *type, *ptr_type; - size_t i, base_value_idx, value_idx; -- enum vkd3d_data_type reg_data_type; - const struct dxil_record *record; - const struct sm6_value *src; - enum vkd3d_result ret; -@@ -3275,18 +3447,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const - if (!(type = sm6_parser_get_type(sm6, record->operands[0]))) - return VKD3D_ERROR_INVALID_SHADER; - -- elem_type = sm6_type_get_element_type(type); -- if (sm6_type_is_numeric(elem_type)) -- { -- reg_data_type = vkd3d_data_type_from_sm6_type(elem_type); -- reg_type = elem_type->u.width > 32 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST; -- } -- else -- { -- reg_data_type = VKD3D_DATA_UNUSED; -- reg_type = VKD3DSPR_INVALID; -- } -- - if (i == block->record_count - 1) - WARN("Unused SETTYPE record.\n"); - -@@ -3301,19 +3461,21 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const - - dst = sm6_parser_get_current_value(sm6); - dst->type = type; -- dst->value_type = VALUE_TYPE_REG; - dst->is_back_ref = true; -- vsir_register_init(&dst->reg, reg_type, reg_data_type, 0); - - switch (record->code) - { - case CST_CODE_NULL: -- if (sm6_type_is_array(type) -- && (ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) -+ if (sm6_type_is_array(type)) - { -- return ret; -+ if ((ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) -+ return ret; -+ } -+ else -+ { -+ dst->value_type = VALUE_TYPE_CONSTANT; -+ memset(&dst->u.constant, 0, sizeof(dst->u.constant)); - } -- /* For non-aggregates, register constant data is already zero-filled. */ - break; - - case CST_CODE_INTEGER: -@@ -3326,11 +3488,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const - return VKD3D_ERROR_INVALID_SHADER; - } - -+ dst->value_type = VALUE_TYPE_CONSTANT; -+ - value = decode_rotated_signed_value(record->operands[0]); - if (type->u.width <= 32) -- dst->reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1); -+ dst->u.constant.immconst.immconst_u32[0] = value & ((1ull << type->u.width) - 1); - else -- dst->reg.u.immconst_u64[0] = value; -+ dst->u.constant.immconst.immconst_u64[0] = value; - - break; - -@@ -3344,14 +3508,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const - return VKD3D_ERROR_INVALID_SHADER; - } - -- if (type->u.width == 16) -- dst->reg.u.immconst_u32[0] = record->operands[0]; -- else if (type->u.width == 32) -- dst->reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); -- else if (type->u.width == 64) -- dst->reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); -+ dst->value_type = VALUE_TYPE_CONSTANT; -+ -+ value = record->operands[0]; -+ if (type->u.width <= 32) -+ dst->u.constant.immconst.immconst_u32[0] = value & ((1ull << type->u.width) - 1); - else -- vkd3d_unreachable(); -+ dst->u.constant.immconst.immconst_u64[0] = value; - - break; - -@@ -3377,6 +3540,46 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const - return ret; - break; - -+ case CST_CODE_CE_CAST: -+ /* Resolve later in case forward refs exist. */ -+ dst->type = type; -+ dst->value_type = VALUE_TYPE_INVALID; -+ break; -+ -+ case CST_CODE_UNDEF: -+ dxil_record_validate_operand_max_count(record, 0, sm6); -+ dst->value_type = VALUE_TYPE_UNDEFINED; -+ break; -+ -+ default: -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Constant code %u is unhandled.", record->code); -+ dst->value_type = VALUE_TYPE_INVALID; -+ break; -+ } -+ -+ if (record->attachment) -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, -+ "Ignoring a metadata attachment for a constant."); -+ -+ ++sm6->value_count; -+ } -+ -+ value_idx = base_value_idx; -+ -+ for (i = 0; i < block->record_count; ++i) -+ { -+ sm6->p.location.column = i; -+ record = block->records[i]; -+ -+ switch (record->code) -+ { -+ case CST_CODE_SETTYPE: -+ continue; -+ -+ default: -+ break; -+ - case CST_CODE_CE_CAST: - if (!dxil_record_validate_operand_count(record, 3, 3, sm6)) - return VKD3D_ERROR_INVALID_SHADER; -@@ -3413,59 +3616,26 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const - return VKD3D_ERROR_INVALID_SHADER; - } - -- /* Resolve later in case forward refs exist. */ -- dst->type = type; -- dst->reg.type = VKD3DSPR_COUNT; -- dst->reg.idx[0].offset = value; -- break; -+ dst = &sm6->values[value_idx]; -+ src = &sm6->values[value]; - -- case CST_CODE_UNDEF: -- dxil_record_validate_operand_max_count(record, 0, sm6); -- dst->value_type = VALUE_TYPE_UNDEFINED; -- sm6_register_from_value(&dst->reg, dst); -- break; -+ if (!sm6_value_is_numeric_array(src)) -+ { -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Constexpr cast source value is not a global array element."); -+ return VKD3D_ERROR_INVALID_SHADER; -+ } - -- default: -- FIXME("Unhandled constant code %u.\n", record->code); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -- "Constant code %u is unhandled.", record->code); -- dst->value_type = VALUE_TYPE_INVALID; -- sm6_register_from_value(&dst->reg, dst); -+ type = dst->type; -+ *dst = *src; -+ dst->type = type; - break; - } - -- if (record->attachment) -- { -- WARN("Ignoring metadata attachment.\n"); -- vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, -- "Ignoring a metadata attachment for a constant."); -- } -- -- ++sm6->value_count; -+ ++value_idx; - } - -- /* Resolve cast forward refs. */ -- for (i = base_value_idx; i < sm6->value_count; ++i) -- { -- dst = &sm6->values[i]; -- if (dst->reg.type != VKD3DSPR_COUNT) -- continue; -- -- type = dst->type; -- -- src = &sm6->values[dst->reg.idx[0].offset]; -- if (!sm6_value_is_numeric_array(src)) -- { -- WARN("Value is not an array.\n"); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -- "Constexpr cast source value is not a global array element."); -- return VKD3D_ERROR_INVALID_SHADER; -- } -- -- *dst = *src; -- dst->type = type; -- dst->reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type); -- } -+ VKD3D_ASSERT(value_idx == sm6->value_count); - - return VKD3D_OK; - } -@@ -3509,7 +3679,7 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type - { - struct vkd3d_shader_instruction *ins; - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER); - /* 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; -@@ -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); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_INDEXABLE_TEMP); - else -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_INDEXABLE_TEMP); - ins->declaration.indexable_temp.register_idx = sm6->indexable_temp_count++; - ins->declaration.indexable_temp.register_size = count; - ins->declaration.indexable_temp.alignment = alignment; -@@ -3537,7 +3707,6 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru - - dst->value_type = VALUE_TYPE_IDXTEMP; - dst->u.idxtemp.id = ins->declaration.indexable_temp.register_idx; -- sm6_register_from_value(&dst->reg, dst); - } - - static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type, -@@ -3546,15 +3715,17 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 - struct vkd3d_shader_instruction *ins; - unsigned int byte_count; - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_RAW); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TGSM_RAW); - dst_param_init(&ins->declaration.tgsm_raw.reg); - dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; - dst->u.groupsharedmem.id = sm6->tgsm_count++; - dst->structure_stride = 0; -- sm6_register_from_value(&dst->reg, dst); -- sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst); -+ sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst, sm6); - ins->declaration.tgsm_raw.alignment = alignment; -- byte_count = elem_type->u.width / 8u; -+ byte_count = elem_type->u.width / CHAR_BIT; -+ /* Convert minimum precision types to their 32-bit equivalent. */ -+ if (byte_count == 2) -+ byte_count = 4; - if (byte_count != 4) - { - FIXME("Unsupported byte count %u.\n", byte_count); -@@ -3571,13 +3742,15 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str - { - struct vkd3d_shader_instruction *ins; - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_STRUCTURED); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TGSM_STRUCTURED); - dst_param_init(&ins->declaration.tgsm_structured.reg); - dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; - dst->u.groupsharedmem.id = sm6->tgsm_count++; -- dst->structure_stride = elem_type->u.width / 8u; -- sm6_register_from_value(&dst->reg, dst); -- sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst); -+ dst->structure_stride = elem_type->u.width / CHAR_BIT; -+ /* Convert minimum precision types to their 32-bit equivalent. */ -+ if (dst->structure_stride == 2) -+ dst->structure_stride = 4; -+ sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst, sm6); - if (dst->structure_stride != 4) - { - FIXME("Unsupported structure stride %u.\n", dst->structure_stride); -@@ -3697,7 +3870,6 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ - - dst = sm6_parser_get_current_value(sm6); - dst->type = type; -- dst->value_type = VALUE_TYPE_REG; - dst->is_back_ref = true; - - if (is_constant && !init) -@@ -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]; -- 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) - { - ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser( - (uintptr_t)ins->declaration.indexable_temp.initialiser, sm6); - } -- else if (ins->opcode == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER) -+ else if (ins->opcode == VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER) - { - ins->declaration.icb = resolve_forward_initialiser((uintptr_t)ins->declaration.icb, sm6); - } -- else if (ins->opcode == VKD3DSIH_DCL_TGSM_RAW) -+ else if (ins->opcode == VSIR_OP_DCL_TGSM_RAW) - { - ins->declaration.tgsm_raw.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6); - ins->flags = 0; - } -- else if (ins->opcode == VKD3DSIH_DCL_TGSM_STRUCTURED) -+ else if (ins->opcode == VSIR_OP_DCL_TGSM_STRUCTURED) - { - ins->declaration.tgsm_structured.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6); - ins->flags = 0; -@@ -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; -- sm6_register_from_value(&value->reg, value); - } - - 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; - -@@ -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, -- const struct sm6_value **operands, unsigned int count) -+ const struct sm6_value **operands, unsigned int count, struct sm6_parser *sm6) - { - unsigned int i; - - for (i = 0; i < count; ++i) -- src_param_init_from_value(&src_params[i], operands[i]); -+ src_param_init_from_value(&src_params[i], operands[i], sm6); - } - - 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) - { -+ 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. */ -- if (sm6_value_get_constant_uint(size) != 1) -+ if (sm6_value_get_constant_uint(size, sm6) != 1) - { - FIXME("Allocation size is not 1.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -4186,26 +4368,26 @@ static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code) - switch (code) - { - case RMW_ADD: -- return VKD3DSIH_IMM_ATOMIC_IADD; -+ return VSIR_OP_IMM_ATOMIC_IADD; - case RMW_AND: -- return VKD3DSIH_IMM_ATOMIC_AND; -+ return VSIR_OP_IMM_ATOMIC_AND; - case RMW_MAX: -- return VKD3DSIH_IMM_ATOMIC_IMAX; -+ return VSIR_OP_IMM_ATOMIC_IMAX; - case RMW_MIN: -- return VKD3DSIH_IMM_ATOMIC_IMIN; -+ return VSIR_OP_IMM_ATOMIC_IMIN; - case RMW_OR: -- return VKD3DSIH_IMM_ATOMIC_OR; -+ return VSIR_OP_IMM_ATOMIC_OR; - case RMW_UMAX: -- return VKD3DSIH_IMM_ATOMIC_UMAX; -+ return VSIR_OP_IMM_ATOMIC_UMAX; - case RMW_UMIN: -- return VKD3DSIH_IMM_ATOMIC_UMIN; -+ return VSIR_OP_IMM_ATOMIC_UMIN; - case RMW_XCHG: -- return VKD3DSIH_IMM_ATOMIC_EXCH; -+ return VSIR_OP_IMM_ATOMIC_EXCH; - case RMW_XOR: -- return VKD3DSIH_IMM_ATOMIC_XOR; -+ return VSIR_OP_IMM_ATOMIC_XOR; - default: - /* DXIL currently doesn't use SUB and NAND. */ -- return VKD3DSIH_INVALID; -+ return VSIR_OP_INVALID; - } - } - -@@ -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; - -- sm6_register_from_value(®, ptr); -+ sm6_register_from_value(®, ptr, sm6); - - if (reg.type != VKD3DSPR_GROUPSHAREDMEM) - { -@@ -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; - -- if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VKD3DSIH_INVALID) -+ if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VSIR_OP_INVALID) - { - FIXME("Unhandled atomicrmw op %"PRIu64".\n", code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -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); -- src_param_init_from_value(&src_params[1], src); -+ src_param_init_from_value(&src_params[1], src, sm6); - - sm6_parser_init_ssa_value(sm6, dst); - - dst_params = instruction_dst_params_alloc(ins, 2, sm6); -- sm6_register_from_value(&dst_params[0].reg, dst); -+ sm6_register_from_value(&dst_params[0].reg, dst, sm6); - 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; -@@ -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."); -- return VKD3DSIH_INVALID; -+ return VSIR_OP_INVALID; - } - if (type_a != type_b) - { -@@ -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. */ -- op = is_int ? VKD3DSIH_IADD : (is_double ? VKD3DSIH_DADD : VKD3DSIH_ADD); -+ op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD); - is_valid = !is_bool; - break; - case BINOP_AND: -- op = VKD3DSIH_AND; -+ op = VSIR_OP_AND; - is_valid = is_int; - break; - case BINOP_ASHR: -- op = VKD3DSIH_ISHR; -+ op = VSIR_OP_ISHR; - is_valid = is_int && !is_bool; - break; - case BINOP_LSHR: -- op = VKD3DSIH_USHR; -+ op = VSIR_OP_USHR; - is_valid = is_int && !is_bool; - break; - case BINOP_MUL: -- op = is_int ? VKD3DSIH_UMUL : (is_double ? VKD3DSIH_DMUL : VKD3DSIH_MUL); -+ op = is_int ? VSIR_OP_IMUL_LOW : (is_double ? VSIR_OP_DMUL : VSIR_OP_MUL); - is_valid = !is_bool; - break; - case BINOP_OR: -- op = VKD3DSIH_OR; -+ op = VSIR_OP_OR; - is_valid = is_int; - break; - case BINOP_SDIV: -- op = is_int ? VKD3DSIH_IDIV : (is_double ? VKD3DSIH_DDIV : VKD3DSIH_DIV); -+ op = is_int ? VSIR_OP_IDIV : (is_double ? VSIR_OP_DDIV : VSIR_OP_DIV); - is_valid = !is_bool; - break; - case BINOP_SREM: -- op = is_int ? VKD3DSIH_IDIV : VKD3DSIH_FREM; -+ op = is_int ? VSIR_OP_IREM : VSIR_OP_FREM; - is_valid = !is_bool; - break; - case BINOP_SHL: -- op = VKD3DSIH_ISHL; -+ op = VSIR_OP_ISHL; - is_valid = is_int && !is_bool; - break; - case BINOP_UDIV: -+ op = VSIR_OP_UDIV_SIMPLE; -+ is_valid = is_int && !is_bool; -+ break; - case BINOP_UREM: -- op = VKD3DSIH_UDIV; -+ op = VSIR_OP_UREM; - is_valid = is_int && !is_bool; - break; - case BINOP_XOR: -- op = VKD3DSIH_XOR; -+ op = VSIR_OP_XOR; - is_valid = is_int; - break; - default: - FIXME("Unhandled binary op %#"PRIx64".\n", code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Binary operation %#"PRIx64" is unhandled.", code); -- return VKD3DSIH_INVALID; -+ return VSIR_OP_INVALID; - } - - if (!is_valid) -@@ -4411,7 +4596,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco - return; - - code = record->operands[i++]; -- if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VKD3DSIH_INVALID) -+ if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VSIR_OP_INVALID) - return; - - vsir_instruction_init(ins, &sm6->p.location, handler_idx); -@@ -4421,25 +4606,27 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco - - switch (handler_idx) - { -- case VKD3DSIH_ADD: -- case VKD3DSIH_MUL: -- case VKD3DSIH_DIV: -- case VKD3DSIH_FREM: -+ case VSIR_OP_ADD: -+ case VSIR_OP_MUL: -+ case VSIR_OP_DIV: -+ case VSIR_OP_FREM: - if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA)) - ins->flags |= VKD3DSI_PRECISE_X; - flags &= ~FP_ALLOW_UNSAFE_ALGEBRA; - /* SPIR-V FPFastMathMode is only available in the Kernel execution model. */ - silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL)); - break; -- case VKD3DSIH_IADD: -- case VKD3DSIH_UMUL: -- case VKD3DSIH_ISHL: -+ case VSIR_OP_IADD: -+ case VSIR_OP_IMUL_LOW: -+ case VSIR_OP_ISHL: - silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP)); - break; -- case VKD3DSIH_ISHR: -- case VKD3DSIH_USHR: -- case VKD3DSIH_IDIV: -- case VKD3DSIH_UDIV: -+ case VSIR_OP_ISHR: -+ case VSIR_OP_USHR: -+ case VSIR_OP_IDIV: -+ case VSIR_OP_UDIV_SIMPLE: -+ case VSIR_OP_IREM: -+ case VSIR_OP_UREM: - silence_warning = !(flags & ~PEB_EXACT); - break; - default: -@@ -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; -- src_param_init_from_value(&src_params[0], a); -- src_param_init_from_value(&src_params[1], b); -+ src_param_init_from_value(&src_params[0], a, sm6); -+ src_param_init_from_value(&src_params[1], b, sm6); - if (code == BINOP_SUB) - src_params[1].modifiers = VKD3DSPSM_NEG; - - 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; -- -- dst_param_init(&dst_params[0]); -- dst_param_init(&dst_params[1]); -- sm6_parser_init_ssa_value(sm6, dst); -- sm6_register_from_value(&dst_params[index].reg, dst); -- vsir_dst_param_init_null(&dst_params[index ^ 1]); -- } -- else -- { -- 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 -- * do not imply masking the shift as the TPF equivalents do. */ -- ins->flags |= VKD3DSI_SHIFT_UNMASKED; -- } -- instruction_dst_param_init_ssa_scalar(ins, sm6); -+ /* DXC emits AND instructions where necessary to mask shift counts. -+ * Shift binops do not imply masking the shift as the TPF equivalents -+ * do. */ -+ ins->flags |= VKD3DSI_SHIFT_UNMASKED; - } -+ instruction_dst_param_init_ssa_scalar(ins, sm6); - } - - static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index, -@@ -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; -- sm6_register_from_value(&code_block->terminator.conditional_reg, value); -+ sm6_register_from_value(&code_block->terminator.conditional_reg, value, sm6); - code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6); - code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6); - } - -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - } - - 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) - { -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - - if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) - return false; -@@ -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) -- sm6_register_from_value(&operand_regs[i], operands[i]); -+ sm6_register_from_value(&operand_regs[i], operands[i], sm6); - - return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); - } -@@ -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; -- sm6_register_from_value(&operand_regs[component_count], operands[component_count]); -+ sm6_register_from_value(&operand_regs[component_count], operands[component_count], sm6); - } - - if (z_operand) -- sm6_register_from_value(&operand_regs[component_count++], z_operand); -+ sm6_register_from_value(&operand_regs[component_count++], z_operand, sm6); - - return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); - } -@@ -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: -- return VKD3DSIH_WAVE_IS_FIRST_LANE; -+ return VSIR_OP_WAVE_IS_FIRST_LANE; - default: - vkd3d_unreachable(); - } -@@ -4656,77 +4830,81 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) - switch (op) - { - case DX_ISNAN: -- return VKD3DSIH_ISNAN; -+ return VSIR_OP_ISNAN; - case DX_ISINF: -- return VKD3DSIH_ISINF; -+ return VSIR_OP_ISINF; - case DX_ISFINITE: -- return VKD3DSIH_ISFINITE; -+ return VSIR_OP_ISFINITE; -+ case DX_COS: -+ return VSIR_OP_COS; -+ case DX_SIN: -+ return VSIR_OP_SIN; - case DX_TAN: -- return VKD3DSIH_TAN; -+ return VSIR_OP_TAN; - case DX_ACOS: -- return VKD3DSIH_ACOS; -+ return VSIR_OP_ACOS; - case DX_ASIN: -- return VKD3DSIH_ASIN; -+ return VSIR_OP_ASIN; - case DX_ATAN: -- return VKD3DSIH_ATAN; -+ return VSIR_OP_ATAN; - case DX_HCOS: -- return VKD3DSIH_HCOS; -+ return VSIR_OP_HCOS; - case DX_HSIN: -- return VKD3DSIH_HSIN; -+ return VSIR_OP_HSIN; - case DX_HTAN: -- return VKD3DSIH_HTAN; -+ return VSIR_OP_HTAN; - case DX_EXP: -- return VKD3DSIH_EXP; -+ return VSIR_OP_EXP; - case DX_FRC: -- return VKD3DSIH_FRC; -+ return VSIR_OP_FRC; - case DX_LOG: -- return VKD3DSIH_LOG; -+ return VSIR_OP_LOG; - case DX_SQRT: -- return VKD3DSIH_SQRT; -+ return VSIR_OP_SQRT; - case DX_RSQRT: -- return VKD3DSIH_RSQ; -+ return VSIR_OP_RSQ; - case DX_ROUND_NE: -- return VKD3DSIH_ROUND_NE; -+ return VSIR_OP_ROUND_NE; - case DX_ROUND_NI: -- return VKD3DSIH_ROUND_NI; -+ return VSIR_OP_ROUND_NI; - case DX_ROUND_PI: -- return VKD3DSIH_ROUND_PI; -+ return VSIR_OP_ROUND_PI; - case DX_ROUND_Z: -- return VKD3DSIH_ROUND_Z; -+ return VSIR_OP_ROUND_Z; - case DX_BFREV: -- return VKD3DSIH_BFREV; -+ return VSIR_OP_BFREV; - case DX_COUNT_BITS: -- return VKD3DSIH_COUNTBITS; -+ return VSIR_OP_COUNTBITS; - case DX_FIRST_BIT_LO: -- return VKD3DSIH_FIRSTBIT_LO; -+ return VSIR_OP_FIRSTBIT_LO; - case DX_FIRST_BIT_HI: -- return VKD3DSIH_FIRSTBIT_HI; -+ return VSIR_OP_FIRSTBIT_HI; - case DX_FIRST_BIT_SHI: -- return VKD3DSIH_FIRSTBIT_SHI; -+ return VSIR_OP_FIRSTBIT_SHI; - case DX_DERIV_COARSEX: -- return VKD3DSIH_DSX_COARSE; -+ return VSIR_OP_DSX_COARSE; - case DX_DERIV_COARSEY: -- return VKD3DSIH_DSY_COARSE; -+ return VSIR_OP_DSY_COARSE; - case DX_DERIV_FINEX: -- return VKD3DSIH_DSX_FINE; -+ return VSIR_OP_DSX_FINE; - case DX_DERIV_FINEY: -- return VKD3DSIH_DSY_FINE; -+ return VSIR_OP_DSY_FINE; - case DX_LEGACY_F32TOF16: -- return VKD3DSIH_F32TOF16; -+ return VSIR_OP_F32TOF16; - case DX_LEGACY_F16TOF32: -- return VKD3DSIH_F16TOF32; -+ return VSIR_OP_F16TOF32; - case DX_WAVE_ACTIVE_ALL_EQUAL: -- return VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL; -+ return VSIR_OP_WAVE_ACTIVE_ALL_EQUAL; - case DX_WAVE_ALL_BIT_COUNT: -- return VKD3DSIH_WAVE_ALL_BIT_COUNT; -+ return VSIR_OP_WAVE_ALL_BIT_COUNT; - case DX_WAVE_ALL_TRUE: -- return VKD3DSIH_WAVE_ALL_TRUE; -+ return VSIR_OP_WAVE_ALL_TRUE; - case DX_WAVE_ANY_TRUE: -- return VKD3DSIH_WAVE_ANY_TRUE; -+ return VSIR_OP_WAVE_ANY_TRUE; - case DX_WAVE_PREFIX_BIT_COUNT: -- return VKD3DSIH_WAVE_PREFIX_BIT_COUNT; -+ return VSIR_OP_WAVE_PREFIX_BIT_COUNT; - case DX_WAVE_READ_LANE_FIRST: -- return VKD3DSIH_WAVE_READ_LANE_FIRST; -+ return VSIR_OP_WAVE_READ_LANE_FIRST; - default: - vkd3d_unreachable(); - } -@@ -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; -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -4751,21 +4929,21 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co - switch (op) - { - case DX_FMAX: -- return type->u.width == 64 ? VKD3DSIH_DMAX : VKD3DSIH_MAX; -+ return type->u.width == 64 ? VSIR_OP_DMAX : VSIR_OP_MAX; - case DX_FMIN: -- return type->u.width == 64 ? VKD3DSIH_DMIN : VKD3DSIH_MIN; -+ return type->u.width == 64 ? VSIR_OP_DMIN : VSIR_OP_MIN; - case DX_IMAX: -- return VKD3DSIH_IMAX; -+ return VSIR_OP_IMAX; - case DX_IMIN: -- return VKD3DSIH_IMIN; -+ return VSIR_OP_IMIN; - case DX_QUAD_READ_LANE_AT: -- return VKD3DSIH_QUAD_READ_LANE_AT; -+ return VSIR_OP_QUAD_READ_LANE_AT; - case DX_UMAX: -- return VKD3DSIH_UMAX; -+ return VSIR_OP_UMAX; - case DX_UMIN: -- return VKD3DSIH_UMIN; -+ return VSIR_OP_UMIN; - case DX_WAVE_READ_LANE_AT: -- return VKD3DSIH_WAVE_READ_LANE_AT; -+ return VSIR_OP_WAVE_READ_LANE_AT; - default: - vkd3d_unreachable(); - } -@@ -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; -- src_param_init_from_value(&src_params[0], operands[0]); -- src_param_init_from_value(&src_params[1], operands[1]); -+ src_param_init_from_value(&src_params[0], operands[0], sm6); -+ src_param_init_from_value(&src_params[1], operands[1], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } - - static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6) - { -- uint64_t code = sm6_value_get_constant_uint(operand); -+ uint64_t code = sm6_value_get_constant_uint(operand, sm6); - - switch (code) - { - case ATOMIC_BINOP_ADD: -- return VKD3DSIH_IMM_ATOMIC_IADD; -+ return VSIR_OP_IMM_ATOMIC_IADD; - case ATOMIC_BINOP_AND: -- return VKD3DSIH_IMM_ATOMIC_AND; -+ return VSIR_OP_IMM_ATOMIC_AND; - case ATOMIC_BINOP_IMAX: -- return VKD3DSIH_IMM_ATOMIC_IMAX; -+ return VSIR_OP_IMM_ATOMIC_IMAX; - case ATOMIC_BINOP_IMIN: -- return VKD3DSIH_IMM_ATOMIC_IMIN; -+ return VSIR_OP_IMM_ATOMIC_IMIN; - case ATOMIC_BINOP_OR: -- return VKD3DSIH_IMM_ATOMIC_OR; -+ return VSIR_OP_IMM_ATOMIC_OR; - case ATOMIC_BINOP_UMAX: -- return VKD3DSIH_IMM_ATOMIC_UMAX; -+ return VSIR_OP_IMM_ATOMIC_UMAX; - case ATOMIC_BINOP_UMIN: -- return VKD3DSIH_IMM_ATOMIC_UMIN; -+ return VSIR_OP_IMM_ATOMIC_UMIN; - case ATOMIC_BINOP_XCHG: -- return VKD3DSIH_IMM_ATOMIC_EXCH; -+ return VSIR_OP_IMM_ATOMIC_EXCH; - case ATOMIC_BINOP_XOR: -- return VKD3DSIH_IMM_ATOMIC_XOR; -+ return VSIR_OP_IMM_ATOMIC_XOR; - /* DXIL currently doesn't use SUB and NAND. */ - default: - FIXME("Unhandled atomic binop %"PRIu64".\n", code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Operation %"PRIu64" for an atomic binop instruction is unhandled.", code); -- return VKD3DSIH_INVALID; -+ return VSIR_OP_INVALID; - } - } - -@@ -4838,8 +5016,8 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr - return; - - if (is_cmp_xchg) -- handler_idx = VKD3DSIH_IMM_ATOMIC_CMP_EXCH; -- else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VKD3DSIH_INVALID) -+ handler_idx = VSIR_OP_IMM_ATOMIC_CMP_EXCH; -+ else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID) - return; - - coord_idx = 2 - is_cmp_xchg; -@@ -4852,7 +5030,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr - } - else - { -- sm6_register_from_value(®, operands[coord_idx]); -+ sm6_register_from_value(®, operands[coord_idx], sm6); - } - - for (i = coord_idx + coord_count; i < coord_idx + 3; ++i) -@@ -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) -- src_param_init_from_value(&src_params[1], operands[4]); -- src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5]); -+ src_param_init_from_value(&src_params[1], operands[4], sm6); -+ src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5], sm6); - - sm6_parser_init_ssa_value(sm6, dst); - - dst_params = instruction_dst_params_alloc(ins, 2, sm6); - dst_param_init(&dst_params[0]); -- sm6_register_from_value(&dst_params[0].reg, dst); -+ sm6_register_from_value(&dst_params[0].reg, dst, sm6); - dst_param_init(&dst_params[1]); - sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); - } -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SYNC); -- flags = sm6_value_get_constant_uint(operands[0]); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SYNC); -+ flags = sm6_value_get_constant_uint(operands[0], sm6); - ins->flags = flags & (SYNC_THREAD_GROUP | SYNC_THREAD_GROUP_UAV); - if (flags & SYNC_GLOBAL_UAV) - ins->flags |= VKD3DSSF_GLOBAL_UAV; -@@ -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; - } -- i = sm6_value_get_constant_uint(operands[1]); -+ i = sm6_value_get_constant_uint(operands[1], sm6); - if (i != 1 && i != 255) - { - WARN("Unexpected update value %#x.\n", i); -@@ -4935,7 +5113,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu - } - inc = i; - -- vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VKD3DSIH_IMM_ATOMIC_CONSUME : VKD3DSIH_IMM_ATOMIC_ALLOC); -+ vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VSIR_OP_IMM_ATOMIC_CONSUME : VSIR_OP_IMM_ATOMIC_ALLOC); - 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 +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; - -- clamp = sm6_value_get_constant_uint(operands[5]); -+ clamp = sm6_value_get_constant_uint(operands[5], sm6); - - ins = state->ins; -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LOD); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_LOD); - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - return; - src_param_init_vector_from_reg(&src_params[0], &coord); -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -@@ -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 -+ register_convert_to_minimum_precision(&src_param->reg); - - instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), 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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- 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); - - 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; - -- register_index = sm6_value_get_constant_uint(address); -+ register_index = sm6_value_get_constant_uint(address, sm6); - if (register_index >= d->range.first && register_index <= d->range.last) - return d; - } -@@ -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; - -- type = sm6_value_get_constant_uint(operands[0]); -- id = sm6_value_get_constant_uint(operands[1]); -+ type = sm6_value_get_constant_uint(operands[0], sm6); -+ id = sm6_value_get_constant_uint(operands[1], sm6); - if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2]))) - { - WARN("Failed to find resource type %#x, id %#x.\n", type, id); -@@ -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]; -- dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3]); -+ dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3], sm6); - - /* NOP is used to flag no instruction emitted. */ -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - } - - static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, (op == DX_CUT_STREAM) ? VKD3DSIH_CUT_STREAM : VKD3DSIH_EMIT_STREAM); -+ vsir_instruction_init(ins, &sm6->p.location, (op == DX_CUT_STREAM) ? VSIR_OP_CUT_STREAM : VSIR_OP_EMIT_STREAM); - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; - -- i = sm6_value_get_constant_uint(operands[0]); -+ i = sm6_value_get_constant_uint(operands[0], sm6); - if (i >= MAX_GS_OUTPUT_STREAMS) - { - WARN("Invalid stream index %u.\n", i); -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DISCARD); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DISCARD); - - if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - } - - static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - -- if ((component_idx = sm6_value_get_constant_uint(operands[0])) >= 3) -+ if ((component_idx = sm6_value_get_constant_uint(operands[0], sm6)) >= 3) - { - WARN("Invalid component index %u.\n", component_idx); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -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); -- 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 +5365,15 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc - switch (op) - { - case DX_DOT2: -- handler_idx = VKD3DSIH_DP2; -+ handler_idx = VSIR_OP_DP2; - component_count = 2; - break; - case DX_DOT3: -- handler_idx = VKD3DSIH_DP3; -+ handler_idx = VSIR_OP_DP3; - component_count = 3; - break; - case DX_DOT4: -- handler_idx = VKD3DSIH_DP4; -+ handler_idx = VSIR_OP_DP4; - component_count = 4; - break; - default: -@@ -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; - -- row_index = sm6_value_get_constant_uint(operands[0]); -- column_index = sm6_value_get_constant_uint(operands[2]); -+ row_index = sm6_value_get_constant_uint(operands[0], sm6); -+ column_index = sm6_value_get_constant_uint(operands[2], sm6); - - signature = &sm6->p.program->input_signature; - if (row_index >= signature->element_count) -@@ -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) -- ? VKD3DSIH_EVAL_CENTROID : VKD3DSIH_EVAL_SAMPLE_INDEX); -+ ? VSIR_OP_EVAL_CENTROID : VSIR_OP_EVAL_SAMPLE_INDEX); - - if (!(src_params = instruction_src_params_alloc(ins, 1 + (op == DX_EVAL_SAMPLE_INDEX), sm6))) - return; -@@ -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) -- src_param_init_from_value(&src_params[1], operands[3]); -+ src_param_init_from_value(&src_params[1], operands[3], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - src_param->modifiers = VKD3DSPSM_ABS; - - instruction_dst_param_init_ssa_scalar(ins, sm6); -@@ -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, 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) -- { -- 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); - - 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: -- return VKD3DSIH_DFMA; -+ return VSIR_OP_DFMA; - case DX_FMAD: -- return VKD3DSIH_MAD; -+ return VSIR_OP_MAD; - case DX_IMAD: - case DX_UMAD: -- return VKD3DSIH_IMAD; -+ return VSIR_OP_IMAD; - default: - vkd3d_unreachable(); - } -@@ -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) -- src_param_init_from_value(&src_params[i], operands[i]); -+ src_param_init_from_value(&src_params[i], operands[i], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -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; - -- instruction_init_with_resource(ins, is_texture ? VKD3DSIH_RESINFO : VKD3DSIH_BUFINFO, resource, sm6); -+ instruction_init_with_resource(ins, is_texture ? VSIR_OP_RESINFO : VSIR_OP_BUFINFO, resource, sm6); - - if (!(src_params = instruction_src_params_alloc(ins, 1 + is_texture, sm6))) - return; -@@ -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; -- src_param_init_from_value(&src_params[0], operands[1]); -+ src_param_init_from_value(&src_params[0], operands[1], sm6); - component_count = VKD3D_VEC4_SIZE; - - if (resource_kind_is_multisampled(resource_kind)) - { -- instruction_dst_param_init_temp_vector(ins++, sm6); -+ instruction_dst_param_init_uint_temp_vector(ins++, sm6); - state->temp_idx = 1; - - /* DXIL does not have an intrinsic for sample info, and resinfo is expected to return - * the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */ -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_INFO); - ins->flags = VKD3DSI_SAMPLE_INFO_UINT; - - if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) -@@ -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); - -- if (!instruction_dst_param_init_temp_vector(ins, sm6)) -+ if (!instruction_dst_param_init_uint_temp_vector(ins, sm6)) - return; - dst = ins->dst; - dst->write_mask = VKD3DSP_WRITEMASK_3; -@@ -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; -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) - return; - src_param_init_vector_from_reg(&src_params[0], &dst->reg); -@@ -5429,9 +5608,9 @@ static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode - switch (op) - { - case DX_IBFE: -- return VKD3DSIH_IBFE; -+ return VSIR_OP_IBFE; - case DX_UBFE: -- return VKD3DSIH_UBFE; -+ return VSIR_OP_UBFE; - default: - vkd3d_unreachable(); - } -@@ -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) -- src_param_init_from_value(&src_params[i], operands[i]); -+ src_param_init_from_value(&src_params[i], operands[i], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -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; - -- row_index = sm6_value_get_constant_uint(operands[0]); -- column_index = sm6_value_get_constant_uint(operands[2]); -+ row_index = sm6_value_get_constant_uint(operands[0], sm6); -+ column_index = sm6_value_get_constant_uint(operands[2], sm6); - - if (is_control_point && operands[3]->value_type == VALUE_TYPE_UNDEFINED) - { -@@ -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."); - } - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - - if (is_patch_constant) - { -@@ -5532,7 +5711,7 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri - return; - - ins = state->ins; -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) - return; - src_params[0].reg = reg; -@@ -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: -- return VKD3DSIH_QUAD_READ_ACROSS_X; -+ return VSIR_OP_QUAD_READ_ACROSS_X; - case QUAD_READ_ACROSS_Y: -- return VKD3DSIH_QUAD_READ_ACROSS_Y; -+ return VSIR_OP_QUAD_READ_ACROSS_Y; - case QUAD_READ_ACROSS_D: -- return VKD3DSIH_QUAD_READ_ACROSS_D; -+ return VSIR_OP_QUAD_READ_ACROSS_D; - default: -- return VKD3DSIH_INVALID; -+ return VSIR_OP_INVALID; - } - } - -@@ -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; - -- quad_op = sm6_value_get_constant_uint(operands[1]); -- if ((opcode = dx_map_quad_op(quad_op)) == VKD3DSIH_INVALID) -+ quad_op = sm6_value_get_constant_uint(operands[1], sm6); -+ if ((opcode = dx_map_quad_op(quad_op)) == VSIR_OP_INVALID) - { - FIXME("Unhandled quad op kind %u.\n", quad_op); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_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; -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -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) - { -- write_mask = sm6_value_get_constant_uint(operands[3]); -+ write_mask = sm6_value_get_constant_uint(operands[3], sm6); - if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) - { - WARN("Invalid write mask %#x.\n", write_mask); -@@ -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); - } - -- instruction_init_with_resource(ins, raw ? VKD3DSIH_LD_RAW : VKD3DSIH_LD_STRUCTURED, resource, sm6); -+ instruction_init_with_resource(ins, raw ? VSIR_OP_LD_RAW : VSIR_OP_LD_STRUCTURED, resource, sm6); - operand_count = 2 + !raw; - if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) - return; -- src_params_init_from_operands(src_params, &operands[1], operand_count - 1); -+ src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6); - 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 +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; - -- write_mask = sm6_value_get_constant_uint(operands[7]); -+ write_mask = sm6_value_get_constant_uint(operands[7], sm6); - if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) - { - WARN("Invalid write mask %#x.\n", write_mask); -@@ -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."); - } - -- alignment = sm6_value_get_constant_uint(operands[8]); -+ alignment = sm6_value_get_constant_uint(operands[8], sm6); - if (alignment & (alignment - 1)) - { - FIXME("Invalid alignment %#x.\n", alignment); -@@ -5692,13 +5871,13 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ - return; - - ins = state->ins; -- vsir_instruction_init(ins, &sm6->p.location, raw ? VKD3DSIH_STORE_RAW : VKD3DSIH_STORE_STRUCTURED); -+ vsir_instruction_init(ins, &sm6->p.location, raw ? VSIR_OP_STORE_RAW : VSIR_OP_STORE_STRUCTURED); - operand_count = 2 + !raw; - - 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 = VSIR_DATA_U32; - src_param_init_vector_from_reg(&src_params[operand_count - 1], &data); - - 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) -- ? VKD3DSIH_LD_UAV_TYPED : VKD3DSIH_LD, resource, sm6); -+ ? VSIR_OP_LD_UAV_TYPED : VSIR_OP_LD, resource, sm6); - - if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) - return; -- src_param_init_from_value(&src_params[0], operands[1]); -+ src_param_init_from_value(&src_params[0], operands[1], sm6); - if (!sm6_value_is_undef(operands[2])) - { - /* Constant zero would be ok, but is not worth checking for unless it shows up. */ -@@ -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."); - } - -- write_mask = sm6_value_get_constant_uint(operands[7]); -+ write_mask = sm6_value_get_constant_uint(operands[7], sm6); - if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) - { - WARN("Invalid write mask %#x.\n", write_mask); -@@ -5797,11 +5976,11 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr - return; - - ins = state->ins; -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_UAV_TYPED); - - if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) - return; -- src_param_init_from_value(&src_params[0], operands[1]); -+ src_param_init_from_value(&src_params[0], operands[1], sm6); - if (!sm6_value_is_undef(operands[2])) - { - /* Constant zero would have no effect, but is not worth checking for unless it shows up. */ -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_INFO); - ins->flags = VKD3DSI_SAMPLE_INFO_UINT; - - 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_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; - } - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_POS); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_POS); - - if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) - return; - if (op == DX_TEX2DMS_GET_SAMPLE_POS) - { - src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); -- src_param_init_from_value(&src_params[1], operands[1]); -+ src_param_init_from_value(&src_params[1], operands[1], sm6); - } - 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]); -+ src_param_init_from_value(&src_params[1], operands[0], sm6); - } - - instruction_dst_param_init_ssa_vector(ins, 2, sm6); - } - --static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value) -+static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value, struct sm6_parser *sm6) - { -- return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value); -+ return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value, sm6); - } - - static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, - const struct sm6_value **operands, struct sm6_parser *sm6) - { -- ins->texel_offset.u = sm6_value_get_texel_offset(operands[0]); -- ins->texel_offset.v = sm6_value_get_texel_offset(operands[1]); -- ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]); -+ ins->texel_offset.u = sm6_value_get_texel_offset(operands[0], sm6); -+ ins->texel_offset.v = sm6_value_get_texel_offset(operands[1], sm6); -+ ins->texel_offset.w = sm6_value_get_texel_offset(operands[2], sm6); - } - - static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5914,7 +6093,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ - switch (op) - { - case DX_SAMPLE: -- instruction_init_with_resource(ins, VKD3DSIH_SAMPLE, resource, sm6); -+ instruction_init_with_resource(ins, VSIR_OP_SAMPLE, resource, sm6); - src_params = instruction_src_params_alloc(ins, 3, sm6); - clamp_idx = 9; - break; -@@ -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: -- instruction_init_with_resource(ins, (op == DX_SAMPLE_B) ? VKD3DSIH_SAMPLE_B : VKD3DSIH_SAMPLE_LOD, -+ instruction_init_with_resource(ins, (op == DX_SAMPLE_B) ? VSIR_OP_SAMPLE_B : VSIR_OP_SAMPLE_LOD, - resource, sm6); - src_params = instruction_src_params_alloc(ins, 4, sm6); -- src_param_init_from_value(&src_params[3], operands[9]); -+ src_param_init_from_value(&src_params[3], operands[9], sm6); - break; - case DX_SAMPLE_C: - clamp_idx = 10; - /* fall through */ - case DX_SAMPLE_C_LZ: -- instruction_init_with_resource(ins, (op == DX_SAMPLE_C_LZ) ? VKD3DSIH_SAMPLE_C_LZ : VKD3DSIH_SAMPLE_C, -+ instruction_init_with_resource(ins, (op == DX_SAMPLE_C_LZ) ? VSIR_OP_SAMPLE_C_LZ : VSIR_OP_SAMPLE_C, - resource, sm6); - src_params = instruction_src_params_alloc(ins, 4, sm6); -- src_param_init_from_value(&src_params[3], operands[9]); -+ src_param_init_from_value(&src_params[3], operands[9], sm6); - component_count = 1; - break; - case DX_SAMPLE_GRAD: -- instruction_init_with_resource(ins, VKD3DSIH_SAMPLE_GRAD, resource, sm6); -+ instruction_init_with_resource(ins, VSIR_OP_SAMPLE_GRAD, resource, sm6); - 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 +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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - - /* 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 +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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - - if (instruction_dst_param_init_ssa_scalar(ins, sm6)) - ins->dst->modifiers = VKD3DSPDM_SATURATE; - } - --static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -- const struct sm6_value **operands, struct function_emission_state *state) --{ -- struct sm6_value *dst = sm6_parser_get_current_value(sm6); -- struct vkd3d_shader_instruction *ins = state->ins; -- struct vkd3d_shader_dst_param *dst_params; -- struct vkd3d_shader_src_param *src_param; -- unsigned int index; -- -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SINCOS); -- if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) -- return; -- src_param_init_from_value(src_param, operands[0]); -- -- sm6_parser_init_ssa_value(sm6, dst); -- -- index = op == DX_COS; -- dst_params = instruction_dst_params_alloc(ins, 2, sm6); -- dst_param_init(&dst_params[0]); -- dst_param_init(&dst_params[1]); -- sm6_register_from_value(&dst_params[index].reg, dst); -- vsir_dst_param_init_null(&dst_params[index ^ 1]); --} -- - static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { - struct vkd3d_shader_instruction *ins = state->ins; - struct vkd3d_shader_src_param *src_param; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - - instruction_dst_param_init_ssa_vector(ins, 2, sm6); - } -@@ -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; - -- row_index = sm6_value_get_constant_uint(operands[0]); -- column_index = sm6_value_get_constant_uint(operands[2]); -+ row_index = sm6_value_get_constant_uint(operands[0], sm6); -+ column_index = sm6_value_get_constant_uint(operands[2], sm6); - - signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature; - if (row_index >= signature->element_count) -@@ -6092,7 +6247,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr - return; - } - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - - if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) - return; -@@ -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) - { -- sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_OUTPUT, dst_param->reg.type, -+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_OUTPUT, dst_param->reg.type, - dst_param->reg.data_type, vsir_write_mask_component_count(e->mask)); - } - - if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) -- src_param_init_from_value(src_param, value); -+ src_param_init_from_value(src_param, value, sm6); - } - - static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -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) - { -- instruction_init_with_resource(ins, extended_offset ? VKD3DSIH_GATHER4_PO : VKD3DSIH_GATHER4, resource, sm6); -+ instruction_init_with_resource(ins, extended_offset ? VSIR_OP_GATHER4_PO : VSIR_OP_GATHER4, resource, sm6); - if (!(src_params = instruction_src_params_alloc(ins, 3 + extended_offset, sm6))) - return; - } - else - { -- instruction_init_with_resource(ins, extended_offset ? VKD3DSIH_GATHER4_PO_C : VKD3DSIH_GATHER4_C, resource, sm6); -+ instruction_init_with_resource(ins, extended_offset ? VSIR_OP_GATHER4_PO_C : VSIR_OP_GATHER4_C, resource, sm6); - if (!(src_params = instruction_src_params_alloc(ins, 4 + extended_offset, sm6))) - return; -- src_param_init_from_value(&src_params[3 + extended_offset], operands[9]); -+ src_param_init_from_value(&src_params[3 + extended_offset], operands[9], sm6); - } - - src_param_init_vector_from_reg(&src_params[0], &coord); -@@ -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. */ -- swizzle = sm6_value_get_constant_uint(operands[8]); -+ swizzle = sm6_value_get_constant_uint(operands[8], sm6); - if (swizzle >= VKD3D_VEC4_SIZE) - { - WARN("Invalid swizzle %#x.\n", swizzle); -@@ -6201,8 +6360,8 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr - } - - ins = state->ins; -- instruction_init_with_resource(ins, is_uav ? VKD3DSIH_LD_UAV_TYPED -- : is_multisample ? VKD3DSIH_LD2DMS : VKD3DSIH_LD, resource, sm6); -+ instruction_init_with_resource(ins, is_uav ? VSIR_OP_LD_UAV_TYPED -+ : is_multisample ? VSIR_OP_LD2DMS : VSIR_OP_LD, resource, sm6); - instruction_set_texel_offset(ins, &operands[5], sm6); - - for (i = 0; i < VKD3D_VEC4_SIZE; ++i) -@@ -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) -- src_param_init_from_value(&src_params[2], mip_level_or_sample_count); -+ src_param_init_from_value(&src_params[2], mip_level_or_sample_count, sm6); - - instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); - } -@@ -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; - -- write_mask = sm6_value_get_constant_uint(operands[8]); -+ write_mask = sm6_value_get_constant_uint(operands[8], sm6); - if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) - { - WARN("Invalid write mask %#x.\n", write_mask); -@@ -6256,7 +6415,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int - return; - - ins = state->ins; -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_UAV_TYPED); - - if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) - return; -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_WAVE_ACTIVE_BALLOT); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_WAVE_ACTIVE_BALLOT); - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - - instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); - } -@@ -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: -- return VKD3DSIH_WAVE_ACTIVE_BIT_AND; -+ return VSIR_OP_WAVE_ACTIVE_BIT_AND; - case WAVE_BIT_OP_OR: -- return VKD3DSIH_WAVE_ACTIVE_BIT_OR; -+ return VSIR_OP_WAVE_ACTIVE_BIT_OR; - case WAVE_BIT_OP_XOR: -- return VKD3DSIH_WAVE_ACTIVE_BIT_XOR; -+ return VSIR_OP_WAVE_ACTIVE_BIT_XOR; - default: - FIXME("Unhandled wave bit op %u.\n", op); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, -- "Wave bit operation %u is unhandled.\n", op); -- return VKD3DSIH_INVALID; -+ "Wave bit operation %u is unhandled.", op); -+ return VSIR_OP_INVALID; - } - } - -@@ -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; - -- wave_op = sm6_value_get_constant_uint(operands[1]); -+ wave_op = sm6_value_get_constant_uint(operands[1], sm6); - -- if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VKD3DSIH_INVALID) -+ if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VSIR_OP_INVALID) - return; - vsir_instruction_init(ins, &sm6->p.location, opcode); - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -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: -- return VKD3DSIH_WAVE_OP_ADD; -+ return VSIR_OP_WAVE_OP_ADD; - case WAVE_OP_MUL: -- return VKD3DSIH_WAVE_OP_MUL; -+ return VSIR_OP_WAVE_OP_MUL; - case WAVE_OP_MIN: - if (is_float) -- return VKD3DSIH_WAVE_OP_MIN; -- return is_signed ? VKD3DSIH_WAVE_OP_IMIN : VKD3DSIH_WAVE_OP_UMIN; -+ return VSIR_OP_WAVE_OP_MIN; -+ return is_signed ? VSIR_OP_WAVE_OP_IMIN : VSIR_OP_WAVE_OP_UMIN; - case WAVE_OP_MAX: - if (is_float) -- return VKD3DSIH_WAVE_OP_MAX; -- return is_signed ? VKD3DSIH_WAVE_OP_IMAX : VKD3DSIH_WAVE_OP_UMAX; -+ return VSIR_OP_WAVE_OP_MAX; -+ return is_signed ? VSIR_OP_WAVE_OP_IMAX : VSIR_OP_WAVE_OP_UMAX; - default: - FIXME("Unhandled wave op %u.\n", op); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, -- "Wave operation %u is unhandled.\n", op); -- return VKD3DSIH_INVALID; -+ "Wave operation %u is unhandled.", op); -+ return VSIR_OP_INVALID; - } - } - -@@ -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; - -- wave_op = sm6_value_get_constant_uint(operands[1]); -- is_signed = !sm6_value_get_constant_uint(operands[2]); -+ wave_op = sm6_value_get_constant_uint(operands[1], sm6); -+ is_signed = !sm6_value_get_constant_uint(operands[2], sm6); - opcode = sm6_dx_map_wave_op(wave_op, is_signed, sm6_type_is_floating_point(operands[0]->type), sm6); - -- if (opcode == VKD3DSIH_INVALID) -+ if (opcode == VSIR_OP_INVALID) - return; - - vsir_instruction_init(ins, &sm6->p.location, opcode); -@@ -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; -- src_param_init_from_value(src_param, operands[0]); -+ src_param_init_from_value(src_param, operands[0], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -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}, -- [DX_COS ] = {"g", "R", sm6_parser_emit_dx_sincos}, -+ [DX_COS ] = {"g", "R", sm6_parser_emit_dx_unary}, - [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 +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}, -- [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, -+ [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_unary}, - [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 +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, -- const struct sm6_type *ret_type, bool is_return) -+ const struct sm6_type *ret_type) - { - const struct sm6_type *type = value->type; - -- if (info_type != 'H' && !sm6_value_is_register(value)) -+ if (info_type != 'H' && info_type != 'v' && !sm6_value_is_register(value)) -+ return false; -+ if (!type && info_type != 'v') - return false; - - switch (info_type) -@@ -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': -- return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type; -+ return sm6_value_is_handle(value) && type == sm6->handle_type; - case 'D': - return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Dimensions"); - case 'S': -@@ -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': -- return !type; -+ return sm6_value_is_invalid(value) && !type; - case 'o': - /* TODO: some type checking may be possible */ - return true; -@@ -6606,18 +6767,10 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ - - info = &sm6_dx_op_table[op]; - -- VKD3D_ASSERT(info->ret_type[0]); -- if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type[0], NULL, true)) -- { -- WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name); -- /* Return type validation failure is not so critical. We only need to set -- * a data type for the SSA result. */ -- } -- - for (i = 0; i < operand_count; ++i) - { - const struct sm6_value *value = operands[i]; -- if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], dst->type, false)) -+ if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], dst->type)) - { - 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 +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) - { -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - - if (!dst->type) - return; - - dst->value_type = VALUE_TYPE_INVALID; -- sm6_register_from_value(&dst->reg, dst); - } - - static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -6661,10 +6813,22 @@ static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_op - return; - } - -- if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst)) -- sm6_dx_op_table[op].handler(sm6, op, operands, state); -- else -+ if (!sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst)) -+ { - sm6_parser_emit_unhandled(sm6, state->ins, dst); -+ return; -+ } -+ -+ sm6_dx_op_table[op].handler(sm6, op, operands, state); -+ -+ VKD3D_ASSERT(sm6_dx_op_table[op].ret_type[0]); -+ if (!sm6_parser_validate_operand_type(sm6, dst, sm6_dx_op_table[op].ret_type[0], NULL)) -+ { -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Failed to validate return type for dx intrinsic id %u, '%s'.", op, name); -+ /* Return type validation failure is not so critical. We only need to set -+ * a data type for the SSA result. */ -+ } - } - - static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -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; - } -- sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value), -+ sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value, sm6), - fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); - } - - static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from, - const struct sm6_type *to, struct sm6_parser *sm6) - { -- enum vkd3d_shader_opcode op = VKD3DSIH_INVALID; -+ enum vkd3d_shader_opcode op = VSIR_OP_INVALID; - bool from_int, to_int, from_fp, to_fp; -+ unsigned int from_width, to_width; - bool is_valid = false; - - from_int = sm6_type_is_integer(from); -@@ -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); -- return VKD3DSIH_INVALID; -+ return VSIR_OP_INVALID; - } - if (to->u.width == 8 || from->u.width == 8) - { - FIXME("Unhandled 8-bit value.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Cast to/from an 8-bit type is not implemented."); -- return VKD3DSIH_INVALID; -+ return VSIR_OP_INVALID; - } - -- /* DXC emits minimum precision types as 16-bit. These must be emitted -- * as 32-bit in VSIR, so all width extensions to 32 bits are no-ops. */ - switch (code) - { - case CAST_TRUNC: -- /* nop or min precision. TODO: native 16-bit */ -- if (to->u.width == from->u.width || (to->u.width == 16 && from->u.width == 32)) -- op = VKD3DSIH_NOP; -- else -- op = VKD3DSIH_UTOU; -+ op = VSIR_OP_UTOU; - is_valid = from_int && to_int && to->u.width <= from->u.width; - break; -+ - case CAST_ZEXT: -+ op = VSIR_OP_UTOU; -+ is_valid = from_int && to_int && to->u.width >= from->u.width; -+ break; -+ - case CAST_SEXT: -- /* nop or min precision. TODO: native 16-bit. -- * Extension instructions could be emitted for min precision, but in Windows -- * the AMD RX 580 simply drops such instructions, which makes sense as no -- * assumptions should be made about any behaviour which depends on bit width. */ -- if (to->u.width == from->u.width || (to->u.width == 32 && from->u.width == 16)) -- { -- op = VKD3DSIH_NOP; -- is_valid = from_int && to_int; -- } -- else if (to->u.width > from->u.width) -- { -- op = (code == CAST_ZEXT) ? VKD3DSIH_UTOU : VKD3DSIH_ITOI; -- VKD3D_ASSERT(from->u.width == 1 || to->u.width == 64); -- is_valid = from_int && to_int; -- } -+ op = VSIR_OP_ITOI; -+ is_valid = from_int && to_int && to->u.width >= from->u.width; - break; -+ - case CAST_FPTOUI: -- op = VKD3DSIH_FTOU; -+ op = VSIR_OP_FTOU; - is_valid = from_fp && to_int && to->u.width > 1; - break; -+ - case CAST_FPTOSI: -- op = VKD3DSIH_FTOI; -+ op = VSIR_OP_FTOI; - is_valid = from_fp && to_int && to->u.width > 1; - break; -+ - case CAST_UITOFP: -- op = VKD3DSIH_UTOF; -+ op = VSIR_OP_UTOF; - is_valid = from_int && to_fp; - break; -+ - case CAST_SITOFP: -- op = VKD3DSIH_ITOF; -+ op = VSIR_OP_ITOF; - is_valid = from_int && to_fp; - break; -+ - case CAST_FPTRUNC: -- /* TODO: native 16-bit */ -- op = (from->u.width == 64) ? VKD3DSIH_DTOF : VKD3DSIH_NOP; -- is_valid = from_fp && to_fp; -+ op = VSIR_OP_DTOF; -+ is_valid = from_fp && to_fp && to->u.width <= from->u.width; - break; -+ - case CAST_FPEXT: -- /* TODO: native 16-bit */ -- op = (to->u.width == 64) ? VKD3DSIH_FTOD : VKD3DSIH_NOP; -- is_valid = from_fp && to_fp; -+ op = VSIR_OP_FTOD; -+ is_valid = from_fp && to_fp && to->u.width >= from->u.width; - break; -+ - case CAST_BITCAST: -- op = VKD3DSIH_MOV; -+ op = VSIR_OP_MOV; - is_valid = to->u.width == from->u.width; - break; -+ - default: - FIXME("Unhandled cast op %"PRIu64".\n", code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -- "Cast operation %"PRIu64" is unhandled.\n", code); -- return VKD3DSIH_INVALID; -+ "Cast operation %"PRIu64" is unhandled.", code); -+ return VSIR_OP_INVALID; - } - - if (!is_valid) - { - FIXME("Invalid types %u and/or %u for op %"PRIu64".\n", from->class, to->class, code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -- "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.\n", -+ "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.", - code, from->class, from->u.width, to->class, to->u.width); -- return VKD3DSIH_INVALID; -+ return VSIR_OP_INVALID; - } - -+ /* 16-bit values are currently treated as 32-bit, because 16-bit is -+ * interpreted as a minimum precision hint in SM 6.0, and we don't handle -+ * SM > 6.0 yet. */ -+ from_width = from->u.width; -+ if (from_width == 16) -+ from_width = 32; -+ -+ to_width = to->u.width; -+ if (to_width == 16) -+ to_width = 32; -+ -+ if (from->class == to->class && from_width == to_width) -+ op = VSIR_OP_NOP; -+ - return op; - } - -@@ -6885,33 +7056,33 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor - { - *dst = *value; - dst->type = type; -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - return; - } - -- if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VKD3DSIH_INVALID) -+ if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VSIR_OP_INVALID) - return; - - vsir_instruction_init(ins, &sm6->p.location, handler_idx); - -- if (handler_idx == VKD3DSIH_NOP) -+ if (handler_idx == VSIR_OP_NOP) - { -- sm6_register_from_value(&dst->reg, value); -- /* Set the result type for casts from 16-bit min precision. */ -- if (type->u.width != 16) -- dst->reg.data_type = vkd3d_data_type_from_sm6_type(type); -+ *dst = *value; -+ dst->type = type; - return; - } - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_from_value(src_param, value); -+ src_param_init_from_value(src_param, value, sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - -- /* bitcast */ -- if (handler_idx == VKD3DSIH_MOV) -- src_param->reg.data_type = dst->reg.data_type; -+ /* VSIR bitcasts are represented by source registers with types different -+ * from the types they were written with, rather than with different types -+ * for the MOV source and destination. */ -+ if (handler_idx == VSIR_OP_MOV) -+ src_param->reg.data_type = ins->dst[0].reg.data_type; - } - - struct sm6_cmp_info -@@ -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[] = - { -- [FCMP_FALSE] = {VKD3DSIH_INVALID}, -- [FCMP_OEQ] = {VKD3DSIH_EQO}, -- [FCMP_OGT] = {VKD3DSIH_LTO, true}, -- [FCMP_OGE] = {VKD3DSIH_GEO}, -- [FCMP_OLT] = {VKD3DSIH_LTO}, -- [FCMP_OLE] = {VKD3DSIH_GEO, true}, -- [FCMP_ONE] = {VKD3DSIH_NEO}, -- [FCMP_ORD] = {VKD3DSIH_ORD}, -- [FCMP_UNO] = {VKD3DSIH_UNO}, -- [FCMP_UEQ] = {VKD3DSIH_EQU}, -- [FCMP_UGT] = {VKD3DSIH_LTU, true}, -- [FCMP_UGE] = {VKD3DSIH_GEU}, -- [FCMP_ULT] = {VKD3DSIH_LTU}, -- [FCMP_ULE] = {VKD3DSIH_GEU, true}, -- [FCMP_UNE] = {VKD3DSIH_NEU}, -- [FCMP_TRUE] = {VKD3DSIH_INVALID}, -- -- [ICMP_EQ] = {VKD3DSIH_IEQ}, -- [ICMP_NE] = {VKD3DSIH_INE}, -- [ICMP_UGT] = {VKD3DSIH_ULT, true}, -- [ICMP_UGE] = {VKD3DSIH_UGE}, -- [ICMP_ULT] = {VKD3DSIH_ULT}, -- [ICMP_ULE] = {VKD3DSIH_UGE, true}, -- [ICMP_SGT] = {VKD3DSIH_ILT, true}, -- [ICMP_SGE] = {VKD3DSIH_IGE}, -- [ICMP_SLT] = {VKD3DSIH_ILT}, -- [ICMP_SLE] = {VKD3DSIH_IGE, true}, -+ [FCMP_FALSE] = {VSIR_OP_INVALID}, -+ [FCMP_OEQ] = {VSIR_OP_EQO}, -+ [FCMP_OGT] = {VSIR_OP_LTO, true}, -+ [FCMP_OGE] = {VSIR_OP_GEO}, -+ [FCMP_OLT] = {VSIR_OP_LTO}, -+ [FCMP_OLE] = {VSIR_OP_GEO, true}, -+ [FCMP_ONE] = {VSIR_OP_NEO}, -+ [FCMP_ORD] = {VSIR_OP_ORD}, -+ [FCMP_UNO] = {VSIR_OP_UNO}, -+ [FCMP_UEQ] = {VSIR_OP_EQU}, -+ [FCMP_UGT] = {VSIR_OP_LTU, true}, -+ [FCMP_UGE] = {VSIR_OP_GEU}, -+ [FCMP_ULT] = {VSIR_OP_LTU}, -+ [FCMP_ULE] = {VSIR_OP_GEU, true}, -+ [FCMP_UNE] = {VSIR_OP_NEU}, -+ [FCMP_TRUE] = {VSIR_OP_INVALID}, -+ -+ [ICMP_EQ] = {VSIR_OP_IEQ}, -+ [ICMP_NE] = {VSIR_OP_INE}, -+ [ICMP_UGT] = {VSIR_OP_ULT, true}, -+ [ICMP_UGE] = {VSIR_OP_UGE}, -+ [ICMP_ULT] = {VSIR_OP_ULT}, -+ [ICMP_ULE] = {VSIR_OP_UGE, true}, -+ [ICMP_SGT] = {VSIR_OP_ILT, true}, -+ [ICMP_SGE] = {VSIR_OP_IGE}, -+ [ICMP_SLT] = {VSIR_OP_ILT}, -+ [ICMP_SLE] = {VSIR_OP_IGE, true}, - }; - - return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL; -@@ -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)) - { -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - *dst = *a; - return; - } -@@ -7017,7 +7188,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor - "Type mismatch in comparison operation arguments."); - } - -- if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VKD3DSIH_INVALID) -+ if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VSIR_OP_INVALID) - { - FIXME("Unhandled operation %"PRIu64".\n", code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -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; -- src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a); -- src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b); -+ src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a, sm6); -+ src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b, sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -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; - -- sm6_register_from_value(®, ptr); -+ sm6_register_from_value(®, ptr, sm6); - - if (reg.type != VKD3DSPR_GROUPSHAREDMEM) - { -@@ -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"); - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_IMM_ATOMIC_CMP_EXCH); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_IMM_ATOMIC_CMP_EXCH); - ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST; - - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - return; - src_param_make_constant_uint(&src_params[0], 0); -- src_param_init_from_value(&src_params[1], cmp); -- src_param_init_from_value(&src_params[2], new); -+ src_param_init_from_value(&src_params[1], cmp, sm6); -+ src_param_init_from_value(&src_params[2], new, sm6); - - sm6_parser_init_ssa_value(sm6, dst); - - if (!(dst_params = instruction_dst_params_alloc(ins, 2, sm6))) - return; -- sm6_register_from_value(&dst_params[0].reg, dst); -+ sm6_register_from_value(&dst_params[0].reg, dst, sm6); - dst_param_init(&dst_params[0]); - dst_params[1].reg = reg; - dst_param_init(&dst_params[1]); -@@ -7191,11 +7362,11 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil - } - dst->type = type; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- sm6_register_from_value(&src_param->reg, src); -+ sm6_register_from_value(&src_param->reg, src, sm6); - src_param_init_scalar(src_param, elem_idx); - - instruction_dst_param_init_ssa_scalar(ins, sm6); -@@ -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; -- struct vkd3d_shader_register reg; - const struct sm6_value *src; -- bool is_in_bounds; -+ struct sm6_index *index; - - if (!dxil_record_validate_operand_min_count(record, 5, sm6) - || !(type = sm6_parser_get_type(sm6, record->operands[1])) -@@ -7222,9 +7392,13 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record - return; - } - -- sm6_register_from_value(®, src); -+ *dst = *src; -+ index = sm6_get_value_index(sm6, dst); - -- if (reg.idx_count > 1) -+ if (!index) -+ return; -+ -+ if (index->index) - { - WARN("Unsupported stacked GEP.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -7232,8 +7406,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record - return; - } - -- is_in_bounds = record->operands[0]; -- - 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 +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. */ -- if (sm6_value_get_constant_uint(elem_value)) -+ if (sm6_value_get_constant_uint(elem_value, sm6)) - { - WARN("Expected constant zero.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -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. */ -- elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value) : 0; -+ elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value, sm6) : 0; - type = sm6_type_get_element_type_at_index(pointee_type, elem_idx); - if (!type) - { -@@ -7293,15 +7465,10 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record - return; - } - -- reg.idx[1].offset = 0; -- 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]; - -- 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 +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"); - -- sm6_register_from_value(®, ptr); -+ sm6_register_from_value(®, ptr, sm6); - - if (ptr->structure_stride) - { - VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM); -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LD_STRUCTURED); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_LD_STRUCTURED); - - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - return; -@@ -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); -- src_param_init_from_value(&src_params[2], ptr); -+ src_param_init_from_value(&src_params[2], ptr, sm6); - src_params[2].reg.alignment = alignment; - /* The offset is already in src_params[0]. */ - src_params[2].reg.idx_count = 1; -@@ -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); -- vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_LD_RAW : VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VSIR_OP_LD_RAW : VSIR_OP_MOV); - - if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) - return; - if (operand_count > 1) - src_param_make_constant_uint(&src_params[0], 0); -- src_param_init_from_value(&src_params[operand_count - 1], ptr); -+ src_param_init_from_value(&src_params[operand_count - 1], ptr, sm6); - src_params[operand_count - 1].reg.alignment = alignment; - } - -@@ -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; -- sm6_register_from_value(&phi->reg, dst); - phi->incoming_count = record->operand_count / 2u; - - if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count, -@@ -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); - } - -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - - qsort(incoming, phi->incoming_count, sizeof(*incoming), phi_incoming_compare); - -@@ -7491,7 +7657,7 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record - - code_block->terminator.type = TERMINATOR_RET; - -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - } - - static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -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"); - -- sm6_register_from_value(®, ptr); -+ sm6_register_from_value(®, ptr, sm6); - - if (ptr->structure_stride) - { - VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM); -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_STRUCTURED); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_STRUCTURED); - - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - return; -@@ -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); -- src_param_init_from_value(&src_params[2], src); -+ src_param_init_from_value(&src_params[2], src, sm6); - } - else - { - operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM); -- vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_STORE_RAW : VKD3DSIH_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VSIR_OP_STORE_RAW : VSIR_OP_MOV); - - if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) - return; - if (operand_count > 1) - src_param_make_constant_uint(&src_params[0], 0); -- src_param_init_from_value(&src_params[operand_count - 1], src); -+ src_param_init_from_value(&src_params[operand_count - 1], src, sm6); - } - - dst_param = instruction_dst_params_alloc(ins, 1, sm6); -@@ -7612,7 +7778,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec - return; - } - -- sm6_register_from_value(&terminator->conditional_reg, src); -+ sm6_register_from_value(&terminator->conditional_reg, src, sm6); - terminator->type = TERMINATOR_SWITCH; - - terminator->case_count = record->operand_count / 2u; -@@ -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."); - } - -- terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src); -+ terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src, sm6); - } - -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - } - - static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -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; - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOVC); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOVC); - - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - return; - for (i = 0; i < 3; ++i) -- src_param_init_from_value(&src_params[i], src[i]); -+ src_param_init_from_value(&src_params[i], src[i], sm6); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -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)); - } - --static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, -+static bool sm6_metadata_get_uint_value(struct sm6_parser *sm6, - const struct sm6_metadata_value *m, unsigned int *u) - { - const struct sm6_value *value; -@@ -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; - -- *u = sm6_value_get_constant_uint(value); -+ *u = sm6_value_get_constant_uint(value, sm6); - - return true; - } - --static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, -+static bool sm6_metadata_get_uint64_value(struct sm6_parser *sm6, - const struct sm6_metadata_value *m, uint64_t *u) - { - const struct sm6_value *value; -@@ -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; - -- *u = sm6_value_get_constant_uint(value); -+ *u = sm6_value_get_constant_uint(value, sm6); - - return true; - } - --static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, -+static bool sm6_metadata_get_float_value(struct sm6_parser *sm6, - const struct sm6_metadata_value *m, float *f) - { - const struct sm6_value *value; -@@ -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; - -- *f = register_get_float_value(&value->reg); -+ *f = sm6_value_get_constant_float(value, sm6); - - return true; - } -@@ -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)) - { -- dst->reg.non_uniform = !!operand; -+ dst->non_uniform = !!operand; - } - } - else -@@ -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; - } -- if (src->reg.data_type != phi->reg.data_type) -+ if (src->type != phi->value.type) - { - WARN("Type mismatch.\n"); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, - "The type of a phi incoming value does not match the result type."); - } -- sm6_register_from_value(&phi->incoming[j].reg, src); -+ sm6_register_from_value(&phi->incoming[j].reg, src, sm6); - } - } - } -@@ -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]; -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - - dst = sm6_parser_get_current_value(sm6); - fwd_type = dst->type; - dst->type = NULL; -- dst->value_type = VALUE_TYPE_REG; - dst->is_back_ref = true; - is_terminator = false; - -@@ -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); - -+ /* This is specific for PHI nodes, but must happen after attachments have been applied. */ -+ if (record->code == FUNC_CODE_INST_PHI) -+ code_block->phi[code_block->phi_count - 1].value = *dst; -+ - if (is_terminator) - { - ++block_idx; - code_block = (block_idx < function->block_count) ? function->blocks[block_idx] : NULL; - } - if (code_block) -- code_block->instruction_count += ins->opcode != VKD3DSIH_NOP; -+ code_block->instruction_count += ins->opcode != VSIR_OP_NOP; - - if (dst->type && fwd_type && dst->type != fwd_type) - { -@@ -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; -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_BRANCH); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_BRANCH); - 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 +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; -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_BRANCH); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_BRANCH); - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - return; - src_param_init(&src_params[0]); -@@ -8253,7 +8422,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ - break; - - case TERMINATOR_SWITCH: -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_SWITCH_MONOLITHIC); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_SWITCH_MONOLITHIC); - if (!(src_params = instruction_src_params_alloc(ins, block->terminator.case_count * 2u + 1, sm6))) - return; - src_param_init(&src_params[0]); -@@ -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: -- sm6_parser_add_instruction(sm6, VKD3DSIH_RET); -+ sm6_parser_add_instruction(sm6, VSIR_OP_RET); - break; - - default: -@@ -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; - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_PHI); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_PHI); - 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 +8511,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser - } - - dst_param_init(dst_param); -- dst_param->reg = src_phi->reg; -+ sm6_register_from_value(&dst_param->reg, &src_phi->value, sm6); - } - } - -@@ -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; - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_LABEL); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_LABEL); - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -@@ -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) - { -- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; -+ ins->opcode = is_uav ? VSIR_OP_DCL_UAV_RAW : VSIR_OP_DCL_RESOURCE_RAW; - ins->declaration.raw_resource.resource.reg.write_mask = 0; - return &ins->declaration.raw_resource.resource; - } -@@ -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."); - } - -- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_TYPED : VKD3DSIH_DCL; -+ ins->opcode = is_uav ? VSIR_OP_DCL_UAV_TYPED : VSIR_OP_DCL; - 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 +9221,14 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc - } - else if (kind == RESOURCE_KIND_RAWBUFFER) - { -- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; -+ ins->opcode = is_uav ? VSIR_OP_DCL_UAV_RAW : VSIR_OP_DCL_RESOURCE_RAW; - ins->declaration.raw_resource.resource.reg.write_mask = 0; - - return &ins->declaration.raw_resource.resource; - } - else if (kind == RESOURCE_KIND_STRUCTUREDBUFFER) - { -- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED; -+ ins->opcode = is_uav ? VSIR_OP_DCL_UAV_STRUCTURED : VSIR_OP_DCL_RESOURCE_STRUCTURED; - ins->declaration.structured_resource.byte_stride = resource_values.byte_stride; - ins->declaration.structured_resource.resource.reg.write_mask = 0; - -@@ -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; - } - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_INVALID); - - if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], false, kind, - node->operands[8], ins))) -@@ -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->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] : VSIR_DATA_UNUSED; - - init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range); - -@@ -9197,7 +9365,7 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, - } - } - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_INVALID); - if (values[1]) - ins->flags = VKD3DSUF_GLOBALLY_COHERENT; - if (values[2]) -@@ -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->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] : VSIR_DATA_UNUSED; - - init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range); - -@@ -9251,14 +9419,14 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, - return VKD3D_ERROR_INVALID_SHADER; - } - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_CONSTANT_BUFFER); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_CONSTANT_BUFFER); - ins->resource_type = VKD3D_SHADER_RESOURCE_BUFFER; - ins->declaration.cb.size = buffer_size; - ins->declaration.cb.src.swizzle = VKD3D_SHADER_NO_SWIZZLE; - 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); - } - -- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_SAMPLER); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_SAMPLER); - ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; - - if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind)) -@@ -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; - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_GLOBAL_FLAGS); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_GLOBAL_FLAGS); - ins->declaration.global_flags = global_flags; - sm6->p.program->global_flags = global_flags; - } -@@ -9870,7 +10040,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co - } - } - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_THREAD_GROUP); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_THREAD_GROUP); - 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 +10080,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, - "Domain shader tessellator domain %u is unhandled.", tessellator_domain); - } - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_DOMAIN); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_DOMAIN); - ins->declaration.tessellator_domain = tessellator_domain; - sm6->p.program->tess_domain = tessellator_domain; - } -@@ -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); - } - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_PARTITIONING); - ins->declaration.tessellator_partitioning = tessellator_partitioning; - - sm6->p.program->tess_partitioning = tessellator_partitioning; -@@ -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); - } - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE); -+ 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; -@@ -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); - } - -- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_HS_MAX_TESSFACTOR); -+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_HS_MAX_TESSFACTOR); - ins->declaration.max_tessellation_factor = max_tessellation_factor; - } - -@@ -10070,7 +10240,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s - break; - } - -- sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); -+ 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; - -@@ -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); - } -- sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_VERTICES_OUT, i); -+ sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_VERTICES_OUT, i); - sm6->p.program->vertices_out_count = i; - - if (operands[2] > 1) -@@ -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; - } -- sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); -+ sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); - sm6->p.program->output_topology = output_primitive; - - i = operands[4]; -@@ -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); - } -- sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_GS_INSTANCES, i); -+ sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_GS_INSTANCES, i); - } - - static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6, -@@ -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"); -- sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]); -+ sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]); - 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 +10912,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro - - if (version.type == VKD3D_SHADER_TYPE_HULL) - { -- sm6_parser_add_instruction(sm6, VKD3DSIH_HS_CONTROL_POINT_PHASE); -+ sm6_parser_add_instruction(sm6, VSIR_OP_HS_CONTROL_POINT_PHASE); - - if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) - goto fail; -@@ -10757,7 +10927,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro - goto fail; - } - -- sm6_parser_add_instruction(sm6, VKD3DSIH_HS_FORK_PHASE); -+ sm6_parser_add_instruction(sm6, VSIR_OP_HS_FORK_PHASE); - if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) - goto fail; - -diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c -index a4f1a371299..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)); -@@ -54,6 +56,22 @@ enum state_property_component_type - FX_COMPONENT_TYPE_COUNT, - }; - -+enum fxlvm_constants -+{ -+ FX_FXLC_COMP_COUNT_MASK = 0xffff, -+ FX_FXLC_OPCODE_MASK = 0x7ff, -+ FX_FXLC_OPCODE_SHIFT = 20, -+ FX_FXLC_IS_SCALAR_MASK = 0x80000000, -+ -+ FX_FXLC_REG_UNUSED = 0, -+ FX_FXLC_REG_LITERAL = 1, -+ FX_FXLC_REG_CB = 2, -+ FX_FXLC_REG_INPUT = 3, -+ FX_FXLC_REG_OUTPUT = 4, -+ FX_FXLC_REG_TEMP = 7, -+ FX_FXLC_REG_MAX = FX_FXLC_REG_TEMP, -+}; -+ - struct rhs_named_value - { - const char *name; -@@ -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); -+ void (*write_state_assignment)(const struct hlsl_ir_var *var, -+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx); - bool are_child_effects_supported; - }; - -@@ -289,15 +309,6 @@ static void set_status(struct fx_write_context *fx, int status) - fx->status = status; - } - --static void fx_print_string(struct vkd3d_string_buffer *buffer, const char *prefix, -- const char *s, size_t len) --{ -- if (len) -- --len; /* Trim terminating null. */ -- vkd3d_string_buffer_printf(buffer, "%s", prefix); -- vkd3d_string_buffer_print_string_escaped(buffer, s, len); --} -- - static uint32_t write_string(const char *string, struct fx_write_context *fx) - { - return fx->ops->write_string(string, fx); -@@ -308,6 +319,15 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) - fx->ops->write_pass(var, fx); - } - -+static void write_state_assignment(const struct hlsl_ir_var *var, -+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx) -+{ -+ fx->ops->write_state_assignment(var, entry, fx); -+} -+ -+static uint32_t write_state_block(struct hlsl_ir_var *var, -+ unsigned int block_index, struct fx_write_context *fx); -+ - static uint32_t write_annotations(struct hlsl_scope *scope, struct fx_write_context *fx) - { - struct hlsl_ctx *ctx = fx->ctx; -@@ -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); --static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index, -- uint32_t count_offset, struct fx_write_context *fx); - - static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx) - { -@@ -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; - -- LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry) -+ /* We don't try to reuse nameless types; they will get the same -+ * "" name, but are not available for the type cache. */ -+ if (name) - { -- if (strcmp(type_entry->name, name)) -- continue; -+ LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry) -+ { -+ if (strcmp(type_entry->name, name)) -+ continue; - -- if (type_entry->elements_count != elements_count) -- continue; -+ if (type_entry->elements_count != elements_count) -+ continue; - -- if (type_entry->modifiers != modifiers) -- continue; -+ if (type_entry->modifiers != modifiers) -+ continue; - -- return type_entry->offset; -+ return type_entry->offset; -+ } - } - - if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry)))) -@@ -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; - -- list_add_tail(&fx->types, &type_entry->entry); -+ if (name) -+ list_add_tail(&fx->types, &type_entry->entry); - - return type_entry->offset; - } -@@ -491,17 +515,22 @@ static uint32_t write_fx_4_string(const char *string, struct fx_write_context *f - return string_entry->offset; - } - -+static void fx_4_decompose_state_blocks(struct hlsl_ir_var *var, struct fx_write_context *fx); -+ - static void write_fx_4_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) - { - struct vkd3d_bytecode_buffer *buffer = &fx->structured; -- uint32_t name_offset, count_offset; -+ uint32_t name_offset, count_offset, count; - - name_offset = write_string(var->name, fx); - put_u32(buffer, name_offset); - count_offset = put_u32(buffer, 0); - -+ fx_4_decompose_state_blocks(var, fx); -+ - write_fx_4_annotations(var->annotations, fx); -- write_fx_4_state_block(var, 0, count_offset, fx); -+ count = write_state_block(var, 0, fx); -+ set_u32(buffer, count_offset, count); - } - - static void write_fx_2_annotations(struct hlsl_ir_var *var, uint32_t count_offset, struct fx_write_context *fx) -@@ -764,208 +793,227 @@ static const struct rhs_named_value fx_2_filter_values[] = - { NULL } - }; - --static const struct fx_2_state -+struct fx_state - { - const char *name; -+ enum hlsl_type_class container; - enum hlsl_type_class class; - enum state_property_component_type type; - unsigned int dimx; - uint32_t array_size; - uint32_t id; - const struct rhs_named_value *values; --} --fx_2_states[] = --{ -- { "ZEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values }, -- { "FillMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values }, -- { "ShadeMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 2, fx_2_shademode_values }, -- { "ZWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 3 }, -- { "AlphaTestEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 4 }, -- { "LastPixel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 5 }, -- { "SrcBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 6, fx_2_blendmode_values }, -- { "DestBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 7, fx_2_blendmode_values }, -- { "CullMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 8, fx_2_cullmode_values }, -- { "ZFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9, fx_2_cmpfunc_values }, -- { "AlphaRef", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 10 }, -- { "AlphaFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11, fx_2_cmpfunc_values }, -- { "DitherEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12 }, -- { "AlphaBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13 }, -- { "FogEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 14 }, -- { "SpecularEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 }, -- { "FogColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 16 }, -- { "FogTableMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 17, fx_2_fogmode_values }, -- { "FogStart", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 18 }, -- { "FogEnd", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 19 }, -- { "FogDensity", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 20 }, -- { "RangeFogEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 21 }, -- { "StencilEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 22 }, -- { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, fx_2_stencilcaps_values }, -- { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, fx_2_stencilcaps_values }, -- { "StencilPass", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 25, fx_2_stencilcaps_values }, -- { "StencilFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 26, fx_2_cmpfunc_values }, -- { "StencilRef", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 27 }, -- { "StencilMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28 }, -- { "StencilWriteMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 29 }, -- { "TextureFactor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 30 }, -- { "Wrap0", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 31, fx_2_wrap_values }, -- { "Wrap1", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 32, fx_2_wrap_values }, -- { "Wrap2", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 33, fx_2_wrap_values }, -- { "Wrap3", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 34, fx_2_wrap_values }, -- { "Wrap4", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 35, fx_2_wrap_values }, -- { "Wrap5", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 36, fx_2_wrap_values }, -- { "Wrap6", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 37, fx_2_wrap_values }, -- { "Wrap7", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, fx_2_wrap_values }, -- { "Wrap8", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, fx_2_wrap_values }, -- { "Wrap9", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, fx_2_wrap_values }, -- { "Wrap10", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, fx_2_wrap_values }, -- { "Wrap11", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, fx_2_wrap_values }, -- { "Wrap12", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, fx_2_wrap_values }, -- { "Wrap13", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 44, fx_2_wrap_values }, -- { "Wrap14", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 45, fx_2_wrap_values }, -- { "Wrap15", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 46, fx_2_wrap_values }, -- { "Clipping", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 47 }, -- { "Lighting", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 48 }, -- { "Ambient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 49 }, -- { "FogVertexMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 50, fx_2_fogmode_values }, -- { "ColorVertex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 51 }, -- { "LocalViewer", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 52 }, -- { "NormalizeNormals", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 53 }, -- -- { "DiffuseMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 54, fx_2_materialcolorsource_values }, -- { "SpecularMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 55, fx_2_materialcolorsource_values }, -- { "AmbientMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 56, fx_2_materialcolorsource_values }, -- { "EmissiveMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 57, fx_2_materialcolorsource_values }, -- -- { "VertexBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 58, fx_2_vertexblend_values }, -- { "ClipPlaneEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 59, fx_2_clipplane_values }, -- { "PointSize", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 60 }, -- { "PointSize_Min", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 61 }, -- { "PointSize_Max", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 62 }, -- { "PointSpriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 63 }, -- { "PointScaleEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 64 }, -- { "PointScale_A", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 65 }, -- { "PointScale_B", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 66 }, -- { "PointScale_C", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 67 }, -- -- { "MultiSampleAntialias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 68 }, -- { "MultiSampleMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 69 }, -- { "PatchEdgeStyle", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 70, fx_2_patchedgestyle_values }, -- { "DebugMonitorToken", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 71 }, -- { "IndexedVertexBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 72 }, -- { "ColorWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 73, fx_2_colorwriteenable_values }, -- { "TweenFactor", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 74 }, -- { "BlendOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 75, fx_2_blendop_values }, -- { "PositionDegree", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 76, fx_2_degree_values }, -- { "NormalDegree", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 77, fx_2_degree_values }, -- { "ScissorTestEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 78 }, -- { "SlopeScaleDepthBias", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 79 }, -- -- { "AntialiasedLineEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 80 }, -- { "MinTessellationLevel", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 81 }, -- { "MaxTessellationLevel", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 82 }, -- { "AdaptiveTess_X", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 83 }, -- { "AdaptiveTess_Y", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 84 }, -- { "AdaptiveTess_Z", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 85 }, -- { "AdaptiveTess_W", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 86 }, -- { "EnableAdaptiveTesselation", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 }, -- { "TwoSidedStencilMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 88 }, -- { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 89, fx_2_stencilcaps_values }, -- { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 90, fx_2_stencilcaps_values }, -- { "StencilPass", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 91, fx_2_stencilcaps_values }, -- { "StencilFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 92, fx_2_cmpfunc_values }, -- -- { "ColorWriteEnable1", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 93, fx_2_colorwriteenable_values }, -- { "ColorWriteEnable2", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 94, fx_2_colorwriteenable_values }, -- { "ColorWriteEnable3", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 95, fx_2_colorwriteenable_values }, -- { "BlendFactor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 96 }, -- { "SRGBWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 97 }, -- { "DepthBias", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 98 }, -- { "SeparateAlphaBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 99 }, -- { "SrcBlendAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 100, fx_2_blendmode_values }, -- { "DestBlendAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 101, fx_2_blendmode_values }, -- { "BlendOpAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 102, fx_2_blendmode_values }, -- -- { "ColorOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 103, fx_2_textureop_values }, -- { "ColorArg0", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 104, fx_2_colorarg_values }, -- { "ColorArg1", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 105, fx_2_colorarg_values }, -- { "ColorArg2", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 106, fx_2_colorarg_values }, -- { "AlphaOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 107, fx_2_textureop_values }, -- { "AlphaArg0", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 108, fx_2_colorarg_values }, -- { "AlphaArg1", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 109, fx_2_colorarg_values }, -- { "AlphaArg2", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 110, fx_2_colorarg_values }, -- { "ResultArg", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 111, fx_2_colorarg_values }, -- { "BumpEnvMat00", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 112 }, -- { "BumpEnvMat01", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 113 }, -- { "BumpEnvMat10", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 114 }, -- { "BumpEnvMat11", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 115 }, -- { "TextCoordIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 }, -- { "BumpEnvLScale", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 117 }, -- { "BumpEnvLOffset", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 118 }, -- { "TextureTransformFlags", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 119, fx_2_texturetransform_values }, -- { "Constant", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 120 }, -- { "NPatchMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 }, -- { "FVF", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 122 }, -- -- { "ProjectionTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 123 }, -- { "ViewTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 124 }, -- { "WorldTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 125 }, -- { "TextureTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 8, 126 }, -- -- { "MaterialAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 127 }, -- { "MaterialDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 128 }, -- { "MaterialSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 129 }, -- { "MaterialEmissive", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 130 }, -- { "MaterialPower", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 131 }, -- -- { "LightType", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 132, fx_2_lighttype_values }, -- { "LightDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 133 }, -- { "LightSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 134 }, -- { "LightAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 135 }, -- { "LightPosition", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 136 }, -- { "LightDirection", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 137 }, -- { "LightRange", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 138 }, -- { "LightFalloff", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 139 }, -- { "LightAttenuation0", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 140 }, -- { "LightAttenuation1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 141 }, -- { "LightAttenuation2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 142 }, -- { "LightTheta", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 143 }, -- { "LightPhi", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 144 }, -- { "LightEnable", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 145 }, -- -- { "VertexShader", HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 }, -- { "PixelShader", HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 }, -- -- { "VertexShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 148 }, -- { "VertexShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 149 }, -- { "VertexShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 150 }, -- { "VertexShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 151 }, -- { "VertexShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 152 }, -- { "VertexShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 153 }, -- { "VertexShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 154 }, -- { "VertexShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 155 }, -- -- { "PixelShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 156 }, -- { "PixelShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 157 }, -- { "PixelShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 158 }, -- { "PixelShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 159 }, -- { "PixelShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 160 }, -- { "PixelShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 161 }, -- { "PixelShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 162 }, -- { "PixelShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 163 }, -- -- { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 }, -- { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values }, -- { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values }, -- { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values }, -- { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 }, -- { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values }, -- { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values }, -- { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values }, -- { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 }, -- { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 }, -- { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 }, -- { "SRBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 }, -- { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 }, -+}; -+ -+static const struct fx_state fx_2_pass_states[] = -+{ -+ { "ZEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values }, -+ { "FillMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values }, -+ { "ShadeMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 2, fx_2_shademode_values }, -+ { "ZWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 3 }, -+ { "AlphaTestEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 4 }, -+ { "LastPixel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 5 }, -+ { "SrcBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 6, fx_2_blendmode_values }, -+ { "DestBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 7, fx_2_blendmode_values }, -+ { "CullMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 8, fx_2_cullmode_values }, -+ { "ZFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9, fx_2_cmpfunc_values }, -+ { "AlphaRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 10 }, -+ { "AlphaFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11, fx_2_cmpfunc_values }, -+ { "DitherEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12 }, -+ { "AlphaBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13 }, -+ { "FogEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 14 }, -+ { "SpecularEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 }, -+ { "FogColor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 16 }, -+ { "FogTableMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 17, fx_2_fogmode_values }, -+ { "FogStart", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 18 }, -+ { "FogEnd", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 19 }, -+ { "FogDensity", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 20 }, -+ { "RangeFogEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 21 }, -+ { "StencilEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 22 }, -+ { "StencilFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, fx_2_stencilcaps_values }, -+ { "StencilZFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, fx_2_stencilcaps_values }, -+ { "StencilPass", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 25, fx_2_stencilcaps_values }, -+ { "StencilFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 26, fx_2_cmpfunc_values }, -+ { "StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 27 }, -+ { "StencilMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28 }, -+ { "StencilWriteMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 29 }, -+ { "TextureFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 30 }, -+ { "Wrap0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 31, fx_2_wrap_values }, -+ { "Wrap1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 32, fx_2_wrap_values }, -+ { "Wrap2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 33, fx_2_wrap_values }, -+ { "Wrap3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 34, fx_2_wrap_values }, -+ { "Wrap4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 35, fx_2_wrap_values }, -+ { "Wrap5", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 36, fx_2_wrap_values }, -+ { "Wrap6", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 37, fx_2_wrap_values }, -+ { "Wrap7", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, fx_2_wrap_values }, -+ { "Wrap8", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, fx_2_wrap_values }, -+ { "Wrap9", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, fx_2_wrap_values }, -+ { "Wrap10", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, fx_2_wrap_values }, -+ { "Wrap11", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, fx_2_wrap_values }, -+ { "Wrap12", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, fx_2_wrap_values }, -+ { "Wrap13", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 44, fx_2_wrap_values }, -+ { "Wrap14", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 45, fx_2_wrap_values }, -+ { "Wrap15", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 46, fx_2_wrap_values }, -+ { "Clipping", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 47 }, -+ { "Lighting", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 48 }, -+ { "Ambient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 49 }, -+ { "FogVertexMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 50, fx_2_fogmode_values }, -+ { "ColorVertex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 51 }, -+ { "LocalViewer", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 52 }, -+ { "NormalizeNormals", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 53 }, -+ -+ { "DiffuseMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 54, fx_2_materialcolorsource_values }, -+ { "SpecularMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 55, fx_2_materialcolorsource_values }, -+ { "AmbientMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 56, fx_2_materialcolorsource_values }, -+ { "EmissiveMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 57, fx_2_materialcolorsource_values }, -+ -+ { "VertexBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 58, fx_2_vertexblend_values }, -+ { "ClipPlaneEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 59, fx_2_clipplane_values }, -+ { "PointSize", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 60 }, -+ { "PointSize_Min", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 61 }, -+ { "PointSize_Max", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 62 }, -+ { "PointSpriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 63 }, -+ { "PointScaleEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 64 }, -+ { "PointScale_A", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 65 }, -+ { "PointScale_B", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 66 }, -+ { "PointScale_C", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 67 }, -+ -+ { "MultiSampleAntialias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 68 }, -+ { "MultiSampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 69 }, -+ { "PatchEdgeStyle", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 70, fx_2_patchedgestyle_values }, -+ { "DebugMonitorToken", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 71 }, -+ { "IndexedVertexBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 72 }, -+ { "ColorWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 73, fx_2_colorwriteenable_values }, -+ { "TweenFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 74 }, -+ { "BlendOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 75, fx_2_blendop_values }, -+ { "PositionDegree", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 76, fx_2_degree_values }, -+ { "NormalDegree", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 77, fx_2_degree_values }, -+ { "ScissorTestEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 78 }, -+ { "SlopeScaleDepthBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 79 }, -+ -+ { "AntialiasedLineEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 80 }, -+ { "MinTessellationLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 81 }, -+ { "MaxTessellationLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 82 }, -+ { "AdaptiveTess_X", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 83 }, -+ { "AdaptiveTess_Y", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 84 }, -+ { "AdaptiveTess_Z", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 85 }, -+ { "AdaptiveTess_W", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 86 }, -+ { "EnableAdaptiveTessellation",HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 }, -+ { "TwoSidedStencilMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 88 }, -+ { "StencilFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 89, fx_2_stencilcaps_values }, -+ { "StencilZFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 90, fx_2_stencilcaps_values }, -+ { "StencilPass", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 91, fx_2_stencilcaps_values }, -+ { "StencilFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 92, fx_2_cmpfunc_values }, -+ -+ { "ColorWriteEnable1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 93, fx_2_colorwriteenable_values }, -+ { "ColorWriteEnable2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 94, fx_2_colorwriteenable_values }, -+ { "ColorWriteEnable3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 95, fx_2_colorwriteenable_values }, -+ { "BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 96 }, -+ { "SRGBWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 97 }, -+ { "DepthBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 98 }, -+ { "SeparateAlphaBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 99 }, -+ { "SrcBlendAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 100, fx_2_blendmode_values }, -+ { "DestBlendAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 101, fx_2_blendmode_values }, -+ { "BlendOpAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 102, fx_2_blendmode_values }, -+ -+ { "ColorOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 103, fx_2_textureop_values }, -+ { "ColorArg0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 104, fx_2_colorarg_values }, -+ { "ColorArg1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 105, fx_2_colorarg_values }, -+ { "ColorArg2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 106, fx_2_colorarg_values }, -+ { "AlphaOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 107, fx_2_textureop_values }, -+ { "AlphaArg0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 108, fx_2_colorarg_values }, -+ { "AlphaArg1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 109, fx_2_colorarg_values }, -+ { "AlphaArg2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 110, fx_2_colorarg_values }, -+ { "ResultArg", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 111, fx_2_colorarg_values }, -+ { "BumpEnvMat00", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 112 }, -+ { "BumpEnvMat01", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 113 }, -+ { "BumpEnvMat10", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 114 }, -+ { "BumpEnvMat11", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 115 }, -+ { "TexCoordIndex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 }, -+ { "BumpEnvLScale", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 117 }, -+ { "BumpEnvLOffset", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 118 }, -+ { "TextureTransformFlags", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 119, fx_2_texturetransform_values }, -+ { "Constant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 120 }, -+ { "PatchSegments", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 }, -+ { "FVF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 122 }, -+ -+ { "ProjectionTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 123 }, -+ { "ViewTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 124 }, -+ { "WorldTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 256, 125 }, -+ { "TextureTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 8, 126 }, -+ -+ { "MaterialDiffuse", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 127 }, -+ { "MaterialAmbient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 128 }, -+ { "MaterialSpecular", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 129 }, -+ { "MaterialEmissive", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 130 }, -+ { "MaterialPower", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 131 }, -+ -+ { "LightType", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 132, fx_2_lighttype_values }, -+ { "LightDiffuse", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 133 }, -+ { "LightSpecular", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 134 }, -+ { "LightAmbient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 135 }, -+ { "LightPosition", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 3, ~0u, 136 }, -+ { "LightDirection", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 3, ~0u, 137 }, -+ { "LightRange", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 138 }, -+ { "LightFalloff", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 139 }, -+ { "LightAttenuation0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 140 }, -+ { "LightAttenuation1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 141 }, -+ { "LightAttenuation2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 142 }, -+ { "LightTheta", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 143 }, -+ { "LightPhi", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 144 }, -+ { "LightEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 145 }, -+ -+ { "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 }, -+ { "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 }, -+ -+ { "VertexShaderConstantF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 148 }, -+ { "VertexShaderConstantB", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u, 149 }, -+ { "VertexShaderConstantI", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 150 }, -+ { "VertexShaderConstant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 151 }, -+ { "VertexShaderConstant1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 152 }, -+ { "VertexShaderConstant2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 153 }, -+ { "VertexShaderConstant3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 154 }, -+ { "VertexShaderConstant4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 155 }, -+ -+ { "PixelShaderConstantF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 156 }, -+ { "PixelShaderConstantB", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u, 157 }, -+ { "PixelShaderConstantI", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 158 }, -+ { "PixelShaderConstant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 159 }, -+ { "PixelShaderConstant1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 160 }, -+ { "PixelShaderConstant2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 161 }, -+ { "PixelShaderConstant3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 162 }, -+ { "PixelShaderConstant4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 163 }, -+ -+ { "Texture", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 261, 164 }, -+ { "AddressU", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 165, fx_2_address_values }, -+ { "AddressV", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 166, fx_2_address_values }, -+ { "AddressW", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 167, fx_2_address_values }, -+ { "BorderColor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 168 }, -+ { "MagFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 169, fx_2_filter_values }, -+ { "MinFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 170, fx_2_filter_values }, -+ { "MipFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 171, fx_2_filter_values }, -+ { "MipMapLodBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 172 }, -+ { "MaxMipLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 173 }, -+ { "MaxAnisotropy", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 174 }, -+ { "SRGBTexture", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 175 }, -+ { "ElementIndex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 176 }, -+}; -+ -+static const struct fx_state fx_2_sampler_states[] = -+{ -+ { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 }, -+ { "AddressU", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values }, -+ { "AddressV", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values }, -+ { "AddressW", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values }, -+ { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 }, -+ { "MagFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values }, -+ { "MinFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values }, -+ { "MipFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values }, -+ { "MipMapLodBias", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 }, -+ { "MaxMipLevel", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 }, -+ { "MaxAnisotropy", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 }, -+ { "SRGBTexture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 }, -+ { "ElementIndex", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 }, - }; - - 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++; - } - --static uint32_t get_fx_4_type_size(const struct hlsl_type *type) --{ -- uint32_t elements_count; -- -- elements_count = hlsl_get_multiarray_size(type); -- type = hlsl_get_multiarray_element_type(type); -- -- return type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float) * elements_count; --} -- - enum fx_4_type_constants - { - /* Numeric types encoding */ -@@ -1015,6 +1053,9 @@ enum fx_4_type_constants - FX_4_NUMERIC_COLUMNS_SHIFT = 11, - FX_4_NUMERIC_COLUMN_MAJOR_MASK = 0x4000, - -+ /* Variable flags */ -+ FX_4_HAS_EXPLICIT_BIND_POINT = 0x4, -+ - /* Object types */ - FX_4_OBJECT_TYPE_STRING = 0x1, - FX_4_OBJECT_TYPE_BLEND_STATE = 0x2, -@@ -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, -- -- /* FXLVM constants */ -- FX_4_FXLC_COMP_COUNT_MASK = 0xffff, -- FX_4_FXLC_OPCODE_MASK = 0x7ff, -- FX_4_FXLC_OPCODE_SHIFT = 20, -- FX_4_FXLC_IS_SCALAR_MASK = 0x80000000, -- -- FX_4_FXLC_REG_LITERAL = 1, -- FX_4_FXLC_REG_CB = 2, -- FX_4_FXLC_REG_OUTPUT = 4, -- FX_4_FXLC_REG_TEMP = 7, - }; - - static const uint32_t fx_4_numeric_base_types[] = -@@ -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); - -- name_offset = write_string(name, fx); -+ name_offset = write_string(name ? name : "", fx); - if (element_type->class == HLSL_CLASS_STRUCT) - { - if (!(field_offsets = hlsl_calloc(ctx, element_type->e.record.field_count, sizeof(*field_offsets)))) -@@ -1541,12 +1571,33 @@ static uint32_t get_fx_2_type_class(const struct hlsl_type *type) - return hlsl_sm1_class(type); - } - --static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, -- const struct hlsl_semantic *semantic, bool is_combined_sampler, struct fx_write_context *fx) -+struct fx_2_write_type_context - { -- struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; -- uint32_t semantic_offset, offset, elements_count = 0, name_offset; -- size_t i; -+ uint32_t *names; -+ uint32_t *semantics; -+ uint32_t count; -+ -+ uint32_t offset; -+ -+ bool is_combined_sampler; -+ struct fx_write_context *fx; -+}; -+ -+static void count_type_iter(const struct hlsl_type *type, const char *name, -+ const struct hlsl_semantic *semantic, void *context) -+{ -+ struct fx_2_write_type_context *ctx = context; -+ -+ ++ctx->count; -+} -+ -+static void write_fx_2_type_iter(const struct hlsl_type *type, const char *name, -+ const struct hlsl_semantic *semantic, void *context) -+{ -+ struct fx_2_write_type_context *ctx = context; -+ struct fx_write_context *fx = ctx->fx; -+ struct vkd3d_bytecode_buffer *buffer; -+ uint32_t offset, elements_count = 0; - - /* Resolve arrays to element type and number of elements. */ - if (type->class == HLSL_CLASS_ARRAY) -@@ -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); - } - -- name_offset = write_string(name, fx); -- semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0; -- -- offset = put_u32(buffer, hlsl_sm1_base_type(type, is_combined_sampler)); -+ buffer = &fx->unstructured; -+ offset = put_u32(buffer, hlsl_sm1_base_type(type, ctx->is_combined_sampler)); - put_u32(buffer, get_fx_2_type_class(type)); -- put_u32(buffer, name_offset); -- put_u32(buffer, semantic_offset); -+ *ctx->names++ = put_u32(buffer, 0); -+ *ctx->semantics++ = put_u32(buffer, 0); - put_u32(buffer, elements_count); - - switch (type->class) -@@ -1586,19 +1635,68 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n - ; - } - -+ /* Save the offset of the top level type. */ -+ if (!ctx->offset) -+ ctx->offset = offset; -+} -+ -+static void write_fx_2_type_strings_iter(const struct hlsl_type *type, const char *name, -+ const struct hlsl_semantic *semantic, void *context) -+{ -+ struct fx_2_write_type_context *ctx = context; -+ struct fx_write_context *fx = ctx->fx; -+ struct vkd3d_bytecode_buffer *buffer; -+ -+ buffer = &fx->unstructured; -+ set_u32(buffer, *ctx->names++, write_string(name, fx)); -+ set_u32(buffer, *ctx->semantics++, semantic->raw_name ? write_string(semantic->raw_name, fx) : 0); -+} -+ -+static void foreach_type(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, -+ void (*iter_func)(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, void *context), -+ void *context) -+{ -+ iter_func(type, name, semantic, context); -+ -+ type = hlsl_get_multiarray_element_type(type); - if (type->class == HLSL_CLASS_STRUCT) - { -- for (i = 0; i < type->e.record.field_count; ++i) -+ for (size_t i = 0; i < type->e.record.field_count; ++i) - { - const struct hlsl_struct_field *field = &type->e.record.fields[i]; -- -- /* Validated in check_invalid_object_fields(). */ -- VKD3D_ASSERT(hlsl_is_numeric_type(field->type)); -- write_fx_2_parameter(field->type, field->name, &field->semantic, false, fx); -+ foreach_type(field->type, field->name, &field->semantic, iter_func, context); - } - } -+} - -- return offset; -+static uint32_t write_fx_2_parameter(const struct hlsl_ir_var *var, struct fx_write_context *fx) -+{ -+ struct fx_2_write_type_context ctx = { .fx = fx, .is_combined_sampler = var->is_combined_sampler }; -+ uint32_t *offsets; -+ -+ /* Parameter type information has to be stored in a contiguous segment, so -+ * that any structure fields come right after each other. To achieve that -+ * the variable length string data is written after the type data. */ -+ -+ /* Calculate the number of string entries needed for this type. */ -+ foreach_type(var->data_type, var->name, &var->semantic, count_type_iter, &ctx); -+ -+ if (!(offsets = calloc(ctx.count, 2 * sizeof(*offsets)))) -+ return 0; -+ -+ /* Writing type information also sets string offsets. */ -+ ctx.names = offsets; -+ ctx.semantics = &offsets[ctx.count]; -+ foreach_type(var->data_type, var->name, &var->semantic, write_fx_2_type_iter, &ctx); -+ -+ /* Now the final pass to write the string data. */ -+ ctx.names = offsets; -+ ctx.semantics = &offsets[ctx.count]; -+ foreach_type(var->data_type, var->name, &var->semantic, write_fx_2_type_strings_iter, &ctx); -+ -+ free(offsets); -+ -+ return ctx.offset; - } - - static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_context *fx) -@@ -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); - } - -+/* Effects represent bool values as 1/0, as opposed to ~0u/0 as used by -+ * Direct3D shader model 4+. */ -+static uint32_t get_fx_default_numeric_value(const struct hlsl_type *type, uint32_t value) -+{ -+ if (type->e.numeric.type == HLSL_TYPE_BOOL) -+ return !!value; -+ return value; -+} -+ - 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 +1763,7 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl - - for (j = 0; j < comp_count; ++j) - { -- put_u32(buffer, value->number.u); -+ put_u32(buffer, get_fx_default_numeric_value(type, value->number.u)); - value++; - } - break; -@@ -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) - { -- write_fx_2_default_value(fields[i].type, value, fx); -- value += hlsl_type_component_count(fields[i].type); -+ write_fx_2_default_value(fields[j].type, value, fx); -+ value += hlsl_type_component_count(fields[j].type); - } - break; - } -@@ -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; - -- desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx); -+ desc_offset = write_fx_2_parameter(var, fx); - value_offset = write_fx_2_initial_value(var, fx); - - flags = 0; -@@ -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; - -- desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx); -+ desc_offset = write_fx_2_parameter(var, fx); - value_offset = write_fx_2_initial_value(var, fx); - - put_u32(buffer, desc_offset); - put_u32(buffer, value_offset); - } - -+static void write_fx_2_state_assignment(const struct hlsl_ir_var *var, -+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx) -+{ -+ struct hlsl_ctx *ctx = fx->ctx; -+ -+ hlsl_fixme(ctx, &var->loc, "Writing fx_2_0 state assignments is not implemented."); -+} -+ - static const struct fx_write_context_ops fx_2_ops = - { - .write_string = write_fx_2_string, - .write_technique = write_fx_2_technique, - .write_pass = write_fx_2_pass, - .write_annotation = write_fx_2_annotation, -+ .write_state_assignment = write_fx_2_state_assignment, - }; - - 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); - } - -+static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, -+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx); -+ - static const struct fx_write_context_ops fx_4_ops = - { - .write_string = write_fx_4_string, - .write_technique = write_fx_4_technique, - .write_pass = write_fx_4_pass, - .write_annotation = write_fx_4_annotation, -+ .write_state_assignment = write_fx_4_state_assignment, - .are_child_effects_supported = true, - }; - -@@ -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) - { -- put_u32_unaligned(buffer, value->number.u); -+ put_u32_unaligned(buffer, get_fx_default_numeric_value(type, value->number.u)); - value++; - } - break; -@@ -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) - { -- write_fx_4_default_value(fields[i].type, value, fx); -- value += hlsl_type_component_count(fields[i].type); -+ write_fx_4_default_value(fields[j].type, value, fx); -+ value += hlsl_type_component_count(fields[j].type); - } - break; - } -@@ -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; -- enum fx_4_numeric_variable_flags -- { -- HAS_EXPLICIT_BIND_POINT = 0x4, -- }; - - if (var->has_explicit_bind_point) -- flags |= HAS_EXPLICIT_BIND_POINT; -+ flags |= FX_4_HAS_EXPLICIT_BIND_POINT; - - type_offset = write_type(var->data_type, fx); - name_offset = write_string(var->name, fx); -@@ -2163,7 +2279,7 @@ static uint32_t write_fx_4_state_numeric_value(struct hlsl_ir_constant *value, s - } - - put_u32_unaligned(buffer, type); -- put_u32_unaligned(buffer, value->value.u[i].u); -+ put_u32_unaligned(buffer, get_fx_default_numeric_value(data_type, value->value.u[i].u)); - } - - return offset; -@@ -2576,18 +2692,7 @@ static const struct rhs_named_value null_values[] = - { NULL } - }; - --static const struct fx_4_state --{ -- const char *name; -- enum hlsl_type_class container; -- enum hlsl_type_class class; -- enum state_property_component_type type; -- unsigned int dimx; -- unsigned int array_size; -- int id; -- const struct rhs_named_value *values; --} --fx_4_states[] = -+static const struct fx_state fx_4_states[] = - { - { "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 +2760,7 @@ fx_4_states[] = - { "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 }, - }; - --static const struct fx_4_state fx_5_blend_states[] = -+static const struct fx_state fx_5_blend_states[] = - { - { "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 +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 }, - }; - --struct fx_4_state_table -+struct fx_state_table - { -- const struct fx_4_state *ptr; -+ const struct fx_state *ptr; - unsigned int count; - }; - --static struct fx_4_state_table fx_4_get_state_table(enum hlsl_type_class type_class, -+static struct fx_state_table fx_get_state_table(enum hlsl_type_class type_class, - unsigned int major, unsigned int minor) - { -- struct fx_4_state_table table; -+ struct fx_state_table table; - -- if (type_class == HLSL_CLASS_BLEND_STATE && (major == 5 || (major == 4 && minor == 1))) -+ if (major == 2) - { -- table.ptr = fx_5_blend_states; -- table.count = ARRAY_SIZE(fx_5_blend_states); -+ if (type_class == HLSL_CLASS_PASS) -+ { -+ table.ptr = fx_2_pass_states; -+ table.count = ARRAY_SIZE(fx_2_pass_states); -+ } -+ else -+ { -+ table.ptr = fx_2_sampler_states; -+ table.count = ARRAY_SIZE(fx_2_sampler_states); -+ } - } - else - { -- table.ptr = fx_4_states; -- table.count = ARRAY_SIZE(fx_4_states); -+ if (type_class == HLSL_CLASS_BLEND_STATE && (major == 5 || (major == 4 && minor == 1))) -+ { -+ table.ptr = fx_5_blend_states; -+ table.count = ARRAY_SIZE(fx_5_blend_states); -+ } -+ else -+ { -+ table.ptr = fx_4_states; -+ table.count = ARRAY_SIZE(fx_4_states); -+ } - } - - return table; - } - --static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, -+static void resolve_fx_state_block_values(struct hlsl_ir_var *var, - struct hlsl_state_block_entry *entry, struct fx_write_context *fx) - { - const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); - struct replace_state_context replace_context; -- const struct fx_4_state *state = NULL; -+ const struct fx_state *state = NULL; - struct hlsl_type *state_type = NULL; - struct hlsl_ctx *ctx = fx->ctx; - enum hlsl_base_type base_type; -- struct fx_4_state_table table; -+ struct fx_state_table table; - struct hlsl_ir_node *node; - unsigned int i; - -- table = fx_4_get_state_table(type->class, ctx->profile->major_version, ctx->profile->minor_version); -+ table = fx_get_state_table(type->class, ctx->profile->major_version, ctx->profile->minor_version); - - for (i = 0; i < table.count; ++i) - { -@@ -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); - } - --static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index, -- uint32_t count_offset, struct fx_write_context *fx) -+static void fx_4_decompose_state_blocks(struct hlsl_ir_var *var, struct fx_write_context *fx) - { -- struct vkd3d_bytecode_buffer *buffer = &fx->structured; -+ unsigned int block_count = hlsl_get_multiarray_size(var->data_type); - struct hlsl_state_block *block; -- uint32_t i, count = 0; - -- if (var->state_blocks) -+ if (!var->state_blocks) -+ return; -+ -+ for (unsigned int i = 0; i < block_count; ++i) - { -- block = var->state_blocks[block_index]; -+ block = var->state_blocks[i]; - -- for (i = 0; i < block->count;) -+ for (unsigned int j = 0; j < block->count;) - { -- i += decompose_fx_4_state_block(var, block, i, fx); -+ j += decompose_fx_4_state_block(var, block, j, fx); - } -+ } -+} -+ -+static uint32_t write_state_block(struct hlsl_ir_var *var, unsigned int block_index, -+ struct fx_write_context *fx) -+{ -+ struct hlsl_state_block *block; -+ uint32_t i, count = 0; -+ -+ if (var->state_blocks) -+ { -+ block = var->state_blocks[block_index]; - - for (i = 0; i < block->count; ++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. */ -- resolve_fx_4_state_block_values(var, entry, fx); -+ resolve_fx_state_block_values(var, entry, fx); - -- write_fx_4_state_assignment(var, entry, fx); -+ write_state_assignment(var, entry, fx); - ++count; - } - } - -- set_u32(buffer, count_offset, count); -+ return count; - } - - static void write_fx_4_state_object_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) - { - uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i; - struct vkd3d_bytecode_buffer *buffer = &fx->structured; -- uint32_t count_offset; -+ uint32_t count_offset, count; -+ -+ fx_4_decompose_state_blocks(var, fx); - - for (i = 0; i < elements_count; ++i) - { - count_offset = put_u32(buffer, 0); -- -- write_fx_4_state_block(var, i, count_offset, fx); -+ count = write_state_block(var, i, fx); -+ set_u32(buffer, count_offset, count); - } - } - -@@ -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) - { -+ uint32_t unpacked_size; -+ - if (!is_numeric_fx_4_type(var->data_type)) - continue; - -@@ -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); -- size += get_fx_4_type_size(var->data_type); -+ -+ unpacked_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float); -+ size = max(size, unpacked_size + var->buffer_offset * 4); - ++count; - } - -@@ -3446,6 +3586,7 @@ int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) - - struct fx_parser - { -+ enum vkd3d_shader_source_type source_type; - const uint8_t *ptr, *start, *end; - struct vkd3d_shader_message_context *message_context; - struct vkd3d_string_buffer buffer; -@@ -3572,20 +3713,43 @@ static void parse_fx_print_indent(struct fx_parser *parser) - vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); - } - --static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset, uint32_t *size) -+static void fx_2_print_string_literal(struct fx_parser *parser, const char *prefix, -+ const char *s, uint32_t max_len, const char *suffix) - { -- const char *ptr; -+ uint32_t len; - -- 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) -+ { -+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to parse a string entry."); -+ return; -+ } - -- 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); -+} -+ -+static void fx_2_parse_string_literal(struct fx_parser *parser, uint32_t offset, -+ bool unstructured, const char *prefix, const char *suffix) -+{ -+ uint32_t max_len; -+ const char *s; -+ -+ if (unstructured) - { -- parser->failed = true; -- return ""; -+ fx_parser_read_unstructured(parser, &max_len, offset, sizeof(max_len)); -+ s = fx_parser_get_unstructured_ptr(parser, offset + 4, max_len); -+ } -+ else -+ { -+ max_len = fx_parser_read_u32(parser); -+ s = fx_parser_get_ptr(parser, max_len); -+ fx_parser_skip(parser, align(max_len, 4)); - } - -- return ptr; -+ fx_2_print_string_literal(parser, prefix, s, max_len, suffix); - } - - static unsigned int fx_get_fx_2_type_size(struct fx_parser *parser, uint32_t *offset) -@@ -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; -- const char *name; -- uint32_t size; - - fx_parser_read_unstructured(parser, &var, offset, sizeof(var)); - - fx_parse_fx_2_type(parser, offset); - -- name = fx_2_get_string(parser, var.name, &size); -- fx_print_string(&parser->buffer, " ", name, size); -+ fx_2_parse_string_literal(parser, var.name, true, " ", ""); - if (var.element_count) - vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count); - } -@@ -3764,7 +3925,8 @@ static bool is_fx_2_sampler(uint32_t type) - || type == D3DXPT_SAMPLERCUBE; - } - --static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry); -+static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container, -+ const struct fx_assignment *entry); - - static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, - uint32_t offset) -@@ -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); -- fx_parse_fx_2_assignment(parser, &entry); -+ fx_parse_fx_2_assignment(parser, HLSL_CLASS_SAMPLER, &entry); - } - parse_fx_end_indent(parser); - parse_fx_print_indent(parser); -@@ -3867,15 +4029,25 @@ static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count) - vkd3d_string_buffer_printf(&parser->buffer, ">"); - } - --static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry) -+static const struct fx_state *fx_2_get_state_by_id(enum hlsl_type_class container, uint32_t id) -+{ -+ struct fx_state_table table = fx_get_state_table(container, 2, 0); -+ -+ /* State identifiers are sequential, no gaps */ -+ if (id >= table.ptr[0].id && id <= table.ptr[table.count - 1].id) -+ return &table.ptr[id - table.ptr[0].id]; -+ -+ return NULL; -+} -+ -+static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container, -+ const struct fx_assignment *entry) - { - const struct rhs_named_value *named_value = NULL; -- const struct fx_2_state *state = NULL; -+ const struct fx_state *state; - -- if (entry->id <= ARRAY_SIZE(fx_2_states)) -+ if ((state = fx_2_get_state_by_id(container, entry->id))) - { -- state = &fx_2_states[entry->id]; -- - vkd3d_string_buffer_printf(&parser->buffer, "%s", state->name); - if (state->array_size > 1) - vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry->lhs_index); -@@ -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, " = "); - -- if (state && state->type == FX_UINT) -+ if (state && state->type == FX_UINT && state->values) - { - const struct rhs_named_value *ptr = state->values; - uint32_t value; -@@ -3910,13 +4082,14 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a - } - else if (state) - { -- if (state->type == FX_UINT || state->type == FX_FLOAT) -+ if (state->type == FX_UINT || state->type == FX_FLOAT || state->type == FX_BOOL) - { -- uint32_t offset = entry->type; -+ uint32_t offset = entry->type, base_type; - unsigned int size; - - size = fx_get_fx_2_type_size(parser, &offset); -- parse_fx_2_numeric_value(parser, entry->value, size, entry->type); -+ fx_parser_read_unstructured(parser, &base_type, entry->type, sizeof(base_type)); -+ parse_fx_2_numeric_value(parser, entry->value, size, base_type); - } - else if (state->type == FX_VERTEXSHADER || state->type == FX_PIXELSHADER) - { -@@ -3951,18 +4124,14 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) - uint32_t annotation_count; - uint32_t assignment_count; - } pass; -- const char *name; -- uint32_t size; - - if (parser->failed) - return; - - fx_parser_read_u32s(parser, &technique, sizeof(technique)); - -- name = fx_2_get_string(parser, technique.name, &size); -- - parse_fx_print_indent(parser); -- fx_print_string(&parser->buffer, "technique ", name, size); -+ fx_2_parse_string_literal(parser, technique.name, true, "technique ", ""); - fx_parse_fx_2_annotations(parser, technique.annotation_count); - - vkd3d_string_buffer_printf(&parser->buffer, "\n"); -@@ -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)); -- name = fx_2_get_string(parser, pass.name, &size); - - parse_fx_print_indent(parser); -- fx_print_string(&parser->buffer, "pass ", name, size); -+ fx_2_parse_string_literal(parser, pass.name, true, "pass ", ""); - fx_parse_fx_2_annotations(parser, pass.annotation_count); - - vkd3d_string_buffer_printf(&parser->buffer, "\n"); -@@ -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)); -- fx_parse_fx_2_assignment(parser, &entry); -+ fx_parse_fx_2_assignment(parser, HLSL_CLASS_PASS, &entry); - } - parse_fx_end_indent(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); -- fx_print_string(&parser->buffer, "\"", (const char *)data, size); -- vkd3d_string_buffer_printf(&parser->buffer, "\""); -+ fx_2_print_string_literal(parser, "\"", (const char *)data, size, "\""); - parse_fx_end_indent(parser); - } - else if (type == D3DXPT_PIXELSHADER || type == D3DXPT_VERTEXSHADER) -@@ -4135,38 +4302,18 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) - fx_parser_skip(parser, align(size, 4)); - } - --static void fx_dump_blob(struct fx_parser *parser, const void *blob, uint32_t size) --{ -- 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) -- { -- parse_fx_print_indent(parser); -- n = min(size - i, 8); -- for (j = 0; j < n; ++j) -- vkd3d_string_buffer_printf(&parser->buffer, "0x%08x,", data[i + j]); -- i += n; -- vkd3d_string_buffer_printf(&parser->buffer, "\n"); -- } --} -- --static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size) -+static void fx_parse_fx_2_array_selector(struct fx_parser *parser) - { -- const uint8_t *end = parser->ptr + size; -- uint32_t name_size, blob_size = 0; -+ uint32_t size, blob_size = 0; - const void *blob = NULL; -- const char *name; -+ const uint8_t *end; - -- name_size = fx_parser_read_u32(parser); -- name = fx_parser_get_ptr(parser, name_size); -- fx_parser_skip(parser, name_size); -+ size = fx_parser_read_u32(parser); -+ end = parser->ptr + size; - -- if (!name || (uint8_t *)name >= end) -- fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, -- "Malformed name entry in the array selector."); -+ fx_2_parse_string_literal(parser, 0, false, "array \"", "\"\n"); - - if (parser->ptr <= end) - { -@@ -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."); - } - -- if (name) -- { -- fx_print_string(&parser->buffer, "array \"", name, name_size); -- vkd3d_string_buffer_printf(&parser->buffer, "\"\n"); -- } - if (blob) - { - parse_fx_print_indent(parser); - 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); - } - - 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; -- const char *data; -+ const uint32_t *data; - uint32_t size; - - fx_parser_read_u32s(parser, &state, sizeof(state)); -@@ -4219,28 +4387,29 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) - state.technique, state.index, state.state); - } - -- size = fx_parser_read_u32(parser); -- - parse_fx_print_indent(parser); - - if (state.assignment_type == FX_2_ASSIGNMENT_PARAMETER) - { -- data = fx_parser_get_ptr(parser, size); -- fx_print_string(&parser->buffer, "parameter \"", data, size); -- vkd3d_string_buffer_printf(&parser->buffer, "\"\n"); -- fx_parser_skip(parser, align(size, 4)); -+ fx_2_parse_string_literal(parser, 0, false, "parameter \"", "\"\n"); - } - else if (state.assignment_type == FX_2_ASSIGNMENT_ARRAY_SELECTOR) - { -- fx_parse_fx_2_array_selector(parser, size); -+ fx_parse_fx_2_array_selector(parser); - } -- else -+ else if (state.assignment_type == FX_2_ASSIGNMENT_CODE_BLOB) - { -- vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size); -+ size = fx_parser_read_u32(parser); - 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_code_blob(parser, data, size); - fx_parser_skip(parser, align(size, 4)); - } -+ else -+ { -+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, -+ "Unknown state assignment type %u.", state.assignment_type); -+ } - } - - static void fx_2_parse(struct fx_parser *parser) -@@ -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); - } -+ if (var.flags & FX_4_HAS_EXPLICIT_BIND_POINT) -+ { -+ vkd3d_string_buffer_printf(&parser->buffer, " : packoffset(c%u.%c)", -+ var.offset / 16, "xyzw"[(var.offset % 16) / 4]); -+ } - fx_parse_fx_4_annotations(parser); - - if (var.value) -@@ -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); -+ if (buffer.bind_point != ~0u) -+ vkd3d_string_buffer_printf(&parser->buffer, " : register(b%u)", buffer.bind_point); - fx_parse_fx_4_annotations(parser); - - vkd3d_string_buffer_printf(&parser->buffer, "\n{\n"); -@@ -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) - { -- const struct fx_4_state *state = b; -+ const struct fx_state *state = b; - int id = *(int *)a; - - return id - state->id; -@@ -4609,7 +4785,7 @@ static const struct - uint32_t opcode; - const char *name; - } --fx_4_fxlc_opcodes[] = -+fxlc_opcodes[] = - { - { 0x100, "mov" }, - { 0x101, "neg" }, -@@ -4634,6 +4810,8 @@ fx_4_fxlc_opcodes[] = - { 0x13a, "ceil" }, - { 0x200, "min" }, - { 0x201, "max" }, -+ { 0x202, "lt" }, -+ { 0x203, "ge" }, - { 0x204, "add" }, - { 0x205, "mul" }, - { 0x206, "atan2" }, -@@ -4659,29 +4837,24 @@ fx_4_fxlc_opcodes[] = - { 0x236, "ushr" }, - { 0x301, "movc" }, - { 0x500, "dot" }, -+ { 0x502, "noise" }, - { 0x70e, "d3ds_dotswiz" }, -+ { 0x711, "d3ds_noiseswiz" }, - }; - --static const char *fx_4_get_fxlc_opcode_name(uint32_t opcode) -+static const char *get_fxlc_opcode_name(uint32_t opcode) - { - size_t i; - -- for (i = 0; i < ARRAY_SIZE(fx_4_fxlc_opcodes); ++i) -+ for (i = 0; i < ARRAY_SIZE(fxlc_opcodes); ++i) - { -- if (fx_4_fxlc_opcodes[i].opcode == opcode) -- return fx_4_fxlc_opcodes[i].name; -+ if (fxlc_opcodes[i].opcode == opcode) -+ return fxlc_opcodes[i].name; - } - - return ""; - } - --struct fx_4_fxlc_argument --{ -- uint32_t flags; -- uint32_t reg_type; -- uint32_t address; --}; -- - struct fx_4_ctab_entry - { - uint32_t name; -@@ -4693,10 +4866,29 @@ struct fx_4_ctab_entry - uint32_t default_value; - }; - -+struct fxlc_arg -+{ -+ uint32_t reg_type; -+ uint32_t address; -+ bool indexed; -+ struct -+ { -+ uint32_t reg_type; -+ uint32_t address; -+ } index; -+}; -+ - struct fxlvm_code - { -- const float *cli4; -- uint32_t cli4_count; -+ const uint32_t *ptr, *end; -+ bool failed; -+ -+ union -+ { -+ const float *_4; -+ const double *_8; -+ } cli; -+ uint32_t cli_count; - - const struct fx_4_ctab_entry *constants; - uint32_t ctab_offset; -@@ -4707,7 +4899,45 @@ struct fxlvm_code - bool scalar; - }; - --static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr) -+static uint32_t fxlvm_read_u32(struct fxlvm_code *code) -+{ -+ if (code->end == code->ptr) -+ { -+ code->failed = true; -+ return 0; -+ } -+ -+ return *code->ptr++; -+} -+ -+static const uint32_t *find_d3dbc_section(const uint32_t *ptr, uint32_t count, uint32_t tag, uint32_t *size) -+{ -+ if (!count) -+ return NULL; -+ -+ /* Skip version tag */ -+ ptr++; -+ count--; -+ -+ while (count > 2 && (*ptr & 0xffff) == 0xfffe) -+ { -+ unsigned int section_size; -+ -+ section_size = (*ptr >> 16); -+ if (!section_size || section_size + 1 > count) -+ break; -+ if (*(ptr + 1) == tag) -+ { -+ *size = section_size; -+ return ptr + 2; -+ } -+ count -= section_size + 1; -+ ptr += section_size + 1; -+ } -+ return NULL; -+} -+ -+static void fx_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr) - { - unsigned int comp_count = code->scalar ? 1 : code->comp_count; - static const char comp[] = "xyzw"; -@@ -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]); - } - --static void fx_4_parse_fxlc_constant_argument(struct fx_parser *parser, -- 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) -+{ -+ static const char *table_names[FX_FXLC_REG_MAX + 1] = -+ { -+ [FX_FXLC_REG_LITERAL] = "imm", -+ [FX_FXLC_REG_CB] = "c", -+ [FX_FXLC_REG_INPUT] = "i", -+ [FX_FXLC_REG_OUTPUT] = "expr", -+ [FX_FXLC_REG_TEMP] = "r", -+ }; -+ uint32_t reg_index = address / 4; -+ -+ if (parser->source_type == VKD3D_SHADER_SOURCE_TX -+ && (reg_type == FX_FXLC_REG_INPUT || reg_type == FX_FXLC_REG_OUTPUT)) -+ { -+ if (reg_type == FX_FXLC_REG_INPUT) -+ { -+ if (reg_index == 0) -+ vkd3d_string_buffer_printf(&parser->buffer, "vPos"); -+ else if (reg_index == 1) -+ vkd3d_string_buffer_printf(&parser->buffer, "vPSize"); -+ } -+ else -+ { -+ vkd3d_string_buffer_printf(&parser->buffer, "oC%u", reg_index); -+ } -+ } -+ else -+ { -+ vkd3d_string_buffer_printf(&parser->buffer, "%s%u", table_names[reg_type], reg_index); -+ } -+ if (index_type != FX_FXLC_REG_UNUSED) -+ { -+ vkd3d_string_buffer_printf(&parser->buffer, "[%s%u.%c]", table_names[index_type], -+ index_address / 4, "xyzw"[index_address % 4]); -+ } -+ 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; -+ 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; -+ /* Register offset within variable */ -+ offset = arg->address - c->register_index * 4; -+ -+ if (offset / 4) -+ vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4); -+ fx_parse_print_swizzle(parser, code, offset); -+ return; -+ } -+ -+ vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)"); -+ } -+ else -+ { -+ vkd3d_string_buffer_printf(&parser->buffer, "c%u", register_index); -+ fx_parse_print_swizzle(parser, code, arg->address); -+ } -+} -+ -+static void fx_parse_fxlc_argument(struct fx_parser *parser, struct fxlc_arg *arg, struct fxlvm_code *code) -+{ -+ uint32_t flags; -+ -+ memset(arg, 0, sizeof(*arg)); -+ -+ flags = fxlvm_read_u32(code); -+ if (flags) -+ { -+ arg->indexed = true; -+ arg->index.reg_type = fxlvm_read_u32(code); -+ arg->index.address = fxlvm_read_u32(code); - } -+ arg->reg_type = fxlvm_read_u32(code); -+ arg->address = fxlvm_read_u32(code); -+} - -- vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)"); -+static void fx_print_fxlc_literal(struct fx_parser *parser, uint32_t address, struct fxlvm_code *code) -+{ -+ if (parser->version.major >= 4) -+ vkd3d_string_buffer_print_f32(&parser->buffer, code->cli._4[address]); -+ else -+ vkd3d_string_buffer_print_f64(&parser->buffer, code->cli._8[address]); - } - --static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, const struct fxlvm_code *code) -+static void fx_print_fxlc_argument(struct fx_parser *parser, const struct fxlc_arg *arg, struct fxlvm_code *code) - { -- struct fx_4_fxlc_argument arg; - uint32_t count; - -- fx_parser_read_unstructured(parser, &arg, offset, sizeof(arg)); -+ if (arg->reg_type > FX_FXLC_REG_MAX) -+ { -+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, -+ "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; -+ } -+ -+ if (arg->indexed) -+ { -+ fx_print_fxlc_register(parser, arg->reg_type, arg->address, arg->index.reg_type, -+ arg->index.address, code); -+ return; -+ } -+ -+ switch (arg->reg_type) -+ { -+ case FX_FXLC_REG_LITERAL: - count = code->scalar ? 1 : code->comp_count; -- if (arg.address >= code->cli4_count || count > code->cli4_count - arg.address) -+ if (arg->address >= code->cli_count || count > code->cli_count - arg->address) - { - vkd3d_string_buffer_printf(&parser->buffer, "()"); - parser->failed = true; -@@ -4761,42 +5084,131 @@ static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, - } - - vkd3d_string_buffer_printf(&parser->buffer, "("); -- vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address]); -+ fx_print_fxlc_literal(parser, arg->address, code); - for (unsigned int i = 1; i < code->comp_count; ++i) - { - vkd3d_string_buffer_printf(&parser->buffer, ", "); -- vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address + (code->scalar ? 0 : i)]); -+ fx_print_fxlc_literal(parser, arg->address + (code->scalar ? 0 : i), code); - } - vkd3d_string_buffer_printf(&parser->buffer, ")"); - break; - -- case FX_4_FXLC_REG_CB: -- fx_4_parse_fxlc_constant_argument(parser, &arg, code); -+ case FX_FXLC_REG_CB: -+ fx_parse_fxlc_constant_argument(parser, arg, code); - break; - -- case FX_4_FXLC_REG_OUTPUT: -- case FX_4_FXLC_REG_TEMP: -- if (arg.reg_type == FX_4_FXLC_REG_OUTPUT) -- vkd3d_string_buffer_printf(&parser->buffer, "expr"); -- else -- vkd3d_string_buffer_printf(&parser->buffer, "r%u", arg.address / 4); -- fx_4_parse_print_swizzle(parser, code, arg.address); -+ case FX_FXLC_REG_INPUT: -+ case FX_FXLC_REG_OUTPUT: -+ case FX_FXLC_REG_TEMP: -+ fx_print_fxlc_register(parser, arg->reg_type, arg->address, FX_FXLC_REG_UNUSED, 0, code); - break; - - default: -- vkd3d_string_buffer_printf(&parser->buffer, "", arg.reg_type); -+ vkd3d_string_buffer_printf(&parser->buffer, "", arg->reg_type); - break; - } - } - -+static void fx_parse_fxlvm_expression(struct fx_parser *parser, struct fxlvm_code *code) -+{ -+ struct fxlc_arg args[9]; -+ uint32_t ins_count; -+ size_t i, j; -+ -+ parse_fx_start_indent(parser); -+ if (parser->source_type == VKD3D_SHADER_SOURCE_TX) -+ { -+ parse_fx_print_indent(parser); -+ vkd3d_string_buffer_printf(&parser->buffer, "tx_1_0\n"); -+ } -+ -+ ins_count = fxlvm_read_u32(code); -+ -+ for (i = 0; i < ins_count; ++i) -+ { -+ uint32_t instr, opcode, src_count; -+ -+ instr = fxlvm_read_u32(code); -+ src_count = fxlvm_read_u32(code); -+ -+ if (src_count >= ARRAY_SIZE(args)) -+ { -+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, -+ "Unexpected instruction source count %u.", src_count); -+ break; -+ } -+ -+ /* Sources entries are followed by the destination, first read them all. -+ Output format is "opcode dst, src[0]...src[n]". */ -+ for (j = 0; j < src_count; ++j) -+ fx_parse_fxlc_argument(parser, &args[j], code); -+ fx_parse_fxlc_argument(parser, &args[src_count], code); -+ -+ opcode = (instr >> FX_FXLC_OPCODE_SHIFT) & FX_FXLC_OPCODE_MASK; -+ code->comp_count = instr & FX_FXLC_COMP_COUNT_MASK; -+ -+ parse_fx_print_indent(parser); -+ vkd3d_string_buffer_printf(&parser->buffer, "%s ", get_fxlc_opcode_name(opcode)); -+ -+ code->scalar = false; -+ fx_print_fxlc_argument(parser, &args[src_count], code); -+ vkd3d_string_buffer_printf(&parser->buffer, ", "); -+ -+ for (j = 0; j < src_count; ++j) -+ { -+ /* Scalar modifier applies only to the first source. */ -+ code->scalar = j == 0 && !!(instr & FX_FXLC_IS_SCALAR_MASK); -+ fx_print_fxlc_argument(parser, &args[j], code); -+ if (j < src_count - 1) -+ vkd3d_string_buffer_printf(&parser->buffer, ", "); -+ } -+ -+ vkd3d_string_buffer_printf(&parser->buffer, "\n"); -+ } -+ -+ parse_fx_end_indent(parser); -+} -+ -+static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size) -+{ -+ uint32_t count = size / sizeof(uint32_t); -+ struct fxlvm_code code = { 0 }; -+ uint32_t section_size; -+ const uint32_t *data; -+ -+ if (!blob) -+ return; -+ -+ /* Literal constants, using 64-bit floats. */ -+ if ((data = find_d3dbc_section(blob, count, TAG_CLIT, §ion_size))) -+ { -+ code.cli_count = *data++; -+ code.cli._8 = (const double *)data; -+ } -+ -+ /* CTAB does not contain variable names */ -+ -+ /* Code blob */ -+ 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; - struct vkd3d_shader_dxbc_desc dxbc_desc; -+ struct fxlvm_code code = { 0 }; - struct vkd3d_shader_code dxbc; -- uint32_t size, ins_count; -- struct fxlvm_code code; -- size_t i, j; -+ uint32_t size; -+ size_t i; - - offset = fx_parser_read_unstructured(parser, &size, offset, sizeof(size)); - -@@ -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; - -- fx_parser_read_unstructured(parser, &code.cli4_count, cli4_offset, sizeof(code.cli4_count)); -- code.cli4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli4_count * sizeof(float)); -+ fx_parser_read_unstructured(parser, &code.cli_count, cli4_offset, sizeof(code.cli_count)); -+ code.cli._4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli_count * sizeof(float)); - } - - if (ctab.data.code) -@@ -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)); - } - -- offset += (size_t)fxlc.data.code - (size_t)dxbc.code; -- 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; -- struct fx_4_fxlc_argument arg; -- -- offset = fx_parser_read_unstructured(parser, &instr, offset, sizeof(instr)); -- offset = fx_parser_read_unstructured(parser, &src_count, offset, sizeof(src_count)); -- -- opcode = (instr >> FX_4_FXLC_OPCODE_SHIFT) & FX_4_FXLC_OPCODE_MASK; -- code.comp_count = instr & FX_4_FXLC_COMP_COUNT_MASK; -- code.scalar = false; -- -- parse_fx_print_indent(parser); -- vkd3d_string_buffer_printf(&parser->buffer, "%s ", fx_4_get_fxlc_opcode_name(opcode)); -- -- /* Destination first. */ -- fx_4_parse_fxlc_argument(parser, offset + sizeof(arg) * src_count, &code); -- -- for (j = 0; j < src_count; ++j) -- { -- vkd3d_string_buffer_printf(&parser->buffer, ", "); -- -- /* Scalar modifier applies only to first source. */ -- code.scalar = j == 0 && !!(instr & FX_4_FXLC_IS_SCALAR_MASK); -- fx_4_parse_fxlc_argument(parser, offset, &code); -- -- offset += sizeof(arg); -- } -- -- /* Destination */ -- offset += sizeof(arg); -- -- vkd3d_string_buffer_printf(&parser->buffer, "\n"); -- } -- -- 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 +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 }; -- struct fx_4_state_table table; -+ struct fx_state_table table; - unsigned int shader_type = 0; - uint32_t i, j, comp_count; -- struct fx_4_state *state; -+ struct fx_state *state; - -- table = fx_4_get_state_table(type_class, parser->version.major, parser->version.minor); -+ table = fx_get_state_table(type_class, parser->version.major, parser->version.minor); - - for (i = 0; i < count; ++i) - { -@@ -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); -+ else if (state->type == FX_BOOL) -+ vkd3d_string_buffer_printf(&parser->buffer, "%s", value.u ? "true" : "false"); - else if (state->type == FX_FLOAT) - vkd3d_string_buffer_printf(&parser->buffer, "%g", value.f); - -@@ -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)); -+ parser->source_type = compile_info->source_type; - 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 +5812,38 @@ int fx_parse(const struct vkd3d_shader_compile_info *compile_info, - return VKD3D_ERROR_INVALID_SHADER; - return VKD3D_OK; - } -+ -+int tx_parse(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) -+{ -+ struct fx_parser parser; -+ uint32_t version; -+ -+ fx_parser_init(&parser, compile_info, message_context); -+ -+ if (parser.end - parser.start < sizeof(version)) -+ { -+ fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_SIZE, -+ "Source size %zu is smaller than the TX header size.", compile_info->source.size); -+ return VKD3D_ERROR_INVALID_SHADER; -+ } -+ version = *(uint32_t *)parser.ptr; -+ -+ switch (version) -+ { -+ case 0x54580100: -+ fx_2_parse_fxlvm_expression(&parser, (const uint32_t *)parser.ptr, parser.end - parser.ptr); -+ break; -+ default: -+ fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_VERSION, -+ "Invalid texture shader binary version value 0x%08x.", version); -+ break; -+ } -+ -+ vkd3d_shader_code_from_string_buffer(out, &parser.buffer); -+ fx_parser_cleanup(&parser); -+ -+ if (parser.failed) -+ return VKD3D_ERROR_INVALID_SHADER; -+ return VKD3D_OK; -+} -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -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); - break; -+ case VKD3DSPSM_ABSNEG: -+ vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); -+ break; - default: - vkd3d_string_buffer_printf(buffer, "(%s)", - vsir_src->modifiers, str->buffer); -@@ -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; - -+ /* It is always legitimate to ignore _pp. */ -+ modifiers &= ~VKD3DSPDM_PARTIALPRECISION; -+ - 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) - { -+ const char *name = vsir_opcode_get_name(ins->opcode, ""); -+ - shader_glsl_print_indent(gen->buffer, gen->indent); -- vkd3d_string_buffer_printf(gen->buffer, "/* */\n", ins->opcode); -+ vkd3d_string_buffer_printf(gen->buffer, "/* */\n", name, ins->opcode); - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled instruction %#x.", ins->opcode); -+ "Internal compiler error: Unhandled instruction \"%s\" (%#x).", name, ins->opcode); - } - - static void shader_glsl_binop(struct vkd3d_glsl_generator *gen, -@@ -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) - { - vkd3d_string_buffer_printf(fetch, ", "); -- if (ins->opcode != VKD3DSIH_LD2DMS) -+ if (ins->opcode != VSIR_OP_LD2DMS) - 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 -@@ -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; -- dynamic_offset = ins->opcode == VKD3DSIH_GATHER4_PO; -- gather = ins->opcode == VKD3DSIH_GATHER4 || ins->opcode == VKD3DSIH_GATHER4_PO; -- grad = ins->opcode == VKD3DSIH_SAMPLE_GRAD; -- lod = ins->opcode == VKD3DSIH_SAMPLE_LOD || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; -- lod_zero = ins->opcode == VKD3DSIH_SAMPLE_C_LZ; -+ bias = ins->opcode == VSIR_OP_SAMPLE_B; -+ dynamic_offset = ins->opcode == VSIR_OP_GATHER4_PO; -+ gather = ins->opcode == VSIR_OP_GATHER4 || ins->opcode == VSIR_OP_GATHER4_PO; -+ grad = ins->opcode == VSIR_OP_SAMPLE_GRAD; -+ lod = ins->opcode == VSIR_OP_SAMPLE_LOD || ins->opcode == VSIR_OP_SAMPLE_C_LZ; -+ lod_zero = ins->opcode == VSIR_OP_SAMPLE_C_LZ; - offset = dynamic_offset || vkd3d_shader_instruction_has_texel_offset(ins); -- shadow = ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; -+ shadow = ins->opcode == VSIR_OP_SAMPLE_C || ins->opcode == VSIR_OP_SAMPLE_C_LZ; - - 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); - } - --static void shader_glsl_mul_extended(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) --{ -- struct glsl_src src[2]; -- struct glsl_dst dst; -- uint32_t mask; -- -- if (ins->dst[0].reg.type != VKD3DSPR_NULL) -- { -- /* FIXME: imulExtended()/umulExtended() from ARB_gpu_shader5/GLSL 4.00+. */ -- mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); -- shader_glsl_print_assignment(gen, &dst, ""); -- glsl_dst_cleanup(&dst, &gen->string_buffers); -- -- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled 64-bit integer multiplication."); -- } -- -- if (ins->dst[1].reg.type != VKD3DSPR_NULL) -- { -- mask = glsl_dst_init(&dst, gen, ins, &ins->dst[1]); -- glsl_src_init(&src[0], gen, &ins->src[0], mask); -- glsl_src_init(&src[1], gen, &ins->src[1], mask); -- -- shader_glsl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer); -- -- glsl_src_cleanup(&src[1], &gen->string_buffers); -- glsl_src_cleanup(&src[0], &gen->string_buffers); -- glsl_dst_cleanup(&dst, &gen->string_buffers); -- } --} -- - static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, - enum vkd3d_shader_sysval_semantic sysval, unsigned int idx) - { -@@ -1482,177 +1459,177 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - - switch (ins->opcode) - { -- case VKD3DSIH_ADD: -- case VKD3DSIH_IADD: -+ case VSIR_OP_ADD: -+ case VSIR_OP_IADD: - shader_glsl_binop(gen, ins, "+"); - break; -- case VKD3DSIH_AND: -+ case VSIR_OP_AND: - shader_glsl_binop(gen, ins, "&"); - break; -- case VKD3DSIH_BREAK: -+ case VSIR_OP_BREAK: - shader_glsl_break(gen); - break; -- case VKD3DSIH_CASE: -+ case VSIR_OP_CASE: - shader_glsl_case(gen, ins); - break; -- case VKD3DSIH_CONTINUE: -+ case VSIR_OP_CONTINUE: - shader_glsl_continue(gen); - break; -- case VKD3DSIH_DCL_INDEXABLE_TEMP: -+ case VSIR_OP_DCL_INDEXABLE_TEMP: - shader_glsl_dcl_indexable_temp(gen, ins); - break; -- case VKD3DSIH_NOP: -+ case VSIR_OP_NOP: - break; -- case VKD3DSIH_DEFAULT: -+ case VSIR_OP_DEFAULT: - shader_glsl_default(gen); - break; -- case VKD3DSIH_DIV: -+ case VSIR_OP_DIV: - shader_glsl_binop(gen, ins, "/"); - break; -- case VKD3DSIH_DP2: -+ case VSIR_OP_DP2: - shader_glsl_dot(gen, ins, vkd3d_write_mask_from_component_count(2)); - break; -- case VKD3DSIH_DP3: -+ case VSIR_OP_DP3: - shader_glsl_dot(gen, ins, vkd3d_write_mask_from_component_count(3)); - break; -- case VKD3DSIH_DP4: -+ case VSIR_OP_DP4: - shader_glsl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); - break; -- case VKD3DSIH_ELSE: -+ case VSIR_OP_ELSE: - shader_glsl_else(gen, ins); - break; -- case VKD3DSIH_ENDIF: -- case VKD3DSIH_ENDLOOP: -- case VKD3DSIH_ENDSWITCH: -+ case VSIR_OP_ENDIF: -+ case VSIR_OP_ENDLOOP: -+ case VSIR_OP_ENDSWITCH: - shader_glsl_end_block(gen); - break; -- case VKD3DSIH_EQO: -- case VKD3DSIH_IEQ: -+ case VSIR_OP_EQO: -+ case VSIR_OP_IEQ: - shader_glsl_relop(gen, ins, "==", "equal"); - break; -- case VKD3DSIH_EXP: -+ case VSIR_OP_EXP: - shader_glsl_intrinsic(gen, ins, "exp2"); - break; -- case VKD3DSIH_FRC: -+ case VSIR_OP_FRC: - shader_glsl_intrinsic(gen, ins, "fract"); - break; -- case VKD3DSIH_FTOI: -+ case VSIR_OP_FTOI: - shader_glsl_cast(gen, ins, "int", "ivec"); - break; -- case VKD3DSIH_FTOU: -+ case VSIR_OP_FTOU: - shader_glsl_cast(gen, ins, "uint", "uvec"); - break; -- case VKD3DSIH_GATHER4: -- case VKD3DSIH_GATHER4_PO: -- case VKD3DSIH_SAMPLE: -- case VKD3DSIH_SAMPLE_B: -- case VKD3DSIH_SAMPLE_C: -- case VKD3DSIH_SAMPLE_C_LZ: -- case VKD3DSIH_SAMPLE_GRAD: -- case VKD3DSIH_SAMPLE_LOD: -+ case VSIR_OP_GATHER4: -+ case VSIR_OP_GATHER4_PO: -+ case VSIR_OP_SAMPLE: -+ case VSIR_OP_SAMPLE_B: -+ case VSIR_OP_SAMPLE_C: -+ case VSIR_OP_SAMPLE_C_LZ: -+ case VSIR_OP_SAMPLE_GRAD: -+ case VSIR_OP_SAMPLE_LOD: - shader_glsl_sample(gen, ins); - break; -- case VKD3DSIH_GEO: -- case VKD3DSIH_IGE: -+ case VSIR_OP_GEO: -+ case VSIR_OP_IGE: - shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); - break; -- case VKD3DSIH_IF: -+ case VSIR_OP_IF: - shader_glsl_if(gen, ins); - break; -- case VKD3DSIH_MAD: -+ case VSIR_OP_MAD: - shader_glsl_intrinsic(gen, ins, "fma"); - break; -- case VKD3DSIH_ILT: -- case VKD3DSIH_LTO: -- case VKD3DSIH_ULT: -+ case VSIR_OP_ILT: -+ case VSIR_OP_LTO: -+ case VSIR_OP_ULT: - shader_glsl_relop(gen, ins, "<", "lessThan"); - break; -- case VKD3DSIH_IMAX: -- case VKD3DSIH_MAX: -- case VKD3DSIH_UMAX: -+ case VSIR_OP_IMAX: -+ case VSIR_OP_MAX: -+ case VSIR_OP_UMAX: - shader_glsl_intrinsic(gen, ins, "max"); - break; -- case VKD3DSIH_MIN: -- case VKD3DSIH_UMIN: -+ case VSIR_OP_MIN: -+ case VSIR_OP_UMIN: - shader_glsl_intrinsic(gen, ins, "min"); - break; -- case VKD3DSIH_IMUL: -- shader_glsl_mul_extended(gen, ins); -+ case VSIR_OP_IMUL_LOW: -+ shader_glsl_binop(gen, ins, "*"); - break; -- case VKD3DSIH_INE: -- case VKD3DSIH_NEU: -+ case VSIR_OP_INE: -+ case VSIR_OP_NEU: - shader_glsl_relop(gen, ins, "!=", "notEqual"); - break; -- case VKD3DSIH_INEG: -+ case VSIR_OP_INEG: - shader_glsl_unary_op(gen, ins, "-"); - break; -- case VKD3DSIH_ISHL: -+ case VSIR_OP_ISHL: - shader_glsl_binop(gen, ins, "<<"); - break; -- case VKD3DSIH_ISHR: -- case VKD3DSIH_USHR: -+ case VSIR_OP_ISHR: -+ case VSIR_OP_USHR: - shader_glsl_binop(gen, ins, ">>"); - break; -- case VKD3DSIH_ITOF: -- case VKD3DSIH_UTOF: -+ case VSIR_OP_ITOF: -+ case VSIR_OP_UTOF: - shader_glsl_cast(gen, ins, "float", "vec"); - break; -- case VKD3DSIH_LD: -- case VKD3DSIH_LD2DMS: -+ case VSIR_OP_LD: -+ case VSIR_OP_LD2DMS: - shader_glsl_ld(gen, ins); - break; -- case VKD3DSIH_LD_UAV_TYPED: -+ case VSIR_OP_LD_UAV_TYPED: - shader_glsl_load_uav_typed(gen, ins); - break; -- case VKD3DSIH_LOG: -+ case VSIR_OP_LOG: - shader_glsl_intrinsic(gen, ins, "log2"); - break; -- case VKD3DSIH_LOOP: -+ case VSIR_OP_LOOP: - shader_glsl_loop(gen); - break; -- case VKD3DSIH_MOV: -+ case VSIR_OP_MOV: - shader_glsl_mov(gen, ins); - break; -- case VKD3DSIH_MOVC: -+ case VSIR_OP_MOVC: - shader_glsl_movc(gen, ins); - break; -- case VKD3DSIH_MUL: -+ case VSIR_OP_MUL: - shader_glsl_binop(gen, ins, "*"); - break; -- case VKD3DSIH_NOT: -+ case VSIR_OP_NOT: - shader_glsl_unary_op(gen, ins, "~"); - break; -- case VKD3DSIH_OR: -+ case VSIR_OP_OR: - shader_glsl_binop(gen, ins, "|"); - break; -- case VKD3DSIH_RET: -+ case VSIR_OP_RET: - shader_glsl_ret(gen, ins); - break; -- case VKD3DSIH_ROUND_NE: -+ case VSIR_OP_ROUND_NE: - shader_glsl_intrinsic(gen, ins, "roundEven"); - break; -- case VKD3DSIH_ROUND_NI: -+ case VSIR_OP_ROUND_NI: - shader_glsl_intrinsic(gen, ins, "floor"); - break; -- case VKD3DSIH_ROUND_PI: -+ case VSIR_OP_ROUND_PI: - shader_glsl_intrinsic(gen, ins, "ceil"); - break; -- case VKD3DSIH_ROUND_Z: -+ case VSIR_OP_ROUND_Z: - shader_glsl_intrinsic(gen, ins, "trunc"); - break; -- case VKD3DSIH_RSQ: -+ case VSIR_OP_RSQ: - shader_glsl_intrinsic(gen, ins, "inversesqrt"); - break; -- case VKD3DSIH_SQRT: -+ case VSIR_OP_SQRT: - shader_glsl_intrinsic(gen, ins, "sqrt"); - break; -- case VKD3DSIH_STORE_UAV_TYPED: -+ case VSIR_OP_STORE_UAV_TYPED: - shader_glsl_store_uav_typed(gen, ins); - break; -- case VKD3DSIH_SWITCH: -+ case VSIR_OP_SWITCH: - shader_glsl_switch(gen, ins); - break; -- case VKD3DSIH_XOR: -+ case VSIR_OP_XOR: - 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; - } - -- if (flags) -+ if (flags & ~VKD3DSGF_REFACTORING_ALLOWED) - 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..62335086e20 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) -@@ -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) - { -- static const char components[] = {'x', 'y', 'z', 'w'}; -- char string[5]; -- unsigned int i = 0, pos = 0; -- -- VKD3D_ASSERT(!(writemask & ~VKD3DSP_WRITEMASK_ALL)); -- -- while (writemask) -- { -- if (writemask & 1) -- string[pos++] = components[i]; -- writemask >>= 1; -- i++; -- } -- string[pos] = '\0'; -- return vkd3d_dbg_sprintf(".%s", string); -+ return debug_vsir_writemask(writemask); - } - - const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size) -@@ -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] = "-", -+ [HLSL_OP1_NOISE] = "noise", - [HLSL_OP1_RCP] = "rcp", - [HLSL_OP1_REINTERPRET] = "reinterpret", - [HLSL_OP1_ROUND] = "round", -@@ -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)); - } - --static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store) -+static void dump_ir_store(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store) - { - vkd3d_string_buffer_printf(buffer, "= ("); - dump_deref(buffer, &store->lhs); -- if (store->writemask != VKD3DSP_WRITEMASK_ALL) -+ if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->lhs))) - vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask)); - vkd3d_string_buffer_printf(buffer, " "); - dump_src(buffer, &store->rhs); -@@ -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: -- dump_ir_store(buffer, hlsl_ir_store(instr)); -+ dump_ir_store(ctx, buffer, hlsl_ir_store(instr)); - break; - - case HLSL_IR_SWITCH: -@@ -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; - -- if (hlsl_is_numeric_type(old_type)) -+ if (old_type && hlsl_is_numeric_type(old_type)) - { - 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..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 - - static inline void hlsl_swizzle_set_component(uint32_t *swizzle, unsigned int idx, unsigned int component) - { -- *swizzle &= ~(VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(idx)); -- *swizzle |= component << VKD3D_SHADER_SWIZZLE_SHIFT(idx); -+ vsir_swizzle_set_component(swizzle, idx, component); - } - - enum hlsl_type_class -@@ -126,7 +125,7 @@ enum hlsl_sampler_dim - HLSL_SAMPLER_DIM_STRUCTURED_BUFFER, - HLSL_SAMPLER_DIM_RAW_BUFFER, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_RAW_BUFFER, -- /* NOTE: Remember to update object_methods[] in hlsl.y if this enum is modified. */ -+ /* NOTE: Remember to update texture_methods[] and uav_methods[] in hlsl.y if this is modified. */ - }; - - enum hlsl_so_object_type -@@ -245,6 +244,7 @@ struct hlsl_semantic - { - const char *name; - uint32_t index; -+ uint32_t stream_index; - - /* Name exactly as it appears in the sources. */ - const char *raw_name; -@@ -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; -+ /* Currently only used for numeric registers. */ -+ enum vkd3d_shader_register_type type; - }; - - /* Types of instruction nodes for the IR. -@@ -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, -+ HLSL_OP1_NOISE, - HLSL_OP1_NEG, - HLSL_OP1_RCP, - HLSL_OP1_REINTERPRET, -@@ -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; -+ /* Number of allocated SSA IDs, used in translation to vsir. */ -+ unsigned int ssa_count; - - /* 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..024d96c5663 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) -@@ -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); - -+ if ((modifiers & HLSL_STORAGE_GROUPSHARED) && ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE) -+ { -+ modifiers &= ~HLSL_STORAGE_GROUPSHARED; -+ hlsl_warning(ctx, &var->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER, -+ "Ignoring the 'groupshared' modifier in a non-compute shader."); -+ } -+ - /* 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) -@@ -4291,6 +4299,28 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, - return true; - } - -+static bool intrinsic_noise(struct hlsl_ctx *ctx, -+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_type *type = params->args[0]->data_type, *ret_type; -+ struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; -+ -+ type = params->args[0]->data_type; -+ if (type->class == HLSL_CLASS_MATRIX) -+ { -+ struct vkd3d_string_buffer *string; -+ if ((string = hlsl_type_to_string(ctx, type))) -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Wrong argument type for noise(): expected vector or scalar, but got '%s'.", string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ } -+ -+ args[0] = intrinsic_float_convert_arg(ctx, params, params->args[0], loc); -+ ret_type = hlsl_get_scalar_type(ctx, args[0]->data_type->e.numeric.type); -+ -+ return !!add_expr(ctx, params->instrs, HLSL_OP1_NOISE, args, ret_type, loc); -+} -+ - static bool intrinsic_normalize(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -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) - { -- if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE || hlsl_version_lt(ctx, 5, 0)) -+ if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, -- "Group barriers can only be used in compute shaders 5.0 or higher."); -+ "Group barriers can only be used in compute shaders."); - } - } - -@@ -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) -- || hlsl_version_lt(ctx, 5, 0)) -+ || hlsl_version_lt(ctx, 4, 0)) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, -- "DeviceMemoryBarrier() can only be used in pixel and compute shaders 5.0 or higher."); -+ "DeviceMemoryBarrier() can only be used in compute and pixel shaders 4.0 or higher."); - } - return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV, loc); - } -@@ -5255,6 +5297,7 @@ intrinsic_functions[] = - {"min", 2, true, intrinsic_min}, - {"modf", 2, true, intrinsic_modf}, - {"mul", 2, true, intrinsic_mul}, -+ {"noise", 1, true, intrinsic_noise}, - {"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..0b3dee4d2ce 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) -@@ -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) -+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; - 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"; - -- if (!(new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", prefix, semantic->name, index))) -+ if (stream_index) -+ new_name = hlsl_sprintf_alloc(ctx, "<%s-m%u:%s%u>", prefix, stream_index, semantic->name, index); -+ else -+ new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", prefix, semantic->name, index); -+ -+ 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)) - { -@@ -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; -+ new_semantic.stream_index = stream_index; - if (!(ext_var = hlsl_new_var(ctx, new_name, type, loc, &new_semantic, modifiers, NULL))) - { - vkd3d_free(new_name); -@@ -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, -- modifiers, semantic, semantic_index + i, 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); - - 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, -- modifiers, semantic, semantic_index + i, 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))) - 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_semantic *semantic, uint32_t semantic_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; -@@ -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, -- modifiers, semantic, semantic_index + i, 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) - { -@@ -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, -- struct hlsl_semantic *semantic, uint32_t semantic_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; -@@ -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); - - 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); -+ 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, 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; - - /* 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); -+ 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 *), -@@ -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; -- 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) - { - 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; -+ uint32_t stream_index; - - if (instr->type != HLSL_IR_RESOURCE_STORE) - return false; -@@ -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); -+ stream_index = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; - -- if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) -- { -- hlsl_fixme(ctx, &instr->loc, "Append to an output stream with a nonzero stream index."); -- return false; -- } -+ VKD3D_ASSERT(stream_index < ARRAY_SIZE(append_ctx->created)); - - hlsl_block_init(&block); - -- 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; -+ 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); - - 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, -- "Texel offsets are not supported on profiles lower than 4.0.\n"); -+ "Texel offsets are not supported on profiles lower than 4.0."); - return false; - } - -@@ -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)); - -+ ret.type = VKD3DSPR_TEMP; - ret.id = reg_idx; - ret.writemask = hlsl_combine_writemasks(writemask, - vkd3d_write_mask_from_component_count(component_count)); -@@ -5658,6 +6031,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a - } - } - -+ ret.type = VKD3DSPR_TEMP; - ret.id = allocator->reg_count; - ret.writemask = vkd3d_write_mask_from_component_count(component_count); - record_allocation(ctx, allocator, allocator->reg_count, -@@ -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); - -+ ret.type = VKD3DSPR_TEMP; - ret.id = reg_idx; - ret.allocation_size = 1; - ret.writemask = writemask; -@@ -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); - -+ ret.type = VKD3DSPR_TEMP; - ret.id = reg_idx; - ret.allocation_size = align(reg_size, 4) / 4; - ret.allocated = true; -@@ -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); - } - --static const char *debug_register(char class, struct hlsl_reg reg, const struct hlsl_type *type) -+static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type) - { - static const char writemask_offset[] = {'w','x','y','z'}; - unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; -+ const char *class = "r"; - -- if (reg_size > 4) -+ if (reg.type == VKD3DSPR_CONST) -+ class = "c"; -+ else if (reg.type == VKD3DSPR_INPUT) -+ class = "v"; -+ else if (reg.type == VKD3DSPR_OUTPUT) -+ class = "o"; -+ else if (reg.type == VKD3DSPR_SSA) -+ class = "sr"; -+ -+ if (reg_size > 4 && !hlsl_type_is_patch_array(type)) - { - if (reg_size & 3) -- return vkd3d_dbg_sprintf("%c%u-%c%u.%c", class, reg.id, class, reg.id + (reg_size / 4), -+ return vkd3d_dbg_sprintf("%s%u-%s%u.%c", class, reg.id, class, reg.id + (reg_size / 4), - writemask_offset[reg_size & 3]); - -- return vkd3d_dbg_sprintf("%c%u-%c%u", class, reg.id, class, reg.id + (reg_size / 4) - 1); -+ return vkd3d_dbg_sprintf("%s%u-%s%u", class, reg.id, class, reg.id + (reg_size / 4) - 1); - } -- return vkd3d_dbg_sprintf("%c%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); -+ return vkd3d_dbg_sprintf("%s%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); - } - - static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -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; -+ bool is_per_component = false; - - if (instr->reg.allocated || !instr->last_read) - return; - -- if (instr->type == HLSL_IR_EXPR) -+ if (instr->type == HLSL_IR_EXPR && ctx->profile->major_version < 4) - { - switch (hlsl_ir_expr(instr)->op) - { -@@ -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; - -+ case HLSL_OP1_EXP2: -+ case HLSL_OP1_LOG2: -+ case HLSL_OP1_RCP: -+ case HLSL_OP1_RSQ: -+ /* These ops can only be written one component at a time in sm1, -+ * so it'll take more than one instruction to fill the variable -+ * and thus we can't use an SSA. -+ * FIXME: We should probably handle this by splitting at the vsir -+ * level instead. */ -+ is_per_component = true; -+ break; -+ - default: - break; - } - } - -+ VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); -+ - if (reg_writemask) -- instr->reg = allocate_register_with_masks(ctx, allocator, instr->index, -- instr->last_read, reg_writemask, dst_writemask, 0, false); -- else -+ instr->reg = allocate_register_with_masks(ctx, allocator, -+ instr->index, instr->last_read, reg_writemask, dst_writemask, 0, false); -+ else if (is_per_component) - instr->reg = allocate_numeric_registers_for_type(ctx, allocator, - instr->index, instr->last_read, instr->data_type); -+ else -+ { -+ instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx); -+ instr->reg.allocation_size = 1; -+ instr->reg.allocated = true; -+ instr->reg.type = VKD3DSPR_SSA; -+ instr->reg.id = ctx->ssa_count++; -+ } - - TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, -- debug_register('r', instr->reg, instr->data_type), instr->index, instr->last_read); -+ debug_register(instr->reg, instr->data_type), instr->index, instr->last_read); - } - - 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); - -- TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r', -- var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); -+ TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, -+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); - } - } - } -@@ -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))) - { -+ ret->type = VKD3DSPR_CONST; - ret->id = reg->index; - ret->allocation_size = 1; - ret->writemask = writemask; -@@ -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", -- debug_register('c', constant->reg, type), instr->index); -+ debug_register(constant->reg, type), instr->index); - break; - } - - constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); -- TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); -+ constant->reg.type = VKD3DSPR_CONST; -+ TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type)); - - for (unsigned int x = 0, i = 0; x < 4; ++x) - { -@@ -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); -- TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register('c', ctx->d3dsincosconst1, type)); -+ ctx->d3dsincosconst1.type = VKD3DSPR_CONST; -+ TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register(ctx->d3dsincosconst1, type)); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 0, -1.55009923e-06f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 1, -2.17013894e-05f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 2, 2.60416674e-03f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 3, 2.60416680e-04f, &instr->loc); - - ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); -- TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register('c', ctx->d3dsincosconst2, type)); -+ ctx->d3dsincosconst2.type = VKD3DSPR_CONST; -+ TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register(ctx->d3dsincosconst2, type)); - 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); -@@ -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); - } - -+ var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; - var->regs[HLSL_REGSET_NUMERIC].id = reg_idx; - var->regs[HLSL_REGSET_NUMERIC].allocation_size = reg_size / 4; - var->regs[HLSL_REGSET_NUMERIC].writemask = VKD3DSP_WRITEMASK_ALL; - var->regs[HLSL_REGSET_NUMERIC].allocated = true; - TRACE("Allocated reserved %s to %s.\n", var->name, -- debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); -+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); - } - } - -@@ -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); -+ var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; - TRACE("Allocated %s to %s.\n", var->name, -- debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); -+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); - } - } - -- 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; -+ -+ optimize = false; - } - else - { -@@ -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); -+ var->regs[HLSL_REGSET_NUMERIC].type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT; - -- TRACE("Allocated %s to %s (mode %d).\n", var->name, debug_register(output ? 'o' : 'v', -- var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode); -+ TRACE("Allocated %s to %s (mode %d).\n", var->name, -+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode); - } - } - --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}; -- struct register_allocator input_allocator = {0}, output_allocator = {0}; - 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,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; -- output_allocator.prioritize_smaller_writemasks = true; -+ 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) - { -@@ -6550,15 +6972,22 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun - } - - if (var->is_output_semantic) -- allocate_semantic_register(ctx, var, &output_allocator, true, !is_pixel_shader); -+ { -+ VKD3D_ASSERT(var->semantic.stream_index < ARRAY_SIZE(output_allocators)); -+ allocate_semantic_register(ctx, var, &output_allocators[var->semantic.stream_index], -+ true, !is_pixel_shader); -+ } - } - -- *output_reg_count = output_allocator.reg_count; -+ *output_reg_count = output_allocators[0].reg_count; -+ for (unsigned int i = 1; i < ARRAY_SIZE(output_allocators); ++i) -+ *output_reg_count = max(*output_reg_count, output_allocators[i].reg_count); - - vkd3d_free(in_prim_allocator.allocations); - vkd3d_free(patch_constant_out_patch_allocator.allocations); - vkd3d_free(input_allocator.allocations); -- vkd3d_free(output_allocator.allocations); -+ for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) -+ vkd3d_free(output_allocators[i].allocations); - } - - static const struct hlsl_buffer *get_reserved_buffer(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; - } - } -- -- /* TODO: check that maxvertexcount * outputdatasize <= 1024. */ - } - --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; - -- if (!sm1_register_from_semantic_name(&program->shader_version, -+ if (sm1_register_from_semantic_name(&program->shader_version, - var->semantic.name, var->semantic.index, output, &sysval, &type, ®ister_index)) -+ { -+ if (!vkd3d_shader_ver_ge(&program->shader_version, 3, 0)) -+ { -+ if (type == VKD3DSPR_RASTOUT) -+ register_index += SM1_RASTOUT_REGISTER_OFFSET; -+ else if (type == VKD3DSPR_ATTROUT -+ || (type == VKD3DSPR_INPUT && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)) -+ register_index += SM1_COLOR_REGISTER_OFFSET; -+ } -+ } -+ else - { - enum vkd3d_decl_usage usage; - unsigned int usage_idx; -@@ -8018,6 +8479,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog - return; - } - element->semantic_index = var->semantic.index; -+ element->stream_index = var->semantic.stream_index; - element->sysval_semantic = sysval; - element->component_type = component_type; - element->register_index = register_index; -@@ -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 VSIR_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); -@@ -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]; - -- 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, 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; - } - -- 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 (!(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; - - 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 - { -- vsir_register_init(&src->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); -+ vsir_register_init(&src->reg, instr->reg.type, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); - 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 +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; - -+ reg->data_type = vsir_data_type_from_hlsl_type(ctx, data_type); -+ - if (var->is_uniform) - { - enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); -@@ -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; -- if (vkd3d_shader_ver_ge(version, 5, 1)) -- { -- reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id; -- reg->idx[1].offset = var->regs[HLSL_REGSET_TEXTURES].index; /* FIXME: array index */ -- reg->idx_count = 2; -- } -- else -- { -- reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].index; -- reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); -- reg->idx_count = 1; -- } -+ reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id; -+ reg->idx[1].offset = var->regs[HLSL_REGSET_TEXTURES].index; -+ reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref); -+ reg->idx_count = 2; - VKD3D_ASSERT(regset == HLSL_REGSET_TEXTURES); - *writemask = VKD3DSP_WRITEMASK_ALL; - } -@@ -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; -- if (vkd3d_shader_ver_ge(version, 5, 1)) -- { -- reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id; -- reg->idx[1].offset = var->regs[HLSL_REGSET_UAVS].index; /* FIXME: array index */ -- reg->idx_count = 2; -- } -- else -- { -- reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].index; -- reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); -- reg->idx_count = 1; -- } -+ reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id; -+ reg->idx[1].offset = var->regs[HLSL_REGSET_UAVS].index; -+ reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref); -+ reg->idx_count = 2; - VKD3D_ASSERT(regset == HLSL_REGSET_UAVS); - *writemask = VKD3DSP_WRITEMASK_ALL; - } -@@ -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; -- if (vkd3d_shader_ver_ge(version, 5, 1)) -- { -- reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id; -- reg->idx[1].offset = var->regs[HLSL_REGSET_SAMPLERS].index; /* FIXME: array index */ -- reg->idx_count = 2; -- } -- else -- { -- reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index; -- reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); -- reg->idx_count = 1; -- } -+ reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id; -+ reg->idx[1].offset = var->regs[HLSL_REGSET_SAMPLERS].index; -+ reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref); -+ reg->idx_count = 2; - VKD3D_ASSERT(regset == HLSL_REGSET_SAMPLERS); - *writemask = VKD3DSP_WRITEMASK_ALL; - } -+ else if (regset == HLSL_REGSET_STREAM_OUTPUTS) -+ { -+ reg->type = VKD3DSPR_STREAM; -+ reg->dimension = VSIR_DIMENSION_NONE; -+ reg->idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; -+ reg->idx_count = 1; -+ *writemask = VKD3DSP_WRITEMASK_ALL; -+ } - else - { - unsigned int offset = deref->const_offset + var->buffer_offset; -@@ -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; -- if (vkd3d_shader_ver_ge(version, 5, 1)) -- { -- reg->idx[0].offset = var->buffer->reg.id; -- reg->idx[1].offset = var->buffer->reg.index; /* FIXME: array index */ -- reg->idx[2].offset = offset / 4; -- reg->idx_count = 3; -- } -- else -- { -- reg->idx[0].offset = var->buffer->reg.index; -- reg->idx[1].offset = offset / 4; -- reg->idx_count = 2; -- } -+ reg->idx[0].offset = var->buffer->reg.id; -+ reg->idx[1].offset = var->buffer->reg.index; /* FIXME: array index */ -+ reg->idx[2].offset = offset / 4; -+ reg->idx_count = 3; - - if (deref->rel_offset.node) - { -@@ -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); -- vsir_dst_param_init(dst, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); -+ vsir_dst_param_init(dst, instr->reg.type, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); - dst->reg.idx[0].offset = instr->reg.id; - dst->reg.dimension = VSIR_DIMENSION_VEC4; - dst->write_mask = instr->reg.writemask; -@@ -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); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) - 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); -@@ -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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SAMPLE_INFO, 1, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SAMPLE_INFO, 1, 1))) - return; - ins->flags = VKD3DSI_SAMPLE_INFO_UINT; - - 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, 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, 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 +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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SINCOS, 1, src_count))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SINCOS, 1, src_count))) - return; - - vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - return true; - - case HLSL_TYPE_DOUBLE: - if (ctx->double_as_float_alias) - { -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - return true; - } - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - return true; - - case HLSL_TYPE_DOUBLE: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - return true; - break; - -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ABS, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ABS, 0, 0, true); - break; - - case HLSL_OP1_CAST: -@@ -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; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX, 0, 0, true); - break; - - case HLSL_OP1_DSY: - if (!hlsl_type_is_floating_point(type)) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY, 0, 0, true); - break; - - case HLSL_OP1_EXP2: - if (!hlsl_type_is_floating_point(type)) - goto err; -- sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_EXP); -+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_EXP); - break; - - case HLSL_OP1_LOG2: - if (!hlsl_type_is_floating_point(type)) - goto err; -- sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_LOG); -+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_LOG); - break; - - case HLSL_OP1_NEG: - if (type->e.numeric.type == HLSL_TYPE_BOOL) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_NEG, 0, true); - break; - - case HLSL_OP1_RCP: - if (!hlsl_type_is_floating_point(type)) - goto err; -- sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RCP); -+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_RCP); - break; - - case HLSL_OP1_REINTERPRET: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - break; - - case HLSL_OP1_RSQ: - if (!hlsl_type_is_floating_point(type)) - goto err; -- sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RSQ); -+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_RSQ); - break; - - case HLSL_OP1_SAT: - if (!hlsl_type_is_floating_point(type)) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, VKD3DSPDM_SATURATE, true); - break; - - case HLSL_OP1_SIN_REDUCED: -@@ -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; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ADD, 0, 0, true); - break; - - case HLSL_OP2_DOT: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP3, 0, 0, false); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP3, 0, 0, false); - break; - - case 4: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP4, 0, 0, false); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP4, 0, 0, false); - break; - - default: -@@ -8997,55 +9433,55 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr - break; - - case HLSL_OP2_MAX: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true); - break; - - case HLSL_OP2_MIN: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true); - break; - - case HLSL_OP2_MUL: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MUL, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MUL, 0, 0, true); - break; - - case HLSL_OP1_FRACT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FRC, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FRC, 0, 0, true); - break; - - case HLSL_OP2_LOGIC_AND: - if (type->e.numeric.type != HLSL_TYPE_BOOL) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true); - break; - - case HLSL_OP2_LOGIC_OR: - if (type->e.numeric.type != HLSL_TYPE_BOOL) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true); - break; - - case HLSL_OP2_SLT: - if (!hlsl_type_is_floating_point(type)) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SLT, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_SLT, 0, 0, true); - break; - - case HLSL_OP3_CMP: - if (!hlsl_type_is_floating_point(type)) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_CMP, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_CMP, 0, 0, true); - break; - - case HLSL_OP3_DP2ADD: - if (!hlsl_type_is_floating_point(type)) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2ADD, 0, 0, false); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP2ADD, 0, 0, false); - break; - - case HLSL_OP3_MAD: - if (!hlsl_type_is_floating_point(type)) - goto err; -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAD, 0, 0, true); - break; - - default: -@@ -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) - { -- enum vkd3d_shader_opcode opcode = hlsl_version_ge(ctx, 2, 0) ? VKD3DSIH_MOVA : VKD3DSIH_MOV; -+ enum vkd3d_shader_opcode opcode = hlsl_version_ge(ctx, 2, 0) ? VSIR_OP_MOVA : VSIR_OP_MOV; - struct vkd3d_shader_dst_param *dst_param; - struct vkd3d_shader_instruction *ins; - -@@ -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); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) - return; - - vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); -@@ -9279,21 +9715,25 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, - switch (load->load_type) - { - case HLSL_RESOURCE_SAMPLE: -- opcode = VKD3DSIH_TEX; -+ opcode = VSIR_OP_TEXLD; - break; - - case HLSL_RESOURCE_SAMPLE_PROJ: -- opcode = VKD3DSIH_TEX; -+ opcode = VSIR_OP_TEXLD; - 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; - flags |= VKD3DSI_TEXLD_BIAS; - break; - - case HLSL_RESOURCE_SAMPLE_GRAD: -- opcode = VKD3DSIH_TEXLDD; -+ opcode = VSIR_OP_TEXLDD; - src_count += 2; - break; - -@@ -9334,7 +9774,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, - - VKD3D_ASSERT(instr->reg.allocated); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) - return; - - vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); -@@ -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); -- vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, val), 1); -+ vsir_register_init(&src_param->reg, val->reg.type, vsir_data_type_from_hlsl_instruction(ctx, val), 1); - src_param->reg.idx[0].offset = val->reg.id; - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - src_param->swizzle = swizzle; -@@ -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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) - return; - - sm1_generate_vsir_init_dst_param_from_deref(ctx, &ins->dst[0], &store->lhs, &ins->location, store->writemask); -@@ -9377,7 +9817,7 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, - - if (jump->type == HLSL_IR_JUMP_DISCARD_NEG) - { -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 0, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_TEXKILL, 0, 1))) - return; - - vsir_src_from_hlsl_node(&ins->src[0], ctx, condition, VKD3DSP_WRITEMASK_ALL); -@@ -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); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_IFC, 0, 2))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_IFC, 0, 2))) - return; - ins->flags = VKD3D_SHADER_REL_OP_NE; - -@@ -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); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ELSE, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ELSE, 0, 0))) - return; - - sm1_generate_vsir_block(ctx, &iff->else_block, program); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDIF, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDIF, 0, 0))) - 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, body, semantic_vars); - if (ctx->result) - return; - -- 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 +10359,57 @@ static void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ct - ctab->size = buffer.size; - } - -+static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, -+ unsigned int index) -+{ -+ switch (sysval) -+ { -+ case VKD3D_SHADER_SV_COVERAGE: -+ case VKD3D_SHADER_SV_DEPTH: -+ case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: -+ case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: -+ case VKD3D_SHADER_SV_NONE: -+ case VKD3D_SHADER_SV_STENCIL_REF: -+ case VKD3D_SHADER_SV_TARGET: -+ return VKD3D_SIV_NONE; -+ case VKD3D_SHADER_SV_POSITION: -+ return VKD3D_SIV_POSITION; -+ case VKD3D_SHADER_SV_CLIP_DISTANCE: -+ return VKD3D_SIV_CLIP_DISTANCE; -+ case VKD3D_SHADER_SV_CULL_DISTANCE: -+ return VKD3D_SIV_CULL_DISTANCE; -+ case VKD3D_SHADER_SV_INSTANCE_ID: -+ return VKD3D_SIV_INSTANCE_ID; -+ case VKD3D_SHADER_SV_IS_FRONT_FACE: -+ return VKD3D_SIV_IS_FRONT_FACE; -+ case VKD3D_SHADER_SV_PRIMITIVE_ID: -+ return VKD3D_SIV_PRIMITIVE_ID; -+ case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX: -+ return VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX; -+ case VKD3D_SHADER_SV_SAMPLE_INDEX: -+ return VKD3D_SIV_SAMPLE_INDEX; -+ case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE: -+ return VKD3D_SIV_QUAD_U0_TESS_FACTOR + index; -+ case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT: -+ return VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR + index; -+ case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE: -+ return VKD3D_SIV_TRIANGLE_U_TESS_FACTOR + index; -+ case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT: -+ return VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR; -+ case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET: -+ return VKD3D_SIV_LINE_DETAIL_TESS_FACTOR; -+ case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN: -+ return VKD3D_SIV_LINE_DENSITY_TESS_FACTOR; -+ case VKD3D_SHADER_SV_VERTEX_ID: -+ return VKD3D_SIV_VERTEX_ID; -+ case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX: -+ return VKD3D_SIV_VIEWPORT_ARRAY_INDEX; -+ default: -+ FIXME("Unhandled sysval %#x, index %u.\n", sysval, index); -+ return VKD3D_SIV_NONE; -+ } -+} -+ - 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 +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) -- ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT; -+ ? VSIR_OP_DCL_INPUT_PS : VSIR_OP_DCL_INPUT; - break; - - case VKD3D_SHADER_SV_PRIMITIVE_ID: - if (version->type == VKD3D_SHADER_TYPE_PIXEL) -- opcode = VKD3DSIH_DCL_INPUT_PS_SGV; -+ opcode = VSIR_OP_DCL_INPUT_PS_SGV; - else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY) -- opcode = VKD3DSIH_DCL_INPUT; -+ opcode = VSIR_OP_DCL_INPUT; - else -- opcode = VKD3DSIH_DCL_INPUT_SGV; -+ opcode = VSIR_OP_DCL_INPUT_SGV; - break; - - case VKD3D_SHADER_SV_INSTANCE_ID: -@@ -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) -- ? VKD3DSIH_DCL_INPUT_PS_SGV : VKD3DSIH_DCL_INPUT_SGV; -+ ? VSIR_OP_DCL_INPUT_PS_SGV : VSIR_OP_DCL_INPUT_SGV; - break; - - default: - if (version->type == VKD3D_SHADER_TYPE_PIXEL) -- opcode = VKD3DSIH_DCL_INPUT_PS_SIV; -+ opcode = VSIR_OP_DCL_INPUT_PS_SIV; - else if (is_primitive && version->type != VKD3D_SHADER_TYPE_GEOMETRY) -- opcode = VKD3DSIH_DCL_INPUT; -+ opcode = VSIR_OP_DCL_INPUT; - else -- opcode = VKD3DSIH_DCL_INPUT_SIV; -+ opcode = VSIR_OP_DCL_INPUT_SIV; - break; - } - } -@@ -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)) -- opcode = VKD3DSIH_DCL_OUTPUT; -+ opcode = VSIR_OP_DCL_OUTPUT; -+ else if ((semantic == VKD3D_SHADER_SV_PRIMITIVE_ID || semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) -+ && version->type == VKD3D_SHADER_TYPE_GEOMETRY) -+ opcode = VSIR_OP_DCL_OUTPUT_SGV; - else -- opcode = VKD3DSIH_DCL_OUTPUT_SIV; -+ opcode = VSIR_OP_DCL_OUTPUT_SIV; - } - - if (sm4_register_from_semantic_name(version, var->semantic.name, output, &type, &has_idx)) -@@ -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; - -- if (opcode == VKD3DSIH_DCL_OUTPUT) -+ if (opcode == VSIR_OP_DCL_OUTPUT) - { - VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || semantic == VKD3D_SHADER_SV_TARGET - || version->type == VKD3D_SHADER_TYPE_HULL || type != VKD3DSPR_OUTPUT); - dst_param = &ins->declaration.dst; - } -- else if (opcode == VKD3DSIH_DCL_INPUT || opcode == VKD3DSIH_DCL_INPUT_PS) -+ else if (opcode == VSIR_OP_DCL_INPUT || opcode == VSIR_OP_DCL_INPUT_PS) - { - VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || is_primitive || version->type == VKD3D_SHADER_TYPE_GEOMETRY); - dst_param = &ins->declaration.dst; -@@ -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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VKD3DSIH_DCL_TEMPS, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VSIR_OP_DCL_TEMPS, 0, 0))) - return; - - ins->declaration.count = temp_count; -@@ -10068,13 +10559,13 @@ static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx, - { - struct vkd3d_shader_instruction *ins; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VKD3DSIH_DCL_INDEXABLE_TEMP, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VSIR_OP_DCL_INDEXABLE_TEMP, 0, 0))) - return; - - 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; - } -@@ -10095,16 +10586,17 @@ static void sm4_generate_vsir_cast_from_bool(struct hlsl_ctx *ctx, struct vsir_p - - VKD3D_ASSERT(instr->reg.allocated); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_AND, 1, 2))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_AND, 1, 2))) - return; - - dst_param = &ins->dst[0]; - vsir_dst_from_hlsl_node(dst_param, ctx, instr); -+ 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, -@@ -10131,16 +10623,16 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, - { - case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - return true; - - case HLSL_TYPE_INT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ITOF, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ITOF, 0, 0, true); - return true; - - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UTOF, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UTOF, 0, 0, true); - return true; - - case HLSL_TYPE_BOOL: -@@ -10158,13 +10650,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, - { - case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FTOI, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FTOI, 0, 0, true); - return true; - - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - return true; - - case HLSL_TYPE_BOOL: -@@ -10183,13 +10675,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, - { - case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FTOU, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FTOU, 0, 0, true); - return true; - - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - return true; - - case HLSL_TYPE_BOOL: -@@ -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)); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DIV, 1, 2))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DIV, 1, 2))) - return; - - dst_param = &ins->dst[0]; -@@ -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)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_ABS, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_ABS, 0, true); - return true; - - case HLSL_OP1_BIT_NOT: - VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NOT, 0, 0, true); - return true; - - case HLSL_OP1_CAST: -@@ -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)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_PI, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_PI, 0, 0, true); - return true; - - case HLSL_OP1_COS: - VKD3D_ASSERT(type_is_float(dst_type)); -- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_SINCOS, expr, 1); -+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_SINCOS, expr, 1); - return true; - - case HLSL_OP1_DSX: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX, 0, 0, true); - return true; - - case HLSL_OP1_DSX_COARSE: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX_COARSE, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX_COARSE, 0, 0, true); - return true; - - case HLSL_OP1_DSX_FINE: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX_FINE, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX_FINE, 0, 0, true); - return true; - - case HLSL_OP1_DSY: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY, 0, 0, true); - return true; - - case HLSL_OP1_DSY_COARSE: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY_COARSE, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY_COARSE, 0, 0, true); - return true; - - case HLSL_OP1_DSY_FINE: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY_FINE, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY_FINE, 0, 0, true); - return true; - - case HLSL_OP1_EXP2: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_EXP, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_EXP, 0, 0, true); - return true; - - case HLSL_OP1_F16TOF32: - VKD3D_ASSERT(type_is_float(dst_type)); - VKD3D_ASSERT(hlsl_version_ge(ctx, 5, 0)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_F16TOF32, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_F16TOF32, 0, 0, true); - return true; - - case HLSL_OP1_F32TOF16: - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_UINT); - VKD3D_ASSERT(hlsl_version_ge(ctx, 5, 0)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_F32TOF16, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_F32TOF16, 0, 0, true); - return true; - - case HLSL_OP1_FLOOR: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_NI, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_NI, 0, 0, true); - return true; - - case HLSL_OP1_FRACT: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FRC, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FRC, 0, 0, true); - return true; - - case HLSL_OP1_LOG2: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_LOG, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_LOG, 0, 0, true); - return true; - - case HLSL_OP1_LOGIC_NOT: - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NOT, 0, 0, true); - return true; - - case HLSL_OP1_NEG: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_NEG, 0, true); - return true; - - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INEG, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_INEG, 0, 0, true); - return true; - - default: -@@ -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)) -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_RCP, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_RCP, 0, 0, true); - else - sm4_generate_vsir_rcp_using_div(ctx, program, expr); - return true; -@@ -10410,50 +10902,50 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, - } - - case HLSL_OP1_REINTERPRET: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); - return true; - - case HLSL_OP1_ROUND: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_NE, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_NE, 0, 0, true); - return true; - - case HLSL_OP1_RSQ: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_RSQ, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_RSQ, 0, 0, true); - return true; - - case HLSL_OP1_SAT: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, VKD3DSPDM_SATURATE, true); - return true; - - case HLSL_OP1_SIN: - VKD3D_ASSERT(type_is_float(dst_type)); -- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_SINCOS, expr, 0); -+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_SINCOS, expr, 0); - return true; - - case HLSL_OP1_SQRT: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SQRT, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_SQRT, 0, 0, true); - return true; - - case HLSL_OP1_TRUNC: - VKD3D_ASSERT(type_is_float(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_Z, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_Z, 0, 0, true); - return true; - - case HLSL_OP2_ADD: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ADD, 0, 0, true); - return true; - - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IADD, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IADD, 0, 0, true); - return true; - - default: -@@ -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)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_AND, 0, 0, true); - return true; - - case HLSL_OP2_BIT_OR: - VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_OR, 0, 0, true); - return true; - - case HLSL_OP2_BIT_XOR: - VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_XOR, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_XOR, 0, 0, true); - return true; - - case HLSL_OP2_DIV: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DIV, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DIV, 0, 0, true); - return true; - - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 0); -+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_UDIV, expr, 0); - return true; - - default: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP4, 0, 0, false); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP4, 0, 0, false); - return true; - - case 3: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP3, 0, 0, false); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP3, 0, 0, false); - return true; - - case 2: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2, 0, 0, false); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP2, 0, 0, false); - return true; - - case 1: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_EQO, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_EQO, 0, 0, true); - return true; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IEQ, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IEQ, 0, 0, true); - return true; - - default: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_GEO, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_GEO, 0, 0, true); - return true; - - case HLSL_TYPE_INT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IGE, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IGE, 0, 0, true); - return true; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UGE, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UGE, 0, 0, true); - return true; - - default: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_LTO, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_LTO, 0, 0, true); - return true; - - case HLSL_TYPE_INT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ILT, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ILT, 0, 0, true); - return true; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ULT, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ULT, 0, 0, true); - return true; - - default: -@@ -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); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_AND, 0, 0, true); - return true; - - case HLSL_OP2_LOGIC_OR: - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_OR, 0, 0, true); - return true; - - case HLSL_OP2_LSHIFT: - 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, VKD3DSIH_ISHL, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ISHL, 0, 0, true); - return true; - - case HLSL_OP3_MAD: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAD, 0, 0, true); - return true; - - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAD, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMAD, 0, 0, true); - return true; - - default: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true); - return true; - - case HLSL_TYPE_INT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAX, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMAX, 0, 0, true); - return true; - - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMAX, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UMAX, 0, 0, true); - return true; - - default: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true); - return true; - - case HLSL_TYPE_INT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMIN, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMIN, 0, 0, true); - return true; - - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMIN, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UMIN, 0, 0, true); - return true; - - default: -@@ -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: -- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 1); -+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_UDIV, expr, 1); - return true; - - default: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MUL, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MUL, 0, 0, true); - return true; - - case HLSL_TYPE_INT: -@@ -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. */ -- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_IMUL, expr, 1); -+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_IMUL, expr, 1); - return true; - - default: -@@ -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: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NEU, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NEU, 0, 0, true); - return true; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ - case HLSL_TYPE_UINT: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INE, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_INE, 0, 0, true); - return true; - - default: -@@ -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, -- dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3DSIH_ISHR : VKD3DSIH_USHR, 0, 0, true); -+ dst_type->e.numeric.type == HLSL_TYPE_INT ? VSIR_OP_ISHR : VSIR_OP_USHR, 0, 0, true); - return true; - - case HLSL_OP3_TERNARY: -- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOVC, 0, 0, true); -+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOVC, 0, 0, true); - return true; - - default: -@@ -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]; -@@ -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. */ - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOVC, 1, 3))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOVC, 1, 3))) - return false; - - dst_param = &ins->dst[0]; -@@ -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 - { -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) - return false; - - dst_param = &ins->dst[0]; -@@ -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) - { -- enum vkd3d_shader_opcode opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND -- ? VKD3DSIH_EMIT : VKD3DSIH_CUT; -+ enum vkd3d_shader_opcode opcode; - - VKD3D_ASSERT(!store->value.node && !store->coords.node); - VKD3D_ASSERT(store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); - -- if (store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) -+ if (hlsl_version_lt(ctx, 5, 0)) - { -- hlsl_fixme(ctx, &instr->loc, "Stream output operation with a nonzero stream index."); -- return false; -+ opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ? VSIR_OP_EMIT : VSIR_OP_CUT; -+ ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0); -+ return !!ins; - } - -- ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0); -- return !!ins; -+ opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ? VSIR_OP_EMIT_STREAM : VSIR_OP_CUT_STREAM; -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 1))) -+ return false; -+ -+ if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, &ins->src[0], -+ &store->resource, VKD3DSP_WRITEMASK_ALL, &instr->loc)) -+ return false; -+ -+ 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; - } - -@@ -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); -- 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 - { -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_STORE_UAV_TYPED, 1, 2))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_UAV_TYPED, 1, 2))) - return false; - - if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, -@@ -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; - else if (raw) -- opcode = VKD3DSIH_LD_RAW; -+ opcode = VSIR_OP_LD_RAW; - else -- opcode = multisampled ? VKD3DSIH_LD2DMS : VKD3DSIH_LD; -+ opcode = multisampled ? VSIR_OP_LD2DMS : VSIR_OP_LD; - - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 2 + multisampled))) - return false; -@@ -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: -- opcode = VKD3DSIH_SAMPLE; -+ opcode = VSIR_OP_SAMPLE; - src_count = 3; - break; - - case HLSL_RESOURCE_SAMPLE_CMP: -- opcode = VKD3DSIH_SAMPLE_C; -+ opcode = VSIR_OP_SAMPLE_C; - src_count = 4; - break; - - case HLSL_RESOURCE_SAMPLE_CMP_LZ: -- opcode = VKD3DSIH_SAMPLE_C_LZ; -+ opcode = VSIR_OP_SAMPLE_C_LZ; - src_count = 4; - break; - - case HLSL_RESOURCE_SAMPLE_LOD: -- opcode = VKD3DSIH_SAMPLE_LOD; -+ opcode = VSIR_OP_SAMPLE_LOD; - src_count = 4; - break; - - case HLSL_RESOURCE_SAMPLE_LOD_BIAS: -- opcode = VKD3DSIH_SAMPLE_B; -+ opcode = VSIR_OP_SAMPLE_B; - src_count = 4; - break; - - case HLSL_RESOURCE_SAMPLE_GRAD: -- opcode = VKD3DSIH_SAMPLE_GRAD; -+ opcode = VSIR_OP_SAMPLE_GRAD; - src_count = 5; - break; - -@@ -11068,15 +11591,15 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, - sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc)) - return false; - -- if (opcode == VKD3DSIH_SAMPLE_LOD || opcode == VKD3DSIH_SAMPLE_B) -+ if (opcode == VSIR_OP_SAMPLE_LOD || opcode == VSIR_OP_SAMPLE_B) - { - vsir_src_from_hlsl_node(&ins->src[3], ctx, load->lod.node, VKD3DSP_WRITEMASK_ALL); - } -- else if (opcode == VKD3DSIH_SAMPLE_C || opcode == VKD3DSIH_SAMPLE_C_LZ) -+ else if (opcode == VSIR_OP_SAMPLE_C || opcode == VSIR_OP_SAMPLE_C_LZ) - { - vsir_src_from_hlsl_node(&ins->src[3], ctx, load->cmp.node, VKD3DSP_WRITEMASK_ALL); - } -- else if (opcode == VKD3DSIH_SAMPLE_GRAD) -+ else if (opcode == VSIR_OP_SAMPLE_GRAD) - { - 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 +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; -- enum vkd3d_shader_opcode opcode = VKD3DSIH_GATHER4; -+ enum vkd3d_shader_opcode opcode = VSIR_OP_GATHER4; - 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 +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; - } -- opcode = VKD3DSIH_GATHER4_PO; -+ opcode = VSIR_OP_GATHER4_PO; - ++src_count; - } - - if (compare) - { -- opcode = opcode == VKD3DSIH_GATHER4 ? VKD3DSIH_GATHER4_C : VKD3DSIH_GATHER4_PO_C; -+ opcode = opcode == VSIR_OP_GATHER4 ? VSIR_OP_GATHER4_C : VSIR_OP_GATHER4_PO_C; - ++src_count; - } - -@@ -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); - -- if (opcode == VKD3DSIH_GATHER4_PO || opcode == VKD3DSIH_GATHER4_PO_C) -+ if (opcode == VSIR_OP_GATHER4_PO || opcode == VSIR_OP_GATHER4_PO_C) - 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 +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); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SAMPLE_INFO, 1, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SAMPLE_INFO, 1, 1))) - return false; - - if (type->e.numeric.type == HLSL_TYPE_UINT) -@@ -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); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_RESINFO, 1, 2))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_RESINFO, 1, 2))) - return false; - - if (type->e.numeric.type == HLSL_TYPE_UINT) -@@ -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[] = - { -- [HLSL_INTERLOCKED_ADD] = VKD3DSIH_ATOMIC_IADD, -- [HLSL_INTERLOCKED_AND] = VKD3DSIH_ATOMIC_AND, -- [HLSL_INTERLOCKED_CMP_EXCH] = VKD3DSIH_ATOMIC_CMP_STORE, -- [HLSL_INTERLOCKED_MAX] = VKD3DSIH_ATOMIC_UMAX, -- [HLSL_INTERLOCKED_MIN] = VKD3DSIH_ATOMIC_UMIN, -- [HLSL_INTERLOCKED_OR] = VKD3DSIH_ATOMIC_OR, -- [HLSL_INTERLOCKED_XOR] = VKD3DSIH_ATOMIC_XOR, -+ [HLSL_INTERLOCKED_ADD] = VSIR_OP_ATOMIC_IADD, -+ [HLSL_INTERLOCKED_AND] = VSIR_OP_ATOMIC_AND, -+ [HLSL_INTERLOCKED_CMP_EXCH] = VSIR_OP_ATOMIC_CMP_STORE, -+ [HLSL_INTERLOCKED_MAX] = VSIR_OP_ATOMIC_UMAX, -+ [HLSL_INTERLOCKED_MIN] = VSIR_OP_ATOMIC_UMIN, -+ [HLSL_INTERLOCKED_OR] = VSIR_OP_ATOMIC_OR, -+ [HLSL_INTERLOCKED_XOR] = VSIR_OP_ATOMIC_XOR, - }; - - static const enum vkd3d_shader_opcode imm_opcodes[] = - { -- [HLSL_INTERLOCKED_ADD] = VKD3DSIH_IMM_ATOMIC_IADD, -- [HLSL_INTERLOCKED_AND] = VKD3DSIH_IMM_ATOMIC_AND, -- [HLSL_INTERLOCKED_CMP_EXCH] = VKD3DSIH_IMM_ATOMIC_CMP_EXCH, -- [HLSL_INTERLOCKED_EXCH] = VKD3DSIH_IMM_ATOMIC_EXCH, -- [HLSL_INTERLOCKED_MAX] = VKD3DSIH_IMM_ATOMIC_UMAX, -- [HLSL_INTERLOCKED_MIN] = VKD3DSIH_IMM_ATOMIC_UMIN, -- [HLSL_INTERLOCKED_OR] = VKD3DSIH_IMM_ATOMIC_OR, -- [HLSL_INTERLOCKED_XOR] = VKD3DSIH_IMM_ATOMIC_XOR, -+ [HLSL_INTERLOCKED_ADD] = VSIR_OP_IMM_ATOMIC_IADD, -+ [HLSL_INTERLOCKED_AND] = VSIR_OP_IMM_ATOMIC_AND, -+ [HLSL_INTERLOCKED_CMP_EXCH] = VSIR_OP_IMM_ATOMIC_CMP_EXCH, -+ [HLSL_INTERLOCKED_EXCH] = VSIR_OP_IMM_ATOMIC_EXCH, -+ [HLSL_INTERLOCKED_MAX] = VSIR_OP_IMM_ATOMIC_UMAX, -+ [HLSL_INTERLOCKED_MIN] = VSIR_OP_IMM_ATOMIC_UMIN, -+ [HLSL_INTERLOCKED_OR] = VSIR_OP_IMM_ATOMIC_OR, -+ [HLSL_INTERLOCKED_XOR] = VSIR_OP_IMM_ATOMIC_XOR, - }; - - struct hlsl_ir_node *cmp_value = interlocked->cmp_value.node, *value = interlocked->value.node; -@@ -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) - { -- if (opcode == VKD3DSIH_ATOMIC_UMAX) -- opcode = VKD3DSIH_ATOMIC_IMAX; -- else if (opcode == VKD3DSIH_ATOMIC_UMIN) -- opcode = VKD3DSIH_ATOMIC_IMIN; -- else if (opcode == VKD3DSIH_IMM_ATOMIC_UMAX) -- opcode = VKD3DSIH_IMM_ATOMIC_IMAX; -- else if (opcode == VKD3DSIH_IMM_ATOMIC_UMIN) -- opcode = VKD3DSIH_IMM_ATOMIC_IMIN; -+ if (opcode == VSIR_OP_ATOMIC_UMAX) -+ opcode = VSIR_OP_ATOMIC_IMAX; -+ else if (opcode == VSIR_OP_ATOMIC_UMIN) -+ opcode = VSIR_OP_ATOMIC_IMIN; -+ else if (opcode == VSIR_OP_IMM_ATOMIC_UMAX) -+ opcode = VSIR_OP_IMM_ATOMIC_IMAX; -+ else if (opcode == VSIR_OP_IMM_ATOMIC_UMIN) -+ opcode = VSIR_OP_IMM_ATOMIC_IMIN; - } - - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, -@@ -11368,13 +11891,13 @@ static bool sm4_generate_vsir_instr_jump(struct hlsl_ctx *ctx, - switch (jump->type) - { - case HLSL_IR_JUMP_BREAK: -- return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_BREAK, 0, 0); -+ return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_BREAK, 0, 0); - - case HLSL_IR_JUMP_CONTINUE: -- return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_CONTINUE, 0, 0); -+ return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_CONTINUE, 0, 0); - - case HLSL_IR_JUMP_DISCARD_NZ: -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DISCARD, 0, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DISCARD, 0, 1))) - return false; - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; - -@@ -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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SYNC, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SYNC, 0, 0))) - return false; - ins->flags = sync->sync_flags; - -@@ -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); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_IF, 0, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_IF, 0, 1))) - return; - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; - -@@ -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)) - { -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ELSE, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ELSE, 0, 0))) - return; - sm4_generate_vsir_block(ctx, &iff->else_block, program); - } - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDIF, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDIF, 0, 0))) - return; - } - -@@ -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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_LOOP, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_LOOP, 0, 0))) - return; - - sm4_generate_vsir_block(ctx, &loop->body, program); - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDLOOP, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDLOOP, 0, 0))) - return; - } - -@@ -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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SWITCH, 0, 1))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SWITCH, 0, 1))) - return; - vsir_src_from_hlsl_node(&ins->src[0], ctx, selector, VKD3DSP_WRITEMASK_ALL); - -@@ -11462,22 +11985,22 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, - { - if (cas->is_default) - { -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DEFAULT, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DEFAULT, 0, 0))) - return; - } - else - { - struct hlsl_constant_value value = {.u[0].u = cas->value}; - -- 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, VSIR_DATA_U32, 1, VKD3DSP_WRITEMASK_ALL); - } - - sm4_generate_vsir_block(ctx, &cas->body, program); - } - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDSWITCH, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDSWITCH, 0, 0))) - return; - } - -@@ -11563,8 +12086,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; -@@ -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) -@@ -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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &cbuffer->loc, VKD3DSIH_DCL_CONSTANT_BUFFER, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &cbuffer->loc, VSIR_OP_DCL_CONSTANT_BUFFER, 0, 0))) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; -@@ -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; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &resource->loc, VKD3DSIH_DCL_SAMPLER, 0, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &resource->loc, VSIR_OP_DCL_SAMPLER, 0, 0))) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; -@@ -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; -- struct vkd3d_shader_structured_resource *structured_resource; -- struct vkd3d_shader_dst_param *dst_param; -- struct vkd3d_shader_semantic *semantic; - struct vkd3d_shader_instruction *ins; - struct hlsl_type *component_type; - enum vkd3d_shader_opcode opcode; - bool multisampled; -- unsigned int i, j; -+ unsigned int i; - - VKD3D_ASSERT(resource->regset == regset); - VKD3D_ASSERT(hlsl_version_lt(ctx, 5, 1) || resource->bind_count == 1); -@@ -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. */ -+ struct vkd3d_shader_resource *vsir_resource; - - if (resource->var && !resource->var->objects_usage[regset][i].used) - continue; -@@ -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: -- opcode = VKD3DSIH_DCL_UAV_STRUCTURED; -+ opcode = VSIR_OP_DCL_UAV_STRUCTURED; - break; - case HLSL_SAMPLER_DIM_RAW_BUFFER: -- opcode = VKD3DSIH_DCL_UAV_RAW; -+ opcode = VSIR_OP_DCL_UAV_RAW; - break; - default: -- opcode = VKD3DSIH_DCL_UAV_TYPED; -+ opcode = VSIR_OP_DCL_UAV_TYPED; - break; - } - } -@@ -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: -- opcode = VKD3DSIH_DCL_RESOURCE_RAW; -+ opcode = VSIR_OP_DCL_RESOURCE_RAW; - break; - default: -- opcode = VKD3DSIH_DCL; -+ opcode = VSIR_OP_DCL; - break; - } - } -@@ -12081,13 +12606,16 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; - } -- semantic = &ins->declaration.semantic; -- structured_resource = &ins->declaration.structured_resource; -- dst_param = &semantic->resource.reg; -- vsir_dst_param_init(dst_param, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 0); - -- if (uav && component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -- structured_resource->byte_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; -+ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) -+ vsir_resource = &ins->declaration.raw_resource.resource; -+ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ vsir_resource = &ins->declaration.structured_resource.resource; -+ else -+ vsir_resource = &ins->declaration.semantic.resource; -+ -+ 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,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); -+ 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; -- dst_param->reg.idx_count = 3; -+ vsir_resource->reg.reg.idx[0].offset = resource->id; -+ vsir_resource->reg.reg.idx[1].offset = array_first; -+ vsir_resource->reg.reg.idx[2].offset = array_last; -+ vsir_resource->reg.reg.idx_count = 3; - - ins->resource_type = sm4_generate_vsir_get_resource_type(resource->component_type); -- if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) -+ -+ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) -+ { - ins->raw = true; -- if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ } -+ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) - { - 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 (!(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, 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 -+ * 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_HULL) -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ 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]) -+ sm4_generate_vsir_add_dcl_stream(ctx, program, var); -+ } -+ } -+ -+ program->ssa_count = 0; -+ -+ 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, 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, 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; - } - - /* For some reason, for matrices, values from default value initializers end -@@ -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) -+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, -+ "Geometry shaders cannot return values."); -+ else if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT -+ && !entry_func->return_var->semantic.name) -+ 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, body, semantic_vars, entry_func->return_var); -+ } -+ - for (i = 0; i < entry_func->parameters.count; ++i) - { - var = entry_func->parameters.vars[i]; -@@ -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); - } - } - } -+ - if (entry_func->return_var) - { -- if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) -- hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, -- "Geometry shaders cannot return values."); -- else if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT -- && !entry_func->return_var->semantic.name) -- 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); -- - if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func) - ctx->output_control_point_type = entry_func->return_var->data_type; - } - else - { - if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func) -- hlsl_fixme(ctx, &entry_func->loc, "Passthrough hull shader control point function."); -+ { -+ if (!ctx->input_control_point_type) -+ { -+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INPUT_PATCH, -+ "Pass-through control point function \"%s\" is missing an InputPatch parameter.", -+ entry_func->func->name); -+ } -+ else if (ctx->output_control_point_count -+ && ctx->output_control_point_count != ctx->input_control_point_count) -+ { -+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, -+ "Output control point count %u does not match the input control point count %u.", -+ ctx->output_control_point_count, ctx->input_control_point_count); -+ } -+ else -+ { -+ ctx->output_control_point_type = ctx->input_control_point_type; -+ ctx->output_control_point_count = ctx->input_control_point_count; -+ } -+ } - } - - if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && ctx->input_primitive_type == VKD3D_PT_UNDEFINED) -@@ -13540,8 +14157,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); -@@ -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..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 - struct vkd3d_shader_message_context *message_context; - }; - -+const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) -+{ -+ static const char * const names[] = -+ { -+ [VSIR_OP_ABS ] = "abs", -+ [VSIR_OP_ACOS ] = "acos", -+ [VSIR_OP_ADD ] = "add", -+ [VSIR_OP_AND ] = "and", -+ [VSIR_OP_ASIN ] = "asin", -+ [VSIR_OP_ATAN ] = "atan", -+ [VSIR_OP_ATOMIC_AND ] = "atomic_and", -+ [VSIR_OP_ATOMIC_CMP_STORE ] = "atomic_cmp_store", -+ [VSIR_OP_ATOMIC_IADD ] = "atomic_iadd", -+ [VSIR_OP_ATOMIC_IMAX ] = "atomic_imax", -+ [VSIR_OP_ATOMIC_IMIN ] = "atomic_imin", -+ [VSIR_OP_ATOMIC_OR ] = "atomic_or", -+ [VSIR_OP_ATOMIC_UMAX ] = "atomic_umax", -+ [VSIR_OP_ATOMIC_UMIN ] = "atomic_umin", -+ [VSIR_OP_ATOMIC_XOR ] = "atomic_xor", -+ [VSIR_OP_BEM ] = "bem", -+ [VSIR_OP_BFI ] = "bfi", -+ [VSIR_OP_BFREV ] = "bfrev", -+ [VSIR_OP_BRANCH ] = "branch", -+ [VSIR_OP_BREAK ] = "break", -+ [VSIR_OP_BREAKC ] = "break", -+ [VSIR_OP_BREAKP ] = "breakp", -+ [VSIR_OP_BUFINFO ] = "bufinfo", -+ [VSIR_OP_CALL ] = "call", -+ [VSIR_OP_CALLNZ ] = "callnz", -+ [VSIR_OP_CASE ] = "case", -+ [VSIR_OP_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped", -+ [VSIR_OP_CMP ] = "cmp", -+ [VSIR_OP_CND ] = "cnd", -+ [VSIR_OP_COS ] = "cos", -+ [VSIR_OP_CONTINUE ] = "continue", -+ [VSIR_OP_CONTINUEP ] = "continuec", -+ [VSIR_OP_COUNTBITS ] = "countbits", -+ [VSIR_OP_CRS ] = "crs", -+ [VSIR_OP_CUT ] = "cut", -+ [VSIR_OP_CUT_STREAM ] = "cut_stream", -+ [VSIR_OP_DADD ] = "dadd", -+ [VSIR_OP_DCL ] = "dcl", -+ [VSIR_OP_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer", -+ [VSIR_OP_DCL_FUNCTION_BODY ] = "dcl_function_body", -+ [VSIR_OP_DCL_FUNCTION_TABLE ] = "dcl_function_table", -+ [VSIR_OP_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags", -+ [VSIR_OP_DCL_GS_INSTANCES ] = "dcl_gs_instances", -+ [VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count", -+ [VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count", -+ [VSIR_OP_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor", -+ [VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer", -+ [VSIR_OP_DCL_INDEX_RANGE ] = "dcl_index_range", -+ [VSIR_OP_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp", -+ [VSIR_OP_DCL_INPUT ] = "dcl_input", -+ [VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count", -+ [VSIR_OP_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive", -+ [VSIR_OP_DCL_INPUT_PS ] = "dcl_input_ps", -+ [VSIR_OP_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv", -+ [VSIR_OP_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv", -+ [VSIR_OP_DCL_INPUT_SGV ] = "dcl_input_sgv", -+ [VSIR_OP_DCL_INPUT_SIV ] = "dcl_input_siv", -+ [VSIR_OP_DCL_INTERFACE ] = "dcl_interface", -+ [VSIR_OP_DCL_OUTPUT ] = "dcl_output", -+ [VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", -+ [VSIR_OP_DCL_OUTPUT_SGV ] = "dcl_output_sgv", -+ [VSIR_OP_DCL_OUTPUT_SIV ] = "dcl_output_siv", -+ [VSIR_OP_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", -+ [VSIR_OP_DCL_RESOURCE_RAW ] = "dcl_resource_raw", -+ [VSIR_OP_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured", -+ [VSIR_OP_DCL_SAMPLER ] = "dcl_sampler", -+ [VSIR_OP_DCL_STREAM ] = "dcl_stream", -+ [VSIR_OP_DCL_TEMPS ] = "dcl_temps", -+ [VSIR_OP_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain", -+ [VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive", -+ [VSIR_OP_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning", -+ [VSIR_OP_DCL_TGSM_RAW ] = "dcl_tgsm_raw", -+ [VSIR_OP_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured", -+ [VSIR_OP_DCL_THREAD_GROUP ] = "dcl_thread_group", -+ [VSIR_OP_DCL_UAV_RAW ] = "dcl_uav_raw", -+ [VSIR_OP_DCL_UAV_STRUCTURED ] = "dcl_uav_structured", -+ [VSIR_OP_DCL_UAV_TYPED ] = "dcl_uav_typed", -+ [VSIR_OP_DCL_VERTICES_OUT ] = "dcl_maxout", -+ [VSIR_OP_DDIV ] = "ddiv", -+ [VSIR_OP_DEF ] = "def", -+ [VSIR_OP_DEFAULT ] = "default", -+ [VSIR_OP_DEFB ] = "defb", -+ [VSIR_OP_DEFI ] = "defi", -+ [VSIR_OP_DEQO ] = "deq", -+ [VSIR_OP_DFMA ] = "dfma", -+ [VSIR_OP_DGEO ] = "dge", -+ [VSIR_OP_DISCARD ] = "discard", -+ [VSIR_OP_DIV ] = "div", -+ [VSIR_OP_DLT ] = "dlt", -+ [VSIR_OP_DMAX ] = "dmax", -+ [VSIR_OP_DMIN ] = "dmin", -+ [VSIR_OP_DMOV ] = "dmov", -+ [VSIR_OP_DMOVC ] = "dmovc", -+ [VSIR_OP_DMUL ] = "dmul", -+ [VSIR_OP_DNE ] = "dne", -+ [VSIR_OP_DP2 ] = "dp2", -+ [VSIR_OP_DP2ADD ] = "dp2add", -+ [VSIR_OP_DP3 ] = "dp3", -+ [VSIR_OP_DP4 ] = "dp4", -+ [VSIR_OP_DRCP ] = "drcp", -+ [VSIR_OP_DST ] = "dst", -+ [VSIR_OP_DSX ] = "dsx", -+ [VSIR_OP_DSX_COARSE ] = "deriv_rtx_coarse", -+ [VSIR_OP_DSX_FINE ] = "deriv_rtx_fine", -+ [VSIR_OP_DSY ] = "dsy", -+ [VSIR_OP_DSY_COARSE ] = "deriv_rty_coarse", -+ [VSIR_OP_DSY_FINE ] = "deriv_rty_fine", -+ [VSIR_OP_DTOF ] = "dtof", -+ [VSIR_OP_DTOI ] = "dtoi", -+ [VSIR_OP_DTOU ] = "dtou", -+ [VSIR_OP_ELSE ] = "else", -+ [VSIR_OP_EMIT ] = "emit", -+ [VSIR_OP_EMIT_STREAM ] = "emit_stream", -+ [VSIR_OP_ENDIF ] = "endif", -+ [VSIR_OP_ENDLOOP ] = "endloop", -+ [VSIR_OP_ENDREP ] = "endrep", -+ [VSIR_OP_ENDSWITCH ] = "endswitch", -+ [VSIR_OP_EQO ] = "eq", -+ [VSIR_OP_EQU ] = "eq_unord", -+ [VSIR_OP_EVAL_CENTROID ] = "eval_centroid", -+ [VSIR_OP_EVAL_SAMPLE_INDEX ] = "eval_sample_index", -+ [VSIR_OP_EXP ] = "exp", -+ [VSIR_OP_EXPP ] = "expp", -+ [VSIR_OP_F16TOF32 ] = "f16tof32", -+ [VSIR_OP_F32TOF16 ] = "f32tof16", -+ [VSIR_OP_FCALL ] = "fcall", -+ [VSIR_OP_FIRSTBIT_HI ] = "firstbit_hi", -+ [VSIR_OP_FIRSTBIT_LO ] = "firstbit_lo", -+ [VSIR_OP_FIRSTBIT_SHI ] = "firstbit_shi", -+ [VSIR_OP_FRC ] = "frc", -+ [VSIR_OP_FREM ] = "frem", -+ [VSIR_OP_FTOD ] = "ftod", -+ [VSIR_OP_FTOI ] = "ftoi", -+ [VSIR_OP_FTOU ] = "ftou", -+ [VSIR_OP_GATHER4 ] = "gather4", -+ [VSIR_OP_GATHER4_C ] = "gather4_c", -+ [VSIR_OP_GATHER4_C_S ] = "gather4_c_s", -+ [VSIR_OP_GATHER4_PO ] = "gather4_po", -+ [VSIR_OP_GATHER4_PO_C ] = "gather4_po_c", -+ [VSIR_OP_GATHER4_PO_C_S ] = "gather4_po_c_s", -+ [VSIR_OP_GATHER4_PO_S ] = "gather4_po_s", -+ [VSIR_OP_GATHER4_S ] = "gather4_s", -+ [VSIR_OP_GEO ] = "ge", -+ [VSIR_OP_GEU ] = "ge_unord", -+ [VSIR_OP_HCOS ] = "hcos", -+ [VSIR_OP_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", -+ [VSIR_OP_HS_DECLS ] = "hs_decls", -+ [VSIR_OP_HS_FORK_PHASE ] = "hs_fork_phase", -+ [VSIR_OP_HS_JOIN_PHASE ] = "hs_join_phase", -+ [VSIR_OP_HSIN ] = "hsin", -+ [VSIR_OP_HTAN ] = "htan", -+ [VSIR_OP_IADD ] = "iadd", -+ [VSIR_OP_IBFE ] = "ibfe", -+ [VSIR_OP_IDIV ] = "idiv", -+ [VSIR_OP_IEQ ] = "ieq", -+ [VSIR_OP_IF ] = "if", -+ [VSIR_OP_IFC ] = "if", -+ [VSIR_OP_IGE ] = "ige", -+ [VSIR_OP_ILT ] = "ilt", -+ [VSIR_OP_IMAD ] = "imad", -+ [VSIR_OP_IMAX ] = "imax", -+ [VSIR_OP_IMIN ] = "imin", -+ [VSIR_OP_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc", -+ [VSIR_OP_IMM_ATOMIC_AND ] = "imm_atomic_and", -+ [VSIR_OP_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch", -+ [VSIR_OP_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume", -+ [VSIR_OP_IMM_ATOMIC_EXCH ] = "imm_atomic_exch", -+ [VSIR_OP_IMM_ATOMIC_IADD ] = "imm_atomic_iadd", -+ [VSIR_OP_IMM_ATOMIC_IMAX ] = "imm_atomic_imax", -+ [VSIR_OP_IMM_ATOMIC_IMIN ] = "imm_atomic_imin", -+ [VSIR_OP_IMM_ATOMIC_OR ] = "imm_atomic_or", -+ [VSIR_OP_IMM_ATOMIC_UMAX ] = "imm_atomic_umax", -+ [VSIR_OP_IMM_ATOMIC_UMIN ] = "imm_atomic_umin", -+ [VSIR_OP_IMM_ATOMIC_XOR ] = "imm_atomic_xor", -+ [VSIR_OP_IMUL ] = "imul", -+ [VSIR_OP_IMUL_LOW ] = "imul_low", -+ [VSIR_OP_INE ] = "ine", -+ [VSIR_OP_INEG ] = "ineg", -+ [VSIR_OP_IREM ] = "irem", -+ [VSIR_OP_ISFINITE ] = "isfinite", -+ [VSIR_OP_ISHL ] = "ishl", -+ [VSIR_OP_ISHR ] = "ishr", -+ [VSIR_OP_ISINF ] = "isinf", -+ [VSIR_OP_ISNAN ] = "isnan", -+ [VSIR_OP_ITOD ] = "itod", -+ [VSIR_OP_ITOF ] = "itof", -+ [VSIR_OP_ITOI ] = "itoi", -+ [VSIR_OP_LABEL ] = "label", -+ [VSIR_OP_LD ] = "ld", -+ [VSIR_OP_LD2DMS ] = "ld2dms", -+ [VSIR_OP_LD2DMS_S ] = "ld2dms_s", -+ [VSIR_OP_LD_RAW ] = "ld_raw", -+ [VSIR_OP_LD_RAW_S ] = "ld_raw_s", -+ [VSIR_OP_LD_S ] = "ld_s", -+ [VSIR_OP_LD_STRUCTURED ] = "ld_structured", -+ [VSIR_OP_LD_STRUCTURED_S ] = "ld_structured_s", -+ [VSIR_OP_LD_UAV_TYPED ] = "ld_uav_typed", -+ [VSIR_OP_LD_UAV_TYPED_S ] = "ld_uav_typed_s", -+ [VSIR_OP_LIT ] = "lit", -+ [VSIR_OP_LOD ] = "lod", -+ [VSIR_OP_LOG ] = "log", -+ [VSIR_OP_LOGP ] = "logp", -+ [VSIR_OP_LOOP ] = "loop", -+ [VSIR_OP_LRP ] = "lrp", -+ [VSIR_OP_LTO ] = "lt", -+ [VSIR_OP_LTU ] = "lt_unord", -+ [VSIR_OP_M3x2 ] = "m3x2", -+ [VSIR_OP_M3x3 ] = "m3x3", -+ [VSIR_OP_M3x4 ] = "m3x4", -+ [VSIR_OP_M4x3 ] = "m4x3", -+ [VSIR_OP_M4x4 ] = "m4x4", -+ [VSIR_OP_MAD ] = "mad", -+ [VSIR_OP_MAX ] = "max", -+ [VSIR_OP_MIN ] = "min", -+ [VSIR_OP_MOV ] = "mov", -+ [VSIR_OP_MOVA ] = "mova", -+ [VSIR_OP_MOVC ] = "movc", -+ [VSIR_OP_MSAD ] = "msad", -+ [VSIR_OP_MUL ] = "mul", -+ [VSIR_OP_NEO ] = "ne_ord", -+ [VSIR_OP_NEU ] = "ne", -+ [VSIR_OP_NOP ] = "nop", -+ [VSIR_OP_NOT ] = "not", -+ [VSIR_OP_NRM ] = "nrm", -+ [VSIR_OP_OR ] = "or", -+ [VSIR_OP_ORD ] = "ord", -+ [VSIR_OP_PHASE ] = "phase", -+ [VSIR_OP_PHI ] = "phi", -+ [VSIR_OP_POW ] = "pow", -+ [VSIR_OP_QUAD_READ_ACROSS_D ] = "quad_read_across_d", -+ [VSIR_OP_QUAD_READ_ACROSS_X ] = "quad_read_across_x", -+ [VSIR_OP_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", -+ [VSIR_OP_QUAD_READ_LANE_AT ] = "quad_read_lane_at", -+ [VSIR_OP_RCP ] = "rcp", -+ [VSIR_OP_REP ] = "rep", -+ [VSIR_OP_RESINFO ] = "resinfo", -+ [VSIR_OP_RET ] = "ret", -+ [VSIR_OP_RETP ] = "retp", -+ [VSIR_OP_ROUND_NE ] = "round_ne", -+ [VSIR_OP_ROUND_NI ] = "round_ni", -+ [VSIR_OP_ROUND_PI ] = "round_pi", -+ [VSIR_OP_ROUND_Z ] = "round_z", -+ [VSIR_OP_RSQ ] = "rsq", -+ [VSIR_OP_SAMPLE ] = "sample", -+ [VSIR_OP_SAMPLE_B ] = "sample_b", -+ [VSIR_OP_SAMPLE_B_CL_S ] = "sample_b_cl_s", -+ [VSIR_OP_SAMPLE_C ] = "sample_c", -+ [VSIR_OP_SAMPLE_C_CL_S ] = "sample_c_cl_s", -+ [VSIR_OP_SAMPLE_C_LZ ] = "sample_c_lz", -+ [VSIR_OP_SAMPLE_C_LZ_S ] = "sample_c_lz_s", -+ [VSIR_OP_SAMPLE_CL_S ] = "sample_cl_s", -+ [VSIR_OP_SAMPLE_GRAD ] = "sample_d", -+ [VSIR_OP_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s", -+ [VSIR_OP_SAMPLE_INFO ] = "sample_info", -+ [VSIR_OP_SAMPLE_LOD ] = "sample_l", -+ [VSIR_OP_SAMPLE_LOD_S ] = "sample_l_s", -+ [VSIR_OP_SAMPLE_POS ] = "sample_pos", -+ [VSIR_OP_SETP ] = "setp", -+ [VSIR_OP_SGE ] = "sge", -+ [VSIR_OP_SGN ] = "sgn", -+ [VSIR_OP_SIN ] = "sin", -+ [VSIR_OP_SINCOS ] = "sincos", -+ [VSIR_OP_SLT ] = "slt", -+ [VSIR_OP_SQRT ] = "sqrt", -+ [VSIR_OP_STORE_RAW ] = "store_raw", -+ [VSIR_OP_STORE_STRUCTURED ] = "store_structured", -+ [VSIR_OP_STORE_UAV_TYPED ] = "store_uav_typed", -+ [VSIR_OP_SUB ] = "sub", -+ [VSIR_OP_SWAPC ] = "swapc", -+ [VSIR_OP_SWITCH ] = "switch", -+ [VSIR_OP_SWITCH_MONOLITHIC ] = "switch", -+ [VSIR_OP_SYNC ] = "sync", -+ [VSIR_OP_TAN ] = "tan", -+ [VSIR_OP_TEX ] = "tex", -+ [VSIR_OP_TEXBEM ] = "texbem", -+ [VSIR_OP_TEXBEML ] = "texbeml", -+ [VSIR_OP_TEXCOORD ] = "texcoord", -+ [VSIR_OP_TEXCRD ] = "texcrd", -+ [VSIR_OP_TEXDEPTH ] = "texdepth", -+ [VSIR_OP_TEXDP3 ] = "texdp3", -+ [VSIR_OP_TEXDP3TEX ] = "texdp3tex", -+ [VSIR_OP_TEXKILL ] = "texkill", -+ [VSIR_OP_TEXLD ] = "texld", -+ [VSIR_OP_TEXLDD ] = "texldd", -+ [VSIR_OP_TEXLDL ] = "texldl", -+ [VSIR_OP_TEXM3x2DEPTH ] = "texm3x2depth", -+ [VSIR_OP_TEXM3x2PAD ] = "texm3x2pad", -+ [VSIR_OP_TEXM3x2TEX ] = "texm3x2tex", -+ [VSIR_OP_TEXM3x3 ] = "texm3x3", -+ [VSIR_OP_TEXM3x3DIFF ] = "texm3x3diff", -+ [VSIR_OP_TEXM3x3PAD ] = "texm3x3pad", -+ [VSIR_OP_TEXM3x3SPEC ] = "texm3x3spec", -+ [VSIR_OP_TEXM3x3TEX ] = "texm3x3tex", -+ [VSIR_OP_TEXM3x3VSPEC ] = "texm3x3vspec", -+ [VSIR_OP_TEXREG2AR ] = "texreg2ar", -+ [VSIR_OP_TEXREG2GB ] = "texreg2gb", -+ [VSIR_OP_TEXREG2RGB ] = "texreg2rgb", -+ [VSIR_OP_UBFE ] = "ubfe", -+ [VSIR_OP_UDIV ] = "udiv", -+ [VSIR_OP_UDIV_SIMPLE ] = "udiv_simple", -+ [VSIR_OP_UGE ] = "uge", -+ [VSIR_OP_ULT ] = "ult", -+ [VSIR_OP_UMAX ] = "umax", -+ [VSIR_OP_UMIN ] = "umin", -+ [VSIR_OP_UMUL ] = "umul", -+ [VSIR_OP_UNO ] = "uno", -+ [VSIR_OP_UREM ] = "urem", -+ [VSIR_OP_USHR ] = "ushr", -+ [VSIR_OP_UTOD ] = "utod", -+ [VSIR_OP_UTOF ] = "utof", -+ [VSIR_OP_UTOU ] = "utou", -+ [VSIR_OP_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", -+ [VSIR_OP_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", -+ [VSIR_OP_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", -+ [VSIR_OP_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", -+ [VSIR_OP_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", -+ [VSIR_OP_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count", -+ [VSIR_OP_WAVE_ALL_TRUE ] = "wave_all_true", -+ [VSIR_OP_WAVE_ANY_TRUE ] = "wave_any_true", -+ [VSIR_OP_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane", -+ [VSIR_OP_WAVE_OP_ADD ] = "wave_op_add", -+ [VSIR_OP_WAVE_OP_IMAX ] = "wave_op_imax", -+ [VSIR_OP_WAVE_OP_IMIN ] = "wave_op_imin", -+ [VSIR_OP_WAVE_OP_MAX ] = "wave_op_max", -+ [VSIR_OP_WAVE_OP_MIN ] = "wave_op_min", -+ [VSIR_OP_WAVE_OP_MUL ] = "wave_op_mul", -+ [VSIR_OP_WAVE_OP_UMAX ] = "wave_op_umax", -+ [VSIR_OP_WAVE_OP_UMIN ] = "wave_op_umin", -+ [VSIR_OP_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count", -+ [VSIR_OP_WAVE_READ_LANE_AT ] = "wave_read_lane_at", -+ [VSIR_OP_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first", -+ [VSIR_OP_XOR ] = "xor", -+ }; -+ -+ if ((uint32_t)op < ARRAY_SIZE(names)) -+ return names[op] ? names[op] : error; -+ -+ return error; -+} -+ - static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, - unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) - { -@@ -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; - } - -+const char *debug_vsir_writemask(unsigned int writemask) -+{ -+ static const char components[] = {'x', 'y', 'z', 'w'}; -+ char string[5]; -+ unsigned int i = 0, pos = 0; -+ -+ VKD3D_ASSERT(!(writemask & ~VKD3DSP_WRITEMASK_ALL)); -+ -+ while (writemask) -+ { -+ if (writemask & 1) -+ string[pos++] = components[i]; -+ writemask >>= 1; -+ i++; -+ } -+ string[pos] = '\0'; -+ return vkd3d_dbg_sprintf(".%s", string); -+} -+ -+static unsigned int vsir_combine_write_masks(unsigned int first, unsigned int second) -+{ -+ unsigned int ret = 0, j = 0; -+ -+ for (unsigned int i = 0; i < VKD3D_VEC4_SIZE; ++i) -+ { -+ if (first & (1u << i)) -+ { -+ if (second & (1u << j++)) -+ ret |= (1u << i); -+ } -+ } -+ -+ return ret; -+} -+ -+static uint32_t vsir_combine_swizzles(uint32_t first, uint32_t second) -+{ -+ uint32_t ret = 0; -+ -+ for (unsigned int i = 0; i < VKD3D_VEC4_SIZE; ++i) -+ { -+ unsigned int s = vsir_swizzle_get_component(second, i); -+ vsir_swizzle_set_component(&ret, i, vsir_swizzle_get_component(first, s)); -+ } -+ return ret; -+} -+ - 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; -@@ -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 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); - src->reg.idx[0].offset = idx; -+ -+ if (dimension == VSIR_DIMENSION_VEC4) -+ { -+ src->reg.dimension = VSIR_DIMENSION_VEC4; -+ src->swizzle = VKD3D_SHADER_NO_SWIZZLE; -+ } -+} -+ -+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, 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, VSIR_DATA_F32); - } - - static void src_param_init_ssa_float4(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->reg.dimension = VSIR_DIMENSION_VEC4; -- src->swizzle = VKD3D_SHADER_NO_SWIZZLE; -+ 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) - { -- 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 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); - dst->reg.idx[0].offset = idx; -+ -+ if (dimension == VSIR_DIMENSION_VEC4) -+ { -+ dst->reg.dimension = VSIR_DIMENSION_VEC4; -+ dst->write_mask = VKD3DSP_WRITEMASK_ALL; -+ } -+} -+ -+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, 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, VSIR_DATA_F32); - } - - static void dst_param_init_ssa_float4(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->reg.dimension = VSIR_DIMENSION_VEC4; -- dst->write_mask = VKD3DSP_WRITEMASK_ALL; -+ 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) - { -- 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); - -- vsir_instruction_init(ins, location, VKD3DSIH_LABEL); -+ vsir_instruction_init(ins, location, VSIR_OP_LABEL); - ins->src = src_param; - ins->src_count = 1; - -@@ -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; -- return (VKD3DSIH_DCL <= opcode && opcode <= VKD3DSIH_DCL_VERTICES_OUT) -- || opcode == VKD3DSIH_HS_DECLS; -+ return (VSIR_OP_DCL <= opcode && opcode <= VSIR_OP_DCL_VERTICES_OUT) -+ || opcode == VSIR_OP_HS_DECLS; - } - - static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins) - { - struct vkd3d_shader_location location = ins->location; - -- vsir_instruction_init(ins, &location, VKD3DSIH_NOP); -+ 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 = VKD3DSIH_LTO; -+ *opcode = VSIR_OP_LTO; - return true; - } - break; -@@ -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 == VSIR_DATA_F32) - { -- *opcode = VKD3DSIH_GEO; -+ *opcode = VSIR_OP_GEO; - return true; - } - break; - - case VKD3D_SHADER_REL_OP_EQ: - *requires_swap = false; -- if (data_type == VKD3D_DATA_FLOAT) -+ if (data_type == VSIR_DATA_F32) - { -- *opcode = VKD3DSIH_EQO; -+ *opcode = VSIR_OP_EQO; - return true; - } - break; - - case VKD3D_SHADER_REL_OP_NE: - *requires_swap = false; -- if (data_type == VKD3D_DATA_FLOAT) -+ if (data_type == VSIR_DATA_F32) - { -- *opcode = VKD3DSIH_NEO; -+ *opcode = VSIR_OP_NEO; - return true; - } - break; -@@ -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) - { - if (tmp_idx == ~0u) - 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, VSIR_DATA_U32, 1); - ins->dst[0].reg.idx[0].offset = tmp_idx; - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; - } -- else if (ins->opcode == VKD3DSIH_MOVA) -+ else if (ins->opcode == VSIR_OP_MOVA) - { - 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 = 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, 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); -+ 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]; -- 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; - -- 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]; -- 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); -+ 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]; -- 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); -+ 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]; -- 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; - -- 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; - mul_ins->src_count = 2; - -- if (!(vsir_instruction_init_with_params(program, add_ins, &mul_ins->location, VKD3DSIH_ADD, 1, 2))) -+ if (!(vsir_instruction_init_with_params(program, add_ins, &mul_ins->location, VSIR_OP_ADD, 1, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - add_ins->flags = mul_ins->flags & VKD3DSI_PRECISE_XYZW; -@@ -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, -+ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ "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; -+ -+ return VKD3D_OK; -+} -+ -+static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, -+ struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) -+{ -+ 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 %zu for UDIV.", -+ udiv->dst_count); -+ return VKD3D_ERROR; -+ } -+ -+ if (udiv->dst[0].reg.type != VKD3DSPR_NULL) -+ ++count; -+ if (udiv->dst[1].reg.type != VKD3DSPR_NULL) -+ ++count; -+ -+ if (!vsir_program_iterator_insert_after(it, count)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ udiv = vsir_program_iterator_current(it); -+ -+ /* Save the sources in a SSA in case a destination collides with a source. */ -+ 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); - -- 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; -- 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; -+ -+ ins->flags = udiv->flags; -+ -+ src_param_init_ssa(&ins->src[0], program->ssa_count, -+ udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); -+ 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]; -+ } -+ -+ 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; -+ -+ ins->flags = udiv->flags; -+ -+ src_param_init_ssa(&ins->src[0], program->ssa_count, -+ udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); -+ 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]; -+ } -+ -+ vkd3d_shader_instruction_make_nop(udiv); -+ program->ssa_count += 2; -+ -+ return VKD3D_OK; -+} -+ -+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; -+ -+ sincos = vsir_program_iterator_current(it); -+ count = 1 + vkd3d_popcount(sincos->dst[0].write_mask & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_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 = 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; - -- ins->flags = sincos->flags; -+ mov->src[0] = sincos->src[0]; - -- *ins->src = *sincos->src; - /* Set the source swizzle to replicate the first component. */ - s = vsir_swizzle_get_component(sincos->src->swizzle, 0); -- ins->src->swizzle = vkd3d_shader_create_swizzle(s, s, s, s); -+ mov->src[0].swizzle = vkd3d_shader_create_swizzle(s, s, s, s); -+ -+ dst_param_init_ssa_scalar(&mov->dst[0], program->ssa_count, sincos->src[0].reg.data_type); - - 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; -+ -+ ins->flags = sincos->flags; -+ -+ src_param_init_ssa_scalar(&ins->src[0], program->ssa_count, sincos->src[0].reg.data_type); -+ - ins->dst[0] = *sincos->dst; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_1; - } -- 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; -+ -+ ins->flags = sincos->flags; -+ -+ src_param_init_ssa_scalar(&ins->src[0], program->ssa_count, sincos->src[0].reg.data_type); -+ -+ ins->dst[0] = *sincos->dst; -+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; - } - -- if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) -+ vkd3d_shader_instruction_make_nop(sincos); -+ ++program->ssa_count; -+ -+ return VKD3D_OK; -+} -+ -+static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *program, -+ struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) -+{ -+ 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 %zu for SINCOS.", -+ sincos->dst_count); -+ return VKD3D_ERROR; - } -- else -+ -+ if (sincos->dst[0].reg.type != VKD3DSPR_NULL) -+ ++count; -+ if (sincos->dst[1].reg.type != VKD3DSPR_NULL) -+ ++count; -+ -+ 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 = 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; -+ -+ mov->src[0] = sincos->src[0]; -+ dst_param_init_ssa(&mov->dst[0], program->ssa_count, sincos->src[0].reg.data_type, sincos->src[0].reg.dimension); -+ -+ 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; -+ -+ ins->flags = sincos->flags; -+ -+ 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]; -+ } -+ -+ 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; -+ -+ ins->flags = sincos->flags; -+ -+ 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]; - } - -- /* 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; - } - - 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, &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; -@@ -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, &tex->location, VSIR_OP_TEXLD, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - tex_ins->dst[0] = tex->dst[0]; -@@ -838,7 +1489,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, - return VKD3D_OK; - } - --static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, -+static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program, - struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context) - { - unsigned int idx = tex->src[1].reg.idx[0].offset; -@@ -856,7 +1507,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, - - if (!tex->flags) - { -- tex->opcode = VKD3DSIH_SAMPLE; -+ tex->opcode = VSIR_OP_SAMPLE; - tex->src = srcs; - tex->src_count = 3; - } -@@ -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); - -- tex->opcode = VKD3DSIH_SAMPLE_B; -+ tex->opcode = VSIR_OP_SAMPLE_B; - tex->src = srcs; - tex->src_count = 4; - -@@ -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]; - -- texldd->opcode = VKD3DSIH_SAMPLE_GRAD; -+ texldd->opcode = VSIR_OP_SAMPLE_GRAD; - texldd->src = srcs; - texldd->src_count = 5; - - 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, &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, &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, &it, &tmp_idx)) < 0) - return ret; - break; - -- case VKD3DSIH_DCL: -- case VKD3DSIH_DCL_CONSTANT_BUFFER: -- case VKD3DSIH_DCL_GLOBAL_FLAGS: -- case VKD3DSIH_DCL_SAMPLER: -- case VKD3DSIH_DCL_TEMPS: -- case VKD3DSIH_DCL_TESSELLATOR_DOMAIN: -- case VKD3DSIH_DCL_THREAD_GROUP: -- case VKD3DSIH_DCL_UAV_TYPED: -+ case VSIR_OP_DCL: -+ case VSIR_OP_DCL_CONSTANT_BUFFER: -+ case VSIR_OP_DCL_GLOBAL_FLAGS: -+ case VSIR_OP_DCL_SAMPLER: -+ case VSIR_OP_DCL_TEMPS: -+ case VSIR_OP_DCL_TESSELLATOR_DOMAIN: -+ case VSIR_OP_DCL_THREAD_GROUP: -+ case VSIR_OP_DCL_UAV_TYPED: - vkd3d_shader_instruction_make_nop(ins); - break; - -- case VKD3DSIH_DCL_INPUT: -+ case VSIR_OP_DCL_INPUT: - vsir_program_lower_dcl_input(program, ins, ctx); - vkd3d_shader_instruction_make_nop(ins); - break; - -- case VKD3DSIH_DCL_OUTPUT: -+ case VSIR_OP_DCL_OUTPUT: - vsir_program_lower_dcl_output(program, ins, ctx); - vkd3d_shader_instruction_make_nop(ins); - break; - -- case VKD3DSIH_DCL_INPUT_SGV: -- case VKD3DSIH_DCL_INPUT_SIV: -- case VKD3DSIH_DCL_INPUT_PS: -- case VKD3DSIH_DCL_INPUT_PS_SGV: -- case VKD3DSIH_DCL_INPUT_PS_SIV: -- case VKD3DSIH_DCL_OUTPUT_SIV: -+ case VSIR_OP_DCL_INPUT_SGV: -+ case VSIR_OP_DCL_INPUT_SIV: -+ case VSIR_OP_DCL_INPUT_PS: -+ case VSIR_OP_DCL_INPUT_PS_SGV: -+ case VSIR_OP_DCL_INPUT_PS_SIV: -+ case VSIR_OP_DCL_OUTPUT_SGV: -+ case VSIR_OP_DCL_OUTPUT_SIV: - vkd3d_shader_instruction_make_nop(ins); - break; - -- case VKD3DSIH_SINCOS: -- if ((ret = vsir_program_lower_sm1_sincos(program, ins)) < 0) -+ case VSIR_OP_IMUL: -+ case VSIR_OP_UMUL: -+ if ((ret = vsir_program_lower_imul(program, ins, ctx)) < 0) - return ret; - break; - -- case VKD3DSIH_TEX: -- 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_SINCOS: -+ if (ins->dst_count == 1) - { -- 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_sm4_sincos(program, &it, ctx)) < 0) - return ret; - } - break; - -- case VKD3DSIH_TEXLDD: -+ case VSIR_OP_TEXLDD: - if ((ret = vsir_program_lower_texldd(program, ins)) < 0) - return ret; - break; - -- case VKD3DSIH_TEXBEM: -- case VKD3DSIH_TEXBEML: -- case VKD3DSIH_TEXCOORD: -- case VKD3DSIH_TEXDEPTH: -- case VKD3DSIH_TEXDP3: -- case VKD3DSIH_TEXDP3TEX: -- case VKD3DSIH_TEXLDL: -- case VKD3DSIH_TEXM3x2PAD: -- case VKD3DSIH_TEXM3x2TEX: -- case VKD3DSIH_TEXM3x3DIFF: -- case VKD3DSIH_TEXM3x3PAD: -- case VKD3DSIH_TEXM3x3SPEC: -- case VKD3DSIH_TEXM3x3TEX: -- case VKD3DSIH_TEXM3x3VSPEC: -- 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_TEXDEPTH: -+ case VSIR_OP_TEXDP3: -+ case VSIR_OP_TEXDP3TEX: -+ case VSIR_OP_TEXM3x2PAD: -+ case VSIR_OP_TEXM3x2TEX: -+ case VSIR_OP_TEXM3x3DIFF: -+ case VSIR_OP_TEXM3x3PAD: -+ case VSIR_OP_TEXM3x3SPEC: -+ case VSIR_OP_TEXM3x3TEX: -+ case VSIR_OP_TEXM3x3VSPEC: -+ case VSIR_OP_TEXREG2AR: -+ case VSIR_OP_TEXREG2GB: -+ case VSIR_OP_TEXREG2RGB: - vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -- "Aborting due to unimplemented feature: Combined sampler instruction %#x.", -- ins->opcode); -+ "Aborting due to unimplemented feature: Combined sampler instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(ins->opcode, ""), ins->opcode); - return VKD3D_ERROR_NOT_IMPLEMENTED; - - default: -@@ -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)) -- { -- reg->idx[i].rel_addr = NULL; -- reg->idx[i].offset += instance_id; -- } -- } --} -- --static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_instruction *ins, -- unsigned int instance_id) --{ -- 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; -- if (shader_register_is_phase_instance_id(reg)) -- { -- vsir_register_init(reg, VKD3DSPR_IMMCONST, reg->data_type, 0); -- reg->u.immconst_u32[0] = instance_id; -- continue; -- } -- 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); -+ return VKD3D_OK; - } - --/* 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); -+ } -+ -+ 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 bool add_signature_element(struct shader_signature *signature, const char *semantic_name, -- uint32_t semantic_index, uint32_t mask, uint32_t register_index, -+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) - { - struct signature_element *new_elements, *e; - - if (!(new_elements = vkd3d_realloc(signature->elements, - (signature->element_count + 1) * sizeof(*signature->elements)))) -- return false; -+ return NULL; - signature->elements = new_elements; - e = &signature->elements[signature->element_count++]; - memset(e, 0, sizeof(*e)); -@@ -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; -- return true; -+ return e; - } - - static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program, -@@ -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]; -- -- 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; - } - -- 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, 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, 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; -@@ -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) -+ 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) - { - 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], 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, -@@ -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 - { -- struct vkd3d_shader_instruction_array instructions; -+ struct vsir_program *program; - - unsigned int instance_count; - unsigned int phase_body_idx; - enum vkd3d_shader_opcode phase; - struct vkd3d_shader_location last_ret_location; -+ unsigned int *ssa_map; -+ unsigned int orig_ssa_count; - }; - - static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flattener) - { -- return flattener->phase == VKD3DSIH_HS_FORK_PHASE || flattener->phase == VKD3DSIH_HS_JOIN_PHASE; -+ return flattener->phase == VSIR_OP_HS_FORK_PHASE || flattener->phase == VSIR_OP_HS_JOIN_PHASE; - } - - struct shader_phase_location -@@ -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 shader_phase_location *loc; - bool b; - -- if (ins->opcode == VKD3DSIH_HS_FORK_PHASE || ins->opcode == VKD3DSIH_HS_JOIN_PHASE) -+ if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE) - { - b = flattener_is_in_fork_or_join_phase(normaliser); - /* Reset the phase info. */ -@@ -1518,21 +2245,21 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal - vkd3d_shader_instruction_make_nop(ins); - return; - } -- else if (ins->opcode == VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT -- || ins->opcode == VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) -+ else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT -+ || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) - { - normaliser->instance_count = ins->declaration.count + !ins->declaration.count; - vkd3d_shader_instruction_make_nop(ins); - return; - } - -- if (normaliser->phase == VKD3DSIH_INVALID || vsir_instruction_is_dcl(ins)) -+ if (normaliser->phase == VSIR_OP_INVALID || vsir_instruction_is_dcl(ins)) - return; - - if (normaliser->phase_body_idx == ~0u) - normaliser->phase_body_idx = index; - -- if (ins->opcode == VKD3DSIH_RET) -+ if (ins->opcode == VSIR_OP_RET) - { - normaliser->last_ret_location = ins->location; - vkd3d_shader_instruction_make_nop(ins); -@@ -1548,26 +2275,89 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal - } - } - -+static void flattener_fixup_ssa_register(struct hull_flattener *normaliser, -+ struct vkd3d_shader_register *reg, unsigned int instance_id) -+{ -+ unsigned int id; -+ -+ if (!register_is_ssa(reg)) -+ return; -+ -+ /* No need to alter the first copy, they are already not conflicting. */ -+ if (instance_id == 0) -+ return; -+ -+ id = reg->idx[0].offset; -+ VKD3D_ASSERT(id < normaliser->orig_ssa_count); -+ if (normaliser->ssa_map[id] == UINT_MAX) -+ normaliser->ssa_map[id] = normaliser->program->ssa_count++; -+ reg->idx[0].offset = normaliser->ssa_map[id]; -+} -+ -+static void flattener_fixup_register_indices(struct hull_flattener *normaliser, -+ struct vkd3d_shader_register *reg, unsigned int instance_id) -+{ -+ unsigned int i; -+ -+ flattener_fixup_ssa_register(normaliser, reg, instance_id); -+ -+ for (i = 0; i < reg->idx_count; ++i) -+ { -+ if (reg->idx[i].rel_addr) -+ { -+ flattener_fixup_ssa_register(normaliser, ®->idx[i].rel_addr->reg, instance_id); -+ if (shader_register_is_phase_instance_id(®->idx[i].rel_addr->reg)) -+ { -+ reg->idx[i].rel_addr = NULL; -+ reg->idx[i].offset += instance_id; -+ } -+ } -+ } -+} -+ -+static void flattener_fixup_registers(struct hull_flattener *normaliser, -+ struct vkd3d_shader_instruction *ins, unsigned int instance_id) -+{ -+ struct vkd3d_shader_register *reg; -+ unsigned int i; -+ -+ for (i = 0; i < ins->src_count; ++i) -+ { -+ reg = &ins->src[i].reg; -+ if (shader_register_is_phase_instance_id(reg)) -+ { -+ vsir_register_init(reg, VKD3DSPR_IMMCONST, reg->data_type, 0); -+ reg->u.immconst_u32[0] = instance_id; -+ continue; -+ } -+ flattener_fixup_register_indices(normaliser, reg, instance_id); -+ } -+ -+ for (i = 0; i < ins->dst_count; ++i) -+ flattener_fixup_register_indices(normaliser, &ins->dst[i].reg, instance_id); -+} -+ - static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser, - struct shader_phase_location_array *locations) - { -+ struct vkd3d_shader_instruction_array *instructions = &normaliser->program->instructions; - struct shader_phase_location *loc; - unsigned int i, j, k, end, count; - - for (i = 0, count = 0; i < locations->count; ++i) - count += (locations->locations[i].instance_count - 1) * locations->locations[i].instruction_count; - -- if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count)) -+ if (!shader_instruction_array_reserve(instructions, instructions->count + count)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- end = normaliser->instructions.count; -- normaliser->instructions.count += count; -+ end = instructions->count; -+ instructions->count += count; - - for (i = locations->count; i > 0; --i) - { - loc = &locations->locations[i - 1]; - j = loc->index + loc->instruction_count; -- memmove(&normaliser->instructions.elements[j + count], &normaliser->instructions.elements[j], -- (end - j) * sizeof(*normaliser->instructions.elements)); -+ memmove(&instructions->elements[j + count], &instructions->elements[j], -+ (end - j) * sizeof(*instructions->elements)); - end = j; - count -= (loc->instance_count - 1) * loc->instruction_count; - loc->index += count; -@@ -1581,7 +2371,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali - { - for (k = 0; k < loc->instruction_count; ++k) - { -- if (!shader_instruction_array_clone_instruction(&normaliser->instructions, -+ if (!shader_instruction_array_clone_instruction(instructions, - loc->index + loc->instruction_count * j + k, loc->index + k)) - return VKD3D_ERROR_OUT_OF_MEMORY; - } -@@ -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) - { -+ if (j != 0) -+ memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); -+ - for (k = 0; k < loc->instruction_count; ++k) -- shader_instruction_eliminate_phase_instance_id( -- &normaliser->instructions.elements[loc->index + loc->instruction_count * j + k], j); -+ flattener_fixup_registers(normaliser, -+ &instructions->elements[loc->index + loc->instruction_count * j + k], j); - } - } - -@@ -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 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; -+ 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); - -- if ((result = flattener_flatten_phases(&flattener, &locations)) < 0) -+ flattener.orig_ssa_count = program->ssa_count; -+ if (!(flattener.ssa_map = vkd3d_calloc(flattener.orig_ssa_count, sizeof(*flattener.ssa_map)))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ result = flattener_flatten_phases(&flattener, &locations); -+ -+ vkd3d_free(flattener.ssa_map); -+ flattener.ssa_map = NULL; -+ -+ if (result < 0) - return result; - -- if (flattener.phase != VKD3DSIH_INVALID) -+ if (flattener.phase != VSIR_OP_INVALID) - { -- if (!shader_instruction_array_reserve(&flattener.instructions, flattener.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(ins, &flattener.last_ret_location, VSIR_OP_RET); - } - -- program->instructions = flattener.instructions; - return result; - } - -@@ -1638,7 +2441,7 @@ struct control_point_normaliser - - static bool control_point_normaliser_is_in_control_point_phase(const struct control_point_normaliser *normaliser) - { -- return normaliser->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE; -+ return normaliser->phase == VSIR_OP_HS_CONTROL_POINT_PHASE; - } - - struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_program *program) -@@ -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]; -- vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE); -+ vsir_instruction_init(ins, location, VSIR_OP_HS_CONTROL_POINT_PHASE); - - ++ins; - -@@ -1706,7 +2509,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p - if (!e->used_mask) - continue; - -- vsir_instruction_init(ins, location, VKD3DSIH_MOV); -+ vsir_instruction_init(ins, location, VSIR_OP_MOV); - 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 +2536,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p - ++ins; - } - -- vsir_instruction_init(ins, location, VKD3DSIH_RET); -+ vsir_instruction_init(ins, location, VSIR_OP_RET); - - return VKD3D_OK; - } -@@ -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; -- normaliser.phase = VKD3DSIH_INVALID; -+ 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 VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - normaliser.phase = ins->opcode; - break; - default: -@@ -1786,24 +2587,22 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i - } - } - -- normaliser.phase = VKD3DSIH_INVALID; -+ 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 VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: -+ case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: - input_control_point_count = ins->declaration.count; - break; -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: - program->instructions = normaliser.instructions; - program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; - return VKD3D_OK; -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - /* ins may be relocated if the instruction array expands. */ - location = ins->location; - ret = control_point_normaliser_emit_hs_input(&normaliser, &program->input_signature, -@@ -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; - enum vkd3d_shader_type shader_type; - uint8_t major; - 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) - { -- return normaliser->phase == VKD3DSIH_HS_FORK_PHASE || normaliser->phase == VKD3DSIH_HS_JOIN_PHASE; -+ return normaliser->phase == VSIR_OP_HS_FORK_PHASE || normaliser->phase == VSIR_OP_HS_JOIN_PHASE; - } - - static bool shader_signature_find_element_for_reg(const struct shader_signature *signature, -@@ -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, -- struct io_normaliser *normaliser) -+ struct io_normaliser *normaliser, struct vkd3d_shader_instruction *ins) - { - unsigned int i, id_idx, reg_idx, write_mask, element_idx, component_idx; - struct vkd3d_shader_register *reg = &src_param->reg; -@@ -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)) -- vkd3d_unreachable(); -+ { -+ vkd3d_shader_error(normaliser->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, -+ "Unable to resolve I/O register to a signature element."); -+ normaliser->result = VKD3D_ERROR_INVALID_SHADER; -+ return; -+ } - - e = &signature->elements[element_idx]; - if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic))) -@@ -2424,9 +3228,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi - - switch (ins->opcode) - { -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - 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 +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) -- shader_src_param_io_normalise(&ins->src[i], normaliser); -+ shader_src_param_io_normalise(&ins->src[i], normaliser, ins); - break; - } - } -@@ -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 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); - -- normaliser.phase = VKD3DSIH_INVALID; -+ normaliser.phase = VSIR_OP_INVALID; - normaliser.shader_type = program->shader_version.type; - normaliser.major = program->shader_version.major; - normaliser.input_signature = &program->input_signature; - 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: -+ case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: - normaliser.output_control_point_count = ins->declaration.count; - break; -- case VKD3DSIH_DCL_INDEX_RANGE: -+ case VSIR_OP_DCL_INDEX_RANGE: - if ((ret = io_normaliser_add_index_range(&normaliser, ins)) < 0) - return ret; - vkd3d_shader_instruction_make_nop(ins); - break; -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - normaliser.phase = ins->opcode; - break; - default: -@@ -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 (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 VKD3D_OK; -+ return normaliser.result; - } - - struct flat_constant_def -@@ -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; - -@@ -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: -- case VKD3DSIH_LOOP: -- case VKD3DSIH_SWITCH: -+ case VSIR_OP_IF: -+ case VSIR_OP_LOOP: -+ case VSIR_OP_SWITCH: - if (dead) - { - vkd3d_shader_instruction_make_nop(ins); -@@ -2646,15 +3450,15 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog - } - break; - -- case VKD3DSIH_ENDIF: -- case VKD3DSIH_ENDLOOP: -- case VKD3DSIH_ENDSWITCH: -- case VKD3DSIH_ELSE: -+ case VSIR_OP_ENDIF: -+ case VSIR_OP_ENDLOOP: -+ case VSIR_OP_ENDSWITCH: -+ case VSIR_OP_ELSE: - if (dead) - { - if (depth > 0) - { -- if (ins->opcode != VKD3DSIH_ELSE) -+ if (ins->opcode != VSIR_OP_ELSE) - --depth; - vkd3d_shader_instruction_make_nop(ins); - } -@@ -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. */ -- case VKD3DSIH_BREAK: -- case VKD3DSIH_RET: -- case VKD3DSIH_CONTINUE: -+ case VSIR_OP_BREAK: -+ case VSIR_OP_RET: -+ case VSIR_OP_CONTINUE: - if (dead) - { - vkd3d_shader_instruction_make_nop(ins); -@@ -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. */ -- case VKD3DSIH_CASE: -- case VKD3DSIH_DEFAULT: -+ case VSIR_OP_CASE: -+ case VSIR_OP_DEFAULT: - if (dead) - { - if (depth == 0) -@@ -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. */ -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - dead = false; - break; - -@@ -2817,7 +3621,7 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, - { - struct vkd3d_shader_instruction *dst_ins; - -- if (instruction->opcode == VKD3DSIH_NOP) -+ if (instruction->opcode == VSIR_OP_NOP) - return true; - - if (!(dst_ins = cf_flattener_require_space(flattener, 1))) -@@ -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; -- vsir_instruction_init(ins, &flattener->location, VKD3DSIH_BRANCH); -+ vsir_instruction_init(ins, &flattener->location, VSIR_OP_BRANCH); - - if (condition) - { -@@ -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. */ -- if (!after_declarations_section && instruction->opcode != VKD3DSIH_NOP) -+ if (!after_declarations_section && instruction->opcode != VSIR_OP_NOP) - { -- bool is_function_indexable = instruction->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP -+ bool is_function_indexable = instruction->opcode == VSIR_OP_DCL_INDEXABLE_TEMP - && instruction->declaration.indexable_temp.has_function_scope; - - if (!vsir_instruction_is_dcl(instruction) || is_function_indexable) -@@ -3048,22 +3853,22 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - - switch (instruction->opcode) - { -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - if (!cf_flattener_copy_instruction(flattener, instruction)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- if (instruction->opcode != VKD3DSIH_HS_CONTROL_POINT_PHASE || !instruction->flags) -+ if (instruction->opcode != VSIR_OP_HS_CONTROL_POINT_PHASE || !instruction->flags) - after_declarations_section = false; - break; - -- case VKD3DSIH_LABEL: -+ case VSIR_OP_LABEL: - vkd3d_shader_error(message_context, &instruction->location, - VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Aborting due to not yet implemented feature: Label instruction."); - return VKD3D_ERROR_NOT_IMPLEMENTED; - -- case VKD3DSIH_IF: -+ case VSIR_OP_IF: - if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -3087,7 +3892,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - ++flattener->branch_id; - break; - -- case VKD3DSIH_ELSE: -+ case VSIR_OP_ELSE: - if (cf_info->inside_block) - cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id); - -@@ -3101,7 +3906,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - cf_info->inside_block = true; - break; - -- case VKD3DSIH_ENDIF: -+ case VSIR_OP_ENDIF: - if (cf_info->inside_block) - cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id); - -@@ -3110,7 +3915,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - cf_flattener_pop_control_flow_level(flattener); - break; - -- case VKD3DSIH_LOOP: -+ case VSIR_OP_LOOP: - if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -3139,7 +3944,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - ++flattener->loop_id; - break; - -- case VKD3DSIH_ENDLOOP: -+ case VSIR_OP_ENDLOOP: - if (cf_info->inside_block) - cf_flattener_emit_unconditional_branch(flattener, cf_info->u.loop.continue_block_id); - -@@ -3150,7 +3955,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - cf_flattener_pop_control_flow_level(flattener); - break; - -- case VKD3DSIH_SWITCH: -+ case VSIR_OP_SWITCH: - if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -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; -- vsir_instruction_init(dst_ins, &instruction->location, VKD3DSIH_SWITCH_MONOLITHIC); -+ vsir_instruction_init(dst_ins, &instruction->location, VSIR_OP_SWITCH_MONOLITHIC); - ++flattener->instruction_count; - - cf_info->u.switch_.id = flattener->switch_id; -@@ -3182,7 +3987,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - - break; - -- case VKD3DSIH_ENDSWITCH: -+ case VSIR_OP_ENDSWITCH: - { - struct vkd3d_shader_src_param *src_params; - unsigned int j; -@@ -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; - } - -- case VKD3DSIH_CASE: -+ case VSIR_OP_CASE: - { - unsigned int label_id, value; - -@@ -3249,7 +4054,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - break; - } - -- case VKD3DSIH_DEFAULT: -+ case VSIR_OP_DEFAULT: - 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 +4066,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - cf_info->inside_block = true; - break; - -- case VKD3DSIH_BREAK: -+ case VSIR_OP_BREAK: - { - struct cf_flattener_info *breakable_cf_info; - -@@ -3284,7 +4089,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - break; - } - -- case VKD3DSIH_BREAKP: -+ case VSIR_OP_BREAKP: - { - struct cf_flattener_info *loop_cf_info; - -@@ -3299,7 +4104,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - break; - } - -- case VKD3DSIH_CONTINUE: -+ case VSIR_OP_CONTINUE: - { - struct cf_flattener_info *loop_cf_info; - -@@ -3315,7 +4120,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - break; - } - -- case VKD3DSIH_CONTINUEP: -+ case VSIR_OP_CONTINUEP: - { - struct cf_flattener_info *loop_cf_info; - -@@ -3330,7 +4135,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - break; - } - -- case VKD3DSIH_RET: -+ case VSIR_OP_RET: - if (!cf_flattener_copy_instruction(flattener, instruction)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -@@ -3447,14 +4252,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs - - switch (ins->opcode) - { -- case VKD3DSIH_LABEL: -+ case VSIR_OP_LABEL: - current_label = label_from_src_param(&ins->src[0]); - if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) - goto fail; - instructions[ins_count++] = *ins; - continue; - -- case VKD3DSIH_SWITCH_MONOLITHIC: -+ case VSIR_OP_SWITCH_MONOLITHIC: - break; - - default: -@@ -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], -- &ins->location, VKD3DSIH_BRANCH, 0, 1)) -+ &ins->location, VSIR_OP_BRANCH, 0, 1)) - goto fail; - vsir_src_param_init_label(&instructions[ins_count].src[0], default_label); - ++ins_count; -@@ -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, -- &instructions[ins_count], &ins->location, VKD3DSIH_IEQ, 1, 2)) -+ &instructions[ins_count], &ins->location, VSIR_OP_IEQ, 1, 2)) - goto fail; - dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count); - instructions[ins_count].src[0] = ins->src[0]; -@@ -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], -- &ins->location, VKD3DSIH_BRANCH, 0, 3)) -+ &ins->location, VSIR_OP_BRANCH, 0, 3)) - 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 +4334,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs - else - { - if (!vsir_instruction_init_with_params(program, -- &instructions[ins_count], &ins->location, VKD3DSIH_LABEL, 0, 1)) -+ &instructions[ins_count], &ins->location, VSIR_OP_LABEL, 0, 1)) - goto fail; - vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count); - ++ins_count; -@@ -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. */ -- if (ins->opcode != VKD3DSIH_PHI) -+ if (ins->opcode != VSIR_OP_PHI) - continue; - ++phi_count; - -@@ -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) - { -- case VKD3DSIH_LABEL: -+ case VSIR_OP_LABEL: - current_label = label_from_src_param(&ins->src[0]); - break; - -- case VKD3DSIH_BRANCH: -- case VKD3DSIH_SWITCH_MONOLITHIC: -+ case VSIR_OP_BRANCH: -+ case VSIR_OP_SWITCH_MONOLITHIC: - info = &block_info[current_label - 1]; - - for (j = 0; j < info->incoming_count; ++j) -@@ -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++]; -- if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VKD3DSIH_MOV, 1, 0)) -+ if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VSIR_OP_MOV, 1, 0)) - goto fail; - *mov_ins->dst = *incoming->dst; - mov_ins->src = incoming->src; -@@ -3716,7 +4524,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ - } - break; - -- case VKD3DSIH_PHI: -+ case VSIR_OP_PHI: - continue; - - default: -@@ -3753,7 +4561,7 @@ struct vsir_block_list - - static void vsir_block_list_init(struct vsir_block_list *list) - { -- memset(list, 0, sizeof(*list)); -+ *list = (struct vsir_block_list){0}; - } - - static void vsir_block_list_cleanup(struct vsir_block_list *list) -@@ -4125,11 +4933,11 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg) - - switch (block->end->opcode) - { -- case VKD3DSIH_RET: -+ case VSIR_OP_RET: - shape = "trapezium"; - break; - -- case VKD3DSIH_BRANCH: -+ case VSIR_OP_BRANCH: - shape = vsir_register_is_label(&block->end->src[0].reg) ? "ellipse" : "box"; - break; - -@@ -4267,11 +5075,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - - switch (instruction->opcode) - { -- case VKD3DSIH_PHI: -- case VKD3DSIH_SWITCH_MONOLITHIC: -+ case VSIR_OP_PHI: -+ case VSIR_OP_SWITCH_MONOLITHIC: - vkd3d_unreachable(); - -- case VKD3DSIH_LABEL: -+ case VSIR_OP_LABEL: - { - unsigned int label = label_from_src_param(&instruction->src[0]); - -@@ -4288,16 +5096,16 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - break; - } - -- case VKD3DSIH_BRANCH: -- case VKD3DSIH_RET: -+ case VSIR_OP_BRANCH: -+ case VSIR_OP_RET: - VKD3D_ASSERT(current_block); - current_block->end = instruction; - current_block = NULL; - break; - -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - VKD3D_ASSERT(!current_block); - finish = true; - break; -@@ -4322,10 +5130,10 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - - switch (block->end->opcode) - { -- case VKD3DSIH_RET: -+ case VSIR_OP_RET: - break; - -- case VKD3DSIH_BRANCH: -+ case VSIR_OP_BRANCH: - 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 +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) - { -- case VKD3DSIH_BRANCH: -+ case VSIR_OP_BRANCH: - { - struct vsir_cfg_edge_action action_true, action_false; - bool invert_condition = false; -@@ -5090,7 +5898,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) - break; - } - -- case VKD3DSIH_RET: -+ case VSIR_OP_RET: - if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_JUMP))) - goto fail; - structure->u.jump.type = JUMP_RET; -@@ -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; - -- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_LOOP); -+ vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_LOOP); - - if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0) - return ret; -@@ -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; - -- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ENDLOOP); -+ vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDLOOP); - - /* Add a trampoline to implement multilevel jumping depending on the stored - * jump_target value. */ -@@ -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], -- &no_loc, VKD3DSIH_IEQ, 1, 2)) -+ &no_loc, VSIR_OP_IEQ, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count); -@@ -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], -- &no_loc, VKD3DSIH_CONTINUEP, 0, 1)) -+ &no_loc, VSIR_OP_CONTINUEP, 0, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count); -@@ -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], -- &no_loc, VKD3DSIH_IEQ, 1, 2)) -+ &no_loc, VSIR_OP_IEQ, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count); -@@ -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], -- &no_loc, VKD3DSIH_BREAKP, 0, 1)) -+ &no_loc, VSIR_OP_BREAKP, 0, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z; - -@@ -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], -- &no_loc, VKD3DSIH_IF, 0, 1)) -+ &no_loc, VSIR_OP_IF, 0, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - target->instructions[target->ins_count].src[0] = *selection->condition; -@@ -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; - -- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ELSE); -+ vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ELSE); - - if ((ret = vsir_cfg_structure_list_emit(cfg, &selection->else_body, loop_idx)) < 0) - return ret; -@@ -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; - -- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ENDIF); -+ vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDIF); - - return VKD3D_OK; - } -@@ -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) - { -- opcode = jump->condition ? VKD3DSIH_CONTINUEP : VKD3DSIH_CONTINUE; -+ opcode = jump->condition ? VSIR_OP_CONTINUEP : VSIR_OP_CONTINUE; - break; - } - jump_target |= 1; - /* fall through */ - - case JUMP_BREAK: -- opcode = jump->condition ? VKD3DSIH_BREAKP : VKD3DSIH_BREAK; -+ opcode = jump->condition ? VSIR_OP_BREAKP : VSIR_OP_BREAK; - break; - - case JUMP_RET: - VKD3D_ASSERT(!jump->condition); -- opcode = VKD3DSIH_RET; -+ opcode = VSIR_OP_RET; - break; - - default: -@@ -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], -- &no_loc, VKD3DSIH_MOV, 1, 1)) -+ &no_loc, VSIR_OP_MOV, 1, 1)) - 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 +6672,7 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, - - switch (ins->opcode) - { -- case VKD3DSIH_LABEL: -+ case VSIR_OP_LABEL: - 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 +6681,9 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, - VKD3D_ASSERT(i == program->instructions.count); - break; - -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - 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 +6849,7 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru - - switch (ins->opcode) - { -- case VKD3DSIH_LABEL: -+ case VSIR_OP_LABEL: - 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 +6858,9 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru - VKD3D_ASSERT(i == program->instructions.count); - break; - -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - 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; -@@ -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[] = - { -- [VKD3D_SHADER_COMPARISON_FUNC_EQUAL] = {VKD3DSIH_EQO, VKD3DSIH_IEQ}, -- [VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL] = {VKD3DSIH_NEO, VKD3DSIH_INE}, -- [VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL] = {VKD3DSIH_GEO, VKD3DSIH_UGE}, -- [VKD3D_SHADER_COMPARISON_FUNC_LESS] = {VKD3DSIH_LTO, VKD3DSIH_ULT}, -- [VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL] = {VKD3DSIH_GEO, VKD3DSIH_UGE, true}, -- [VKD3D_SHADER_COMPARISON_FUNC_GREATER] = {VKD3DSIH_LTO, VKD3DSIH_ULT, true}, -+ [VKD3D_SHADER_COMPARISON_FUNC_EQUAL] = {VSIR_OP_EQO, VSIR_OP_IEQ}, -+ [VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL] = {VSIR_OP_NEO, VSIR_OP_INE}, -+ [VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL] = {VSIR_OP_GEO, VSIR_OP_UGE}, -+ [VKD3D_SHADER_COMPARISON_FUNC_LESS] = {VSIR_OP_LTO, VSIR_OP_ULT}, -+ [VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL] = {VSIR_OP_GEO, VSIR_OP_UGE, true}, -+ [VKD3D_SHADER_COMPARISON_FUNC_GREATER] = {VSIR_OP_LTO, VSIR_OP_ULT, true}, - }; - - 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, 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); - -- *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; -- 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; -- 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, 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; -@@ -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) -+ 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, 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 -@@ -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, 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; - 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; -- struct signature_element *new_elements, *clip_element; - uint32_t position_signature_idx, position_temp, mask; - static const struct vkd3d_shader_location no_loc; -+ 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) -@@ -6422,33 +7224,20 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr - - plane_count = vkd3d_popcount(mask); - -- if (!(new_elements = vkd3d_realloc(signature->elements, -- (signature->element_count + 2) * sizeof(*signature->elements)))) -+ /* Register mask is ignored since we operate after I/O normalisation. */ -+ if (!(clip_element = add_signature_element(signature, "SV_ClipDistance", 0, -+ vkd3d_write_mask_from_component_count(min(plane_count, 4)), 0, VKD3DSIM_NONE))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- signature->elements = new_elements; -- -- low_signature_idx = signature->element_count; -- clip_element = &signature->elements[signature->element_count++]; -- memset(clip_element, 0, sizeof(*clip_element)); -+ low_signature_idx = clip_element - signature->elements; - clip_element->sysval_semantic = VKD3D_SHADER_SV_CLIP_DISTANCE; -- clip_element->component_type = VKD3D_SHADER_COMPONENT_FLOAT; -- clip_element->register_count = 1; -- clip_element->mask = vkd3d_write_mask_from_component_count(min(plane_count, 4)); -- clip_element->used_mask = clip_element->mask; -- clip_element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE; - - if (plane_count > 4) - { -- high_signature_idx = signature->element_count; -- clip_element = &signature->elements[signature->element_count++]; -- memset(clip_element, 0, sizeof(*clip_element)); -+ if (!(clip_element = add_signature_element(signature, "SV_ClipDistance", 1, -+ vkd3d_write_mask_from_component_count(plane_count - 4), 0, VKD3DSIM_NONE))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ high_signature_idx = clip_element - signature->elements; - clip_element->sysval_semantic = VKD3D_SHADER_SV_CLIP_DISTANCE; -- clip_element->semantic_index = 1; -- clip_element->component_type = VKD3D_SHADER_COMPONENT_FLOAT; -- clip_element->register_count = 1; -- clip_element->mask = vkd3d_write_mask_from_component_count(plane_count - 4); -- clip_element->used_mask = clip_element->mask; -- clip_element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE; - } - - /* We're going to be reading from the output position, so we need to go -@@ -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) -+ 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, 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); -+ 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; - 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; - } - } - -@@ -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, VSIR_DATA_F32); - if (max_parameter) - { - 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); -+ 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; - } - -- 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 = 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); -+ 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, 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); -+ 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); -+ 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; - -- 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_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: -@@ -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); -+ 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); - -- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_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); -@@ -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); -+ 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); - -- 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_temp2); - src_param_init_ssa_float(&ins->src[0], ssa_temp); - src_param_init_ssa_float(&ins->src[1], ssa_temp); - -- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_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); -@@ -7014,18 +7792,18 @@ 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, VKD3DSIH_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, 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], 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; - } -@@ -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) -+ 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; -+ size_t pos = ret - instructions->elements; -+ struct vkd3d_shader_instruction *ins; -+ -+ if (!shader_instruction_array_insert_at(&program->instructions, pos, 2)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ ret = NULL; -+ -+ ins = &program->instructions.elements[pos]; -+ -+ /* Write the fog output. */ -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -+ 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); -+ else /* Position or specular W. */ -+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); -+ ++ins; -+ -+ /* 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; -+ -+ *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 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; -+ enum vkd3d_shader_fog_source source; -+ const struct signature_element *e; -+ -+ 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) -+ { -+ vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ "Unsupported fog source parameter type %#x.", source_parameter->type); -+ return VKD3D_ERROR_NOT_IMPLEMENTED; -+ } -+ if (source_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) -+ { -+ vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid fog source parameter data type %#x.", source_parameter->data_type); -+ return VKD3D_ERROR_INVALID_ARGUMENT; -+ } -+ source = source_parameter->u.immediate_constant.u.u32; -+ -+ TRACE("Fog source %#x.\n", source); -+ -+ if (source == VKD3D_SHADER_FOG_SOURCE_FOG) -+ return VKD3D_OK; -+ -+ if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W) -+ { -+ if (program->has_fog || !(e = vsir_signature_find_element_by_name(&program->output_signature, "COLOR", 1))) -+ return VKD3D_OK; -+ source_signature_idx = e - program->output_signature.elements; -+ } -+ else -+ { -+ 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; -+ } -+ } -+ -+ if (!(e = vsir_signature_find_element_by_name(&program->output_signature, "FOG", 0))) -+ { -+ ERR("Fog output not found.\n"); -+ return VKD3D_ERROR_INVALID_SHADER; -+ } -+ fog_signature_idx = e - program->output_signature.elements; -+ -+ temp = program->temp_count++; -+ -+ /* 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) -+ { -+ 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) -+ 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 == source_signature_idx) -+ { -+ dst->reg.type = VKD3DSPR_TEMP; -+ dst->reg.idx[0].offset = temp; -+ } -+ } -+ } -+ -+ program->has_fog = true; -+ -+ return VKD3D_OK; -+} -+ -+ -+/* Distinguishes between instruction sources which are masked, where the used -+ * components of the source are determined by the write mask, and sources which -+ * are not masked, where the used components are pre-defined. -+ * -+ * E.g. "add r0.yz, r1.xyzw, r2.xyzw" uses the .yz components of r1 and r2, and -+ * therefore those sources are considered "masked", but -+ * "dp3 r0.y, r1.xyzw, r2.xyzw" uses the .xyz components. */ -+static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src_idx) -+{ -+ switch (opcode) -+ { -+ case VSIR_OP_ABS: -+ case VSIR_OP_ACOS: -+ case VSIR_OP_ADD: -+ case VSIR_OP_AND: -+ case VSIR_OP_ASIN: -+ case VSIR_OP_ATAN: -+ case VSIR_OP_BFI: -+ case VSIR_OP_BFREV: -+ case VSIR_OP_CMP: -+ case VSIR_OP_CND: -+ case VSIR_OP_COS: -+ case VSIR_OP_COUNTBITS: -+ case VSIR_OP_DADD: /* NB: These are masked, but the mask is double-sized. */ -+ case VSIR_OP_DDIV: -+ case VSIR_OP_DFMA: -+ case VSIR_OP_DIV: -+ case VSIR_OP_DMAX: -+ case VSIR_OP_DMIN: -+ case VSIR_OP_DMOV: -+ case VSIR_OP_DMOVC: -+ case VSIR_OP_DMUL: -+ case VSIR_OP_DRCP: -+ case VSIR_OP_DSX: -+ case VSIR_OP_DSX_COARSE: -+ case VSIR_OP_DSX_FINE: -+ case VSIR_OP_DSY: -+ case VSIR_OP_DSY_COARSE: -+ case VSIR_OP_DSY_FINE: -+ case VSIR_OP_EQO: -+ case VSIR_OP_EQU: -+ case VSIR_OP_EXP: -+ case VSIR_OP_EXPP: -+ case VSIR_OP_F16TOF32: -+ case VSIR_OP_F32TOF16: -+ case VSIR_OP_FIRSTBIT_HI: -+ case VSIR_OP_FIRSTBIT_LO: -+ case VSIR_OP_FIRSTBIT_SHI: -+ case VSIR_OP_FRC: -+ case VSIR_OP_FREM: -+ case VSIR_OP_FTOD: -+ case VSIR_OP_FTOI: -+ case VSIR_OP_FTOU: -+ case VSIR_OP_GEO: -+ case VSIR_OP_GEU: -+ case VSIR_OP_HCOS: -+ case VSIR_OP_HSIN: -+ case VSIR_OP_HTAN: -+ case VSIR_OP_IADD: -+ case VSIR_OP_IBFE: -+ case VSIR_OP_IDIV: -+ case VSIR_OP_IEQ: -+ case VSIR_OP_IGE: -+ case VSIR_OP_ILT: -+ case VSIR_OP_IMAD: -+ case VSIR_OP_IMAX: -+ case VSIR_OP_IMIN: -+ case VSIR_OP_IMUL: -+ case VSIR_OP_IMUL_LOW: -+ case VSIR_OP_INE: -+ case VSIR_OP_INEG: -+ case VSIR_OP_IREM: -+ case VSIR_OP_ISFINITE: -+ case VSIR_OP_ISHL: -+ case VSIR_OP_ISHR: -+ case VSIR_OP_ISINF: -+ case VSIR_OP_ISNAN: -+ case VSIR_OP_ITOD: -+ case VSIR_OP_ITOF: -+ case VSIR_OP_ITOI: -+ case VSIR_OP_LOG: -+ case VSIR_OP_LOGP: -+ case VSIR_OP_LRP: -+ case VSIR_OP_LTO: -+ case VSIR_OP_LTU: -+ case VSIR_OP_MAD: -+ case VSIR_OP_MAX: -+ case VSIR_OP_MIN: -+ case VSIR_OP_MOV: -+ case VSIR_OP_MOVA: -+ case VSIR_OP_MOVC: -+ case VSIR_OP_MSAD: /* FIXME: Is this correct? */ -+ case VSIR_OP_MUL: -+ case VSIR_OP_NEO: -+ case VSIR_OP_NEU: -+ case VSIR_OP_NOT: -+ case VSIR_OP_OR: -+ case VSIR_OP_ORD: -+ case VSIR_OP_PHI: -+ case VSIR_OP_POW: -+ case VSIR_OP_QUAD_READ_ACROSS_D: -+ case VSIR_OP_QUAD_READ_ACROSS_X: -+ case VSIR_OP_QUAD_READ_ACROSS_Y: -+ case VSIR_OP_RCP: -+ case VSIR_OP_ROUND_NE: -+ case VSIR_OP_ROUND_NI: -+ case VSIR_OP_ROUND_PI: -+ case VSIR_OP_ROUND_Z: -+ case VSIR_OP_RSQ: -+ case VSIR_OP_SETP: -+ case VSIR_OP_SGE: -+ case VSIR_OP_SGN: -+ case VSIR_OP_SIN: -+ case VSIR_OP_SINCOS: /* FIXME: Only for sm4. */ -+ case VSIR_OP_SLT: -+ case VSIR_OP_SQRT: -+ case VSIR_OP_SUB: -+ case VSIR_OP_SWAPC: -+ case VSIR_OP_TAN: -+ case VSIR_OP_UBFE: -+ case VSIR_OP_UDIV: -+ case VSIR_OP_UDIV_SIMPLE: -+ case VSIR_OP_UGE: -+ case VSIR_OP_ULT: -+ case VSIR_OP_UMAX: -+ case VSIR_OP_UMIN: -+ case VSIR_OP_UMUL: -+ case VSIR_OP_UNO: -+ case VSIR_OP_UREM: -+ case VSIR_OP_USHR: -+ case VSIR_OP_UTOD: -+ case VSIR_OP_UTOF: -+ case VSIR_OP_UTOU: -+ case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL: -+ case VSIR_OP_WAVE_ACTIVE_BIT_AND: -+ case VSIR_OP_WAVE_ACTIVE_BIT_OR: -+ case VSIR_OP_WAVE_ACTIVE_BIT_XOR: -+ case VSIR_OP_WAVE_ALL_TRUE: -+ case VSIR_OP_WAVE_ANY_TRUE: -+ case VSIR_OP_WAVE_OP_ADD: -+ case VSIR_OP_WAVE_OP_IMAX: -+ case VSIR_OP_WAVE_OP_IMIN: -+ case VSIR_OP_WAVE_OP_MAX: -+ case VSIR_OP_WAVE_OP_MIN: -+ case VSIR_OP_WAVE_OP_MUL: -+ case VSIR_OP_WAVE_OP_UMAX: -+ case VSIR_OP_WAVE_OP_UMIN: -+ case VSIR_OP_WAVE_READ_LANE_FIRST: -+ case VSIR_OP_XOR: -+ return true; -+ -+ /* Atomics can't have a writemask. */ -+ case VSIR_OP_ATOMIC_AND: -+ case VSIR_OP_ATOMIC_CMP_STORE: -+ case VSIR_OP_ATOMIC_IADD: -+ case VSIR_OP_ATOMIC_IMAX: -+ case VSIR_OP_ATOMIC_IMIN: -+ case VSIR_OP_ATOMIC_OR: -+ case VSIR_OP_ATOMIC_UMAX: -+ case VSIR_OP_ATOMIC_UMIN: -+ case VSIR_OP_ATOMIC_XOR: -+ case VSIR_OP_BEM: -+ case VSIR_OP_BRANCH: -+ case VSIR_OP_BREAK: -+ case VSIR_OP_BREAKC: -+ case VSIR_OP_BREAKP: -+ case VSIR_OP_BUFINFO: -+ case VSIR_OP_CALL: -+ case VSIR_OP_CALLNZ: -+ case VSIR_OP_CASE: -+ case VSIR_OP_CHECK_ACCESS_FULLY_MAPPED: /* FIXME: Is this correct? */ -+ case VSIR_OP_CONTINUE: -+ case VSIR_OP_CONTINUEP: -+ case VSIR_OP_CRS: -+ case VSIR_OP_CUT: -+ case VSIR_OP_CUT_STREAM: -+ case VSIR_OP_DCL: -+ case VSIR_OP_DCL_CONSTANT_BUFFER: -+ case VSIR_OP_DCL_FUNCTION_BODY: -+ case VSIR_OP_DCL_FUNCTION_TABLE: -+ case VSIR_OP_DCL_GLOBAL_FLAGS: -+ case VSIR_OP_DCL_GS_INSTANCES: -+ case VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT: -+ case VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: -+ case VSIR_OP_DCL_HS_MAX_TESSFACTOR: -+ case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: -+ case VSIR_OP_DCL_INDEXABLE_TEMP: -+ case VSIR_OP_DCL_INDEX_RANGE: -+ case VSIR_OP_DCL_INPUT: -+ case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: -+ case VSIR_OP_DCL_INPUT_PRIMITIVE: -+ case VSIR_OP_DCL_INPUT_PS: -+ case VSIR_OP_DCL_INPUT_PS_SGV: -+ case VSIR_OP_DCL_INPUT_PS_SIV: -+ case VSIR_OP_DCL_INPUT_SGV: -+ case VSIR_OP_DCL_INPUT_SIV: -+ case VSIR_OP_DCL_INTERFACE: -+ case VSIR_OP_DCL_OUTPUT: -+ case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: -+ case VSIR_OP_DCL_OUTPUT_SGV: -+ case VSIR_OP_DCL_OUTPUT_SIV: -+ case VSIR_OP_DCL_OUTPUT_TOPOLOGY: -+ case VSIR_OP_DCL_RESOURCE_RAW: -+ case VSIR_OP_DCL_RESOURCE_STRUCTURED: -+ case VSIR_OP_DCL_SAMPLER: -+ case VSIR_OP_DCL_STREAM: -+ case VSIR_OP_DCL_TEMPS: -+ case VSIR_OP_DCL_TESSELLATOR_DOMAIN: -+ case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: -+ case VSIR_OP_DCL_TESSELLATOR_PARTITIONING: -+ case VSIR_OP_DCL_TGSM_RAW: -+ case VSIR_OP_DCL_TGSM_STRUCTURED: -+ case VSIR_OP_DCL_THREAD_GROUP: -+ case VSIR_OP_DCL_UAV_RAW: -+ case VSIR_OP_DCL_UAV_STRUCTURED: -+ case VSIR_OP_DCL_UAV_TYPED: -+ case VSIR_OP_DCL_VERTICES_OUT: -+ case VSIR_OP_DEF: -+ case VSIR_OP_DEFAULT: -+ case VSIR_OP_DEFB: -+ case VSIR_OP_DEFI: -+ case VSIR_OP_DEQO: -+ case VSIR_OP_DGEO: -+ case VSIR_OP_DISCARD: -+ case VSIR_OP_DLT: -+ case VSIR_OP_DNE: -+ case VSIR_OP_DP2: -+ case VSIR_OP_DP2ADD: -+ case VSIR_OP_DP3: -+ case VSIR_OP_DP4: -+ case VSIR_OP_DST: -+ case VSIR_OP_DTOF: -+ case VSIR_OP_DTOI: -+ case VSIR_OP_DTOU: -+ case VSIR_OP_ELSE: -+ case VSIR_OP_EMIT: -+ case VSIR_OP_EMIT_STREAM: -+ case VSIR_OP_ENDIF: -+ case VSIR_OP_ENDLOOP: -+ case VSIR_OP_ENDREP: -+ case VSIR_OP_ENDSWITCH: -+ case VSIR_OP_FCALL: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_DECLS: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: -+ case VSIR_OP_IF: -+ case VSIR_OP_IFC: -+ /* It's unclear if any mapping is done for the source value. -+ * Does it require replicate swizzle? */ -+ case VSIR_OP_IMM_ATOMIC_ALLOC: -+ case VSIR_OP_IMM_ATOMIC_AND: -+ case VSIR_OP_IMM_ATOMIC_CMP_EXCH: -+ case VSIR_OP_IMM_ATOMIC_CONSUME: -+ case VSIR_OP_IMM_ATOMIC_EXCH: -+ case VSIR_OP_IMM_ATOMIC_IADD: -+ case VSIR_OP_IMM_ATOMIC_IMAX: -+ case VSIR_OP_IMM_ATOMIC_IMIN: -+ case VSIR_OP_IMM_ATOMIC_OR: -+ case VSIR_OP_IMM_ATOMIC_UMAX: -+ case VSIR_OP_IMM_ATOMIC_UMIN: -+ case VSIR_OP_IMM_ATOMIC_XOR: -+ case VSIR_OP_LABEL: -+ case VSIR_OP_LOOP: -+ case VSIR_OP_LIT: -+ case VSIR_OP_M3x2: -+ case VSIR_OP_M3x3: -+ case VSIR_OP_M3x4: -+ case VSIR_OP_M4x3: -+ case VSIR_OP_M4x4: -+ case VSIR_OP_NOP: -+ /* NRM writemask must be .xyz or .xyzw. */ -+ case VSIR_OP_NRM: -+ case VSIR_OP_PHASE: -+ case VSIR_OP_REP: -+ case VSIR_OP_RET: -+ case VSIR_OP_RETP: -+ /* Store instructions always require a trivial writemask. */ -+ case VSIR_OP_STORE_RAW: -+ case VSIR_OP_STORE_STRUCTURED: -+ case VSIR_OP_STORE_UAV_TYPED: -+ case VSIR_OP_SWITCH: -+ case VSIR_OP_SWITCH_MONOLITHIC: -+ case VSIR_OP_SYNC: -+ case VSIR_OP_TEX: -+ 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_TEXKILL: -+ case VSIR_OP_TEXLD: -+ case VSIR_OP_TEXLDD: -+ case VSIR_OP_TEXLDL: -+ case VSIR_OP_TEXM3x2DEPTH: -+ case VSIR_OP_TEXM3x2PAD: -+ case VSIR_OP_TEXM3x2TEX: -+ case VSIR_OP_TEXM3x3: -+ case VSIR_OP_TEXM3x3DIFF: -+ case VSIR_OP_TEXM3x3PAD: -+ case VSIR_OP_TEXM3x3SPEC: -+ case VSIR_OP_TEXM3x3TEX: -+ case VSIR_OP_TEXM3x3VSPEC: -+ case VSIR_OP_TEXREG2AR: -+ case VSIR_OP_TEXREG2GB: -+ case VSIR_OP_TEXREG2RGB: -+ case VSIR_OP_WAVE_ACTIVE_BALLOT: -+ case VSIR_OP_WAVE_ALL_BIT_COUNT: -+ case VSIR_OP_WAVE_IS_FIRST_LANE: -+ case VSIR_OP_WAVE_PREFIX_BIT_COUNT: -+ return false; -+ -+ case VSIR_OP_QUAD_READ_LANE_AT: -+ case VSIR_OP_WAVE_READ_LANE_AT: -+ return (src_idx == 0); -+ -+ /* sm4 resource instructions are an odd case, since they're not actually -+ * per-component. However, the "swizzle" placed on the resource allows -+ * arbitrary destination writemasks to be used. -+ * -+ * This means that for the purposes of the "remapping" done by -+ * temp_allocator_set_dst(), we can basically treat those sources as -+ * "mapped", altering them when we reassign the destination writemask. */ -+ -+ /* FIXME: The documentation seems to say that these instructions behave -+ * this way, but is it correct? -+ * (It's silent about EVAL_*, but presumably they behave the same way.) */ -+ case VSIR_OP_EVAL_CENTROID: -+ case VSIR_OP_EVAL_SAMPLE_INDEX: -+ case VSIR_OP_SAMPLE_INFO: -+ case VSIR_OP_SAMPLE_POS: -+ return (src_idx == 0); -+ case VSIR_OP_GATHER4: -+ case VSIR_OP_GATHER4_C: -+ case VSIR_OP_GATHER4_C_S: -+ case VSIR_OP_GATHER4_S: -+ case VSIR_OP_LD: -+ case VSIR_OP_LD2DMS: -+ case VSIR_OP_LD2DMS_S: -+ case VSIR_OP_LD_RAW: -+ case VSIR_OP_LD_RAW_S: -+ case VSIR_OP_LD_S: -+ case VSIR_OP_LD_UAV_TYPED: -+ case VSIR_OP_LD_UAV_TYPED_S: -+ case VSIR_OP_LOD: -+ case VSIR_OP_RESINFO: -+ case VSIR_OP_SAMPLE: -+ case VSIR_OP_SAMPLE_B: -+ case VSIR_OP_SAMPLE_B_CL_S: -+ case VSIR_OP_SAMPLE_C: -+ case VSIR_OP_SAMPLE_CL_S: -+ case VSIR_OP_SAMPLE_C_CL_S: -+ case VSIR_OP_SAMPLE_C_LZ: -+ case VSIR_OP_SAMPLE_C_LZ_S: -+ case VSIR_OP_SAMPLE_GRAD: -+ case VSIR_OP_SAMPLE_GRAD_CL_S: -+ case VSIR_OP_SAMPLE_LOD: -+ case VSIR_OP_SAMPLE_LOD_S: -+ return (src_idx == 1); -+ case VSIR_OP_GATHER4_PO: -+ case VSIR_OP_GATHER4_PO_C: -+ case VSIR_OP_GATHER4_PO_C_S: -+ case VSIR_OP_GATHER4_PO_S: -+ case VSIR_OP_LD_STRUCTURED: -+ case VSIR_OP_LD_STRUCTURED_S: -+ return (src_idx == 2); -+ -+ case VSIR_OP_INVALID: -+ case VSIR_OP_COUNT: -+ break; -+ } -+ -+ vkd3d_unreachable(); -+} -+ -+struct liveness_tracker -+{ -+ struct liveness_tracker_reg -+ { -+ bool written; -+ bool fixed_mask; -+ uint8_t mask; -+ unsigned int first_write, last_access; -+ } *ssa_regs; -+}; -+ -+static void liveness_track_src(struct liveness_tracker *tracker, -+ struct vkd3d_shader_src_param *src, unsigned int index) -+{ -+ for (unsigned int k = 0; k < src->reg.idx_count; ++k) -+ { -+ if (src->reg.idx[k].rel_addr) -+ liveness_track_src(tracker, src->reg.idx[k].rel_addr, index); -+ } -+ -+ if (src->reg.type == VKD3DSPR_SSA) -+ tracker->ssa_regs[src->reg.idx[0].offset].last_access = index; -+} -+ -+static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_shader_dst_param *dst, -+ unsigned int index, const struct vkd3d_shader_version *version, enum vkd3d_shader_opcode opcode) -+{ -+ struct liveness_tracker_reg *reg; -+ -+ for (unsigned int k = 0; k < dst->reg.idx_count; ++k) -+ { -+ if (dst->reg.idx[k].rel_addr) -+ liveness_track_src(tracker, dst->reg.idx[k].rel_addr, index); -+ } -+ -+ if (dst->reg.type == VKD3DSPR_SSA) -+ reg = &tracker->ssa_regs[dst->reg.idx[0].offset]; -+ else -+ return; -+ -+ if (!reg->written) -+ reg->first_write = index; -+ reg->last_access = index; -+ reg->written = true; -+ reg->mask |= dst->write_mask; -+ -+ switch (opcode) -+ { -+ case VSIR_OP_BEM: -+ case VSIR_OP_CRS: -+ case VSIR_OP_DST: -+ case VSIR_OP_LIT: -+ case VSIR_OP_M3x2: -+ case VSIR_OP_M3x3: -+ case VSIR_OP_M3x4: -+ case VSIR_OP_M4x3: -+ case VSIR_OP_M4x4: -+ case VSIR_OP_NRM: -+ case VSIR_OP_TEX: -+ 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_TEXLD: -+ case VSIR_OP_TEXLDD: -+ case VSIR_OP_TEXLDL: -+ case VSIR_OP_TEXM3x2DEPTH: -+ case VSIR_OP_TEXM3x2PAD: -+ case VSIR_OP_TEXM3x2TEX: -+ case VSIR_OP_TEXM3x3: -+ case VSIR_OP_TEXM3x3DIFF: -+ case VSIR_OP_TEXM3x3PAD: -+ case VSIR_OP_TEXM3x3SPEC: -+ case VSIR_OP_TEXM3x3TEX: -+ case VSIR_OP_TEXM3x3VSPEC: -+ case VSIR_OP_TEXREG2AR: -+ case VSIR_OP_TEXREG2GB: -+ case VSIR_OP_TEXREG2RGB: -+ /* All of these instructions have fixed destinations—they can -+ * in some cases be masked, but the destination cannot be -+ * reallocated to a different set of components. */ -+ case VSIR_OP_IMUL: -+ case VSIR_OP_SWAPC: -+ case VSIR_OP_UDIV: -+ case VSIR_OP_UMUL: -+ /* These instructions don't have fixed destinations, but they have -+ * multiple destination and are per-component, meaning that the -+ * destination masks for each component have to match. -+ * This is a bit tricky to pull off, so for now we just force -+ * these to have a fixed mask as well. -+ * This assumes that the destination masks are equal to each other -+ * to begin with! */ -+ reg->fixed_mask = true; -+ break; -+ -+ case VSIR_OP_SINCOS: -+ /* sm1 has a fixed destination like LIT, NRM. -+ * sm4 is two-component and masked, like IMUL. */ -+ if (version->major < 3) -+ { -+ /* We have the additional constraint here that sincos scratches -+ * whichever components of .xyz it doesn't write. We can achieve -+ * this by simply adding those components to reg->mask. */ -+ reg->mask |= 0x7; -+ } -+ reg->fixed_mask = true; -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+static void liveness_tracker_cleanup(struct liveness_tracker *tracker) -+{ -+ vkd3d_free(tracker->ssa_regs); -+} -+ -+static enum vkd3d_result track_liveness(struct vsir_program *program, struct liveness_tracker *tracker) -+{ -+ struct liveness_tracker_reg *regs; -+ unsigned int loop_depth = 0; -+ unsigned int loop_start = 0; -+ -+ memset(tracker, 0, sizeof(*tracker)); -+ -+ if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ tracker->ssa_regs = regs; -+ -+ for (unsigned int i = 0; i < program->instructions.count; ++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++) -+ loop_start = i; -+ } -+ else if (ins->opcode == VSIR_OP_ENDLOOP || ins->opcode == VSIR_OP_ENDREP) -+ { -+ if (!--loop_depth) -+ { -+ /* Go through the allocator, find anything that was touched -+ * during the loop, and extend its liveness to the whole range -+ * of the loop. -+ * This isn't very sophisticated (e.g. we could try to avoid -+ * this for registers first written inside a loop body and only -+ * ever read inside one), but many of the cases that matter are -+ * affected by other optimizations such as copy propagation -+ * anyway. -+ * -+ * This is overkill for SSA registers. If an SSA register is -+ * written in loop L and last read in L, we don't need to touch -+ * its liveness. If it's last read in an inferior loop of L, we -+ * only need to extend its last-read to the end of L. (And it -+ * should be illegal for an SSA value to be read in a block -+ * containing L.) -+ * We don't try to perform this optimization yet, in the name of -+ * maximal simplicity, and also because this code is intended to -+ * be extended to non-SSA values. */ -+ for (unsigned int j = 0; j < program->ssa_count; ++j) -+ { -+ struct liveness_tracker_reg *reg = &tracker->ssa_regs[j]; -+ -+ if (reg->first_write > loop_start) -+ reg->first_write = loop_start; -+ if (reg->last_access < i) -+ reg->last_access = i; -+ } -+ } -+ } -+ -+ for (unsigned int j = 0; j < ins->dst_count; ++j) -+ liveness_track_dst(tracker, &ins->dst[j], i, &program->shader_version, ins->opcode); -+ for (unsigned int j = 0; j < ins->src_count; ++j) -+ liveness_track_src(tracker, &ins->src[j], i); -+ } -+ -+ return VKD3D_OK; -+} -+ -+struct temp_allocator -+{ -+ struct vkd3d_shader_message_context *message_context; -+ struct temp_allocator_reg -+ { -+ uint8_t allocated_mask; -+ uint32_t temp_id; -+ } *ssa_regs; -+ size_t allocated_ssa_count; -+ enum vkd3d_result result; -+}; -+ -+static uint8_t get_available_writemask(const struct temp_allocator *allocator, -+ struct liveness_tracker *tracker, unsigned int first_write, unsigned int last_access, uint32_t temp_id) -+{ -+ uint8_t writemask = VKD3DSP_WRITEMASK_ALL; -+ -+ for (size_t i = 0; i < allocator->allocated_ssa_count; ++i) -+ { -+ const struct temp_allocator_reg *reg = &allocator->ssa_regs[i]; -+ const struct liveness_tracker_reg *liveness_reg = &tracker->ssa_regs[i]; -+ -+ /* We do not overlap if first write == last read: -+ * this is the case where we are allocating the result of that -+ * expression, e.g. "add r0, r0, r1". */ -+ -+ if (reg->temp_id == temp_id -+ && first_write < liveness_reg->last_access -+ && last_access > liveness_reg->first_write) -+ writemask &= ~reg->allocated_mask; -+ -+ if (!writemask) -+ return writemask; -+ } -+ -+ return writemask; -+} -+ -+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 false; -+ -+ for (uint32_t id = base_id;; ++id) -+ { -+ uint8_t available_mask = get_available_writemask(allocator, tracker, -+ 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 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 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; - -- if (!shader_instruction_array_insert_at(&program->instructions, pos, 2)) -- return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -+ /* Leave replicate swizzles alone; some instructions need them. */ -+ if (swizzle == VKD3D_SHADER_SWIZZLE(X, X, X, X) -+ || swizzle == VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y) -+ || swizzle == VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z) -+ || swizzle == VKD3D_SHADER_SWIZZLE(W, W, W, W)) -+ return swizzle; - -- ins = &program->instructions.elements[pos]; -+ for (unsigned int dst_component = 0; dst_component < VKD3D_VEC4_SIZE; ++dst_component) -+ { -+ if (writemask & (1u << dst_component)) -+ vsir_swizzle_set_component(&ret, dst_component, vsir_swizzle_get_component(swizzle, src_component++)); -+ } -+ return ret; -+} - -- /* Write the fog output. */ -- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); -- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, 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); -- else /* Position or specular W. */ -- ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); -- ++ins; -+static void vsir_remap_immconst(struct vkd3d_shader_src_param *src, unsigned int writemask) -+{ -+ union vsir_immediate_constant prev = src->reg.u; -+ unsigned int src_component = 0; - -- /* Write the position or specular output. */ -- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); -- dst_param_init_output(&ins->dst[0], vkd3d_data_type_from_component_type(e->component_type), -- source_signature_idx, e->mask); -- src_param_init_temp_float4(&ins->src[0], temp); -- ++ins; -+ for (unsigned int dst_component = 0; dst_component < VKD3D_VEC4_SIZE; ++dst_component) -+ { -+ if (writemask & (1u << dst_component)) -+ src->reg.u.immconst_u32[dst_component] = prev.immconst_u32[src_component++]; -+ } -+} - -- *ret_pos = pos + 2; -- return VKD3D_OK; -+static void vsir_remap_immconst64(struct vkd3d_shader_src_param *src, unsigned int writemask) -+{ -+ if (writemask == (VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3)) -+ src->reg.u.immconst_u64[1] = src->reg.u.immconst_u64[0]; - } - --static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *program, -- struct vsir_transformation_context *ctx) -+static bool vsir_opcode_is_double(enum vkd3d_shader_opcode opcode) - { -- 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; -- enum vkd3d_shader_fog_source source; -- const struct signature_element *e; -+ switch (opcode) -+ { -+ case VSIR_OP_DADD: -+ case VSIR_OP_DDIV: -+ case VSIR_OP_DFMA: -+ case VSIR_OP_DMAX: -+ case VSIR_OP_DMIN: -+ case VSIR_OP_DMOV: -+ case VSIR_OP_DMOVC: -+ case VSIR_OP_DMUL: -+ case VSIR_OP_DRCP: -+ case VSIR_OP_DEQO: -+ case VSIR_OP_DGEO: -+ case VSIR_OP_DLT: -+ case VSIR_OP_DNE: -+ case VSIR_OP_DTOF: -+ case VSIR_OP_DTOI: -+ case VSIR_OP_DTOU: -+ case VSIR_OP_FTOD: -+ return true; - -- if (!is_pre_rasterization_shader(program->shader_version.type)) -- return VKD3D_OK; -+ default: -+ return false; -+ } -+} - -- if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE))) -- return VKD3D_OK; -+static void temp_allocator_set_dst(struct temp_allocator *allocator, -+ struct vkd3d_shader_dst_param *dst, const struct vkd3d_shader_instruction *ins) -+{ -+ struct temp_allocator_reg *reg; - -- if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) -+ for (unsigned int k = 0; k < dst->reg.idx_count; ++k) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -- "Unsupported fog source parameter type %#x.", source_parameter->type); -- return VKD3D_ERROR_NOT_IMPLEMENTED; -+ if (dst->reg.idx[k].rel_addr) -+ temp_allocator_set_src(allocator, dst->reg.idx[k].rel_addr); - } -- if (source_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) -+ -+ if (dst->reg.type == VKD3DSPR_SSA) -+ reg = &allocator->ssa_regs[dst->reg.idx[0].offset]; -+ else -+ 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) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid fog source parameter data type %#x.", source_parameter->data_type); -- return VKD3D_ERROR_INVALID_ARGUMENT; -+ dst->write_mask = reg->allocated_mask; -+ -+ if (vsir_opcode_is_double(ins->opcode)) -+ { -+ vkd3d_shader_error(allocator->message_context, &ins->location, -+ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Doubles are not currently handled."); -+ allocator->result = VKD3D_ERROR_NOT_IMPLEMENTED; -+ } -+ -+ for (unsigned int i = 0; i < ins->src_count; ++i) -+ { -+ struct vkd3d_shader_src_param *src = &ins->src[i]; -+ -+ if (vsir_src_is_masked(ins->opcode, i)) -+ { -+ if (src->reg.type == VKD3DSPR_IMMCONST) -+ vsir_remap_immconst(src, dst->write_mask); -+ else if (src->reg.type == VKD3DSPR_IMMCONST64) -+ vsir_remap_immconst64(src, dst->write_mask); -+ else -+ src->swizzle = vsir_map_swizzle(src->swizzle, dst->write_mask); -+ } -+ } - } -- source = source_parameter->u.immediate_constant.u.u32; -+} - -- TRACE("Fog source %#x.\n", source); -+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; -+ enum vkd3d_result ret; - -- if (source == VKD3D_SHADER_FOG_SOURCE_FOG) -+ if (!program->ssa_count) - return VKD3D_OK; - -- if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W) -+ if ((ret = track_liveness(program, &tracker))) -+ return ret; -+ -+ if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) - { -- if (program->has_fog || !(e = vsir_signature_find_element_by_name(&program->output_signature, "COLOR", 1))) -- return VKD3D_OK; -- source_signature_idx = e - program->output_signature.elements; -+ liveness_tracker_cleanup(&tracker); -+ return VKD3D_ERROR_OUT_OF_MEMORY; - } -- else -+ allocator.message_context = message_context; -+ allocator.ssa_regs = regs; -+ -+ for (unsigned int i = 0; i < program->ssa_count; ++i) - { -- if (!vsir_signature_find_sysval(&program->output_signature, -- VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx)) -+ const struct liveness_tracker_reg *liveness_reg = &tracker.ssa_regs[i]; -+ struct temp_allocator_reg *reg = &allocator.ssa_regs[i]; -+ -+ 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; - } - -- if (!(e = vsir_signature_find_element_by_name(&program->output_signature, "FOG", 0))) -+ for (unsigned int i = 0; i < program->instructions.count; ++i) - { -- ERR("Fog output not found.\n"); -- return VKD3D_ERROR_INVALID_SHADER; -+ 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) -+ 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) -+ 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]; - -- if (vsir_instruction_is_dcl(ins)) -+ if (ins->opcode == VSIR_OP_DCL_TEMPS) -+ { -+ ins->declaration.count = temp_count; -+ temp_count = 0; - continue; -+ } - -- 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 -+ || ins->opcode == VSIR_OP_HS_JOIN_PHASE)) - { -- size_t new_pos; -- int ret; -+ /* 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)) -+ 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) -- return ret; -- i = new_pos; -+ ins = &program->instructions.elements[i + 1]; -+ vsir_instruction_init(ins, &program->instructions.elements[i].location, VSIR_OP_DCL_TEMPS); -+ ins->declaration.count = temp_count; -+ temp_count = 0; - continue; - } - -- for (size_t 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) -- { -- 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->has_fog = true; -+ if (temp_count && program->shader_version.major >= 4) -+ { -+ struct vkd3d_shader_instruction *ins; -+ -+ if (!shader_instruction_array_insert_at(&program->instructions, 0, 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->declaration.count = temp_count; -+ } - - 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) - { -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: phase = PHASE_CONTROL_POINT; break; -- case VKD3DSIH_HS_FORK_PHASE: phase = PHASE_FORK; break; -- case VKD3DSIH_HS_JOIN_PHASE: phase = PHASE_JOIN; break; -- case VKD3DSIH_INVALID: phase = PHASE_NONE; break; -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: phase = PHASE_CONTROL_POINT; break; -+ case VSIR_OP_HS_FORK_PHASE: phase = PHASE_FORK; break; -+ case VSIR_OP_HS_JOIN_PHASE: phase = PHASE_JOIN; break; -+ case VSIR_OP_INVALID: phase = PHASE_NONE; break; - - default: - vkd3d_unreachable(); -@@ -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) - { -- if (reg->precision != VKD3D_SHADER_REGISTER_PRECISION_DEFAULT) -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, -- "Invalid precision %#x for a CONSTBUFFER register.", reg->precision); -- - if (reg->dimension != VSIR_DIMENSION_VEC4) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, - "Invalid dimension %#x for a CONSTBUFFER register.", reg->dimension); -@@ -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); - -+ if (dst->modifiers & VKD3DSPDM_SATURATE) -+ { -+ switch (dst->reg.data_type) -+ { -+ case VSIR_DATA_F16: -+ case VSIR_DATA_F32: -+ case VSIR_DATA_F64: -+ break; -+ -+ default: -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid data type %#x for destination with saturate modifier.", dst->reg.data_type); -+ break; -+ -+ } -+ } -+ - switch (dst->shift) - { - case 0: -+ break; -+ - case 1: - case 2: - case 3: - case 13: - case 14: - case 15: -+ 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 +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 << VSIR_DATA_F64) -+#define F32_BIT (1u << VSIR_DATA_F32) -+#define F16_BIT (1u << VSIR_DATA_F16) -+ -+#define I32_BIT (1u << VSIR_DATA_I32) -+ -+#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) - { -+ static const struct -+ { -+ uint32_t data_type_mask; -+ } -+ src_modifier_data[VKD3DSPSM_COUNT] = -+ { -+ [VKD3DSPSM_NEG] = {F64_BIT | F32_BIT | F16_BIT | I32_BIT | U64_BIT | U32_BIT | U16_BIT}, -+ [VKD3DSPSM_BIAS] = {F32_BIT}, -+ [VKD3DSPSM_BIASNEG] = {F32_BIT}, -+ [VKD3DSPSM_SIGN] = {F32_BIT}, -+ [VKD3DSPSM_SIGNNEG] = {F32_BIT}, -+ [VKD3DSPSM_COMP] = {F32_BIT}, -+ [VKD3DSPSM_X2] = {F32_BIT}, -+ [VKD3DSPSM_X2NEG] = {F32_BIT}, -+ [VKD3DSPSM_DZ] = {F32_BIT}, -+ [VKD3DSPSM_DW] = {F32_BIT}, -+ [VKD3DSPSM_ABS] = {F64_BIT | F32_BIT | F16_BIT}, -+ [VKD3DSPSM_ABSNEG] = {F64_BIT | F32_BIT | F16_BIT}, -+ /* This doesn't make a lot of sense. NOT is used only by D3DBC, and -+ * apparently only for IF instructions reading from a CONSTBOOL register. -+ * However, currently the D3DBC parser generates those registers of -+ * type float, so for the moment let's allow that. */ -+ [VKD3DSPSM_NOT] = {F32_BIT}, -+ }; -+ - vsir_validate_register(ctx, &src->reg); - - if (src->swizzle & ~0x03030303u) -@@ -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); - -+ if (src->modifiers != VKD3DSPSM_NONE && src->modifiers < ARRAY_SIZE(src_modifier_data)) -+ { -+ if (!(src_modifier_data[src->modifiers].data_type_mask & (1u << src->reg.data_type))) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, -+ "Source has invalid modifier %#x for data type %u.", src->modifiers, src->reg.data_type); -+ } -+ - switch (src->reg.type) - { - case VKD3DSPR_SSA: -@@ -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 %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 +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 %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 +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 %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 +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 %zu for instruction \"%s\" (%#x); expected at most %u.", -+ instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), -+ instruction->opcode, count); - return false; - } - -@@ -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) -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "Invalid instruction %#x in %s shader.", -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, -+ "Invalid instruction \"%s\" (%#x) in %s shader.", -+ vsir_opcode_get_name(instruction->opcode, ""), - instruction->opcode, name_from_cf_type(ctx->program->cf_type)); - } - -@@ -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) -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, -- "Phase instruction %#x is only valid in a hull shader.", -- instruction->opcode); -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE, -+ "Phase instruction \"%s\" (%#x) is only valid in a hull shader.", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - if (ctx->depth != 0) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, -- "Phase instruction %#x must appear to top level.", -- instruction->opcode); -+ "Phase instruction \"%s\" (%#x) must appear at the top level.", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - ctx->phase = instruction->opcode; - ctx->dcl_temps_found = false; - } - -+static void vsir_validate_elementwise_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) -+{ -+ enum vsir_data_type dst_data_type; -+ unsigned int i; -+ -+ if (instruction->dst_count < 1) -+ return; -+ -+ dst_data_type = instruction->dst[0].reg.data_type; -+ -+ if (dst_data_type >= VSIR_DATA_TYPE_COUNT) -+ return; -+ -+ if (!types[dst_data_type]) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid data type %#x for elementwise operation \"%s\" (%#x).", -+ dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ -+ for (i = 0; i < instruction->src_count; ++i) -+ { -+ if (instruction->src[i].reg.data_type != dst_data_type) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Data type %#x for operand %u doesn't match the destination data type %#x " -+ "for elementwise operation \"%s\" (%#x).", -+ instruction->src[i].reg.data_type, i, dst_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ } -+} -+ -+static void vsir_validate_double_elementwise_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VSIR_DATA_F64] = true, -+ }; -+ -+ vsir_validate_elementwise_operation(ctx, instruction, types); -+} -+ -+static void vsir_validate_float_elementwise_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VSIR_DATA_F32] = true, -+ }; -+ -+ vsir_validate_elementwise_operation(ctx, instruction, types); -+} -+ -+static void vsir_validate_integer_elementwise_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VSIR_DATA_I32] = true, -+ [VSIR_DATA_U32] = true, -+ [VSIR_DATA_U64] = true, -+ }; -+ -+ vsir_validate_elementwise_operation(ctx, instruction, types); -+} -+ -+static void vsir_validate_logic_elementwise_operation(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_elementwise_operation(ctx, instruction, types); -+} -+ -+static void vsir_validate_comparison_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) -+{ -+ enum vsir_data_type dst_data_type, src_data_type; -+ unsigned int i; -+ -+ if (instruction->dst_count < 1) -+ return; -+ -+ dst_data_type = instruction->dst[0].reg.data_type; -+ -+ 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); -+ -+ if (instruction->src_count == 0) -+ return; -+ -+ src_data_type = instruction->src[0].reg.data_type; -+ -+ if (src_data_type >= VSIR_DATA_TYPE_COUNT) -+ return; -+ -+ if (!types[src_data_type]) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Invalid data type %#x for comparison operation \"%s\" (%#x).", -+ src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ -+ for (i = 1; i < instruction->src_count; ++i) -+ { -+ if (instruction->src[i].reg.data_type != src_data_type) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ "Data type %#x for operand %u doesn't match the first operands data type %#x " -+ "for comparison operation \"%s\" (%#x).", -+ instruction->src[i].reg.data_type, i, src_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ } -+} -+ -+static void vsir_validate_double_comparison_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VSIR_DATA_F64] = true, -+ }; -+ -+ vsir_validate_comparison_operation(ctx, instruction, types); -+} -+ -+static void vsir_validate_float_comparison_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [VSIR_DATA_F32] = true, -+ [VSIR_DATA_F64] = true, -+ }; -+ -+ vsir_validate_comparison_operation(ctx, instruction, types); -+} -+ -+static void vsir_validate_integer_comparison_operation(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ static const bool types[VSIR_DATA_TYPE_COUNT] = -+ { -+ [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 +11007,7 @@ static void vsir_validate_dcl_index_range(struct validation_context *ctx, - - if (ctx->program->normalisation_level >= VSIR_NORMALISED_SM6) - { -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE, - "DCL_INDEX_RANGE is not allowed with fully normalised input/output."); - return; - } -@@ -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); -- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF) -+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_IF) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, - "ELSE instruction doesn't terminate IF block."); - else -- ctx->blocks[ctx->depth - 1] = VKD3DSIH_ELSE; -+ ctx->blocks[ctx->depth - 1] = VSIR_OP_ELSE; - } - - static void vsir_validate_endif(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) - { - vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); -- if (ctx->depth == 0 || (ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF -- && ctx->blocks[ctx->depth - 1] != VKD3DSIH_ELSE)) -+ if (ctx->depth == 0 || (ctx->blocks[ctx->depth - 1] != VSIR_OP_IF -+ && ctx->blocks[ctx->depth - 1] != VSIR_OP_ELSE)) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, - "ENDIF instruction doesn't terminate IF/ELSE block."); - else -@@ -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); -- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_LOOP) -+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_LOOP) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, - "ENDLOOP instruction doesn't terminate LOOP block."); - else -@@ -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); -- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_REP) -+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_REP) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, - "ENDREP instruction doesn't terminate REP block."); - else -@@ -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); -- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_SWITCH) -+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_SWITCH) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, - "ENDSWITCH instruction doesn't terminate SWITCH block."); - else - --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); -- vsir_validator_push_block(ctx, VKD3DSIH_IF); -+ vsir_validator_push_block(ctx, VSIR_OP_IF); - } - - static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) - { - 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 +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); -- vsir_validator_push_block(ctx, VKD3DSIH_LOOP); -+ vsir_validator_push_block(ctx, VSIR_OP_LOOP); - } - - static void vsir_validate_nop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -@@ -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); -- vsir_validator_push_block(ctx, VKD3DSIH_REP); -+ vsir_validator_push_block(ctx, VSIR_OP_REP); - } - - static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -@@ -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); -- vsir_validator_push_block(ctx, VKD3DSIH_SWITCH); -+ vsir_validator_push_block(ctx, VSIR_OP_SWITCH); - } - - static void vsir_validate_switch_monolithic(struct validation_context *ctx, -@@ -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[] = - { -- [VKD3DSIH_BRANCH] = {0, ~0u, vsir_validate_branch}, -- [VKD3DSIH_HS_CONTROL_POINT_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, -- [VKD3DSIH_HS_DECLS] = {0, 0, vsir_validate_hull_shader_phase}, -- [VKD3DSIH_HS_FORK_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, -- [VKD3DSIH_HS_JOIN_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, -- [VKD3DSIH_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances}, -- [VKD3DSIH_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor}, -- [VKD3DSIH_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range}, -- [VKD3DSIH_DCL_INPUT] = {0, 0, vsir_validate_dcl_input}, -- [VKD3DSIH_DCL_INPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_input_primitive}, -- [VKD3DSIH_DCL_INPUT_PS] = {0, 0, vsir_validate_dcl_input_ps}, -- [VKD3DSIH_DCL_INPUT_PS_SGV] = {0, 0, vsir_validate_dcl_input_ps_sgv}, -- [VKD3DSIH_DCL_INPUT_PS_SIV] = {0, 0, vsir_validate_dcl_input_ps_siv}, -- [VKD3DSIH_DCL_INPUT_SGV] = {0, 0, vsir_validate_dcl_input_sgv}, -- [VKD3DSIH_DCL_INPUT_SIV] = {0, 0, vsir_validate_dcl_input_siv}, -- [VKD3DSIH_DCL_OUTPUT] = {0, 0, vsir_validate_dcl_output}, -- [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT] = {0, 0, vsir_validate_dcl_output_control_point_count}, -- [VKD3DSIH_DCL_OUTPUT_SIV] = {0, 0, vsir_validate_dcl_output_siv}, -- [VKD3DSIH_DCL_OUTPUT_TOPOLOGY] = {0, 0, vsir_validate_dcl_output_topology}, -- [VKD3DSIH_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps}, -- [VKD3DSIH_DCL_TESSELLATOR_DOMAIN] = {0, 0, vsir_validate_dcl_tessellator_domain}, -- [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_tessellator_output_primitive}, -- [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING] = {0, 0, vsir_validate_dcl_tessellator_partitioning}, -- [VKD3DSIH_DCL_VERTICES_OUT] = {0, 0, vsir_validate_dcl_vertices_out}, -- [VKD3DSIH_ELSE] = {0, 0, vsir_validate_else}, -- [VKD3DSIH_ENDIF] = {0, 0, vsir_validate_endif}, -- [VKD3DSIH_ENDLOOP] = {0, 0, vsir_validate_endloop}, -- [VKD3DSIH_ENDREP] = {0, 0, vsir_validate_endrep}, -- [VKD3DSIH_ENDSWITCH] = {0, 0, vsir_validate_endswitch}, -- [VKD3DSIH_IF] = {0, 1, vsir_validate_if}, -- [VKD3DSIH_IFC] = {0, 2, vsir_validate_ifc}, -- [VKD3DSIH_LABEL] = {0, 1, vsir_validate_label}, -- [VKD3DSIH_LOOP] = {0, ~0u, vsir_validate_loop}, -- [VKD3DSIH_NOP] = {0, 0, vsir_validate_nop}, -- [VKD3DSIH_PHI] = {1, ~0u, vsir_validate_phi}, -- [VKD3DSIH_REP] = {0, 1, vsir_validate_rep}, -- [VKD3DSIH_RET] = {0, 0, vsir_validate_ret}, -- [VKD3DSIH_SWITCH] = {0, 1, vsir_validate_switch}, -- [VKD3DSIH_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, -+ [VSIR_OP_ABS] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_ACOS] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_ADD] = {1, 2, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_AND] = {1, 2, vsir_validate_logic_elementwise_operation}, -+ [VSIR_OP_ASIN] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [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}, -+ [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 +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]); - -- if (instruction->opcode >= VKD3DSIH_INVALID) -+ if (instruction->opcode >= VSIR_OP_INVALID) - { -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Invalid instruction handler %#x.", -- instruction->opcode); -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE, -+ "Invalid opcode %#x.", instruction->opcode); - } - -- if (version->type == VKD3D_SHADER_TYPE_HULL && ctx->phase == VKD3DSIH_INVALID) -+ if (version->type == VKD3D_SHADER_TYPE_HULL && ctx->phase == VSIR_OP_INVALID) - { - switch (instruction->opcode) - { -- case VKD3DSIH_NOP: -- case VKD3DSIH_HS_DECLS: -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_NOP: -+ case VSIR_OP_HS_DECLS: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - break; - - default: - if (!vsir_instruction_is_dcl(instruction)) -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, -- "Instruction %#x appear before any phase instruction in a hull shader.", -- instruction->opcode); -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE, -+ "Instruction \"%s\" (%#x) appears before any phase instruction in a hull shader.", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - break; - } - } -@@ -9721,19 +11886,19 @@ static void vsir_validate_instruction(struct validation_context *ctx) - { - switch (instruction->opcode) - { -- case VKD3DSIH_NOP: -- case VKD3DSIH_LABEL: -- case VKD3DSIH_HS_DECLS: -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_NOP: -+ case VSIR_OP_LABEL: -+ case VSIR_OP_HS_DECLS: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - break; - - default: - if (!vsir_instruction_is_dcl(instruction)) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, -- "Invalid instruction %#x outside any block.", -- instruction->opcode); -+ "Invalid instruction \"%s\" (%#x) outside any block.", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - break; - } - } -@@ -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, -- .phase = VKD3DSIH_INVALID, -+ .phase = VSIR_OP_INVALID, - .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..c6e048adb20 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, -@@ -48,19 +50,29 @@ struct msl_generator - const char *prefix; - bool failed; - -- bool write_depth; -+ bool read_vertex_id; - - const struct vkd3d_shader_interface_info *interface_info; - }; - - struct msl_resource_type_info - { -- size_t read_coord_size; -+ /* The number of coordinates needed to address/sample the resource type. */ -+ size_t coord_size; -+ /* Whether the resource type is an array type. */ - bool array; -- bool lod; -+ /* Whether the resource type has a shadow/comparison variant. */ -+ bool comparison; -+ /* Whether the resource type supports texel sample offsets. */ -+ bool offset; -+ /* The type suffix for the resource type. I.e., the "2d_ms" part of -+ * "texture2d_ms_array" or "depth2d_ms_array". */ - const char *type_suffix; - }; - -+static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, -+ const struct vkd3d_shader_src_param *rel_addr, unsigned int offset); -+ - static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen, - enum vkd3d_shader_error error, const char *fmt, ...) - { -@@ -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[] = - { -- [VKD3D_SHADER_RESOURCE_NONE] = {0, false, false, "none"}, -- [VKD3D_SHADER_RESOURCE_BUFFER] = {1, false, false, "_buffer"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, false, false, "1d"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, false, true, "2d"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, false, false, "2d_ms"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, false, true, "3d"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, false, true, "cube"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, true, false, "1d_array"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, true, true, "2d_array"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, true, false, "2d_ms_array"}, -- [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, true, true, "cube_array"}, -+ [VKD3D_SHADER_RESOURCE_NONE] = {0, 0, 0, 0, "none"}, -+ [VKD3D_SHADER_RESOURCE_BUFFER] = {1, 0, 0, 0, "_buffer"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, 0, 0, 0, "1d"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, 0, 1, 1, "2d"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, 0, 1, 0, "2d_ms"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, 0, 0, 1, "3d"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {3, 0, 1, 0, "cube"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, 1, 0, 0, "1d"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, 1, 1, 1, "2d"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, 1, 1, 0, "2d_ms"}, -+ [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {3, 1, 1, 0, "cube"}, - }; - - if (!t || t >= ARRAY_SIZE(info)) -@@ -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; - } - -+static const struct vkd3d_shader_descriptor_binding *msl_get_sampler_binding(const struct msl_generator *gen, -+ unsigned int register_space, unsigned int register_idx) -+{ -+ const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; -+ const struct vkd3d_shader_resource_binding *binding; -+ unsigned int i; -+ -+ if (!interface_info) -+ return NULL; -+ -+ for (i = 0; i < interface_info->binding_count; ++i) -+ { -+ binding = &interface_info->bindings[i]; -+ -+ if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) -+ continue; -+ if (binding->register_space != register_space) -+ continue; -+ if (binding->register_index != register_idx) -+ continue; -+ if (!msl_check_shader_visibility(gen, binding->shader_visibility)) -+ continue; -+ -+ return &binding->binding; -+ } -+ -+ return NULL; -+} -+ - 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 +301,71 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const s - return NULL; - } - -+static const struct vkd3d_shader_descriptor_binding *msl_get_uav_binding(const struct msl_generator *gen, -+ unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) -+{ -+ const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; -+ const struct vkd3d_shader_resource_binding *binding; -+ enum vkd3d_shader_binding_flag resource_type_flag; -+ unsigned int i; -+ -+ if (!interface_info) -+ return NULL; -+ -+ resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER -+ ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; -+ -+ for (i = 0; i < interface_info->binding_count; ++i) -+ { -+ binding = &interface_info->bindings[i]; -+ -+ if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) -+ continue; -+ if (binding->register_space != register_space) -+ continue; -+ if (binding->register_index != register_idx) -+ continue; -+ if (!msl_check_shader_visibility(gen, binding->shader_visibility)) -+ continue; -+ if (!(binding->flags & resource_type_flag)) -+ continue; -+ -+ return &binding->binding; -+ } -+ -+ return NULL; -+} -+ - static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding) - { - vkd3d_string_buffer_printf(buffer, "descriptors[%u].buf()", binding); - } - -+static void msl_print_sampler_name(struct vkd3d_string_buffer *buffer, unsigned int binding) -+{ -+ vkd3d_string_buffer_printf(buffer, "descriptors[%u].as()", binding); -+} -+ - 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 vsir_data_type resource_data_type, bool compare) - { -- vkd3d_string_buffer_printf(buffer, "descriptors[%u].textype_suffix); -+ vkd3d_string_buffer_printf(buffer, "descriptors[%u].as<%s%s%s<", -+ binding, compare ? "depth" : "texture", resource_type_info->type_suffix, -+ resource_type_info->array ? "_array" : ""); - msl_print_resource_datatype(gen, buffer, resource_data_type); - vkd3d_string_buffer_printf(buffer, ">>()"); - } - -+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 vsir_data_type resource_data_type) -+{ -+ vkd3d_string_buffer_printf(buffer, "descriptors[%u].astype_suffix, -+ resource_type_info->array ? "_array" : ""); -+ msl_print_resource_datatype(gen, buffer, resource_data_type); -+ vkd3d_string_buffer_printf(buffer, ", access::read_write>>()"); -+} -+ - 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 +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; - } -- if (reg->idx[0].rel_addr || reg->idx[1].rel_addr || reg->idx[2].rel_addr) -+ if (reg->idx[0].rel_addr || reg->idx[1].rel_addr) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled constant buffer register indirect addressing."); - vkd3d_string_buffer_printf(buffer, "", reg->type); - return MSL_DATA_UNION; - } -+ /* FIXME: This should use vkd3d_shader_find_descriptor() to -+ * find the resource index/space from the resource ID. */ - if (!(binding = msl_get_cbv_binding(gen, 0, reg->idx[1].offset))) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, -- "Cannot finding binding for CBV register %u.", reg->idx[0].offset); -+ "No descriptor binding specified for CBV %u.", reg->idx[0].offset); - vkd3d_string_buffer_printf(buffer, "", reg->type); - return MSL_DATA_UNION; - } - msl_print_cbv_name(buffer, binding->binding); -- vkd3d_string_buffer_printf(buffer, "[%u]", reg->idx[2].offset); -+ msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); - return MSL_DATA_UNION; - } - -+ case VKD3DSPR_IDXTEMP: -+ vkd3d_string_buffer_printf(buffer, "x%u", reg->idx[0].offset); -+ msl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); -+ return MSL_DATA_UNION; -+ -+ case VKD3DSPR_SAMPLEMASK: -+ if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled sample coverage mask in shader type #%x.", -+ gen->program->shader_version.type); -+ vkd3d_string_buffer_printf(buffer, "o_mask"); -+ return MSL_DATA_UNION; -+ - default: - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled register type %#x.", reg->type); -@@ -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; -+ case VKD3DSPSM_ABSNEG: -+ vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); -+ break; - default: - vkd3d_string_buffer_printf(buffer, "(%s)", - vsir_src->modifiers, str->buffer); -@@ -539,12 +649,34 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, - return write_mask; - } - -+static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, -+ const struct vkd3d_shader_src_param *rel_addr, unsigned int offset) -+{ -+ struct msl_src r; -+ -+ if (!rel_addr) -+ { -+ vkd3d_string_buffer_printf(buffer, "[%u]", offset); -+ return; -+ } -+ -+ msl_src_init(&r, gen, rel_addr, VKD3DSP_WRITEMASK_0); -+ vkd3d_string_buffer_printf(buffer, "[%s", r.str->buffer); -+ if (offset) -+ vkd3d_string_buffer_printf(buffer, " + %u", offset); -+ vkd3d_string_buffer_printf(buffer, "]"); -+ msl_src_cleanup(&r, &gen->string_buffers); -+} -+ - static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment( - struct msl_generator *gen, struct msl_dst *dst, const char *format, ...) - { - uint32_t modifiers = dst->vsir->modifiers; - va_list args; - -+ /* It is always legitimate to ignore _pp. */ -+ modifiers &= ~VKD3DSPDM_PARTIALPRECISION; -+ - 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 +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) - { -+ const char *name = vsir_opcode_get_name(ins->opcode, ""); -+ - msl_print_indent(gen->buffer, gen->indent); -- vkd3d_string_buffer_printf(gen->buffer, "/* */\n", ins->opcode); -+ vkd3d_string_buffer_printf(gen->buffer, "/* */\n", name, ins->opcode); - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled instruction %#x.", ins->opcode); -+ "Internal compiler error: Unhandled instruction \"%s\" (%#x).", name, ins->opcode); - } - - static void msl_binop(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) -@@ -695,19 +829,36 @@ static void msl_begin_block(struct msl_generator *gen) - ++gen->indent; - } - --static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) -+static void msl_print_condition(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, -+ enum vkd3d_shader_conditional_op op, const struct vkd3d_shader_src_param *arg) - { - const char *condition; - struct msl_src src; - -- msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); -+ msl_src_init(&src, gen, arg, VKD3DSP_WRITEMASK_0); - -- msl_print_indent(gen->buffer, gen->indent); -- condition = ins->flags == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; -- vkd3d_string_buffer_printf(gen->buffer, "if (%s(%s))\n", condition, src.str->buffer); -+ condition = op == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; -+ vkd3d_string_buffer_printf(buffer, "if (%s(%s))\n", condition, src.str->buffer); - - msl_src_cleanup(&src, &gen->string_buffers); -+} - -+static void msl_discard(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) -+{ -+ /* Note that discard_fragment() in Metal 2.2 and earlier behaves like -+ * SPIR-V OpKill, while in Metal 2.3 and later it behaves like -+ * OpDemoteToHelperInvocationEXT. We assume we have at least Metal 3 -+ * here. */ -+ msl_print_indent(gen->buffer, gen->indent); -+ msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]); -+ msl_print_indent(gen->buffer, gen->indent + 1); -+ vkd3d_string_buffer_printf(gen->buffer, "discard_fragment();\n"); -+} -+ -+static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) -+{ -+ msl_print_indent(gen->buffer, gen->indent); -+ msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]); - msl_begin_block(gen); - } - -@@ -719,6 +870,77 @@ static void msl_else(struct msl_generator *gen) - msl_begin_block(gen); - } - -+static void msl_loop(struct msl_generator *gen) -+{ -+ msl_print_indent(gen->buffer, gen->indent); -+ vkd3d_string_buffer_printf(gen->buffer, "for (;;)\n"); -+ msl_begin_block(gen); -+} -+ -+static void msl_break(struct msl_generator *gen) -+{ -+ msl_print_indent(gen->buffer, gen->indent); -+ vkd3d_string_buffer_printf(gen->buffer, "break;\n"); -+} -+ -+static void msl_continue(struct msl_generator *gen) -+{ -+ msl_print_indent(gen->buffer, gen->indent); -+ vkd3d_string_buffer_printf(gen->buffer, "continue;\n"); -+} -+ -+static void msl_switch(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) -+{ -+ struct msl_src src; -+ -+ msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); -+ -+ msl_print_indent(gen->buffer, gen->indent); -+ vkd3d_string_buffer_printf(gen->buffer, "switch (%s)\n", src.str->buffer); -+ msl_begin_block(gen); -+ -+ msl_src_cleanup(&src, &gen->string_buffers); -+} -+ -+static void msl_case(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) -+{ -+ struct msl_src src; -+ -+ msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); -+ -+ msl_print_indent(gen->buffer, gen->indent); -+ vkd3d_string_buffer_printf(gen->buffer, "case %s:\n", src.str->buffer); -+ -+ msl_src_cleanup(&src, &gen->string_buffers); -+} -+ -+static void msl_default(struct msl_generator *gen) -+{ -+ msl_print_indent(gen->buffer, gen->indent); -+ vkd3d_string_buffer_printf(gen->buffer, "default:\n"); -+} -+ -+static void msl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, -+ unsigned int offset_size, const struct vkd3d_shader_texel_offset *offset) -+{ -+ switch (offset_size) -+ { -+ case 1: -+ vkd3d_string_buffer_printf(buffer, "%d", offset->u); -+ break; -+ case 2: -+ vkd3d_string_buffer_printf(buffer, "int2(%d, %d)", offset->u, offset->v); -+ break; -+ default: -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Invalid texel offset size %u.", offset_size); -+ /* fall through */ -+ case 3: -+ vkd3d_string_buffer_printf(buffer, "int3(%d, %d, %d)", offset->u, offset->v, offset->w); -+ break; -+ } -+} -+ - static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) - { - const struct msl_resource_type_info *resource_type_info; -@@ -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; -- uint32_t coord_mask; -+ enum vsir_data_type data_type; -+ unsigned int srv_binding; - struct msl_dst dst; - - 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))) -- { -- coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size); -- } -- else -+ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBE -+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY -+ || (ins->opcode != VSIR_OP_LD2DMS -+ && (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS -+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY))) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Texel fetches from resource type %#x are not supported.", resource_type); -+ -+ if (!(resource_type_info = msl_get_resource_type_info(resource_type))) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled resource type %#x.", resource_type); -- coord_mask = vkd3d_write_mask_from_component_count(2); -+ resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); - } -+ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); - -- if (!(binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) -+ if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) -+ { -+ srv_binding = binding->binding; -+ } -+ else - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, -- "Cannot finding binding for SRV register %u index %u space %u.", -+ "No descriptor binding specified for SRV %u (index %u, space %u).", - resource_id, resource_idx, resource_space); -- return; -+ srv_binding = 0; - } - - msl_dst_init(&dst, gen, ins, &ins->dst[0]); - read = vkd3d_string_buffer_get(&gen->string_buffers); - -- 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, 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_info->lod) -+ if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) - { - 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, VSIR_DATA_U32); -+ 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); - -@@ -802,6 +1043,313 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - msl_dst_cleanup(&dst, &gen->string_buffers); - } - -+static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) -+{ -+ bool bias, compare, comparison_sampler, dynamic_offset, gather, grad, lod, lod_zero, offset; -+ const struct msl_resource_type_info *resource_type_info; -+ const struct vkd3d_shader_src_param *resource, *sampler; -+ unsigned int resource_id, resource_idx, resource_space; -+ const struct vkd3d_shader_descriptor_binding *binding; -+ unsigned int sampler_id, sampler_idx, sampler_space; -+ 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; -+ struct msl_dst dst; -+ -+ bias = ins->opcode == VSIR_OP_SAMPLE_B; -+ compare = ins->opcode == VSIR_OP_GATHER4_C || ins->opcode == VSIR_OP_SAMPLE_C -+ || ins->opcode == VSIR_OP_SAMPLE_C_LZ; -+ dynamic_offset = ins->opcode == VSIR_OP_GATHER4_PO; -+ gather = ins->opcode == VSIR_OP_GATHER4 || ins->opcode == VSIR_OP_GATHER4_C -+ || ins->opcode == VSIR_OP_GATHER4_PO; -+ grad = ins->opcode == VSIR_OP_SAMPLE_GRAD; -+ lod = ins->opcode == VSIR_OP_SAMPLE_LOD; -+ lod_zero = ins->opcode == VSIR_OP_SAMPLE_C_LZ; -+ offset = dynamic_offset || vkd3d_shader_instruction_has_texel_offset(ins); -+ -+ resource = &ins->src[1 + dynamic_offset]; -+ sampler = &ins->src[2 + dynamic_offset]; -+ -+ if (resource->reg.idx[0].rel_addr || resource->reg.idx[1].rel_addr -+ || sampler->reg.idx[0].rel_addr || sampler->reg.idx[1].rel_addr) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Descriptor indexing is not supported."); -+ -+ resource_id = resource->reg.idx[0].offset; -+ resource_idx = resource->reg.idx[1].offset; -+ if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) -+ { -+ resource_space = d->register_space; -+ resource_type = d->resource_type; -+ data_type = d->resource_data_type; -+ } -+ else -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Undeclared resource descriptor %u.", resource_id); -+ resource_space = 0; -+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -+ data_type = VSIR_DATA_F32; -+ } -+ -+ if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER -+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS -+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Sampling resource type %#x is not supported.", resource_type); -+ -+ if ((resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1D || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY) -+ && (bias || grad || lod || lod_zero)) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Resource type %#x does not support mipmapping.", resource_type); -+ -+ if ((resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1D || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY -+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_3D) && gather) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Resource type %#x does not support gather operations.", resource_type); -+ -+ if (!(resource_type_info = msl_get_resource_type_info(resource_type))) -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled resource type %#x.", resource_type); -+ resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); -+ } -+ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); -+ -+ if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) -+ { -+ srv_binding = binding->binding; -+ } -+ else -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, -+ "No descriptor binding specified for SRV %u (index %u, space %u).", -+ resource_id, resource_idx, resource_space); -+ srv_binding = 0; -+ } -+ -+ sampler_id = sampler->reg.idx[0].offset; -+ sampler_idx = sampler->reg.idx[1].offset; -+ if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_id))) -+ { -+ sampler_space = d->register_space; -+ comparison_sampler = d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; -+ -+ if (compare) -+ { -+ if (!comparison_sampler) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Sampler %u is not a comparison sampler.", sampler_id); -+ } -+ else -+ { -+ if (comparison_sampler) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Sampler %u is a comparison sampler.", sampler_id); -+ } -+ } -+ else -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Undeclared sampler descriptor %u.", sampler_id); -+ sampler_space = 0; -+ } -+ -+ if ((binding = msl_get_sampler_binding(gen, sampler_space, sampler_idx))) -+ { -+ sampler_binding = binding->binding; -+ } -+ else -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, -+ "No descriptor binding specified for sampler %u (index %u, space %u).", -+ sampler_id, sampler_idx, sampler_space); -+ sampler_binding = 0; -+ } -+ -+ msl_dst_init(&dst, gen, ins, &ins->dst[0]); -+ sample = vkd3d_string_buffer_get(&gen->string_buffers); -+ -+ 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("); -+ else if (gather) -+ vkd3d_string_buffer_printf(sample, ".gather("); -+ else if (compare) -+ vkd3d_string_buffer_printf(sample, ".sample_compare("); -+ else -+ vkd3d_string_buffer_printf(sample, ".sample("); -+ msl_print_sampler_name(sample, sampler_binding); -+ vkd3d_string_buffer_printf(sample, ", "); -+ msl_print_src_with_type(sample, gen, &ins->src[0], coord_mask, ins->src[0].reg.data_type); -+ if (resource_type_info->array) -+ { -+ vkd3d_string_buffer_printf(sample, ", uint("); -+ msl_print_src_with_type(sample, gen, &ins->src[0], coord_mask + 1, ins->src[0].reg.data_type); -+ vkd3d_string_buffer_printf(sample, ")"); -+ } -+ if (compare) -+ { -+ if (!resource_type_info->comparison) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Comparison samplers are not supported with resource type %#x.", resource_type); -+ vkd3d_string_buffer_printf(sample, ", "); -+ msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); -+ } -+ if (grad) -+ { -+ vkd3d_string_buffer_printf(sample, ", gradient%s(", resource_type_info->type_suffix); -+ msl_print_src_with_type(sample, gen, &ins->src[3], coord_mask, ins->src[3].reg.data_type); -+ vkd3d_string_buffer_printf(sample, ", "); -+ msl_print_src_with_type(sample, gen, &ins->src[4], coord_mask, ins->src[4].reg.data_type); -+ vkd3d_string_buffer_printf(sample, ")"); -+ } -+ if (lod_zero) -+ { -+ vkd3d_string_buffer_printf(sample, ", level(0.0f)"); -+ } -+ else if (lod) -+ { -+ vkd3d_string_buffer_printf(sample, ", level("); -+ msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); -+ vkd3d_string_buffer_printf(sample, ")"); -+ } -+ if (bias) -+ { -+ vkd3d_string_buffer_printf(sample, ", bias("); -+ msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); -+ vkd3d_string_buffer_printf(sample, ")"); -+ } -+ if (offset) -+ { -+ if (!resource_type_info->offset) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Texel sample offsets are not supported with resource type %#x.", resource_type); -+ vkd3d_string_buffer_printf(sample, ", "); -+ if (dynamic_offset) -+ msl_print_src_with_type(sample, gen, &ins->src[1], coord_mask, ins->src[1].reg.data_type); -+ else -+ msl_print_texel_offset(sample, gen, resource_type_info->coord_size, &ins->texel_offset); -+ } -+ if (gather && !compare && (component_idx = vsir_swizzle_get_component(sampler->swizzle, 0))) -+ { -+ if (!offset && resource_type_info->offset) -+ vkd3d_string_buffer_printf(sample, ", int2(0)"); -+ vkd3d_string_buffer_printf(sample, ", component::%c", "xyzw"[component_idx]); -+ } -+ 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); -+ -+ vkd3d_string_buffer_release(&gen->string_buffers, sample); -+ msl_dst_cleanup(&dst, &gen->string_buffers); -+} -+ -+static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) -+{ -+ const struct msl_resource_type_info *resource_type_info; -+ const struct vkd3d_shader_descriptor_binding *binding; -+ const struct vkd3d_shader_descriptor_info1 *d; -+ enum vkd3d_shader_resource_type resource_type; -+ unsigned int uav_id, uav_idx, uav_space; -+ struct vkd3d_string_buffer *image_data; -+ enum vsir_data_type data_type; -+ unsigned int uav_binding; -+ uint32_t coord_mask; -+ -+ if (ins->dst[0].reg.idx[0].rel_addr || ins->dst[0].reg.idx[1].rel_addr) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Descriptor indexing is not supported."); -+ -+ uav_id = ins->dst[0].reg.idx[0].offset; -+ uav_idx = ins->dst[0].reg.idx[1].offset; -+ if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, uav_id))) -+ { -+ uav_space = d->register_space; -+ resource_type = d->resource_type; -+ data_type = d->resource_data_type; -+ } -+ else -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); -+ uav_space = 0; -+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -+ data_type = VSIR_DATA_F32; -+ } -+ -+ if (!(resource_type_info = msl_get_resource_type_info(resource_type))) -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled resource type %#x.", resource_type); -+ resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); -+ } -+ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); -+ -+ if ((binding = msl_get_uav_binding(gen, uav_space, uav_idx, resource_type))) -+ { -+ uav_binding = binding->binding; -+ } -+ else -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, -+ "No descriptor binding specified for UAV %u (index %u, space %u).", -+ uav_id, uav_idx, uav_space); -+ uav_binding = 0; -+ } -+ -+ image_data = vkd3d_string_buffer_get(&gen->string_buffers); -+ -+ if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) -+ { -+ switch (data_type) -+ { -+ case VSIR_DATA_U32: -+ vkd3d_string_buffer_printf(image_data, "uint4("); -+ break; -+ 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 VSIR_DATA_F32: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: -+ vkd3d_string_buffer_printf(image_data, "float4("); -+ break; -+ } -+ } -+ msl_print_src_with_type(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, data_type); -+ if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) -+ vkd3d_string_buffer_printf(image_data, ", 0, 0, 0)"); -+ -+ 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, VSIR_DATA_U32); -+ vkd3d_string_buffer_printf(gen->buffer, ");\n"); -+ -+ vkd3d_string_buffer_release(&gen->string_buffers, image_data); -+} -+ - static void msl_unary_op(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) - { - struct msl_src src; -@@ -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, "%s x%u[%u];\n", type, -+ ins->declaration.indexable_temp.register_idx, -+ ins->declaration.indexable_temp.register_size); -+} -+ - static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) - { - gen->location = ins->location; - - switch (ins->opcode) - { -- case VKD3DSIH_ADD: -+ case VSIR_OP_ADD: -+ case VSIR_OP_IADD: - msl_binop(gen, ins, "+"); - break; -- case VKD3DSIH_AND: -+ case VSIR_OP_AND: - msl_binop(gen, ins, "&"); - break; -- case VKD3DSIH_NOP: -+ case VSIR_OP_BREAK: -+ msl_break(gen); -+ break; -+ case VSIR_OP_CASE: -+ msl_case(gen, ins); -+ break; -+ case VSIR_OP_CONTINUE: -+ msl_continue(gen); -+ 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_DEFAULT: -+ msl_default(gen); -+ break; -+ case VSIR_OP_DISCARD: -+ msl_discard(gen, ins); -+ break; -+ case VSIR_OP_DIV: - msl_binop(gen, ins, "/"); - break; -- case VKD3DSIH_DP2: -+ case VSIR_OP_DP2: - msl_dot(gen, ins, vkd3d_write_mask_from_component_count(2)); - break; -- case VKD3DSIH_DP3: -+ case VSIR_OP_DP3: - msl_dot(gen, ins, vkd3d_write_mask_from_component_count(3)); - break; -- case VKD3DSIH_DP4: -+ case VSIR_OP_DP4: - msl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); - break; -- case VKD3DSIH_ELSE: -+ case VSIR_OP_DSX: -+ case VSIR_OP_DSX_COARSE: -+ case VSIR_OP_DSX_FINE: -+ /* dfdx() and dfdy() are specified to return "a high precision -+ * partial derivative", which would seem to correspond to -+ * DSX_FINE/DSY_FINE. As of MSL 3.2, coarse/fast variants don't -+ * appear to be available. */ -+ msl_intrinsic(gen, ins, "dfdx"); -+ break; -+ case VSIR_OP_DSY: -+ case VSIR_OP_DSY_COARSE: -+ case VSIR_OP_DSY_FINE: -+ msl_intrinsic(gen, ins, "dfdy"); -+ break; -+ case VSIR_OP_ELSE: - msl_else(gen); - break; -- case VKD3DSIH_ENDIF: -+ case VSIR_OP_ENDIF: -+ case VSIR_OP_ENDLOOP: -+ case VSIR_OP_ENDSWITCH: - msl_end_block(gen); - break; -- case VKD3DSIH_IEQ: -+ case VSIR_OP_EQO: -+ case VSIR_OP_IEQ: - msl_relop(gen, ins, "=="); - break; -- case VKD3DSIH_EXP: -+ case VSIR_OP_EXP: - msl_intrinsic(gen, ins, "exp2"); - break; -- case VKD3DSIH_FRC: -+ case VSIR_OP_FRC: - msl_intrinsic(gen, ins, "fract"); - break; -- case VKD3DSIH_FTOI: -+ case VSIR_OP_FTOI: - msl_cast(gen, ins, "int"); - break; -- case VKD3DSIH_FTOU: -+ case VSIR_OP_FTOU: - msl_cast(gen, ins, "uint"); - break; -- case VKD3DSIH_GEO: -+ case VSIR_OP_GATHER4: -+ case VSIR_OP_GATHER4_C: -+ case VSIR_OP_GATHER4_PO: -+ case VSIR_OP_SAMPLE: -+ case VSIR_OP_SAMPLE_B: -+ case VSIR_OP_SAMPLE_C: -+ case VSIR_OP_SAMPLE_C_LZ: -+ case VSIR_OP_SAMPLE_GRAD: -+ case VSIR_OP_SAMPLE_LOD: -+ msl_sample(gen, ins); -+ break; -+ case VSIR_OP_GEO: -+ case VSIR_OP_IGE: - msl_relop(gen, ins, ">="); - break; -- case VKD3DSIH_IF: -+ case VSIR_OP_IF: - msl_if(gen, ins); - break; -- case VKD3DSIH_ISHL: -+ case VSIR_OP_ISHL: - msl_binop(gen, ins, "<<"); - break; -- case VKD3DSIH_ISHR: -- case VKD3DSIH_USHR: -+ case VSIR_OP_ISHR: -+ case VSIR_OP_USHR: - msl_binop(gen, ins, ">>"); - break; -- case VKD3DSIH_LTO: -+ case VSIR_OP_ILT: -+ case VSIR_OP_LTO: -+ case VSIR_OP_ULT: - msl_relop(gen, ins, "<"); - break; -- case VKD3DSIH_MAD: -+ case VSIR_OP_MAD: - msl_intrinsic(gen, ins, "fma"); - break; -- case VKD3DSIH_MAX: -+ case VSIR_OP_IMAX: -+ case VSIR_OP_MAX: -+ case VSIR_OP_UMAX: - msl_intrinsic(gen, ins, "max"); - break; -- case VKD3DSIH_MIN: -+ case VSIR_OP_MIN: -+ case VSIR_OP_UMIN: - msl_intrinsic(gen, ins, "min"); - break; -- case VKD3DSIH_INE: -- case VKD3DSIH_NEU: -+ case VSIR_OP_IMUL_LOW: -+ msl_binop(gen, ins, "*"); -+ break; -+ case VSIR_OP_INE: -+ case VSIR_OP_NEU: - msl_relop(gen, ins, "!="); - break; -- case VKD3DSIH_ITOF: -- case VKD3DSIH_UTOF: -+ case VSIR_OP_INEG: -+ msl_unary_op(gen, ins, "-"); -+ break; -+ case VSIR_OP_ITOF: -+ case VSIR_OP_UTOF: - msl_cast(gen, ins, "float"); - break; -- case VKD3DSIH_LD: -+ case VSIR_OP_LD: -+ case VSIR_OP_LD2DMS: - msl_ld(gen, ins); - break; -- case VKD3DSIH_LOG: -+ case VSIR_OP_LOG: - msl_intrinsic(gen, ins, "log2"); - break; -- case VKD3DSIH_MOV: -+ case VSIR_OP_LOOP: -+ msl_loop(gen); -+ break; -+ case VSIR_OP_MOV: - msl_mov(gen, ins); - break; -- case VKD3DSIH_MOVC: -+ case VSIR_OP_MOVC: - msl_movc(gen, ins); - break; -- case VKD3DSIH_MUL: -+ case VSIR_OP_MUL: - msl_binop(gen, ins, "*"); - break; -- case VKD3DSIH_NOT: -+ case VSIR_OP_NOT: - msl_unary_op(gen, ins, "~"); - break; -- case VKD3DSIH_OR: -+ case VSIR_OP_OR: - msl_binop(gen, ins, "|"); - break; -- case VKD3DSIH_RET: -+ case VSIR_OP_RET: - msl_ret(gen, ins); - break; -- case VKD3DSIH_ROUND_NE: -+ case VSIR_OP_ROUND_NE: - msl_intrinsic(gen, ins, "rint"); - break; -- case VKD3DSIH_ROUND_NI: -+ case VSIR_OP_ROUND_NI: - msl_intrinsic(gen, ins, "floor"); - break; -- case VKD3DSIH_ROUND_PI: -+ case VSIR_OP_ROUND_PI: - msl_intrinsic(gen, ins, "ceil"); - break; -- case VKD3DSIH_ROUND_Z: -+ case VSIR_OP_ROUND_Z: - msl_intrinsic(gen, ins, "trunc"); - break; -- case VKD3DSIH_RSQ: -+ case VSIR_OP_RSQ: - msl_intrinsic(gen, ins, "rsqrt"); - break; -- case VKD3DSIH_SQRT: -+ case VSIR_OP_SQRT: - msl_intrinsic(gen, ins, "sqrt"); - break; -+ case VSIR_OP_STORE_UAV_TYPED: -+ msl_store_uav_typed(gen, ins); -+ break; -+ case VSIR_OP_SWITCH: -+ msl_switch(gen, ins); -+ break; -+ case VSIR_OP_XOR: -+ msl_binop(gen, ins, "^"); -+ break; - default: - msl_unhandled(gen, ins); - break; -@@ -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) -+ 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; -+ -+ case VKD3D_SHADER_SV_POSITION: - if (type != VKD3D_SHADER_TYPE_PIXEL) - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type); -+ "Internal compiler error: Unhandled SV_POSITION in shader type #%x.", type); -+ 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, -+ "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type); - msl_print_indent(gen->buffer, 1); - vkd3d_string_buffer_printf(buffer, "bool is_front_face [[front_facing]];\n"); - continue; -- } -- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic); -- continue; -+ -+ case VKD3D_SHADER_SV_SAMPLE_INDEX: -+ if (type != VKD3D_SHADER_TYPE_PIXEL) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled SV_SAMPLE_INDEX in shader type #%x.", type); -+ msl_print_indent(gen->buffer, 1); -+ vkd3d_string_buffer_printf(buffer, "uint sample_index [[sample_id]];\n"); -+ continue; -+ -+ default: -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic); -+ msl_print_indent(gen->buffer, 1); -+ vkd3d_string_buffer_printf(buffer, ";\n", e->sysval_semantic); -+ continue; - } - - if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) -@@ -1059,15 +1728,15 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) - break; - } - -- vkd3d_string_buffer_printf(buffer, "shader_in_%u ", i); -+ vkd3d_string_buffer_printf(buffer, "shader_in_%u [[", i); - - switch (type) - { - case VKD3D_SHADER_TYPE_VERTEX: -- vkd3d_string_buffer_printf(gen->buffer, "[[attribute(%u)]]", e->target_location); -+ vkd3d_string_buffer_printf(gen->buffer, "attribute(%u)", e->target_location); - break; - case VKD3D_SHADER_TYPE_PIXEL: -- vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location); -+ vkd3d_string_buffer_printf(gen->buffer, "user(locn%u)", e->target_location); - break; - default: - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -1081,13 +1750,16 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) - case VKD3DSIM_LINEAR: - case VKD3DSIM_NONE: - break; -+ case VKD3DSIM_CONSTANT: -+ vkd3d_string_buffer_printf(gen->buffer, ", flat"); -+ break; - default: - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); - break; - } - -- vkd3d_string_buffer_printf(buffer, ";\n"); -+ vkd3d_string_buffer_printf(buffer, "]];\n"); - } - - vkd3d_string_buffer_printf(buffer, "};\n\n"); -@@ -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]; - -- if (e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) -- { -- gen->write_depth = true; -- msl_print_indent(gen->buffer, 1); -- vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); -+ if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED -+ || e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) - continue; -- } - -- 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"); - } - -+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) -+ { -+ msl_print_indent(gen->buffer, 1); -+ vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); -+ } -+ -+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) -+ { -+ msl_print_indent(gen->buffer, 1); -+ vkd3d_string_buffer_printf(buffer, "uint shader_out_mask [[sample_mask]];\n"); -+ } -+ - vkd3d_string_buffer_printf(buffer, "};\n\n"); - } - -@@ -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); -- if (e->sysval_semantic == VKD3D_SHADER_SV_NONE) -- { -- msl_print_register_datatype(buffer, gen, vkd3d_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); -- msl_print_write_mask(buffer, e->mask); -- } -- else if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) -- { -- vkd3d_string_buffer_printf(buffer, ".u = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)"); -- } -- else -+ switch (e->sysval_semantic) - { -- vkd3d_string_buffer_printf(buffer, " = ", e->sysval_semantic); -- 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, 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, 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, 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, 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, VSIR_DATA_U32); -+ msl_print_write_mask(buffer, e->mask); -+ vkd3d_string_buffer_printf(buffer, " = uint4(input.sample_index, 0u, 0u, 0u)"); -+ break; -+ -+ default: -+ vkd3d_string_buffer_printf(buffer, " = ", e->sysval_semantic); -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic); -+ break; - } -+ msl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, ";\n"); - } - } -@@ -1259,12 +1964,6 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) - { - e = &signature->elements[i]; - -- if (e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) -- { -- vkd3d_string_buffer_printf(buffer, " output.shader_out_depth = shader_out_depth;\n"); -- continue; -- } -- - if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) - continue; - -@@ -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: -+ continue; - default: - vkd3d_string_buffer_printf(buffer, " ", e->sysval_semantic); - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -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 = o_mask.u;\n"); - } - - 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: -+ if (gen->program->global_flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL) -+ vkd3d_string_buffer_printf(gen->buffer, "[[early_fragment_tests]]\n"); - vkd3d_string_buffer_printf(gen->buffer, "fragment "); - break; - default: -@@ -1316,25 +2022,35 @@ static void msl_generate_entrypoint(struct msl_generator *gen) - "constant descriptor *descriptors [[buffer(0)]],\n"); - } - -+ if (gen->read_vertex_id) -+ { -+ msl_print_indent(gen->buffer, 2); -+ vkd3d_string_buffer_printf(gen->buffer, "uint vertex_id [[vertex_id]],\n"); -+ } -+ - msl_print_indent(gen->buffer, 2); - vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix); - - /* 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, " vkd3d_scalar o_mask;\n"); -+ vkd3d_string_buffer_printf(gen->buffer, "\n"); - - msl_generate_entrypoint_prologue(gen); - - vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix); -- if (gen->write_depth) -- vkd3d_string_buffer_printf(gen->buffer, ", shader_out_depth"); -+ if (gen->read_vertex_id) -+ vkd3d_string_buffer_printf(gen->buffer, ", vertex_id"); -+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) -+ vkd3d_string_buffer_printf(gen->buffer, ", output.shader_out_depth"); -+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) -+ vkd3d_string_buffer_printf(gen->buffer, ", o_mask"); - if (gen->program->descriptors.descriptor_count) - vkd3d_string_buffer_printf(gen->buffer, ", descriptors"); -- vkd3d_string_buffer_printf(gen->buffer, ");\n"); -+ vkd3d_string_buffer_printf(gen->buffer, ");\n\n"); - - msl_generate_entrypoint_epilogue(gen); - -@@ -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"); - -- if (gen->program->global_flags) -+ if (gen->program->global_flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL)) - 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"); -@@ -1370,7 +2091,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader - " const device void *ptr;\n" - "\n" - " template\n" -- " constant T &tex() constant\n" -+ " constant T &as() constant\n" - " {\n" - " return reinterpret_cast(this->ptr);\n" - " }\n" -@@ -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, -- "void %s_main(thread vkd3d_vec4 *v, " -+ "static void %s_main(thread vkd3d_vec4 *v, " - "thread vkd3d_vec4 *o", - gen->prefix); -- if (gen->write_depth) -- vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth"); -+ -+ if (gen->read_vertex_id) -+ vkd3d_string_buffer_printf(gen->buffer, ", uint vertex_id"); -+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) -+ vkd3d_string_buffer_printf(gen->buffer, ", thread float &o_depth"); -+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) -+ vkd3d_string_buffer_printf(gen->buffer, ", thread 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 -+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.h -@@ -38,6 +38,7 @@ struct preproc_buffer - { - void *lexer_buffer; - struct vkd3d_shader_location location; -+ bool eof; - }; - - struct preproc_file -@@ -125,7 +126,6 @@ struct preproc_ctx - int lookahead_token; - - bool last_was_newline; -- bool last_was_eof; - bool last_was_defined; - - bool error; diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l -index 4a8d0fddae1..5c56fba0229 100644 +index a8c0db358bc..5c56fba0229 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l @@ -20,6 +20,7 @@ @@ -21586,4328 +71,8 @@ index 4a8d0fddae1..5c56fba0229 100644 #include "preproc.tab.h" #undef ERROR /* defined in wingdi.h */ -@@ -71,8 +72,8 @@ INT_SUFFIX [uUlL]{0,2} - - %% - --"//" {yy_push_state(CXX_COMMENT, yyscanner);} --"/*" {yy_push_state(C_COMMENT, yyscanner);} -+"//" {yy_push_state(CXX_COMMENT, yyscanner);} -+"/*" {yy_push_state(C_COMMENT, yyscanner);} - \\{NEWLINE} {} - \n { - yy_pop_state(yyscanner); -@@ -80,7 +81,11 @@ INT_SUFFIX [uUlL]{0,2} - return T_NEWLINE; - } - "*/" {yy_pop_state(yyscanner);} --<> {yy_pop_state(yyscanner);} -+<> { -+ yy_pop_state(yyscanner); -+ BEGIN(INITIAL); -+ yyterminate(); -+ } - . {} - \n {} - -@@ -196,6 +201,10 @@ INT_SUFFIX [uUlL]{0,2} - BEGIN(INITIAL); - return T_NEWLINE; - } -+<> { -+ BEGIN(INITIAL); -+ yyterminate(); -+ } - - {WS}+ {} - [-()\[\]{},+!*/<>&|^?:] {return yytext[0];} -@@ -250,8 +259,19 @@ static bool should_concat(struct preproc_ctx *ctx) - return !macro || macro->arg_count; - } - -+static struct preproc_buffer *preproc_get_top_buffer(struct preproc_ctx *ctx) -+{ -+ if (ctx->expansion_count) -+ return &ctx->expansion_stack[ctx->expansion_count - 1].buffer; -+ if (ctx->file_count) -+ return &ctx->file_stack[ctx->file_count - 1].buffer; -+ return NULL; -+} -+ - static void preproc_pop_buffer(struct preproc_ctx *ctx) - { -+ struct preproc_buffer *buffer; -+ - if (ctx->expansion_count) - { - struct preproc_expansion *exp = &ctx->expansion_stack[ctx->expansion_count - 1]; -@@ -290,10 +310,8 @@ static void preproc_pop_buffer(struct preproc_ctx *ctx) - TRACE("File stack size is now %zu.\n", ctx->file_count); - } - -- if (ctx->expansion_count) -- yy_switch_to_buffer(ctx->expansion_stack[ctx->expansion_count - 1].buffer.lexer_buffer, ctx->scanner); -- else if (ctx->file_count) -- yy_switch_to_buffer(ctx->file_stack[ctx->file_count - 1].buffer.lexer_buffer, ctx->scanner); -+ if ((buffer = preproc_get_top_buffer(ctx))) -+ yy_switch_to_buffer(buffer->lexer_buffer, ctx->scanner); - } - - static int return_token(int token, YYSTYPE *lval, const char *text) -@@ -347,6 +365,7 @@ static bool preproc_push_expansion(struct preproc_ctx *ctx, - exp->text = text; - exp->buffer.lexer_buffer = yy_scan_bytes(text->text.buffer, text->text.content_size, ctx->scanner); - exp->buffer.location = text->location; -+ exp->buffer.eof = false; - exp->macro = macro; - exp->arg_values = arg_values; - TRACE("Expansion stack size is now %zu.\n", ctx->expansion_count); -@@ -407,18 +426,17 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) - } - else - { -- if (ctx->last_was_eof) -+ if (preproc_get_top_buffer(ctx)->eof) - { - preproc_pop_buffer(ctx); - if (!ctx->file_count) - return 0; - } -- ctx->last_was_eof = false; - - VKD3D_ASSERT(ctx->file_count); - if (!(token = preproc_lexer_lex(lval, lloc, scanner))) - { -- ctx->last_was_eof = true; -+ preproc_get_top_buffer(ctx)->eof = true; - - /* If we have reached the end of an included file, inject a newline. */ - if (ctx->expansion_count) -@@ -781,6 +799,7 @@ bool preproc_push_include(struct preproc_ctx *ctx, char *filename, const struct - file->buffer.location.source_name = file->filename; - file->buffer.location.line = 1; - file->buffer.location.column = 1; -+ file->buffer.eof = false; - TRACE("File stack size is now %zu.\n", ctx->file_count); - 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..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 - vkd3d_shader_message_context_cleanup(&message_context); - } - --enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, -- unsigned int index) --{ -- switch (sysval) -- { -- case VKD3D_SHADER_SV_COVERAGE: -- case VKD3D_SHADER_SV_DEPTH: -- case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: -- case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: -- case VKD3D_SHADER_SV_NONE: -- case VKD3D_SHADER_SV_STENCIL_REF: -- case VKD3D_SHADER_SV_TARGET: -- return VKD3D_SIV_NONE; -- case VKD3D_SHADER_SV_POSITION: -- return VKD3D_SIV_POSITION; -- case VKD3D_SHADER_SV_CLIP_DISTANCE: -- return VKD3D_SIV_CLIP_DISTANCE; -- case VKD3D_SHADER_SV_CULL_DISTANCE: -- return VKD3D_SIV_CULL_DISTANCE; -- case VKD3D_SHADER_SV_INSTANCE_ID: -- return VKD3D_SIV_INSTANCE_ID; -- case VKD3D_SHADER_SV_IS_FRONT_FACE: -- return VKD3D_SIV_IS_FRONT_FACE; -- case VKD3D_SHADER_SV_PRIMITIVE_ID: -- return VKD3D_SIV_PRIMITIVE_ID; -- case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX: -- return VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX; -- case VKD3D_SHADER_SV_SAMPLE_INDEX: -- return VKD3D_SIV_SAMPLE_INDEX; -- case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE: -- return VKD3D_SIV_QUAD_U0_TESS_FACTOR + index; -- case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT: -- return VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR + index; -- case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE: -- return VKD3D_SIV_TRIANGLE_U_TESS_FACTOR + index; -- case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT: -- return VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR; -- case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET: -- return VKD3D_SIV_LINE_DETAIL_TESS_FACTOR; -- case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN: -- return VKD3D_SIV_LINE_DENSITY_TESS_FACTOR; -- case VKD3D_SHADER_SV_VERTEX_ID: -- return VKD3D_SIV_VERTEX_ID; -- case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX: -- return VKD3D_SIV_VIEWPORT_ARRAY_INDEX; -- default: -- FIXME("Unhandled sysval %#x, index %u.\n", sysval, index); -- return VKD3D_SIV_NONE; -- } --} -- - struct vkd3d_spirv_stream - { - uint32_t *words; -@@ -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); - } - -+static uint32_t vkd3d_spirv_build_op_string(struct vkd3d_spirv_builder *builder, const char *s) -+{ -+ struct vkd3d_spirv_stream *stream = &builder->debug_stream; -+ uint32_t result_id = vkd3d_spirv_alloc_id(builder); -+ unsigned int size; -+ -+ size = vkd3d_spirv_string_word_count(s); -+ vkd3d_spirv_build_word(stream, vkd3d_spirv_opcode_word(SpvOpString, 2 + size)); -+ vkd3d_spirv_build_word(stream, result_id); -+ vkd3d_spirv_build_string(stream, s, size); -+ -+ return result_id; -+} -+ -+static void vkd3d_spirv_build_op_source(struct vkd3d_spirv_builder *builder, const char *source_name) -+{ -+ struct vkd3d_spirv_stream *stream = &builder->debug_stream; -+ -+ 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 +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); - } - --static uint32_t vkd3d_spirv_build_op_glsl_std450_sin(struct vkd3d_spirv_builder *builder, -- uint32_t result_type, uint32_t operand) --{ -- return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Sin, result_type, operand); --} -- --static uint32_t vkd3d_spirv_build_op_glsl_std450_cos(struct vkd3d_spirv_builder *builder, -- uint32_t result_type, uint32_t operand) --{ -- return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Cos, result_type, operand); --} -- - 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) - { -@@ -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); - } - --static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point) -+static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, -+ const char *entry_point, const char *source_name) - { - vkd3d_spirv_stream_init(&builder->debug_stream); - vkd3d_spirv_stream_init(&builder->annotation_stream); -@@ -2631,6 +2598,7 @@ static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const - - rb_init(&builder->declarations, vkd3d_spirv_declaration_compare); - -+ vkd3d_spirv_build_op_source(builder, source_name); - builder->main_function_id = vkd3d_spirv_alloc_id(builder); - vkd3d_spirv_build_op_name(builder, builder->main_function_id, "%s", entry_point); - } -@@ -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) - { -- return compiler->phase == VKD3DSIH_INVALID; -+ return compiler->phase == VSIR_OP_INVALID; - } - - static bool is_in_control_point_phase(const struct spirv_compiler *compiler) - { -- return compiler->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE; -+ return compiler->phase == VSIR_OP_HS_CONTROL_POINT_PHASE; - } - - static bool is_in_fork_or_join_phase(const struct spirv_compiler *compiler) - { -- return compiler->phase == VKD3DSIH_HS_FORK_PHASE || compiler->phase == VKD3DSIH_HS_JOIN_PHASE; -+ return compiler->phase == VSIR_OP_HS_FORK_PHASE || compiler->phase == VSIR_OP_HS_JOIN_PHASE; - } - - static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler); -@@ -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; - } - -- vkd3d_spirv_builder_init(&compiler->spirv_builder, spirv_compiler_get_entry_point_name(compiler)); -+ vkd3d_spirv_builder_init(&compiler->spirv_builder, -+ spirv_compiler_get_entry_point_name(compiler), compile_info->source_name); - - compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT - | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER; -@@ -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; - -- compiler->phase = VKD3DSIH_INVALID; -+ compiler->phase = VSIR_OP_INVALID; - - vkd3d_string_buffer_cache_init(&compiler->string_buffers); - -@@ -3559,8 +3528,12 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind - goto done; - } - -- resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER -- ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; -+ if (resource_type == VKD3D_SHADER_RESOURCE_NONE) -+ resource_type_flag = 0; -+ else if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER) -+ resource_type_flag = VKD3D_SHADER_BINDING_FLAG_BUFFER; -+ else -+ resource_type_flag = VKD3D_SHADER_BINDING_FLAG_IMAGE; - - if (is_uav_counter) - { -@@ -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]; - -- if (!(current->flags & resource_type_flag)) -+ if ((current->flags & resource_type_flag) != resource_type_flag) - continue; - - if (!spirv_compiler_check_shader_visibility(compiler, current->shader_visibility)) -@@ -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, -- "Unrecognized register (%s).\n", debug_vkd3d_symbol(®_symbol)); -+ "Unrecognized register (%s).", debug_vkd3d_symbol(®_symbol)); - memset(register_info, 0, sizeof(*register_info)); - return false; - } -@@ -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); - } - --/* Based on the implementation in the OpenGL Mathematics library. */ --static uint32_t half_to_float(uint16_t value) --{ -- uint32_t s = (value & 0x8000u) << 16; -- uint32_t e = (value >> 10) & 0x1fu; -- uint32_t m = value & 0x3ffu; -- -- if (!e) -- { -- if (!m) -- { -- /* Plus or minus zero */ -- return s; -- } -- else -- { -- /* Denormalized number -- renormalize it */ -- -- while (!(m & 0x400u)) -- { -- m <<= 1; -- --e; -- } -- -- ++e; -- m &= ~0x400u; -- } -- } -- else if (e == 31u) -- { -- /* Positive or negative infinity for zero 'm'. -- * Nan for non-zero 'm' -- preserve sign and significand bits */ -- return s | 0x7f800000u | (m << 13); -- } -- -- /* Normalized number */ -- e += 127u - 15u; -- m <<= 13; -- -- /* Assemble s, e and m. */ -- return s | (e << 23) | m; --} -- --static uint32_t convert_raw_constant32(enum vkd3d_data_type data_type, unsigned int uint_value) --{ -- int16_t i; -- -- /* TODO: native 16-bit support. */ -- if (data_type != VKD3D_DATA_UINT16 && data_type != VKD3D_DATA_HALF) -- return uint_value; -- -- if (data_type == VKD3D_DATA_HALF) -- return half_to_float(uint_value); -- -- /* Values in DXIL have no signedness, so it is ambiguous whether 16-bit constants should or -- * should not be sign-extended when 16-bit execution is not supported. The AMD RX 580 Windows -- * driver has no 16-bit support, and sign-extends all 16-bit constant ints to 32 bits. These -- * results differ from SM 5. The RX 6750 XT supports 16-bit execution, so constants are not -- * extended, and results match SM 5. It seems best to replicate the sign-extension, and if -- * execution is 16-bit, the values will be truncated. */ -- i = uint_value; -- return (int32_t)i; --} -- - 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 +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) -- values[i] = convert_raw_constant32(reg->data_type, reg->u.immconst_u32[0]); -+ values[i] = reg->u.immconst_u32[0]; - } - else - { - for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) - { - if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) -- values[j++] = convert_raw_constant32(reg->data_type, -- reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)]); -+ values[j++] = reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)]; - } - } - -@@ -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) - { -- case VKD3D_DATA_HALF: -- case VKD3D_DATA_UINT16: -- /* Scalar only. */ -- for (i = 0; i < element_count; ++i) -- 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: -+ 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) - { -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: - name = "control"; - break; -- case VKD3DSIH_HS_FORK_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: - name = "fork"; - break; -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - name = "join"; - break; - default: -@@ -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); - -- phase = (instruction->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE) -+ phase = (instruction->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE) - ? &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 +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) - { -- struct vkd3d_shader_phase *phase = (compiler->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE) -+ struct vkd3d_shader_phase *phase = (compiler->phase == VSIR_OP_HS_CONTROL_POINT_PHASE) - ? &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 +7544,40 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru - } - alu_ops[] = - { -- {VKD3DSIH_ADD, SpvOpFAdd}, -- {VKD3DSIH_AND, SpvOpBitwiseAnd}, -- {VKD3DSIH_BFREV, SpvOpBitReverse}, -- {VKD3DSIH_COUNTBITS, SpvOpBitCount}, -- {VKD3DSIH_DADD, SpvOpFAdd}, -- {VKD3DSIH_DDIV, SpvOpFDiv}, -- {VKD3DSIH_DIV, SpvOpFDiv}, -- {VKD3DSIH_DMUL, SpvOpFMul}, -- {VKD3DSIH_DTOI, SpvOpConvertFToS}, -- {VKD3DSIH_DTOU, SpvOpConvertFToU}, -- {VKD3DSIH_FREM, SpvOpFRem}, -- {VKD3DSIH_FTOD, SpvOpFConvert}, -- {VKD3DSIH_IADD, SpvOpIAdd}, -- {VKD3DSIH_INEG, SpvOpSNegate}, -- {VKD3DSIH_ISHL, SpvOpShiftLeftLogical}, -- {VKD3DSIH_ISHR, SpvOpShiftRightArithmetic}, -- {VKD3DSIH_ISINF, SpvOpIsInf}, -- {VKD3DSIH_ISNAN, SpvOpIsNan}, -- {VKD3DSIH_ITOD, SpvOpConvertSToF}, -- {VKD3DSIH_ITOF, SpvOpConvertSToF}, -- {VKD3DSIH_ITOI, SpvOpSConvert}, -- {VKD3DSIH_MUL, SpvOpFMul}, -- {VKD3DSIH_NOT, SpvOpNot}, -- {VKD3DSIH_OR, SpvOpBitwiseOr}, -- {VKD3DSIH_USHR, SpvOpShiftRightLogical}, -- {VKD3DSIH_UTOD, SpvOpConvertUToF}, -- {VKD3DSIH_UTOF, SpvOpConvertUToF}, -- {VKD3DSIH_UTOU, SpvOpUConvert}, -- {VKD3DSIH_XOR, SpvOpBitwiseXor}, -+ {VSIR_OP_ADD, SpvOpFAdd}, -+ {VSIR_OP_AND, SpvOpBitwiseAnd}, -+ {VSIR_OP_BFREV, SpvOpBitReverse}, -+ {VSIR_OP_COUNTBITS, SpvOpBitCount}, -+ {VSIR_OP_DADD, SpvOpFAdd}, -+ {VSIR_OP_DDIV, SpvOpFDiv}, -+ {VSIR_OP_DIV, SpvOpFDiv}, -+ {VSIR_OP_DMUL, SpvOpFMul}, -+ {VSIR_OP_DTOI, SpvOpConvertFToS}, -+ {VSIR_OP_DTOU, SpvOpConvertFToU}, -+ {VSIR_OP_FREM, SpvOpFRem}, -+ {VSIR_OP_FTOD, SpvOpFConvert}, -+ {VSIR_OP_IADD, SpvOpIAdd}, -+ {VSIR_OP_IDIV, SpvOpSDiv}, -+ {VSIR_OP_IMUL_LOW, SpvOpIMul}, -+ {VSIR_OP_INEG, SpvOpSNegate}, -+ {VSIR_OP_IREM, SpvOpSRem}, -+ {VSIR_OP_ISHL, SpvOpShiftLeftLogical}, -+ {VSIR_OP_ISHR, SpvOpShiftRightArithmetic}, -+ {VSIR_OP_ISINF, SpvOpIsInf}, -+ {VSIR_OP_ISNAN, SpvOpIsNan}, -+ {VSIR_OP_ITOD, SpvOpConvertSToF}, -+ {VSIR_OP_ITOF, SpvOpConvertSToF}, -+ {VSIR_OP_ITOI, SpvOpSConvert}, -+ {VSIR_OP_MUL, SpvOpFMul}, -+ {VSIR_OP_NOT, SpvOpNot}, -+ {VSIR_OP_OR, SpvOpBitwiseOr}, -+ {VSIR_OP_UDIV_SIMPLE, SpvOpUDiv}, -+ {VSIR_OP_UREM, SpvOpUMod}, -+ {VSIR_OP_USHR, SpvOpShiftRightLogical}, -+ {VSIR_OP_UTOD, SpvOpConvertUToF}, -+ {VSIR_OP_UTOF, SpvOpConvertUToF}, -+ {VSIR_OP_UTOU, SpvOpUConvert}, -+ {VSIR_OP_XOR, SpvOpBitwiseXor}, - }; - unsigned int i; - -@@ -7671,11 +7594,11 @@ static SpvOp spirv_compiler_map_logical_instruction(const struct vkd3d_shader_in - { - switch (instruction->opcode) - { -- case VKD3DSIH_AND: -+ case VSIR_OP_AND: - return SpvOpLogicalAnd; -- case VKD3DSIH_OR: -+ case VSIR_OP_OR: - return SpvOpLogicalOr; -- case VKD3DSIH_XOR: -+ case VSIR_OP_XOR: - return SpvOpLogicalNotEqual; - default: - return SpvOpMax; -@@ -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 == 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 == 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 == 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 == 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 +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) - { -+ uint32_t src_ids[SPIRV_MAX_SRC_COUNT], condition_id = 0, uint_max_id = 0; - 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 src_ids[SPIRV_MAX_SRC_COUNT]; -+ unsigned int i, component_count; - uint32_t type_id, val_id; - SpvOp op = SpvOpMax; -- unsigned int i; -+ bool check_zero; - -- if (src->reg.data_type == VKD3D_DATA_UINT64 && instruction->opcode == VKD3DSIH_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"); -@@ -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); - } -- else if (instruction->opcode == VKD3DSIH_ITOF || instruction->opcode == VKD3DSIH_UTOF -- || instruction->opcode == VKD3DSIH_ITOI || instruction->opcode == VKD3DSIH_UTOU) -+ else if (instruction->opcode == VSIR_OP_ITOF || instruction->opcode == VSIR_OP_UTOF -+ || instruction->opcode == VSIR_OP_ITOI || instruction->opcode == VSIR_OP_UTOU) - { - /* 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 +7686,50 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil - - if (op == SpvOpMax) - { -- ERR("Unexpected instruction %#x.\n", instruction->opcode); - spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER, -- "Encountered invalid/unhandled instruction handler %#x.", instruction->opcode); -+ "Encountered invalid/unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - return VKD3D_ERROR_INVALID_SHADER; - } - -+ /* SPIR-V doesn't mandate a behaviour when a denominator is zero, -+ * so we have an explicit check. */ -+ switch (instruction->opcode) -+ { -+ case VSIR_OP_IDIV: -+ case VSIR_OP_IREM: -+ case VSIR_OP_UDIV_SIMPLE: -+ case VSIR_OP_UREM: -+ check_zero = true; -+ break; -+ -+ default: -+ check_zero = false; -+ break; -+ } -+ - VKD3D_ASSERT(instruction->dst_count == 1); - VKD3D_ASSERT(instruction->src_count <= SPIRV_MAX_SRC_COUNT); -+ if (check_zero) -+ VKD3D_ASSERT(instruction->src_count == 2); - -+ component_count = vsir_write_mask_component_count(dst[0].write_mask); - type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); - - for (i = 0; i < instruction->src_count; ++i) - src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); - -+ if (check_zero) -+ { -+ 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 == 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); -+ } -+ - /* 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 +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. */ -- if (!(instruction->flags & VKD3DSI_SHIFT_UNMASKED) && (instruction->opcode == VKD3DSIH_ISHL -- || instruction->opcode == VKD3DSIH_ISHR || instruction->opcode == VKD3DSIH_USHR)) -+ if (!(instruction->flags & VKD3DSI_SHIFT_UNMASKED) && (instruction->opcode == VSIR_OP_ISHL -+ || instruction->opcode == VSIR_OP_ISHR || instruction->opcode == VSIR_OP_USHR)) - { - 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 +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); - -+ if (check_zero) -+ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); -+ - spirv_compiler_emit_store_dst(compiler, dst, val_id); - return VKD3D_OK; - } -@@ -7827,36 +7784,38 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( - } - glsl_insts[] = - { -- {VKD3DSIH_ABS, GLSLstd450FAbs}, -- {VKD3DSIH_ACOS, GLSLstd450Acos}, -- {VKD3DSIH_ASIN, GLSLstd450Asin}, -- {VKD3DSIH_ATAN, GLSLstd450Atan}, -- {VKD3DSIH_DFMA, GLSLstd450Fma}, -- {VKD3DSIH_DMAX, GLSLstd450NMax}, -- {VKD3DSIH_DMIN, GLSLstd450NMin}, -- {VKD3DSIH_EXP, GLSLstd450Exp2}, -- {VKD3DSIH_FIRSTBIT_HI, GLSLstd450FindUMsb}, -- {VKD3DSIH_FIRSTBIT_LO, GLSLstd450FindILsb}, -- {VKD3DSIH_FIRSTBIT_SHI, GLSLstd450FindSMsb}, -- {VKD3DSIH_FRC, GLSLstd450Fract}, -- {VKD3DSIH_HCOS, GLSLstd450Cosh}, -- {VKD3DSIH_HSIN, GLSLstd450Sinh}, -- {VKD3DSIH_HTAN, GLSLstd450Tanh}, -- {VKD3DSIH_IMAX, GLSLstd450SMax}, -- {VKD3DSIH_IMIN, GLSLstd450SMin}, -- {VKD3DSIH_LOG, GLSLstd450Log2}, -- {VKD3DSIH_MAD, GLSLstd450Fma}, -- {VKD3DSIH_MAX, GLSLstd450NMax}, -- {VKD3DSIH_MIN, GLSLstd450NMin}, -- {VKD3DSIH_ROUND_NE, GLSLstd450RoundEven}, -- {VKD3DSIH_ROUND_NI, GLSLstd450Floor}, -- {VKD3DSIH_ROUND_PI, GLSLstd450Ceil}, -- {VKD3DSIH_ROUND_Z, GLSLstd450Trunc}, -- {VKD3DSIH_RSQ, GLSLstd450InverseSqrt}, -- {VKD3DSIH_SQRT, GLSLstd450Sqrt}, -- {VKD3DSIH_TAN, GLSLstd450Tan}, -- {VKD3DSIH_UMAX, GLSLstd450UMax}, -- {VKD3DSIH_UMIN, GLSLstd450UMin}, -+ {VSIR_OP_ABS, GLSLstd450FAbs}, -+ {VSIR_OP_ACOS, GLSLstd450Acos}, -+ {VSIR_OP_ASIN, GLSLstd450Asin}, -+ {VSIR_OP_ATAN, GLSLstd450Atan}, -+ {VSIR_OP_COS, GLSLstd450Cos}, -+ {VSIR_OP_DFMA, GLSLstd450Fma}, -+ {VSIR_OP_DMAX, GLSLstd450NMax}, -+ {VSIR_OP_DMIN, GLSLstd450NMin}, -+ {VSIR_OP_EXP, GLSLstd450Exp2}, -+ {VSIR_OP_FIRSTBIT_HI, GLSLstd450FindUMsb}, -+ {VSIR_OP_FIRSTBIT_LO, GLSLstd450FindILsb}, -+ {VSIR_OP_FIRSTBIT_SHI, GLSLstd450FindSMsb}, -+ {VSIR_OP_FRC, GLSLstd450Fract}, -+ {VSIR_OP_HCOS, GLSLstd450Cosh}, -+ {VSIR_OP_HSIN, GLSLstd450Sinh}, -+ {VSIR_OP_HTAN, GLSLstd450Tanh}, -+ {VSIR_OP_IMAX, GLSLstd450SMax}, -+ {VSIR_OP_IMIN, GLSLstd450SMin}, -+ {VSIR_OP_LOG, GLSLstd450Log2}, -+ {VSIR_OP_MAD, GLSLstd450Fma}, -+ {VSIR_OP_MAX, GLSLstd450NMax}, -+ {VSIR_OP_MIN, GLSLstd450NMin}, -+ {VSIR_OP_ROUND_NE, GLSLstd450RoundEven}, -+ {VSIR_OP_ROUND_NI, GLSLstd450Floor}, -+ {VSIR_OP_ROUND_PI, GLSLstd450Ceil}, -+ {VSIR_OP_ROUND_Z, GLSLstd450Trunc}, -+ {VSIR_OP_RSQ, GLSLstd450InverseSqrt}, -+ {VSIR_OP_SIN, GLSLstd450Sin}, -+ {VSIR_OP_SQRT, GLSLstd450Sqrt}, -+ {VSIR_OP_TAN, GLSLstd450Tan}, -+ {VSIR_OP_UMAX, GLSLstd450UMax}, -+ {VSIR_OP_UMIN, GLSLstd450UMin}, - }; - unsigned int i; - -@@ -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 == 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. */ -- FIXME("Unsupported 64-bit source for handler %#x.\n", instruction->opcode); - spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -- "64-bit source for handler %#x is not supported.", instruction->opcode); -+ "64-bit source for instruction \"%s\" (%#x) is not supported.", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - return; - } - - glsl_inst = spirv_compiler_map_ext_glsl_instruction(instruction); - if (glsl_inst == GLSLstd450Bad) - { -- ERR("Unexpected instruction %#x.\n", instruction->opcode); -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - return; - } - -@@ -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); - -- if (instruction->opcode == VKD3DSIH_FIRSTBIT_HI -- || instruction->opcode == VKD3DSIH_FIRSTBIT_SHI) -+ if (instruction->opcode == VSIR_OP_FIRSTBIT_HI -+ || instruction->opcode == VSIR_OP_FIRSTBIT_SHI) - { - /* In D3D bits are numbered from the most significant bit. */ - component_count = vsir_write_mask_component_count(dst->write_mask); -@@ -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; - -- if (vkd3d_swizzle_is_equal(dst_reg_info.write_mask, src->swizzle, src_reg_info.write_mask)) -+ if (dst_reg_info.write_mask == dst->write_mask -+ && vkd3d_swizzle_is_equal(dst_reg_info.write_mask, src->swizzle, src_reg_info.write_mask)) - { - dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); - src_id = spirv_compiler_get_register_id(compiler, &src->reg); -@@ -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 != 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 +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); - -- if (instruction->opcode == VKD3DSIH_DP4) -+ if (instruction->opcode == VSIR_OP_DP4) - write_mask = VKD3DSP_WRITEMASK_ALL; -- else if (instruction->opcode == VKD3DSIH_DP3) -+ else if (instruction->opcode == VSIR_OP_DP3) - write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2; - else - write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; -@@ -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); - } - --static void spirv_compiler_emit_sincos(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) --{ -- const struct vkd3d_shader_dst_param *dst_sin = &instruction->dst[0]; -- const struct vkd3d_shader_dst_param *dst_cos = &instruction->dst[1]; -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- const struct vkd3d_shader_src_param *src = instruction->src; -- uint32_t type_id, src_id, sin_id = 0, cos_id = 0; -- -- if (dst_sin->reg.type != VKD3DSPR_NULL) -- { -- type_id = spirv_compiler_get_type_id_for_dst(compiler, dst_sin); -- src_id = spirv_compiler_emit_load_src(compiler, src, dst_sin->write_mask); -- -- sin_id = vkd3d_spirv_build_op_glsl_std450_sin(builder, type_id, src_id); -- } -- -- if (dst_cos->reg.type != VKD3DSPR_NULL) -- { -- if (dst_sin->reg.type == VKD3DSPR_NULL || dst_cos->write_mask != dst_sin->write_mask) -- { -- type_id = spirv_compiler_get_type_id_for_dst(compiler, dst_cos); -- src_id = spirv_compiler_emit_load_src(compiler, src, dst_cos->write_mask); -- } -- -- cos_id = vkd3d_spirv_build_op_glsl_std450_cos(builder, type_id, src_id); -- } -- -- if (sin_id) -- spirv_compiler_emit_store_dst(compiler, dst_sin, sin_id); -- -- if (cos_id) -- spirv_compiler_emit_store_dst(compiler, dst_cos, cos_id); --} -- --static void spirv_compiler_emit_imul(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) --{ -- 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, val_id, src0_id, src1_id; -- -- if (dst[0].reg.type != VKD3DSPR_NULL) -- FIXME("Extended multiplies not implemented.\n"); /* SpvOpSMulExtended/SpvOpUMulExtended */ -- -- if (dst[1].reg.type == VKD3DSPR_NULL) -- return; -- -- type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]); -- -- src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); -- src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); -- -- val_id = vkd3d_spirv_build_op_imul(builder, type_id, src0_id, src1_id); -- -- spirv_compiler_emit_store_dst(compiler, &dst[1], val_id); --} -- - static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) - { -@@ -8200,67 +8103,6 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, - spirv_compiler_emit_store_dst(compiler, dst, val_id); - } - --static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) --{ -- uint32_t type_id, val_id, src0_id, src1_id, condition_id, uint_max_id; -- 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; -- unsigned int component_count = 0; -- SpvOp div_op, mod_op; -- -- div_op = instruction->opcode == VKD3DSIH_IDIV ? SpvOpSDiv : SpvOpUDiv; -- mod_op = instruction->opcode == VKD3DSIH_IDIV ? SpvOpSRem : SpvOpUMod; -- -- if (dst[0].reg.type != VKD3DSPR_NULL) -- { -- component_count = vsir_write_mask_component_count(dst[0].write_mask); -- type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[0]); -- -- src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[0].write_mask); -- src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[0].write_mask); -- -- condition_id = spirv_compiler_emit_int_to_bool(compiler, -- VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id); -- if (dst[0].reg.data_type == VKD3D_DATA_UINT64) -- 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, 0xffffffff, component_count); -- -- val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id); -- /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ -- val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); -- -- spirv_compiler_emit_store_dst(compiler, &dst[0], val_id); -- } -- -- if (dst[1].reg.type != VKD3DSPR_NULL) -- { -- if (!component_count || dst[0].write_mask != dst[1].write_mask) -- { -- component_count = vsir_write_mask_component_count(dst[1].write_mask); -- type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]); -- -- src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); -- src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); -- -- condition_id = spirv_compiler_emit_int_to_bool(compiler, -- VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id); -- if (dst[1].reg.data_type == VKD3D_DATA_UINT64) -- 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, 0xffffffff, component_count); -- } -- -- val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id); -- /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ -- val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); -- -- spirv_compiler_emit_store_dst(compiler, &dst[1], val_id); -- } --} -- - static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) - { -@@ -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) - { -- case VKD3DSIH_BFI: op = SpvOpBitFieldInsert; break; -- case VKD3DSIH_IBFE: op = SpvOpBitFieldSExtract; break; -- case VKD3DSIH_UBFE: op = SpvOpBitFieldUExtract; break; -+ case VSIR_OP_BFI: op = SpvOpBitFieldInsert; break; -+ case VSIR_OP_IBFE: op = SpvOpBitFieldSExtract; break; -+ case VSIR_OP_UBFE: op = SpvOpBitFieldUExtract; break; - default: -- ERR("Unexpected instruction %#x.\n", instruction->opcode); -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - return; - } - -@@ -8531,26 +8375,28 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co - - switch (instruction->opcode) - { -- case VKD3DSIH_DEQO: -- case VKD3DSIH_EQO: op = SpvOpFOrdEqual; break; -- case VKD3DSIH_EQU: op = SpvOpFUnordEqual; break; -- case VKD3DSIH_DGEO: -- case VKD3DSIH_GEO: op = SpvOpFOrdGreaterThanEqual; break; -- case VKD3DSIH_GEU: op = SpvOpFUnordGreaterThanEqual; break; -- case VKD3DSIH_IEQ: op = SpvOpIEqual; break; -- case VKD3DSIH_IGE: op = SpvOpSGreaterThanEqual; break; -- case VKD3DSIH_ILT: op = SpvOpSLessThan; break; -- case VKD3DSIH_INE: op = SpvOpINotEqual; break; -- case VKD3DSIH_DLT: -- case VKD3DSIH_LTO: op = SpvOpFOrdLessThan; break; -- case VKD3DSIH_LTU: op = SpvOpFUnordLessThan; break; -- case VKD3DSIH_NEO: op = SpvOpFOrdNotEqual; break; -- case VKD3DSIH_DNE: -- case VKD3DSIH_NEU: op = SpvOpFUnordNotEqual; break; -- case VKD3DSIH_UGE: op = SpvOpUGreaterThanEqual; break; -- case VKD3DSIH_ULT: op = SpvOpULessThan; break; -+ case VSIR_OP_DEQO: -+ case VSIR_OP_EQO: op = SpvOpFOrdEqual; break; -+ case VSIR_OP_EQU: op = SpvOpFUnordEqual; break; -+ case VSIR_OP_DGEO: -+ case VSIR_OP_GEO: op = SpvOpFOrdGreaterThanEqual; break; -+ case VSIR_OP_GEU: op = SpvOpFUnordGreaterThanEqual; break; -+ case VSIR_OP_IEQ: op = SpvOpIEqual; break; -+ case VSIR_OP_IGE: op = SpvOpSGreaterThanEqual; break; -+ case VSIR_OP_ILT: op = SpvOpSLessThan; break; -+ case VSIR_OP_INE: op = SpvOpINotEqual; break; -+ case VSIR_OP_DLT: -+ case VSIR_OP_LTO: op = SpvOpFOrdLessThan; break; -+ case VSIR_OP_LTU: op = SpvOpFUnordLessThan; break; -+ case VSIR_OP_NEO: op = SpvOpFOrdNotEqual; break; -+ case VSIR_OP_DNE: -+ case VSIR_OP_NEU: op = SpvOpFUnordNotEqual; break; -+ case VSIR_OP_UGE: op = SpvOpUGreaterThanEqual; break; -+ case VSIR_OP_ULT: op = SpvOpULessThan; break; - default: -- ERR("Unexpected instruction %#x.\n", instruction->opcode); -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - return; - } - -@@ -8558,10 +8404,10 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co - - switch (instruction->opcode) - { -- case VKD3DSIH_DEQO: -- case VKD3DSIH_DGEO: -- case VKD3DSIH_DLT: -- case VKD3DSIH_DNE: -+ case VSIR_OP_DEQO: -+ case VSIR_OP_DGEO: -+ case VSIR_OP_DLT: -+ case VSIR_OP_DNE: - write_mask = vkd3d_write_mask_from_component_count(component_count); - break; - -@@ -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); -- if (instruction->opcode == VKD3DSIH_ORD) -+ if (instruction->opcode == VSIR_OP_ORD) - val_id = vkd3d_spirv_build_op_logical_not(builder, type_id, val_id); - spirv_compiler_emit_store_dst(compiler, dst, val_id); - } -@@ -8613,8 +8459,8 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil - - switch (instruction->opcode) - { -- case VKD3DSIH_SLT: op = SpvOpFOrdLessThan; break; -- case VKD3DSIH_SGE: op = SpvOpFOrdGreaterThanEqual; break; -+ case VSIR_OP_SLT: op = SpvOpFOrdLessThan; break; -+ case VSIR_OP_SGE: op = SpvOpFOrdGreaterThanEqual; break; - default: - vkd3d_unreachable(); - } -@@ -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[] = - { -- {VKD3DSIH_DSX, SpvOpDPdx}, -- {VKD3DSIH_DSX_COARSE, SpvOpDPdxCoarse, true}, -- {VKD3DSIH_DSX_FINE, SpvOpDPdxFine, true}, -- {VKD3DSIH_DSY, SpvOpDPdy}, -- {VKD3DSIH_DSY_COARSE, SpvOpDPdyCoarse, true}, -- {VKD3DSIH_DSY_FINE, SpvOpDPdyFine, true}, -+ {VSIR_OP_DSX, SpvOpDPdx}, -+ {VSIR_OP_DSX_COARSE, SpvOpDPdxCoarse, true}, -+ {VSIR_OP_DSX_FINE, SpvOpDPdxFine, true}, -+ {VSIR_OP_DSY, SpvOpDPdy}, -+ {VSIR_OP_DSY_COARSE, SpvOpDPdyCoarse, true}, -+ {VSIR_OP_DSY_FINE, SpvOpDPdyFine, true}, - }; - - info = NULL; -@@ -8936,7 +8782,9 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile - } - if (!info) - { -- ERR("Unexpected instruction %#x.\n", instruction->opcode); -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - return; - } - -@@ -9147,7 +8995,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, - uint32_t coordinate_mask; - bool multisample; - -- multisample = instruction->opcode == VKD3DSIH_LD2DMS; -+ multisample = instruction->opcode == VSIR_OP_LD2DMS; - - spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); - -@@ -9228,16 +9076,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, - - switch (instruction->opcode) - { -- case VKD3DSIH_SAMPLE: -+ case VSIR_OP_SAMPLE: - op = SpvOpImageSampleImplicitLod; - break; -- case VKD3DSIH_SAMPLE_B: -+ case VSIR_OP_SAMPLE_B: - op = SpvOpImageSampleImplicitLod; - operands_mask |= SpvImageOperandsBiasMask; - image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, - &src[3], VKD3DSP_WRITEMASK_0); - break; -- case VKD3DSIH_SAMPLE_GRAD: -+ case VSIR_OP_SAMPLE_GRAD: - op = SpvOpImageSampleExplicitLod; - operands_mask |= SpvImageOperandsGradMask; - component_count = image.resource_type_info->coordinate_component_count - image.resource_type_info->arrayed; -@@ -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; -- case VKD3DSIH_SAMPLE_LOD: -+ case VSIR_OP_SAMPLE_LOD: - op = SpvOpImageSampleExplicitLod; - operands_mask |= SpvImageOperandsLodMask; - image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, - &src[3], VKD3DSP_WRITEMASK_0); - break; - default: -- ERR("Unexpected instruction %#x.\n", instruction->opcode); -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - return; - } - -@@ -9288,7 +9138,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, - uint32_t image_operands[2]; - SpvOp op; - -- if (instruction->opcode == VKD3DSIH_SAMPLE_C_LZ) -+ if (instruction->opcode == VSIR_OP_SAMPLE_C_LZ) - { - op = SpvOpImageSampleDrefExplicitLod; - operands_mask |= SpvImageOperandsLodMask; -@@ -9338,12 +9188,12 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, - uint32_t coordinate_mask; - bool extended_offset; - -- if (instruction->opcode == VKD3DSIH_GATHER4_C -- || instruction->opcode == VKD3DSIH_GATHER4_PO_C) -+ if (instruction->opcode == VSIR_OP_GATHER4_C -+ || instruction->opcode == VSIR_OP_GATHER4_PO_C) - image_flags |= VKD3D_IMAGE_FLAG_DEPTH; - -- extended_offset = instruction->opcode == VKD3DSIH_GATHER4_PO -- || instruction->opcode == VKD3DSIH_GATHER4_PO_C; -+ extended_offset = instruction->opcode == VSIR_OP_GATHER4_PO -+ || instruction->opcode == VSIR_OP_GATHER4_PO_C; - - addr = &src[0]; - offset = extended_offset ? &src[1] : NULL; -@@ -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; - -- op = instruction->opcode == VKD3DSIH_IMM_ATOMIC_ALLOC -+ op = instruction->opcode == VSIR_OP_IMM_ATOMIC_ALLOC - ? SpvOpAtomicIIncrement : SpvOpAtomicIDecrement; - - resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); -@@ -9872,25 +9722,25 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins - } - atomic_ops[] = - { -- {VKD3DSIH_ATOMIC_AND, SpvOpAtomicAnd}, -- {VKD3DSIH_ATOMIC_CMP_STORE, SpvOpAtomicCompareExchange}, -- {VKD3DSIH_ATOMIC_IADD, SpvOpAtomicIAdd}, -- {VKD3DSIH_ATOMIC_IMAX, SpvOpAtomicSMax}, -- {VKD3DSIH_ATOMIC_IMIN, SpvOpAtomicSMin}, -- {VKD3DSIH_ATOMIC_OR, SpvOpAtomicOr}, -- {VKD3DSIH_ATOMIC_UMAX, SpvOpAtomicUMax}, -- {VKD3DSIH_ATOMIC_UMIN, SpvOpAtomicUMin}, -- {VKD3DSIH_ATOMIC_XOR, SpvOpAtomicXor}, -- {VKD3DSIH_IMM_ATOMIC_AND, SpvOpAtomicAnd}, -- {VKD3DSIH_IMM_ATOMIC_CMP_EXCH, SpvOpAtomicCompareExchange}, -- {VKD3DSIH_IMM_ATOMIC_EXCH, SpvOpAtomicExchange}, -- {VKD3DSIH_IMM_ATOMIC_IADD, SpvOpAtomicIAdd}, -- {VKD3DSIH_IMM_ATOMIC_IMAX, SpvOpAtomicSMax}, -- {VKD3DSIH_IMM_ATOMIC_IMIN, SpvOpAtomicSMin}, -- {VKD3DSIH_IMM_ATOMIC_OR, SpvOpAtomicOr}, -- {VKD3DSIH_IMM_ATOMIC_UMAX, SpvOpAtomicUMax}, -- {VKD3DSIH_IMM_ATOMIC_UMIN, SpvOpAtomicUMin}, -- {VKD3DSIH_IMM_ATOMIC_XOR, SpvOpAtomicXor}, -+ {VSIR_OP_ATOMIC_AND, SpvOpAtomicAnd}, -+ {VSIR_OP_ATOMIC_CMP_STORE, SpvOpAtomicCompareExchange}, -+ {VSIR_OP_ATOMIC_IADD, SpvOpAtomicIAdd}, -+ {VSIR_OP_ATOMIC_IMAX, SpvOpAtomicSMax}, -+ {VSIR_OP_ATOMIC_IMIN, SpvOpAtomicSMin}, -+ {VSIR_OP_ATOMIC_OR, SpvOpAtomicOr}, -+ {VSIR_OP_ATOMIC_UMAX, SpvOpAtomicUMax}, -+ {VSIR_OP_ATOMIC_UMIN, SpvOpAtomicUMin}, -+ {VSIR_OP_ATOMIC_XOR, SpvOpAtomicXor}, -+ {VSIR_OP_IMM_ATOMIC_AND, SpvOpAtomicAnd}, -+ {VSIR_OP_IMM_ATOMIC_CMP_EXCH, SpvOpAtomicCompareExchange}, -+ {VSIR_OP_IMM_ATOMIC_EXCH, SpvOpAtomicExchange}, -+ {VSIR_OP_IMM_ATOMIC_IADD, SpvOpAtomicIAdd}, -+ {VSIR_OP_IMM_ATOMIC_IMAX, SpvOpAtomicSMax}, -+ {VSIR_OP_IMM_ATOMIC_IMIN, SpvOpAtomicSMin}, -+ {VSIR_OP_IMM_ATOMIC_OR, SpvOpAtomicOr}, -+ {VSIR_OP_IMM_ATOMIC_UMAX, SpvOpAtomicUMax}, -+ {VSIR_OP_IMM_ATOMIC_UMIN, SpvOpAtomicUMin}, -+ {VSIR_OP_IMM_ATOMIC_XOR, SpvOpAtomicXor}, - }; - unsigned int i; - -@@ -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) - { -- return VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR; -+ return VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR; - } - - static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compiler, -@@ -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) - { -- ERR("Unexpected instruction %#x.\n", instruction->opcode); -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - return; - } - -@@ -10014,9 +9866,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - - if (instruction->flags & VKD3DARF_VOLATILE) - { -- WARN("Ignoring 'volatile' attribute.\n"); - spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_IGNORING_FLAG, -- "Ignoring the 'volatile' attribute flag for atomic instruction %#x.", instruction->opcode); -+ "Ignoring the 'volatile' attribute flag for atomic instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - } - - memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) -@@ -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; - -- if (instruction->opcode == VKD3DSIH_EVAL_CENTROID) -+ if (instruction->opcode == VSIR_OP_EVAL_CENTROID) - { - op = GLSLstd450InterpolateAtCentroid; - } - else - { -- VKD3D_ASSERT(instruction->opcode == VKD3DSIH_EVAL_SAMPLE_INDEX); -+ VKD3D_ASSERT(instruction->opcode == VSIR_OP_EVAL_SAMPLE_INDEX); - op = GLSLstd450InterpolateAtSample; - src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); - } -@@ -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; - -- if (instruction->opcode == VKD3DSIH_EMIT_STREAM) -+ if (instruction->opcode == VSIR_OP_EMIT_STREAM) - stream_idx = instruction->src[0].reg.idx[0].offset; - else - stream_idx = 0; -@@ -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; - -- if (instruction->opcode == VKD3DSIH_CUT_STREAM) -+ if (instruction->opcode == VSIR_OP_CUT_STREAM) - stream_idx = instruction->src[0].reg.idx[0].offset; - else - stream_idx = 0; -@@ -10467,11 +10315,11 @@ static uint32_t map_quad_read_across_direction(enum vkd3d_shader_opcode opcode) - { - switch (opcode) - { -- case VKD3DSIH_QUAD_READ_ACROSS_X: -+ case VSIR_OP_QUAD_READ_ACROSS_X: - return 0; -- case VKD3DSIH_QUAD_READ_ACROSS_Y: -+ case VSIR_OP_QUAD_READ_ACROSS_Y: - return 1; -- case VKD3DSIH_QUAD_READ_ACROSS_D: -+ case VSIR_OP_QUAD_READ_ACROSS_D: - return 2; - default: - vkd3d_unreachable(); -@@ -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) - { -- case VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL: -+ case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL: - return SpvOpGroupNonUniformAllEqual; -- case VKD3DSIH_WAVE_ALL_TRUE: -+ case VSIR_OP_WAVE_ALL_TRUE: - return SpvOpGroupNonUniformAll; -- case VKD3DSIH_WAVE_ANY_TRUE: -+ case VSIR_OP_WAVE_ANY_TRUE: - return SpvOpGroupNonUniformAny; - default: - vkd3d_unreachable(); -@@ -10584,27 +10432,27 @@ static SpvOp map_wave_alu_op(enum vkd3d_shader_opcode opcode, bool is_float) - { - switch (opcode) - { -- case VKD3DSIH_WAVE_ACTIVE_BIT_AND: -+ case VSIR_OP_WAVE_ACTIVE_BIT_AND: - return SpvOpGroupNonUniformBitwiseAnd; -- case VKD3DSIH_WAVE_ACTIVE_BIT_OR: -+ case VSIR_OP_WAVE_ACTIVE_BIT_OR: - return SpvOpGroupNonUniformBitwiseOr; -- case VKD3DSIH_WAVE_ACTIVE_BIT_XOR: -+ case VSIR_OP_WAVE_ACTIVE_BIT_XOR: - return SpvOpGroupNonUniformBitwiseXor; -- case VKD3DSIH_WAVE_OP_ADD: -+ case VSIR_OP_WAVE_OP_ADD: - return is_float ? SpvOpGroupNonUniformFAdd : SpvOpGroupNonUniformIAdd; -- case VKD3DSIH_WAVE_OP_IMAX: -+ case VSIR_OP_WAVE_OP_IMAX: - return SpvOpGroupNonUniformSMax; -- case VKD3DSIH_WAVE_OP_IMIN: -+ case VSIR_OP_WAVE_OP_IMIN: - return SpvOpGroupNonUniformSMin; -- case VKD3DSIH_WAVE_OP_MAX: -+ case VSIR_OP_WAVE_OP_MAX: - return SpvOpGroupNonUniformFMax; -- case VKD3DSIH_WAVE_OP_MIN: -+ case VSIR_OP_WAVE_OP_MIN: - return SpvOpGroupNonUniformFMin; -- case VKD3DSIH_WAVE_OP_MUL: -+ case VSIR_OP_WAVE_OP_MUL: - return is_float ? SpvOpGroupNonUniformFMul : SpvOpGroupNonUniformIMul; -- case VKD3DSIH_WAVE_OP_UMAX: -+ case VSIR_OP_WAVE_OP_UMAX: - return SpvOpGroupNonUniformUMax; -- case VKD3DSIH_WAVE_OP_UMIN: -+ case VSIR_OP_WAVE_OP_UMIN: - return SpvOpGroupNonUniformUMin; - default: - vkd3d_unreachable(); -@@ -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; - -- group_op = (instruction->opcode == VKD3DSIH_WAVE_PREFIX_BIT_COUNT) ? SpvGroupOperationExclusiveScan -+ group_op = (instruction->opcode == VSIR_OP_WAVE_PREFIX_BIT_COUNT) ? SpvGroupOperationExclusiveScan - : SpvGroupOperationReduce; - - val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); -@@ -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) - { -- case VKD3DSIH_DCL_INDEXABLE_TEMP: -+ case VSIR_OP_DCL_INDEXABLE_TEMP: - spirv_compiler_emit_dcl_indexable_temp(compiler, instruction); - break; -- case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER: -+ case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: - spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction); - break; -- case VKD3DSIH_DCL_TGSM_RAW: -+ case VSIR_OP_DCL_TGSM_RAW: - spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction); - break; -- case VKD3DSIH_DCL_TGSM_STRUCTURED: -+ case VSIR_OP_DCL_TGSM_STRUCTURED: - spirv_compiler_emit_dcl_tgsm_structured(compiler, instruction); - break; -- case VKD3DSIH_DCL_STREAM: -+ case VSIR_OP_DCL_STREAM: - spirv_compiler_emit_dcl_stream(compiler, instruction); - break; -- case VKD3DSIH_DCL_VERTICES_OUT: -+ case VSIR_OP_DCL_VERTICES_OUT: - spirv_compiler_emit_output_vertex_count(compiler, instruction); - break; -- case VKD3DSIH_DCL_INPUT_PRIMITIVE: -+ case VSIR_OP_DCL_INPUT_PRIMITIVE: - spirv_compiler_emit_dcl_input_primitive(compiler, instruction); - break; -- case VKD3DSIH_DCL_OUTPUT_TOPOLOGY: -+ case VSIR_OP_DCL_OUTPUT_TOPOLOGY: - spirv_compiler_emit_dcl_output_topology(compiler, instruction); - break; -- case VKD3DSIH_DCL_GS_INSTANCES: -+ case VSIR_OP_DCL_GS_INSTANCES: - spirv_compiler_emit_dcl_gs_instances(compiler, instruction); - break; -- case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT: -+ case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: - spirv_compiler_emit_output_vertex_count(compiler, instruction); - break; -- case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: -+ case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: - spirv_compiler_emit_tessellator_output_primitive(compiler, - instruction->declaration.tessellator_output_primitive); - break; -- case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING: -+ case VSIR_OP_DCL_TESSELLATOR_PARTITIONING: - spirv_compiler_emit_tessellator_partitioning(compiler, - instruction->declaration.tessellator_partitioning); - break; -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_HS_JOIN_PHASE: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_HS_JOIN_PHASE: - spirv_compiler_enter_shader_phase(compiler, instruction); - break; -- case VKD3DSIH_DMOV: -- case VKD3DSIH_MOV: -+ case VSIR_OP_DMOV: -+ case VSIR_OP_MOV: - spirv_compiler_emit_mov(compiler, instruction); - break; -- case VKD3DSIH_DMOVC: -- case VKD3DSIH_MOVC: -- case VKD3DSIH_CMP: -+ case VSIR_OP_DMOVC: -+ case VSIR_OP_MOVC: -+ case VSIR_OP_CMP: - spirv_compiler_emit_movc(compiler, instruction); - break; -- case VKD3DSIH_SWAPC: -+ case VSIR_OP_SWAPC: - spirv_compiler_emit_swapc(compiler, instruction); - break; -- case VKD3DSIH_ADD: -- case VKD3DSIH_AND: -- case VKD3DSIH_BFREV: -- case VKD3DSIH_COUNTBITS: -- case VKD3DSIH_DADD: -- case VKD3DSIH_DDIV: -- case VKD3DSIH_DIV: -- case VKD3DSIH_DMUL: -- case VKD3DSIH_FREM: -- case VKD3DSIH_FTOD: -- case VKD3DSIH_IADD: -- case VKD3DSIH_INEG: -- case VKD3DSIH_ISHL: -- case VKD3DSIH_ISHR: -- case VKD3DSIH_ISINF: -- case VKD3DSIH_ISNAN: -- case VKD3DSIH_ITOD: -- case VKD3DSIH_ITOF: -- case VKD3DSIH_ITOI: -- case VKD3DSIH_MUL: -- case VKD3DSIH_NOT: -- case VKD3DSIH_OR: -- case VKD3DSIH_USHR: -- case VKD3DSIH_UTOD: -- case VKD3DSIH_UTOF: -- case VKD3DSIH_UTOU: -- case VKD3DSIH_XOR: -+ case VSIR_OP_ADD: -+ case VSIR_OP_AND: -+ case VSIR_OP_BFREV: -+ case VSIR_OP_COUNTBITS: -+ case VSIR_OP_DADD: -+ case VSIR_OP_DDIV: -+ case VSIR_OP_DIV: -+ case VSIR_OP_DMUL: -+ case VSIR_OP_FREM: -+ case VSIR_OP_FTOD: -+ case VSIR_OP_IADD: -+ case VSIR_OP_IDIV: -+ case VSIR_OP_IMUL_LOW: -+ case VSIR_OP_INEG: -+ case VSIR_OP_IREM: -+ case VSIR_OP_ISHL: -+ case VSIR_OP_ISHR: -+ case VSIR_OP_ISINF: -+ case VSIR_OP_ISNAN: -+ case VSIR_OP_ITOD: -+ case VSIR_OP_ITOF: -+ case VSIR_OP_ITOI: -+ case VSIR_OP_MUL: -+ case VSIR_OP_NOT: -+ case VSIR_OP_OR: -+ case VSIR_OP_UDIV_SIMPLE: -+ case VSIR_OP_UREM: -+ case VSIR_OP_USHR: -+ case VSIR_OP_UTOD: -+ case VSIR_OP_UTOF: -+ case VSIR_OP_UTOU: -+ case VSIR_OP_XOR: - ret = spirv_compiler_emit_alu_instruction(compiler, instruction); - break; -- case VKD3DSIH_ISFINITE: -+ case VSIR_OP_ISFINITE: - spirv_compiler_emit_isfinite(compiler, instruction); - break; -- case VKD3DSIH_ABS: -- case VKD3DSIH_ACOS: -- case VKD3DSIH_ASIN: -- case VKD3DSIH_ATAN: -- case VKD3DSIH_HCOS: -- case VKD3DSIH_HSIN: -- case VKD3DSIH_HTAN: -- case VKD3DSIH_DFMA: -- case VKD3DSIH_DMAX: -- case VKD3DSIH_DMIN: -- case VKD3DSIH_EXP: -- case VKD3DSIH_FIRSTBIT_HI: -- case VKD3DSIH_FIRSTBIT_LO: -- case VKD3DSIH_FIRSTBIT_SHI: -- case VKD3DSIH_FRC: -- case VKD3DSIH_IMAX: -- case VKD3DSIH_IMIN: -- case VKD3DSIH_LOG: -- case VKD3DSIH_MAD: -- case VKD3DSIH_MAX: -- case VKD3DSIH_MIN: -- case VKD3DSIH_ROUND_NE: -- case VKD3DSIH_ROUND_NI: -- case VKD3DSIH_ROUND_PI: -- case VKD3DSIH_ROUND_Z: -- case VKD3DSIH_RSQ: -- case VKD3DSIH_SQRT: -- case VKD3DSIH_TAN: -- case VKD3DSIH_UMAX: -- case VKD3DSIH_UMIN: -+ case VSIR_OP_ABS: -+ case VSIR_OP_ACOS: -+ case VSIR_OP_ASIN: -+ case VSIR_OP_ATAN: -+ case VSIR_OP_COS: -+ case VSIR_OP_HCOS: -+ case VSIR_OP_HSIN: -+ case VSIR_OP_HTAN: -+ case VSIR_OP_DFMA: -+ case VSIR_OP_DMAX: -+ case VSIR_OP_DMIN: -+ case VSIR_OP_EXP: -+ case VSIR_OP_FIRSTBIT_HI: -+ case VSIR_OP_FIRSTBIT_LO: -+ case VSIR_OP_FIRSTBIT_SHI: -+ case VSIR_OP_FRC: -+ case VSIR_OP_IMAX: -+ case VSIR_OP_IMIN: -+ case VSIR_OP_LOG: -+ case VSIR_OP_MAD: -+ case VSIR_OP_MAX: -+ case VSIR_OP_MIN: -+ case VSIR_OP_ROUND_NE: -+ case VSIR_OP_ROUND_NI: -+ case VSIR_OP_ROUND_PI: -+ case VSIR_OP_ROUND_Z: -+ case VSIR_OP_RSQ: -+ case VSIR_OP_SIN: -+ case VSIR_OP_SQRT: -+ case VSIR_OP_TAN: -+ case VSIR_OP_UMAX: -+ case VSIR_OP_UMIN: - spirv_compiler_emit_ext_glsl_instruction(compiler, instruction); - break; -- case VKD3DSIH_DP4: -- case VKD3DSIH_DP3: -- case VKD3DSIH_DP2: -+ case VSIR_OP_DP4: -+ case VSIR_OP_DP3: -+ case VSIR_OP_DP2: - spirv_compiler_emit_dot(compiler, instruction); - break; -- case VKD3DSIH_DRCP: -- case VKD3DSIH_RCP: -+ case VSIR_OP_DRCP: -+ case VSIR_OP_RCP: - spirv_compiler_emit_rcp(compiler, instruction); - break; -- case VKD3DSIH_SINCOS: -- spirv_compiler_emit_sincos(compiler, instruction); -- break; -- case VKD3DSIH_IMUL: -- case VKD3DSIH_UMUL: -- spirv_compiler_emit_imul(compiler, instruction); -- break; -- case VKD3DSIH_IMAD: -+ case VSIR_OP_IMAD: - spirv_compiler_emit_imad(compiler, instruction); - break; -- case VKD3DSIH_IDIV: -- case VKD3DSIH_UDIV: -- spirv_compiler_emit_int_div(compiler, instruction); -- break; -- case VKD3DSIH_DTOI: -- case VKD3DSIH_FTOI: -+ case VSIR_OP_DTOI: -+ case VSIR_OP_FTOI: - spirv_compiler_emit_ftoi(compiler, instruction); - break; -- case VKD3DSIH_DTOU: -- case VKD3DSIH_FTOU: -+ case VSIR_OP_DTOU: -+ case VSIR_OP_FTOU: - spirv_compiler_emit_ftou(compiler, instruction); - break; -- case VKD3DSIH_DTOF: -+ case VSIR_OP_DTOF: - spirv_compiler_emit_dtof(compiler, instruction); - break; -- case VKD3DSIH_DEQO: -- case VKD3DSIH_DGEO: -- case VKD3DSIH_DLT: -- case VKD3DSIH_DNE: -- case VKD3DSIH_EQO: -- case VKD3DSIH_EQU: -- case VKD3DSIH_GEO: -- case VKD3DSIH_GEU: -- case VKD3DSIH_IEQ: -- case VKD3DSIH_IGE: -- case VKD3DSIH_ILT: -- case VKD3DSIH_INE: -- case VKD3DSIH_LTO: -- case VKD3DSIH_LTU: -- case VKD3DSIH_NEO: -- case VKD3DSIH_NEU: -- case VKD3DSIH_UGE: -- case VKD3DSIH_ULT: -+ case VSIR_OP_DEQO: -+ case VSIR_OP_DGEO: -+ case VSIR_OP_DLT: -+ case VSIR_OP_DNE: -+ case VSIR_OP_EQO: -+ case VSIR_OP_EQU: -+ case VSIR_OP_GEO: -+ case VSIR_OP_GEU: -+ case VSIR_OP_IEQ: -+ case VSIR_OP_IGE: -+ case VSIR_OP_ILT: -+ case VSIR_OP_INE: -+ case VSIR_OP_LTO: -+ case VSIR_OP_LTU: -+ case VSIR_OP_NEO: -+ case VSIR_OP_NEU: -+ case VSIR_OP_UGE: -+ case VSIR_OP_ULT: - spirv_compiler_emit_comparison_instruction(compiler, instruction); - break; -- case VKD3DSIH_ORD: -- case VKD3DSIH_UNO: -+ case VSIR_OP_ORD: -+ case VSIR_OP_UNO: - spirv_compiler_emit_orderedness_instruction(compiler, instruction); - break; -- case VKD3DSIH_SLT: -- case VKD3DSIH_SGE: -+ case VSIR_OP_SLT: -+ case VSIR_OP_SGE: - spirv_compiler_emit_float_comparison_instruction(compiler, instruction); - break; -- case VKD3DSIH_BFI: -- case VKD3DSIH_IBFE: -- case VKD3DSIH_UBFE: -+ case VSIR_OP_BFI: -+ case VSIR_OP_IBFE: -+ case VSIR_OP_UBFE: - spirv_compiler_emit_bitfield_instruction(compiler, instruction); - break; -- case VKD3DSIH_F16TOF32: -+ case VSIR_OP_F16TOF32: - spirv_compiler_emit_f16tof32(compiler, instruction); - break; -- case VKD3DSIH_F32TOF16: -+ case VSIR_OP_F32TOF16: - spirv_compiler_emit_f32tof16(compiler, instruction); - break; -- case VKD3DSIH_RET: -+ case VSIR_OP_RET: - spirv_compiler_emit_return(compiler, instruction); - break; -- case VKD3DSIH_RETP: -+ case VSIR_OP_RETP: - spirv_compiler_emit_retc(compiler, instruction); - break; -- case VKD3DSIH_DISCARD: -+ case VSIR_OP_DISCARD: - spirv_compiler_emit_discard(compiler, instruction); - break; -- case VKD3DSIH_LABEL: -+ case VSIR_OP_LABEL: - spirv_compiler_emit_label(compiler, instruction); - break; -- case VKD3DSIH_BRANCH: -+ case VSIR_OP_BRANCH: - spirv_compiler_emit_branch(compiler, instruction); - break; -- case VKD3DSIH_SWITCH_MONOLITHIC: -+ case VSIR_OP_SWITCH_MONOLITHIC: - spirv_compiler_emit_switch(compiler, instruction); - break; -- case VKD3DSIH_DSX: -- case VKD3DSIH_DSX_COARSE: -- case VKD3DSIH_DSX_FINE: -- case VKD3DSIH_DSY: -- case VKD3DSIH_DSY_COARSE: -- case VKD3DSIH_DSY_FINE: -+ case VSIR_OP_DSX: -+ case VSIR_OP_DSX_COARSE: -+ case VSIR_OP_DSX_FINE: -+ case VSIR_OP_DSY: -+ case VSIR_OP_DSY_COARSE: -+ case VSIR_OP_DSY_FINE: - spirv_compiler_emit_deriv_instruction(compiler, instruction); - break; -- case VKD3DSIH_LD2DMS: -- case VKD3DSIH_LD: -+ case VSIR_OP_LD2DMS: -+ case VSIR_OP_LD: - spirv_compiler_emit_ld(compiler, instruction); - break; -- case VKD3DSIH_LOD: -+ case VSIR_OP_LOD: - spirv_compiler_emit_lod(compiler, instruction); - break; -- case VKD3DSIH_SAMPLE: -- case VKD3DSIH_SAMPLE_B: -- case VKD3DSIH_SAMPLE_GRAD: -- case VKD3DSIH_SAMPLE_LOD: -+ case VSIR_OP_SAMPLE: -+ case VSIR_OP_SAMPLE_B: -+ case VSIR_OP_SAMPLE_GRAD: -+ case VSIR_OP_SAMPLE_LOD: - spirv_compiler_emit_sample(compiler, instruction); - break; -- case VKD3DSIH_SAMPLE_C: -- case VKD3DSIH_SAMPLE_C_LZ: -+ case VSIR_OP_SAMPLE_C: -+ case VSIR_OP_SAMPLE_C_LZ: - spirv_compiler_emit_sample_c(compiler, instruction); - break; -- case VKD3DSIH_GATHER4: -- case VKD3DSIH_GATHER4_C: -- case VKD3DSIH_GATHER4_PO: -- case VKD3DSIH_GATHER4_PO_C: -+ case VSIR_OP_GATHER4: -+ case VSIR_OP_GATHER4_C: -+ case VSIR_OP_GATHER4_PO: -+ case VSIR_OP_GATHER4_PO_C: - spirv_compiler_emit_gather4(compiler, instruction); - break; -- case VKD3DSIH_LD_RAW: -- case VKD3DSIH_LD_STRUCTURED: -+ case VSIR_OP_LD_RAW: -+ case VSIR_OP_LD_STRUCTURED: - spirv_compiler_emit_ld_raw_structured(compiler, instruction); - break; -- case VKD3DSIH_STORE_RAW: -- case VKD3DSIH_STORE_STRUCTURED: -+ case VSIR_OP_STORE_RAW: -+ case VSIR_OP_STORE_STRUCTURED: - spirv_compiler_emit_store_raw_structured(compiler, instruction); - break; -- case VKD3DSIH_LD_UAV_TYPED: -+ case VSIR_OP_LD_UAV_TYPED: - spirv_compiler_emit_ld_uav_typed(compiler, instruction); - break; -- case VKD3DSIH_STORE_UAV_TYPED: -+ case VSIR_OP_STORE_UAV_TYPED: - spirv_compiler_emit_store_uav_typed(compiler, instruction); - break; -- case VKD3DSIH_IMM_ATOMIC_ALLOC: -- case VKD3DSIH_IMM_ATOMIC_CONSUME: -+ case VSIR_OP_IMM_ATOMIC_ALLOC: -+ case VSIR_OP_IMM_ATOMIC_CONSUME: - spirv_compiler_emit_uav_counter_instruction(compiler, instruction); - break; -- case VKD3DSIH_ATOMIC_AND: -- case VKD3DSIH_ATOMIC_CMP_STORE: -- case VKD3DSIH_ATOMIC_IADD: -- case VKD3DSIH_ATOMIC_IMAX: -- case VKD3DSIH_ATOMIC_IMIN: -- case VKD3DSIH_ATOMIC_OR: -- case VKD3DSIH_ATOMIC_UMAX: -- case VKD3DSIH_ATOMIC_UMIN: -- case VKD3DSIH_ATOMIC_XOR: -- case VKD3DSIH_IMM_ATOMIC_AND: -- case VKD3DSIH_IMM_ATOMIC_CMP_EXCH: -- case VKD3DSIH_IMM_ATOMIC_EXCH: -- case VKD3DSIH_IMM_ATOMIC_IADD: -- case VKD3DSIH_IMM_ATOMIC_IMAX: -- case VKD3DSIH_IMM_ATOMIC_IMIN: -- case VKD3DSIH_IMM_ATOMIC_OR: -- case VKD3DSIH_IMM_ATOMIC_UMAX: -- case VKD3DSIH_IMM_ATOMIC_UMIN: -- case VKD3DSIH_IMM_ATOMIC_XOR: -+ case VSIR_OP_ATOMIC_AND: -+ case VSIR_OP_ATOMIC_CMP_STORE: -+ case VSIR_OP_ATOMIC_IADD: -+ case VSIR_OP_ATOMIC_IMAX: -+ case VSIR_OP_ATOMIC_IMIN: -+ case VSIR_OP_ATOMIC_OR: -+ case VSIR_OP_ATOMIC_UMAX: -+ case VSIR_OP_ATOMIC_UMIN: -+ case VSIR_OP_ATOMIC_XOR: -+ case VSIR_OP_IMM_ATOMIC_AND: -+ case VSIR_OP_IMM_ATOMIC_CMP_EXCH: -+ case VSIR_OP_IMM_ATOMIC_EXCH: -+ case VSIR_OP_IMM_ATOMIC_IADD: -+ case VSIR_OP_IMM_ATOMIC_IMAX: -+ case VSIR_OP_IMM_ATOMIC_IMIN: -+ case VSIR_OP_IMM_ATOMIC_OR: -+ case VSIR_OP_IMM_ATOMIC_UMAX: -+ case VSIR_OP_IMM_ATOMIC_UMIN: -+ case VSIR_OP_IMM_ATOMIC_XOR: - spirv_compiler_emit_atomic_instruction(compiler, instruction); - break; -- case VKD3DSIH_BUFINFO: -+ case VSIR_OP_BUFINFO: - spirv_compiler_emit_bufinfo(compiler, instruction); - break; -- case VKD3DSIH_RESINFO: -+ case VSIR_OP_RESINFO: - spirv_compiler_emit_resinfo(compiler, instruction); - break; -- case VKD3DSIH_SAMPLE_INFO: -+ case VSIR_OP_SAMPLE_INFO: - spirv_compiler_emit_sample_info(compiler, instruction); - break; -- case VKD3DSIH_SAMPLE_POS: -+ case VSIR_OP_SAMPLE_POS: - spirv_compiler_emit_sample_position(compiler, instruction); - break; -- case VKD3DSIH_EVAL_CENTROID: -- case VKD3DSIH_EVAL_SAMPLE_INDEX: -+ case VSIR_OP_EVAL_CENTROID: -+ case VSIR_OP_EVAL_SAMPLE_INDEX: - spirv_compiler_emit_eval_attrib(compiler, instruction); - break; -- case VKD3DSIH_SYNC: -+ case VSIR_OP_SYNC: - spirv_compiler_emit_sync(compiler, instruction); - break; -- case VKD3DSIH_EMIT: -- case VKD3DSIH_EMIT_STREAM: -+ case VSIR_OP_EMIT: -+ case VSIR_OP_EMIT_STREAM: - spirv_compiler_emit_emit_stream(compiler, instruction); - break; -- case VKD3DSIH_CUT: -- case VKD3DSIH_CUT_STREAM: -+ case VSIR_OP_CUT: -+ case VSIR_OP_CUT_STREAM: - spirv_compiler_emit_cut_stream(compiler, instruction); - break; -- case VKD3DSIH_QUAD_READ_ACROSS_D: -- case VKD3DSIH_QUAD_READ_ACROSS_X: -- case VKD3DSIH_QUAD_READ_ACROSS_Y: -+ case VSIR_OP_QUAD_READ_ACROSS_D: -+ case VSIR_OP_QUAD_READ_ACROSS_X: -+ case VSIR_OP_QUAD_READ_ACROSS_Y: - spirv_compiler_emit_quad_read_across(compiler, instruction); - break; -- case VKD3DSIH_QUAD_READ_LANE_AT: -+ case VSIR_OP_QUAD_READ_LANE_AT: - spirv_compiler_emit_quad_read_lane_at(compiler, instruction); - break; -- case VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL: -- case VKD3DSIH_WAVE_ALL_TRUE: -- case VKD3DSIH_WAVE_ANY_TRUE: -+ case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL: -+ case VSIR_OP_WAVE_ALL_TRUE: -+ case VSIR_OP_WAVE_ANY_TRUE: - spirv_compiler_emit_wave_bool_op(compiler, instruction); - break; -- case VKD3DSIH_WAVE_ACTIVE_BALLOT: -+ case VSIR_OP_WAVE_ACTIVE_BALLOT: - spirv_compiler_emit_wave_active_ballot(compiler, instruction); - break; -- case VKD3DSIH_WAVE_ACTIVE_BIT_AND: -- case VKD3DSIH_WAVE_ACTIVE_BIT_OR: -- case VKD3DSIH_WAVE_ACTIVE_BIT_XOR: -- case VKD3DSIH_WAVE_OP_ADD: -- case VKD3DSIH_WAVE_OP_IMAX: -- case VKD3DSIH_WAVE_OP_IMIN: -- case VKD3DSIH_WAVE_OP_MAX: -- case VKD3DSIH_WAVE_OP_MIN: -- case VKD3DSIH_WAVE_OP_MUL: -- case VKD3DSIH_WAVE_OP_UMAX: -- case VKD3DSIH_WAVE_OP_UMIN: -+ case VSIR_OP_WAVE_ACTIVE_BIT_AND: -+ case VSIR_OP_WAVE_ACTIVE_BIT_OR: -+ case VSIR_OP_WAVE_ACTIVE_BIT_XOR: -+ case VSIR_OP_WAVE_OP_ADD: -+ case VSIR_OP_WAVE_OP_IMAX: -+ case VSIR_OP_WAVE_OP_IMIN: -+ case VSIR_OP_WAVE_OP_MAX: -+ case VSIR_OP_WAVE_OP_MIN: -+ case VSIR_OP_WAVE_OP_MUL: -+ case VSIR_OP_WAVE_OP_UMAX: -+ case VSIR_OP_WAVE_OP_UMIN: - spirv_compiler_emit_wave_alu_op(compiler, instruction); - break; -- case VKD3DSIH_WAVE_ALL_BIT_COUNT: -- case VKD3DSIH_WAVE_PREFIX_BIT_COUNT: -+ case VSIR_OP_WAVE_ALL_BIT_COUNT: -+ case VSIR_OP_WAVE_PREFIX_BIT_COUNT: - spirv_compiler_emit_wave_bit_count(compiler, instruction); - break; -- case VKD3DSIH_WAVE_IS_FIRST_LANE: -+ case VSIR_OP_WAVE_IS_FIRST_LANE: - spirv_compiler_emit_wave_is_first_lane(compiler, instruction); - break; -- case VKD3DSIH_WAVE_READ_LANE_AT: -+ case VSIR_OP_WAVE_READ_LANE_AT: - spirv_compiler_emit_wave_read_lane_at(compiler, instruction); - break; -- case VKD3DSIH_WAVE_READ_LANE_FIRST: -+ case VSIR_OP_WAVE_READ_LANE_FIRST: - spirv_compiler_emit_wave_read_lane_first(compiler, instruction); - break; -- case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: -- case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: -- case VKD3DSIH_DCL_RESOURCE_RAW: -- case VKD3DSIH_DCL_RESOURCE_STRUCTURED: -- case VKD3DSIH_DCL_UAV_RAW: -- case VKD3DSIH_DCL_UAV_STRUCTURED: -- case VKD3DSIH_HS_DECLS: -- case VKD3DSIH_NOP: -+ case VSIR_OP_DCL_HS_MAX_TESSFACTOR: -+ case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: -+ case VSIR_OP_DCL_RESOURCE_RAW: -+ case VSIR_OP_DCL_RESOURCE_STRUCTURED: -+ case VSIR_OP_DCL_UAV_RAW: -+ case VSIR_OP_DCL_UAV_STRUCTURED: -+ case VSIR_OP_HS_DECLS: -+ case VSIR_OP_NOP: - /* nothing to do */ - break; - default: -- FIXME("Unhandled instruction %#x.\n", instruction->opcode); - spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER, -- "Encountered invalid/unhandled instruction handler %#x.", instruction->opcode); -+ "Unhandled instruction \"%s\" (%#x).", -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - 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..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 - VKD3D_SM4_OP_DCL_INPUT_PS_SGV = 0x63, - VKD3D_SM4_OP_DCL_INPUT_PS_SIV = 0x64, - VKD3D_SM4_OP_DCL_OUTPUT = 0x65, -+ VKD3D_SM4_OP_DCL_OUTPUT_SGV = 0x66, - VKD3D_SM4_OP_DCL_OUTPUT_SIV = 0x67, - VKD3D_SM4_OP_DCL_TEMPS = 0x68, - VKD3D_SM4_OP_DCL_INDEXABLE_TEMP = 0x69, -@@ -654,7 +655,7 @@ struct sm4_index_range_array - struct vkd3d_sm4_lookup_tables - { - const struct vkd3d_sm4_opcode_info *opcode_info_from_sm4[VKD3D_SM4_OP_COUNT]; -- const struct vkd3d_sm4_opcode_info *opcode_info_from_vsir[VKD3DSIH_COUNT]; -+ const struct vkd3d_sm4_opcode_info *opcode_info_from_vsir[VSIR_OP_COUNT]; - 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) - { - FIXME("Ignoring shader data type %#x.\n", type); -- ins->opcode = VKD3DSIH_NOP; -+ ins->opcode = VSIR_OP_NOP; - return; - } - -@@ -831,7 +832,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui - if (icb_size % 4) - { - FIXME("Unexpected immediate constant buffer size %u.\n", icb_size); -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - return; - } - -@@ -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."); -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - 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; -@@ -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) - { -- return sm4->phase == VKD3DSIH_HS_FORK_PHASE || sm4->phase == VKD3DSIH_HS_JOIN_PHASE; -+ return sm4->phase == VSIR_OP_HS_FORK_PHASE || sm4->phase == VSIR_OP_HS_JOIN_PHASE; - } - - static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins, uint32_t opcode, -@@ -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, -- "No matching signature element for input register %u with mask %#x.\n", -+ "No matching signature element for input register %u with mask %#x.", - dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); - } - else -@@ -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, -- "No matching signature element for input register %u with mask %#x.\n", -+ "No matching signature element for input register %u with mask %#x.", - dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); - } - else -@@ -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[] = - { -- {VKD3D_SM4_OP_ADD, VKD3DSIH_ADD, "f", "ff"}, -- {VKD3D_SM4_OP_AND, VKD3DSIH_AND, "u", "uu"}, -- {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""}, -- {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u", -+ {VKD3D_SM4_OP_ADD, VSIR_OP_ADD, "f", "ff"}, -+ {VKD3D_SM4_OP_AND, VSIR_OP_AND, "u", "uu"}, -+ {VKD3D_SM4_OP_BREAK, VSIR_OP_BREAK, "", ""}, -+ {VKD3D_SM4_OP_BREAKC, VSIR_OP_BREAKP, "", "u", - shader_sm4_read_conditional_op, true}, -- {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u", -+ {VKD3D_SM4_OP_CASE, VSIR_OP_CASE, "", "u", - shader_sm4_read_case_condition}, -- {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""}, -- {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u", -+ {VKD3D_SM4_OP_CONTINUE, VSIR_OP_CONTINUE, "", ""}, -+ {VKD3D_SM4_OP_CONTINUEC, VSIR_OP_CONTINUEP, "", "u", - shader_sm4_read_conditional_op, true}, -- {VKD3D_SM4_OP_CUT, VKD3DSIH_CUT, "", ""}, -- {VKD3D_SM4_OP_DEFAULT, VKD3DSIH_DEFAULT, "", ""}, -- {VKD3D_SM4_OP_DERIV_RTX, VKD3DSIH_DSX, "f", "f"}, -- {VKD3D_SM4_OP_DERIV_RTY, VKD3DSIH_DSY, "f", "f"}, -- {VKD3D_SM4_OP_DISCARD, VKD3DSIH_DISCARD, "", "u", -+ {VKD3D_SM4_OP_CUT, VSIR_OP_CUT, "", ""}, -+ {VKD3D_SM4_OP_DEFAULT, VSIR_OP_DEFAULT, "", ""}, -+ {VKD3D_SM4_OP_DERIV_RTX, VSIR_OP_DSX, "f", "f"}, -+ {VKD3D_SM4_OP_DERIV_RTY, VSIR_OP_DSY, "f", "f"}, -+ {VKD3D_SM4_OP_DISCARD, VSIR_OP_DISCARD, "", "u", - shader_sm4_read_conditional_op, true}, -- {VKD3D_SM4_OP_DIV, VKD3DSIH_DIV, "f", "ff"}, -- {VKD3D_SM4_OP_DP2, VKD3DSIH_DP2, "f", "ff"}, -- {VKD3D_SM4_OP_DP3, VKD3DSIH_DP3, "f", "ff"}, -- {VKD3D_SM4_OP_DP4, VKD3DSIH_DP4, "f", "ff"}, -- {VKD3D_SM4_OP_ELSE, VKD3DSIH_ELSE, "", ""}, -- {VKD3D_SM4_OP_EMIT, VKD3DSIH_EMIT, "", ""}, -- {VKD3D_SM4_OP_ENDIF, VKD3DSIH_ENDIF, "", ""}, -- {VKD3D_SM4_OP_ENDLOOP, VKD3DSIH_ENDLOOP, "", ""}, -- {VKD3D_SM4_OP_ENDSWITCH, VKD3DSIH_ENDSWITCH, "", ""}, -- {VKD3D_SM4_OP_EQ, VKD3DSIH_EQO, "u", "ff"}, -- {VKD3D_SM4_OP_EXP, VKD3DSIH_EXP, "f", "f"}, -- {VKD3D_SM4_OP_FRC, VKD3DSIH_FRC, "f", "f"}, -- {VKD3D_SM4_OP_FTOI, VKD3DSIH_FTOI, "i", "f"}, -- {VKD3D_SM4_OP_FTOU, VKD3DSIH_FTOU, "u", "f"}, -- {VKD3D_SM4_OP_GE, VKD3DSIH_GEO, "u", "ff"}, -- {VKD3D_SM4_OP_IADD, VKD3DSIH_IADD, "i", "ii"}, -- {VKD3D_SM4_OP_IF, VKD3DSIH_IF, "", "u", -+ {VKD3D_SM4_OP_DIV, VSIR_OP_DIV, "f", "ff"}, -+ {VKD3D_SM4_OP_DP2, VSIR_OP_DP2, "f", "ff"}, -+ {VKD3D_SM4_OP_DP3, VSIR_OP_DP3, "f", "ff"}, -+ {VKD3D_SM4_OP_DP4, VSIR_OP_DP4, "f", "ff"}, -+ {VKD3D_SM4_OP_ELSE, VSIR_OP_ELSE, "", ""}, -+ {VKD3D_SM4_OP_EMIT, VSIR_OP_EMIT, "", ""}, -+ {VKD3D_SM4_OP_ENDIF, VSIR_OP_ENDIF, "", ""}, -+ {VKD3D_SM4_OP_ENDLOOP, VSIR_OP_ENDLOOP, "", ""}, -+ {VKD3D_SM4_OP_ENDSWITCH, VSIR_OP_ENDSWITCH, "", ""}, -+ {VKD3D_SM4_OP_EQ, VSIR_OP_EQO, "u", "ff"}, -+ {VKD3D_SM4_OP_EXP, VSIR_OP_EXP, "f", "f"}, -+ {VKD3D_SM4_OP_FRC, VSIR_OP_FRC, "f", "f"}, -+ {VKD3D_SM4_OP_FTOI, VSIR_OP_FTOI, "i", "f"}, -+ {VKD3D_SM4_OP_FTOU, VSIR_OP_FTOU, "u", "f"}, -+ {VKD3D_SM4_OP_GE, VSIR_OP_GEO, "u", "ff"}, -+ {VKD3D_SM4_OP_IADD, VSIR_OP_IADD, "i", "ii"}, -+ {VKD3D_SM4_OP_IF, VSIR_OP_IF, "", "u", - shader_sm4_read_conditional_op, true}, -- {VKD3D_SM4_OP_IEQ, VKD3DSIH_IEQ, "u", "ii"}, -- {VKD3D_SM4_OP_IGE, VKD3DSIH_IGE, "u", "ii"}, -- {VKD3D_SM4_OP_ILT, VKD3DSIH_ILT, "u", "ii"}, -- {VKD3D_SM4_OP_IMAD, VKD3DSIH_IMAD, "i", "iii"}, -- {VKD3D_SM4_OP_IMAX, VKD3DSIH_IMAX, "i", "ii"}, -- {VKD3D_SM4_OP_IMIN, VKD3DSIH_IMIN, "i", "ii"}, -- {VKD3D_SM4_OP_IMUL, VKD3DSIH_IMUL, "ii", "ii"}, -- {VKD3D_SM4_OP_INE, VKD3DSIH_INE, "u", "ii"}, -- {VKD3D_SM4_OP_INEG, VKD3DSIH_INEG, "i", "i"}, -- {VKD3D_SM4_OP_ISHL, VKD3DSIH_ISHL, "i", "ii"}, -- {VKD3D_SM4_OP_ISHR, VKD3DSIH_ISHR, "i", "ii"}, -- {VKD3D_SM4_OP_ITOF, VKD3DSIH_ITOF, "f", "i"}, -- {VKD3D_SM4_OP_LABEL, VKD3DSIH_LABEL, "", "O"}, -- {VKD3D_SM4_OP_LD, VKD3DSIH_LD, "u", "i*"}, -- {VKD3D_SM4_OP_LD2DMS, VKD3DSIH_LD2DMS, "u", "i*i"}, -- {VKD3D_SM4_OP_LOG, VKD3DSIH_LOG, "f", "f"}, -- {VKD3D_SM4_OP_LOOP, VKD3DSIH_LOOP, "", ""}, -- {VKD3D_SM4_OP_LT, VKD3DSIH_LTO, "u", "ff"}, -- {VKD3D_SM4_OP_MAD, VKD3DSIH_MAD, "f", "fff"}, -- {VKD3D_SM4_OP_MIN, VKD3DSIH_MIN, "f", "ff"}, -- {VKD3D_SM4_OP_MAX, VKD3DSIH_MAX, "f", "ff"}, -- {VKD3D_SM4_OP_SHADER_DATA, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", -+ {VKD3D_SM4_OP_IEQ, VSIR_OP_IEQ, "u", "ii"}, -+ {VKD3D_SM4_OP_IGE, VSIR_OP_IGE, "u", "ii"}, -+ {VKD3D_SM4_OP_ILT, VSIR_OP_ILT, "u", "ii"}, -+ {VKD3D_SM4_OP_IMAD, VSIR_OP_IMAD, "i", "iii"}, -+ {VKD3D_SM4_OP_IMAX, VSIR_OP_IMAX, "i", "ii"}, -+ {VKD3D_SM4_OP_IMIN, VSIR_OP_IMIN, "i", "ii"}, -+ {VKD3D_SM4_OP_IMUL, VSIR_OP_IMUL, "ii", "ii"}, -+ {VKD3D_SM4_OP_INE, VSIR_OP_INE, "u", "ii"}, -+ {VKD3D_SM4_OP_INEG, VSIR_OP_INEG, "i", "i"}, -+ {VKD3D_SM4_OP_ISHL, VSIR_OP_ISHL, "i", "ii"}, -+ {VKD3D_SM4_OP_ISHR, VSIR_OP_ISHR, "i", "ii"}, -+ {VKD3D_SM4_OP_ITOF, VSIR_OP_ITOF, "f", "i"}, -+ {VKD3D_SM4_OP_LABEL, VSIR_OP_LABEL, "", "O"}, -+ {VKD3D_SM4_OP_LD, VSIR_OP_LD, "u", "i*"}, -+ {VKD3D_SM4_OP_LD2DMS, VSIR_OP_LD2DMS, "u", "i*i"}, -+ {VKD3D_SM4_OP_LOG, VSIR_OP_LOG, "f", "f"}, -+ {VKD3D_SM4_OP_LOOP, VSIR_OP_LOOP, "", ""}, -+ {VKD3D_SM4_OP_LT, VSIR_OP_LTO, "u", "ff"}, -+ {VKD3D_SM4_OP_MAD, VSIR_OP_MAD, "f", "fff"}, -+ {VKD3D_SM4_OP_MIN, VSIR_OP_MIN, "f", "ff"}, -+ {VKD3D_SM4_OP_MAX, VSIR_OP_MAX, "f", "ff"}, -+ {VKD3D_SM4_OP_SHADER_DATA, VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", - shader_sm4_read_shader_data}, -- {VKD3D_SM4_OP_MOV, VKD3DSIH_MOV, "f", "f"}, -- {VKD3D_SM4_OP_MOVC, VKD3DSIH_MOVC, "f", "uff"}, -- {VKD3D_SM4_OP_MUL, VKD3DSIH_MUL, "f", "ff"}, -- {VKD3D_SM4_OP_NE, VKD3DSIH_NEU, "u", "ff"}, -- {VKD3D_SM4_OP_NOP, VKD3DSIH_NOP, "", ""}, -- {VKD3D_SM4_OP_NOT, VKD3DSIH_NOT, "u", "u"}, -- {VKD3D_SM4_OP_OR, VKD3DSIH_OR, "u", "uu"}, -- {VKD3D_SM4_OP_RESINFO, VKD3DSIH_RESINFO, "f", "i*"}, -- {VKD3D_SM4_OP_RET, VKD3DSIH_RET, "", ""}, -- {VKD3D_SM4_OP_RETC, VKD3DSIH_RETP, "", "u", -+ {VKD3D_SM4_OP_MOV, VSIR_OP_MOV, "f", "f"}, -+ {VKD3D_SM4_OP_MOVC, VSIR_OP_MOVC, "f", "uff"}, -+ {VKD3D_SM4_OP_MUL, VSIR_OP_MUL, "f", "ff"}, -+ {VKD3D_SM4_OP_NE, VSIR_OP_NEU, "u", "ff"}, -+ {VKD3D_SM4_OP_NOP, VSIR_OP_NOP, "", ""}, -+ {VKD3D_SM4_OP_NOT, VSIR_OP_NOT, "u", "u"}, -+ {VKD3D_SM4_OP_OR, VSIR_OP_OR, "u", "uu"}, -+ {VKD3D_SM4_OP_RESINFO, VSIR_OP_RESINFO, "f", "i*"}, -+ {VKD3D_SM4_OP_RET, VSIR_OP_RET, "", ""}, -+ {VKD3D_SM4_OP_RETC, VSIR_OP_RETP, "", "u", - shader_sm4_read_conditional_op, true}, -- {VKD3D_SM4_OP_ROUND_NE, VKD3DSIH_ROUND_NE, "f", "f"}, -- {VKD3D_SM4_OP_ROUND_NI, VKD3DSIH_ROUND_NI, "f", "f"}, -- {VKD3D_SM4_OP_ROUND_PI, VKD3DSIH_ROUND_PI, "f", "f"}, -- {VKD3D_SM4_OP_ROUND_Z, VKD3DSIH_ROUND_Z, "f", "f"}, -- {VKD3D_SM4_OP_RSQ, VKD3DSIH_RSQ, "f", "f"}, -- {VKD3D_SM4_OP_SAMPLE, VKD3DSIH_SAMPLE, "u", "f**"}, -- {VKD3D_SM4_OP_SAMPLE_C, VKD3DSIH_SAMPLE_C, "f", "f**f"}, -- {VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3DSIH_SAMPLE_C_LZ, "f", "f**f"}, -- {VKD3D_SM4_OP_SAMPLE_LOD, VKD3DSIH_SAMPLE_LOD, "u", "f**f"}, -- {VKD3D_SM4_OP_SAMPLE_GRAD, VKD3DSIH_SAMPLE_GRAD, "u", "f**ff"}, -- {VKD3D_SM4_OP_SAMPLE_B, VKD3DSIH_SAMPLE_B, "u", "f**f"}, -- {VKD3D_SM4_OP_SQRT, VKD3DSIH_SQRT, "f", "f"}, -- {VKD3D_SM4_OP_SWITCH, VKD3DSIH_SWITCH, "", "i"}, -- {VKD3D_SM4_OP_SINCOS, VKD3DSIH_SINCOS, "ff", "f"}, -- {VKD3D_SM4_OP_UDIV, VKD3DSIH_UDIV, "uu", "uu"}, -- {VKD3D_SM4_OP_ULT, VKD3DSIH_ULT, "u", "uu"}, -- {VKD3D_SM4_OP_UGE, VKD3DSIH_UGE, "u", "uu"}, -- {VKD3D_SM4_OP_UMUL, VKD3DSIH_UMUL, "uu", "uu"}, -- {VKD3D_SM4_OP_UMAX, VKD3DSIH_UMAX, "u", "uu"}, -- {VKD3D_SM4_OP_UMIN, VKD3DSIH_UMIN, "u", "uu"}, -- {VKD3D_SM4_OP_USHR, VKD3DSIH_USHR, "u", "uu"}, -- {VKD3D_SM4_OP_UTOF, VKD3DSIH_UTOF, "f", "u"}, -- {VKD3D_SM4_OP_XOR, VKD3DSIH_XOR, "u", "uu"}, -- {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "", "", -+ {VKD3D_SM4_OP_ROUND_NE, VSIR_OP_ROUND_NE, "f", "f"}, -+ {VKD3D_SM4_OP_ROUND_NI, VSIR_OP_ROUND_NI, "f", "f"}, -+ {VKD3D_SM4_OP_ROUND_PI, VSIR_OP_ROUND_PI, "f", "f"}, -+ {VKD3D_SM4_OP_ROUND_Z, VSIR_OP_ROUND_Z, "f", "f"}, -+ {VKD3D_SM4_OP_RSQ, VSIR_OP_RSQ, "f", "f"}, -+ {VKD3D_SM4_OP_SAMPLE, VSIR_OP_SAMPLE, "u", "f**"}, -+ {VKD3D_SM4_OP_SAMPLE_C, VSIR_OP_SAMPLE_C, "f", "f**f"}, -+ {VKD3D_SM4_OP_SAMPLE_C_LZ, VSIR_OP_SAMPLE_C_LZ, "f", "f**f"}, -+ {VKD3D_SM4_OP_SAMPLE_LOD, VSIR_OP_SAMPLE_LOD, "u", "f**f"}, -+ {VKD3D_SM4_OP_SAMPLE_GRAD, VSIR_OP_SAMPLE_GRAD, "u", "f**ff"}, -+ {VKD3D_SM4_OP_SAMPLE_B, VSIR_OP_SAMPLE_B, "u", "f**f"}, -+ {VKD3D_SM4_OP_SQRT, VSIR_OP_SQRT, "f", "f"}, -+ {VKD3D_SM4_OP_SWITCH, VSIR_OP_SWITCH, "", "i"}, -+ {VKD3D_SM4_OP_SINCOS, VSIR_OP_SINCOS, "ff", "f"}, -+ {VKD3D_SM4_OP_UDIV, VSIR_OP_UDIV, "uu", "uu"}, -+ {VKD3D_SM4_OP_ULT, VSIR_OP_ULT, "u", "uu"}, -+ {VKD3D_SM4_OP_UGE, VSIR_OP_UGE, "u", "uu"}, -+ {VKD3D_SM4_OP_UMUL, VSIR_OP_UMUL, "uu", "uu"}, -+ {VKD3D_SM4_OP_UMAX, VSIR_OP_UMAX, "u", "uu"}, -+ {VKD3D_SM4_OP_UMIN, VSIR_OP_UMIN, "u", "uu"}, -+ {VKD3D_SM4_OP_USHR, VSIR_OP_USHR, "u", "uu"}, -+ {VKD3D_SM4_OP_UTOF, VSIR_OP_UTOF, "f", "u"}, -+ {VKD3D_SM4_OP_XOR, VSIR_OP_XOR, "u", "uu"}, -+ {VKD3D_SM4_OP_DCL_RESOURCE, VSIR_OP_DCL, "", "", - shader_sm4_read_dcl_resource}, -- {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VKD3DSIH_DCL_CONSTANT_BUFFER, "", "", -+ {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VSIR_OP_DCL_CONSTANT_BUFFER, "", "", - shader_sm4_read_dcl_constant_buffer}, -- {VKD3D_SM4_OP_DCL_SAMPLER, VKD3DSIH_DCL_SAMPLER, "", "", -+ {VKD3D_SM4_OP_DCL_SAMPLER, VSIR_OP_DCL_SAMPLER, "", "", - shader_sm4_read_dcl_sampler}, -- {VKD3D_SM4_OP_DCL_INDEX_RANGE, VKD3DSIH_DCL_INDEX_RANGE, "", "", -+ {VKD3D_SM4_OP_DCL_INDEX_RANGE, VSIR_OP_DCL_INDEX_RANGE, "", "", - shader_sm4_read_dcl_index_range}, -- {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, "", "", -+ {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VSIR_OP_DCL_OUTPUT_TOPOLOGY, "", "", - shader_sm4_read_dcl_output_topology}, -- {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VKD3DSIH_DCL_INPUT_PRIMITIVE, "", "", -+ {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VSIR_OP_DCL_INPUT_PRIMITIVE, "", "", - shader_sm4_read_dcl_input_primitive}, -- {VKD3D_SM4_OP_DCL_VERTICES_OUT, VKD3DSIH_DCL_VERTICES_OUT, "", "", -+ {VKD3D_SM4_OP_DCL_VERTICES_OUT, VSIR_OP_DCL_VERTICES_OUT, "", "", - shader_sm4_read_declaration_count}, -- {VKD3D_SM4_OP_DCL_INPUT, VKD3DSIH_DCL_INPUT, "", "", -+ {VKD3D_SM4_OP_DCL_INPUT, VSIR_OP_DCL_INPUT, "", "", - shader_sm4_read_declaration_dst}, -- {VKD3D_SM4_OP_DCL_INPUT_SGV, VKD3DSIH_DCL_INPUT_SGV, "", "", -+ {VKD3D_SM4_OP_DCL_INPUT_SGV, VSIR_OP_DCL_INPUT_SGV, "", "", - shader_sm4_read_declaration_register_semantic}, -- {VKD3D_SM4_OP_DCL_INPUT_SIV, VKD3DSIH_DCL_INPUT_SIV, "", "", -+ {VKD3D_SM4_OP_DCL_INPUT_SIV, VSIR_OP_DCL_INPUT_SIV, "", "", - shader_sm4_read_declaration_register_semantic}, -- {VKD3D_SM4_OP_DCL_INPUT_PS, VKD3DSIH_DCL_INPUT_PS, "", "", -+ {VKD3D_SM4_OP_DCL_INPUT_PS, VSIR_OP_DCL_INPUT_PS, "", "", - shader_sm4_read_dcl_input_ps}, -- {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VKD3DSIH_DCL_INPUT_PS_SGV, "", "", -+ {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VSIR_OP_DCL_INPUT_PS_SGV, "", "", - shader_sm4_read_declaration_register_semantic}, -- {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VKD3DSIH_DCL_INPUT_PS_SIV, "", "", -+ {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VSIR_OP_DCL_INPUT_PS_SIV, "", "", - shader_sm4_read_dcl_input_ps_siv}, -- {VKD3D_SM4_OP_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT, "", "", -+ {VKD3D_SM4_OP_DCL_OUTPUT, VSIR_OP_DCL_OUTPUT, "", "", - shader_sm4_read_declaration_dst}, -- {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VKD3DSIH_DCL_OUTPUT_SIV, "", "", -+ {VKD3D_SM4_OP_DCL_OUTPUT_SGV, VSIR_OP_DCL_OUTPUT_SGV, "", "", - shader_sm4_read_declaration_register_semantic}, -- {VKD3D_SM4_OP_DCL_TEMPS, VKD3DSIH_DCL_TEMPS, "", "", -+ {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VSIR_OP_DCL_OUTPUT_SIV, "", "", -+ shader_sm4_read_declaration_register_semantic}, -+ {VKD3D_SM4_OP_DCL_TEMPS, VSIR_OP_DCL_TEMPS, "", "", - shader_sm4_read_declaration_count}, -- {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VKD3DSIH_DCL_INDEXABLE_TEMP, "", "", -+ {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VSIR_OP_DCL_INDEXABLE_TEMP, "", "", - shader_sm4_read_dcl_indexable_temp}, -- {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VKD3DSIH_DCL_GLOBAL_FLAGS, "", "", -+ {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VSIR_OP_DCL_GLOBAL_FLAGS, "", "", - shader_sm4_read_dcl_global_flags}, -- {VKD3D_SM4_OP_LOD, VKD3DSIH_LOD, "f", "f**"}, -- {VKD3D_SM4_OP_GATHER4, VKD3DSIH_GATHER4, "u", "f**"}, -- {VKD3D_SM4_OP_SAMPLE_POS, VKD3DSIH_SAMPLE_POS, "f", "*u"}, -- {VKD3D_SM4_OP_SAMPLE_INFO, VKD3DSIH_SAMPLE_INFO, "f", "*"}, -- {VKD3D_SM5_OP_HS_DECLS, VKD3DSIH_HS_DECLS, "", ""}, -- {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VKD3DSIH_HS_CONTROL_POINT_PHASE, "", ""}, -- {VKD3D_SM5_OP_HS_FORK_PHASE, VKD3DSIH_HS_FORK_PHASE, "", ""}, -- {VKD3D_SM5_OP_HS_JOIN_PHASE, VKD3DSIH_HS_JOIN_PHASE, "", ""}, -- {VKD3D_SM5_OP_EMIT_STREAM, VKD3DSIH_EMIT_STREAM, "", "f"}, -- {VKD3D_SM5_OP_CUT_STREAM, VKD3DSIH_CUT_STREAM, "", "f"}, -- {VKD3D_SM5_OP_FCALL, VKD3DSIH_FCALL, "", "O", -+ {VKD3D_SM4_OP_LOD, VSIR_OP_LOD, "f", "f**"}, -+ {VKD3D_SM4_OP_GATHER4, VSIR_OP_GATHER4, "u", "f**"}, -+ {VKD3D_SM4_OP_SAMPLE_POS, VSIR_OP_SAMPLE_POS, "f", "*u"}, -+ {VKD3D_SM4_OP_SAMPLE_INFO, VSIR_OP_SAMPLE_INFO, "f", "*"}, -+ {VKD3D_SM5_OP_HS_DECLS, VSIR_OP_HS_DECLS, "", ""}, -+ {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, "", "*"}, -+ {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", "*"}, -- {VKD3D_SM5_OP_DERIV_RTX_COARSE, VKD3DSIH_DSX_COARSE, "f", "f"}, -- {VKD3D_SM5_OP_DERIV_RTX_FINE, VKD3DSIH_DSX_FINE, "f", "f"}, -- {VKD3D_SM5_OP_DERIV_RTY_COARSE, VKD3DSIH_DSY_COARSE, "f", "f"}, -- {VKD3D_SM5_OP_DERIV_RTY_FINE, VKD3DSIH_DSY_FINE, "f", "f"}, -- {VKD3D_SM5_OP_GATHER4_C, VKD3DSIH_GATHER4_C, "f", "f**f"}, -- {VKD3D_SM5_OP_GATHER4_PO, VKD3DSIH_GATHER4_PO, "f", "fi**"}, -- {VKD3D_SM5_OP_GATHER4_PO_C, VKD3DSIH_GATHER4_PO_C, "f", "fi**f"}, -- {VKD3D_SM5_OP_RCP, VKD3DSIH_RCP, "f", "f"}, -- {VKD3D_SM5_OP_F32TOF16, VKD3DSIH_F32TOF16, "u", "f"}, -- {VKD3D_SM5_OP_F16TOF32, VKD3DSIH_F16TOF32, "f", "u"}, -- {VKD3D_SM5_OP_COUNTBITS, VKD3DSIH_COUNTBITS, "u", "u"}, -- {VKD3D_SM5_OP_FIRSTBIT_HI, VKD3DSIH_FIRSTBIT_HI, "u", "u"}, -- {VKD3D_SM5_OP_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_LO, "u", "u"}, -- {VKD3D_SM5_OP_FIRSTBIT_SHI, VKD3DSIH_FIRSTBIT_SHI, "u", "i"}, -- {VKD3D_SM5_OP_UBFE, VKD3DSIH_UBFE, "u", "iiu"}, -- {VKD3D_SM5_OP_IBFE, VKD3DSIH_IBFE, "i", "iii"}, -- {VKD3D_SM5_OP_BFI, VKD3DSIH_BFI, "u", "iiuu"}, -- {VKD3D_SM5_OP_BFREV, VKD3DSIH_BFREV, "u", "u"}, -- {VKD3D_SM5_OP_SWAPC, VKD3DSIH_SWAPC, "ff", "uff"}, -- {VKD3D_SM5_OP_DCL_STREAM, VKD3DSIH_DCL_STREAM, "", "O"}, -- {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VKD3DSIH_DCL_FUNCTION_BODY, "", "", -+ {VKD3D_SM5_OP_BUFINFO, VSIR_OP_BUFINFO, "i", "*"}, -+ {VKD3D_SM5_OP_DERIV_RTX_COARSE, VSIR_OP_DSX_COARSE, "f", "f"}, -+ {VKD3D_SM5_OP_DERIV_RTX_FINE, VSIR_OP_DSX_FINE, "f", "f"}, -+ {VKD3D_SM5_OP_DERIV_RTY_COARSE, VSIR_OP_DSY_COARSE, "f", "f"}, -+ {VKD3D_SM5_OP_DERIV_RTY_FINE, VSIR_OP_DSY_FINE, "f", "f"}, -+ {VKD3D_SM5_OP_GATHER4_C, VSIR_OP_GATHER4_C, "f", "f**f"}, -+ {VKD3D_SM5_OP_GATHER4_PO, VSIR_OP_GATHER4_PO, "f", "fi**"}, -+ {VKD3D_SM5_OP_GATHER4_PO_C, VSIR_OP_GATHER4_PO_C, "f", "fi**f"}, -+ {VKD3D_SM5_OP_RCP, VSIR_OP_RCP, "f", "f"}, -+ {VKD3D_SM5_OP_F32TOF16, VSIR_OP_F32TOF16, "u", "f"}, -+ {VKD3D_SM5_OP_F16TOF32, VSIR_OP_F16TOF32, "f", "u"}, -+ {VKD3D_SM5_OP_COUNTBITS, VSIR_OP_COUNTBITS, "u", "u"}, -+ {VKD3D_SM5_OP_FIRSTBIT_HI, VSIR_OP_FIRSTBIT_HI, "u", "u"}, -+ {VKD3D_SM5_OP_FIRSTBIT_LO, VSIR_OP_FIRSTBIT_LO, "u", "u"}, -+ {VKD3D_SM5_OP_FIRSTBIT_SHI, VSIR_OP_FIRSTBIT_SHI, "u", "i"}, -+ {VKD3D_SM5_OP_UBFE, VSIR_OP_UBFE, "u", "iiu"}, -+ {VKD3D_SM5_OP_IBFE, VSIR_OP_IBFE, "i", "iii"}, -+ {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, "", "*"}, -+ {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, "", "", -+ {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VSIR_OP_DCL_FUNCTION_TABLE, "", "", - shader_sm5_read_dcl_function_table}, -- {VKD3D_SM5_OP_DCL_INTERFACE, VKD3DSIH_DCL_INTERFACE, "", "", -+ {VKD3D_SM5_OP_DCL_INTERFACE, VSIR_OP_DCL_INTERFACE, "", "", - shader_sm5_read_dcl_interface}, -- {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, "", "", -+ {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT, "", "", - shader_sm5_read_control_point_count}, -- {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", -+ {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", - shader_sm5_read_control_point_count}, -- {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VKD3DSIH_DCL_TESSELLATOR_DOMAIN, "", "", -+ {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VSIR_OP_DCL_TESSELLATOR_DOMAIN, "", "", - shader_sm5_read_dcl_tessellator_domain}, -- {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, "", "", -+ {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VSIR_OP_DCL_TESSELLATOR_PARTITIONING, "", "", - shader_sm5_read_dcl_tessellator_partitioning}, -- {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", -+ {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", - shader_sm5_read_dcl_tessellator_output_primitive}, -- {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VKD3DSIH_DCL_HS_MAX_TESSFACTOR, "", "", -+ {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VSIR_OP_DCL_HS_MAX_TESSFACTOR, "", "", - shader_sm5_read_dcl_hs_max_tessfactor}, -- {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", -+ {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", - shader_sm4_read_declaration_count}, -- {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", -+ {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", - shader_sm4_read_declaration_count}, -- {VKD3D_SM5_OP_DCL_THREAD_GROUP, VKD3DSIH_DCL_THREAD_GROUP, "", "", -+ {VKD3D_SM5_OP_DCL_THREAD_GROUP, VSIR_OP_DCL_THREAD_GROUP, "", "", - shader_sm5_read_dcl_thread_group}, -- {VKD3D_SM5_OP_DCL_UAV_TYPED, VKD3DSIH_DCL_UAV_TYPED, "", "", -+ {VKD3D_SM5_OP_DCL_UAV_TYPED, VSIR_OP_DCL_UAV_TYPED, "", "", - shader_sm4_read_dcl_resource}, -- {VKD3D_SM5_OP_DCL_UAV_RAW, VKD3DSIH_DCL_UAV_RAW, "", "", -+ {VKD3D_SM5_OP_DCL_UAV_RAW, VSIR_OP_DCL_UAV_RAW, "", "", - shader_sm5_read_dcl_uav_raw}, -- {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VKD3DSIH_DCL_UAV_STRUCTURED, "", "", -+ {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VSIR_OP_DCL_UAV_STRUCTURED, "", "", - shader_sm5_read_dcl_uav_structured}, -- {VKD3D_SM5_OP_DCL_TGSM_RAW, VKD3DSIH_DCL_TGSM_RAW, "", "", -+ {VKD3D_SM5_OP_DCL_TGSM_RAW, VSIR_OP_DCL_TGSM_RAW, "", "", - shader_sm5_read_dcl_tgsm_raw}, -- {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VKD3DSIH_DCL_TGSM_STRUCTURED, "", "", -+ {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VSIR_OP_DCL_TGSM_STRUCTURED, "", "", - shader_sm5_read_dcl_tgsm_structured}, -- {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VKD3DSIH_DCL_RESOURCE_RAW, "", "", -+ {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VSIR_OP_DCL_RESOURCE_RAW, "", "", - shader_sm5_read_dcl_resource_raw}, -- {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VKD3DSIH_DCL_RESOURCE_STRUCTURED, "", "", -+ {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VSIR_OP_DCL_RESOURCE_STRUCTURED, "", "", - shader_sm5_read_dcl_resource_structured}, -- {VKD3D_SM5_OP_LD_UAV_TYPED, VKD3DSIH_LD_UAV_TYPED, "u", "i*"}, -- {VKD3D_SM5_OP_STORE_UAV_TYPED, VKD3DSIH_STORE_UAV_TYPED, "*", "iu"}, -- {VKD3D_SM5_OP_LD_RAW, VKD3DSIH_LD_RAW, "u", "i*"}, -- {VKD3D_SM5_OP_STORE_RAW, VKD3DSIH_STORE_RAW, "*", "uu"}, -- {VKD3D_SM5_OP_LD_STRUCTURED, VKD3DSIH_LD_STRUCTURED, "u", "ii*"}, -- {VKD3D_SM5_OP_STORE_STRUCTURED, VKD3DSIH_STORE_STRUCTURED, "*", "iiu"}, -- {VKD3D_SM5_OP_ATOMIC_AND, VKD3DSIH_ATOMIC_AND, "*", "iu"}, -- {VKD3D_SM5_OP_ATOMIC_OR, VKD3DSIH_ATOMIC_OR, "*", "iu"}, -- {VKD3D_SM5_OP_ATOMIC_XOR, VKD3DSIH_ATOMIC_XOR, "*", "iu"}, -- {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VKD3DSIH_ATOMIC_CMP_STORE, "*", "iuu"}, -- {VKD3D_SM5_OP_ATOMIC_IADD, VKD3DSIH_ATOMIC_IADD, "*", "ii"}, -- {VKD3D_SM5_OP_ATOMIC_IMAX, VKD3DSIH_ATOMIC_IMAX, "*", "ii"}, -- {VKD3D_SM5_OP_ATOMIC_IMIN, VKD3DSIH_ATOMIC_IMIN, "*", "ii"}, -- {VKD3D_SM5_OP_ATOMIC_UMAX, VKD3DSIH_ATOMIC_UMAX, "*", "iu"}, -- {VKD3D_SM5_OP_ATOMIC_UMIN, VKD3DSIH_ATOMIC_UMIN, "*", "iu"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VKD3DSIH_IMM_ATOMIC_ALLOC, "u", "*"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VKD3DSIH_IMM_ATOMIC_CONSUME, "u", "*"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VKD3DSIH_IMM_ATOMIC_IADD, "u*", "ii"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_AND, VKD3DSIH_IMM_ATOMIC_AND, "u*", "iu"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_OR, VKD3DSIH_IMM_ATOMIC_OR, "u*", "iu"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VKD3DSIH_IMM_ATOMIC_XOR, "u*", "iu"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VKD3DSIH_IMM_ATOMIC_EXCH, "u*", "iu"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VKD3DSIH_IMM_ATOMIC_CMP_EXCH, "u*", "iuu"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VKD3DSIH_IMM_ATOMIC_IMAX, "i*", "ii"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VKD3DSIH_IMM_ATOMIC_IMIN, "i*", "ii"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VKD3DSIH_IMM_ATOMIC_UMAX, "u*", "iu"}, -- {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "u*", "iu"}, -- {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "", -+ {VKD3D_SM5_OP_LD_UAV_TYPED, VSIR_OP_LD_UAV_TYPED, "u", "i*"}, -+ {VKD3D_SM5_OP_STORE_UAV_TYPED, VSIR_OP_STORE_UAV_TYPED, "*", "iu"}, -+ {VKD3D_SM5_OP_LD_RAW, VSIR_OP_LD_RAW, "u", "i*"}, -+ {VKD3D_SM5_OP_STORE_RAW, VSIR_OP_STORE_RAW, "*", "uu"}, -+ {VKD3D_SM5_OP_LD_STRUCTURED, VSIR_OP_LD_STRUCTURED, "u", "ii*"}, -+ {VKD3D_SM5_OP_STORE_STRUCTURED, VSIR_OP_STORE_STRUCTURED, "*", "iiu"}, -+ {VKD3D_SM5_OP_ATOMIC_AND, VSIR_OP_ATOMIC_AND, "*", "iu"}, -+ {VKD3D_SM5_OP_ATOMIC_OR, VSIR_OP_ATOMIC_OR, "*", "iu"}, -+ {VKD3D_SM5_OP_ATOMIC_XOR, VSIR_OP_ATOMIC_XOR, "*", "iu"}, -+ {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VSIR_OP_ATOMIC_CMP_STORE, "*", "iuu"}, -+ {VKD3D_SM5_OP_ATOMIC_IADD, VSIR_OP_ATOMIC_IADD, "*", "ii"}, -+ {VKD3D_SM5_OP_ATOMIC_IMAX, VSIR_OP_ATOMIC_IMAX, "*", "ii"}, -+ {VKD3D_SM5_OP_ATOMIC_IMIN, VSIR_OP_ATOMIC_IMIN, "*", "ii"}, -+ {VKD3D_SM5_OP_ATOMIC_UMAX, VSIR_OP_ATOMIC_UMAX, "*", "iu"}, -+ {VKD3D_SM5_OP_ATOMIC_UMIN, VSIR_OP_ATOMIC_UMIN, "*", "iu"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VSIR_OP_IMM_ATOMIC_ALLOC, "u", "*"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VSIR_OP_IMM_ATOMIC_CONSUME, "u", "*"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VSIR_OP_IMM_ATOMIC_IADD, "u*", "ii"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_AND, VSIR_OP_IMM_ATOMIC_AND, "u*", "iu"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_OR, VSIR_OP_IMM_ATOMIC_OR, "u*", "iu"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VSIR_OP_IMM_ATOMIC_XOR, "u*", "iu"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VSIR_OP_IMM_ATOMIC_EXCH, "u*", "iu"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VSIR_OP_IMM_ATOMIC_CMP_EXCH, "u*", "iuu"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VSIR_OP_IMM_ATOMIC_IMAX, "i*", "ii"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VSIR_OP_IMM_ATOMIC_IMIN, "i*", "ii"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VSIR_OP_IMM_ATOMIC_UMAX, "u*", "iu"}, -+ {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VSIR_OP_IMM_ATOMIC_UMIN, "u*", "iu"}, -+ {VKD3D_SM5_OP_SYNC, VSIR_OP_SYNC, "", "", - shader_sm5_read_sync}, -- {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"}, -- {VKD3D_SM5_OP_DMAX, VKD3DSIH_DMAX, "d", "dd"}, -- {VKD3D_SM5_OP_DMIN, VKD3DSIH_DMIN, "d", "dd"}, -- {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"}, -- {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQO, "u", "dd"}, -- {VKD3D_SM5_OP_DGE, VKD3DSIH_DGEO, "u", "dd"}, -- {VKD3D_SM5_OP_DLT, VKD3DSIH_DLT, "u", "dd"}, -- {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"}, -- {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, -- {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, -- {VKD3D_SM5_OP_DTOF, VKD3DSIH_DTOF, "f", "d"}, -- {VKD3D_SM5_OP_FTOD, VKD3DSIH_FTOD, "d", "f"}, -- {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"}, -- {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, -- {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", -+ {VKD3D_SM5_OP_DADD, VSIR_OP_DADD, "d", "dd"}, -+ {VKD3D_SM5_OP_DMAX, VSIR_OP_DMAX, "d", "dd"}, -+ {VKD3D_SM5_OP_DMIN, VSIR_OP_DMIN, "d", "dd"}, -+ {VKD3D_SM5_OP_DMUL, VSIR_OP_DMUL, "d", "dd"}, -+ {VKD3D_SM5_OP_DEQ, VSIR_OP_DEQO, "u", "dd"}, -+ {VKD3D_SM5_OP_DGE, VSIR_OP_DGEO, "u", "dd"}, -+ {VKD3D_SM5_OP_DLT, VSIR_OP_DLT, "u", "dd"}, -+ {VKD3D_SM5_OP_DNE, VSIR_OP_DNE, "u", "dd"}, -+ {VKD3D_SM5_OP_DMOV, VSIR_OP_DMOV, "d", "d"}, -+ {VKD3D_SM5_OP_DMOVC, VSIR_OP_DMOVC, "d", "udd"}, -+ {VKD3D_SM5_OP_DTOF, VSIR_OP_DTOF, "f", "d"}, -+ {VKD3D_SM5_OP_FTOD, VSIR_OP_FTOD, "d", "f"}, -+ {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VSIR_OP_EVAL_SAMPLE_INDEX, "f", "fi"}, -+ {VKD3D_SM5_OP_EVAL_CENTROID, VSIR_OP_EVAL_CENTROID, "f", "f"}, -+ {VKD3D_SM5_OP_DCL_GS_INSTANCES, VSIR_OP_DCL_GS_INSTANCES, "", "", - shader_sm4_read_declaration_count}, -- {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, -- {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, -- {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, -- {VKD3D_SM5_OP_MSAD, VKD3DSIH_MSAD, "u", "uuu"}, -- {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"}, -- {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"}, -- {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"}, -- {VKD3D_SM5_OP_UTOD, VKD3DSIH_UTOD, "d", "u"}, -- {VKD3D_SM5_OP_GATHER4_S, VKD3DSIH_GATHER4_S, "uu", "f**"}, -- {VKD3D_SM5_OP_GATHER4_C_S, VKD3DSIH_GATHER4_C_S, "fu", "f**f"}, -- {VKD3D_SM5_OP_GATHER4_PO_S, VKD3DSIH_GATHER4_PO_S, "fu", "fi**"}, -- {VKD3D_SM5_OP_GATHER4_PO_C_S, VKD3DSIH_GATHER4_PO_C_S, "fu", "fi**f"}, -- {VKD3D_SM5_OP_LD_S, VKD3DSIH_LD_S, "uu", "i*"}, -- {VKD3D_SM5_OP_LD2DMS_S, VKD3DSIH_LD2DMS_S, "uu", "i*i"}, -- {VKD3D_SM5_OP_LD_UAV_TYPED_S, VKD3DSIH_LD_UAV_TYPED_S, "uu", "iU"}, -- {VKD3D_SM5_OP_LD_RAW_S, VKD3DSIH_LD_RAW_S, "uu", "iU"}, -- {VKD3D_SM5_OP_LD_STRUCTURED_S, VKD3DSIH_LD_STRUCTURED_S, "uu", "ii*"}, -- {VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3DSIH_SAMPLE_LOD_S, "uu", "f**f"}, -- {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3DSIH_SAMPLE_C_LZ_S, "fu", "f**f"}, -- {VKD3D_SM5_OP_SAMPLE_CL_S, VKD3DSIH_SAMPLE_CL_S, "uu", "f**f"}, -- {VKD3D_SM5_OP_SAMPLE_B_CL_S, VKD3DSIH_SAMPLE_B_CL_S, "uu", "f**ff"}, -- {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3DSIH_SAMPLE_GRAD_CL_S, "uu", "f**fff"}, -- {VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3DSIH_SAMPLE_C_CL_S, "fu", "f**ff"}, -- {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, -+ {VKD3D_SM5_OP_DDIV, VSIR_OP_DDIV, "d", "dd"}, -+ {VKD3D_SM5_OP_DFMA, VSIR_OP_DFMA, "d", "ddd"}, -+ {VKD3D_SM5_OP_DRCP, VSIR_OP_DRCP, "d", "d"}, -+ {VKD3D_SM5_OP_MSAD, VSIR_OP_MSAD, "u", "uuu"}, -+ {VKD3D_SM5_OP_DTOI, VSIR_OP_DTOI, "i", "d"}, -+ {VKD3D_SM5_OP_DTOU, VSIR_OP_DTOU, "u", "d"}, -+ {VKD3D_SM5_OP_ITOD, VSIR_OP_ITOD, "d", "i"}, -+ {VKD3D_SM5_OP_UTOD, VSIR_OP_UTOD, "d", "u"}, -+ {VKD3D_SM5_OP_GATHER4_S, VSIR_OP_GATHER4_S, "uu", "f**"}, -+ {VKD3D_SM5_OP_GATHER4_C_S, VSIR_OP_GATHER4_C_S, "fu", "f**f"}, -+ {VKD3D_SM5_OP_GATHER4_PO_S, VSIR_OP_GATHER4_PO_S, "fu", "fi**"}, -+ {VKD3D_SM5_OP_GATHER4_PO_C_S, VSIR_OP_GATHER4_PO_C_S, "fu", "fi**f"}, -+ {VKD3D_SM5_OP_LD_S, VSIR_OP_LD_S, "uu", "i*"}, -+ {VKD3D_SM5_OP_LD2DMS_S, VSIR_OP_LD2DMS_S, "uu", "i*i"}, -+ {VKD3D_SM5_OP_LD_UAV_TYPED_S, VSIR_OP_LD_UAV_TYPED_S, "uu", "iU"}, -+ {VKD3D_SM5_OP_LD_RAW_S, VSIR_OP_LD_RAW_S, "uu", "iU"}, -+ {VKD3D_SM5_OP_LD_STRUCTURED_S, VSIR_OP_LD_STRUCTURED_S, "uu", "ii*"}, -+ {VKD3D_SM5_OP_SAMPLE_LOD_S, VSIR_OP_SAMPLE_LOD_S, "uu", "f**f"}, -+ {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VSIR_OP_SAMPLE_C_LZ_S, "fu", "f**f"}, -+ {VKD3D_SM5_OP_SAMPLE_CL_S, VSIR_OP_SAMPLE_CL_S, "uu", "f**f"}, -+ {VKD3D_SM5_OP_SAMPLE_B_CL_S, VSIR_OP_SAMPLE_B_CL_S, "uu", "f**ff"}, -+ {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VSIR_OP_SAMPLE_GRAD_CL_S, "uu", "f**fff"}, -+ {VKD3D_SM5_OP_SAMPLE_C_CL_S, VSIR_OP_SAMPLE_C_CL_S, "fu", "f**ff"}, -+ {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VSIR_OP_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, - }; - - static const struct vkd3d_sm4_register_type_info register_type_table[] = -@@ -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) - { -- if (vsir_opcode >= VKD3DSIH_COUNT) -+ if (vsir_opcode >= VSIR_OP_COUNT) - return NULL; - return lookup->opcode_info_from_vsir[vsir_opcode]; - } -@@ -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 -- || (reg->type == VKD3DSPR_INPUT && (priv->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE -+ || (reg->type == VKD3DSPR_INPUT && (priv->phase == VSIR_OP_HS_CONTROL_POINT_PHASE - || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); - } - -@@ -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); -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - *ptr += len; - return; - } - - vsir_instruction_init(ins, &sm4->p.location, opcode_info->handler_idx); -- if (ins->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE || ins->opcode == VKD3DSIH_HS_FORK_PHASE -- || ins->opcode == VKD3DSIH_HS_JOIN_PHASE) -+ if (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE || ins->opcode == VSIR_OP_HS_FORK_PHASE -+ || ins->opcode == VSIR_OP_HS_JOIN_PHASE) - sm4->phase = ins->opcode; -- sm4->has_control_point_phase |= ins->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE; -+ sm4->has_control_point_phase |= ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE; - ins->flags = 0; - ins->coissue = false; - ins->raw = false; -@@ -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."); -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - return; - } - 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; -@@ -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."); -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - return; - } - for (i = 0; i < ins->dst_count; ++i) -@@ -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]))) - { -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - return; - } - dst_params[i].modifiers |= instruction_dst_modifier; -@@ -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]))) - { -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - return; - } - } - } - -+ 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; -- ins->opcode = VKD3DSIH_INVALID; -+ ins->opcode = VSIR_OP_INVALID; - return; - } - -@@ -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) -+ if (ins->opcode == VSIR_OP_INVALID) - { - WARN("Encountered unrecognized or invalid instruction.\n"); - 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) -@@ -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}, -+ {"sv_isfrontface", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_IS_FRONT_FACE}, -+ {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, -+ {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX}, - - {"sv_outputcontrolpointid", false, VKD3D_SHADER_TYPE_HULL, ~0u}, - {"sv_position", false, VKD3D_SHADER_TYPE_HULL, ~0u}, -@@ -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; - -+ if ((ret = vkd3d_u32_compare(e->stream_index, f->stream_index))) -+ return ret; - if ((ret = vkd3d_u32_compare(e->register_index, f->register_index))) - return ret; - return vkd3d_u32_compare(e->mask, f->mask); -@@ -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; -- bool output = tag == TAG_OSGN || (tag == TAG_PCSG -- && tpf->program->shader_version.type == VKD3D_SHADER_TYPE_HULL); -+ const struct vkd3d_shader_version *version = &tpf->program->shader_version; - const struct signature_element **sorted_elements; - struct vkd3d_bytecode_buffer buffer = {0}; -+ bool has_stream_index, output; - unsigned int i; - -+ output = tag == TAG_OSGN || (tag == TAG_PCSG && version->type == VKD3D_SHADER_TYPE_HULL); -+ if (output && version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) -+ tag = TAG_OSG5; -+ has_stream_index = tag == TAG_OSG5 || has_minimum_precision; -+ - put_u32(&buffer, signature->element_count); - put_u32(&buffer, 8); /* unknown */ - -@@ -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; - -- if (has_minimum_precision) -- put_u32(&buffer, 0); /* FIXME: stream index */ -+ if (has_stream_index) -+ put_u32(&buffer, element->stream_index); - put_u32(&buffer, 0); /* name */ - put_u32(&buffer, element->semantic_index); - put_u32(&buffer, sysval); -@@ -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]; -+ size_t name_index = 2 + i * 6; - size_t string_offset; - -- string_offset = put_string(&buffer, element->semantic_name); -+ if (has_stream_index) -+ name_index += i + 1; - if (has_minimum_precision) -- set_u32(&buffer, (2 + i * 8 + 1) * sizeof(uint32_t), string_offset); -- else -- set_u32(&buffer, (2 + i * 6) * sizeof(uint32_t), string_offset); -+ name_index += i; -+ -+ string_offset = put_string(&buffer, element->semantic_name); -+ set_u32(&buffer, name_index * sizeof(uint32_t), string_offset); - } - - if (has_minimum_precision) -@@ -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) - { -- const struct vkd3d_shader_structured_resource *structured_resource = &ins->declaration.structured_resource; -- const struct vkd3d_shader_semantic *semantic = &ins->declaration.semantic; - const struct vkd3d_shader_version *version = &tpf->program->shader_version; -+ const struct vkd3d_shader_resource *resource; - const struct vkd3d_sm4_opcode_info *info; - struct sm4_instruction instr = {0}; - bool uav; -@@ -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); - -- uav = ins->opcode == VKD3DSIH_DCL_UAV_TYPED -- || ins->opcode == VKD3DSIH_DCL_UAV_RAW -- || ins->opcode == VKD3DSIH_DCL_UAV_STRUCTURED; -+ uav = ins->opcode == VSIR_OP_DCL_UAV_TYPED -+ || ins->opcode == VSIR_OP_DCL_UAV_RAW -+ || ins->opcode == VSIR_OP_DCL_UAV_STRUCTURED; - - instr.opcode = info->opcode; - -- instr.dsts[0] = semantic->resource.reg; -- instr.dst_count = 1; -- -- if (ins->opcode == VKD3DSIH_DCL || ins->opcode == VKD3DSIH_DCL_UAV_TYPED) -+ if (ins->opcode == VSIR_OP_DCL || ins->opcode == VSIR_OP_DCL_UAV_TYPED) - { -- instr.idx[0] = pack_resource_data_type(semantic->resource_data_type); -+ instr.idx[0] = pack_resource_data_type(ins->declaration.semantic.resource_data_type); - 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; -+ } -+ else -+ { -+ 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; -- instr.dsts[0].reg.idx[1].offset = semantic->resource.range.first; -- instr.dsts[0].reg.idx[2].offset = semantic->resource.range.last; -+ instr.dsts[0].reg.idx[0].offset = resource->reg.reg.idx[0].offset; -+ instr.dsts[0].reg.idx[1].offset = resource->range.first; -+ instr.dsts[0].reg.idx[2].offset = resource->range.last; - instr.dsts[0].reg.idx_count = 3; - -- instr.idx[instr.idx_count++] = semantic->resource.range.space; -+ instr.idx[instr.idx_count++] = resource->range.space; - } - else - { -- instr.dsts[0].reg.idx[0].offset = semantic->resource.range.first; -+ instr.dsts[0].reg.idx[0].offset = resource->range.first; - instr.dsts[0].reg.idx_count = 1; - } - -@@ -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 +4056,39 @@ static void tpf_write_dcl_vertices_out(const struct tpf_compiler *tpf, unsigned - write_sm4_instruction(tpf, &instr); - } - -+/* Descriptor registers are stored in shader model 5.1 format regardless -+ * of the program's version. Convert them to the 4.0 format if necessary. */ -+static void rewrite_descriptor_register(const struct tpf_compiler *tpf, struct vkd3d_shader_register *reg) -+{ -+ if (vkd3d_shader_ver_ge(&tpf->program->shader_version, 5, 1)) -+ return; -+ -+ switch (reg->type) -+ { -+ case VKD3DSPR_CONSTBUFFER: -+ reg->idx[0] = reg->idx[1]; -+ reg->idx[1] = reg->idx[2]; -+ reg->idx_count = 2; -+ break; -+ -+ case VKD3DSPR_RESOURCE: -+ case VKD3DSPR_SAMPLER: -+ case VKD3DSPR_UAV: -+ reg->idx[0] = reg->idx[1]; -+ reg->idx_count = 1; -+ break; -+ -+ default: -+ break; -+ } -+ -+ for (unsigned int i = 0; i < reg->idx_count; ++i) -+ { -+ if (reg->idx[i].rel_addr) -+ rewrite_descriptor_register(tpf, ®->idx[i].rel_addr->reg); -+ } -+} -+ - static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) - { - struct sm4_instruction_modifier *modifier; -@@ -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]; -+ rewrite_descriptor_register(tpf, &instr.dsts[i].reg); - - if (instr.dsts[i].modifiers & VKD3DSPDM_SATURATE) - { -@@ -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) -+ { - instr.srcs[i] = ins->src[i]; -+ rewrite_descriptor_register(tpf, &instr.srcs[i].reg); -+ } - - if (ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w) - { -@@ -4095,177 +4164,188 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ - { - switch (ins->opcode) - { -- case VKD3DSIH_DCL_CONSTANT_BUFFER: -+ case VSIR_OP_DCL_CONSTANT_BUFFER: - tpf_dcl_constant_buffer(tpf, ins); - break; - -- case VKD3DSIH_DCL_TEMPS: -+ case VSIR_OP_DCL_TEMPS: - tpf_dcl_temps(tpf, ins->declaration.count); - break; - -- case VKD3DSIH_DCL_INDEXABLE_TEMP: -+ case VSIR_OP_DCL_INDEXABLE_TEMP: - tpf_dcl_indexable_temp(tpf, &ins->declaration.indexable_temp); - break; - -- case VKD3DSIH_DCL_INPUT: -+ case VSIR_OP_DCL_INPUT: - tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT, &ins->declaration.dst, 0); - break; - -- case VKD3DSIH_DCL_INPUT_PS: -+ case VSIR_OP_DCL_INPUT_PS: - tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS, &ins->declaration.dst, ins->flags); - break; - -- case VKD3DSIH_DCL_INPUT_PS_SGV: -+ case VSIR_OP_DCL_INPUT_PS_SGV: - tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SGV, &ins->declaration.register_semantic, 0); - break; - -- case VKD3DSIH_DCL_INPUT_PS_SIV: -+ case VSIR_OP_DCL_INPUT_PS_SIV: - tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SIV, &ins->declaration.register_semantic, ins->flags); - break; - -- case VKD3DSIH_DCL_INPUT_SGV: -+ case VSIR_OP_DCL_INPUT_SGV: - tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SGV, &ins->declaration.register_semantic, 0); - break; - -- case VKD3DSIH_DCL_INPUT_SIV: -+ case VSIR_OP_DCL_INPUT_SIV: - tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SIV, &ins->declaration.register_semantic, 0); - break; - -- case VKD3DSIH_DCL_OUTPUT: -+ case VSIR_OP_DCL_OUTPUT: - tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT, &ins->declaration.dst, 0); - break; - -- case VKD3DSIH_DCL_OUTPUT_SIV: -+ case VSIR_OP_DCL_OUTPUT_SGV: -+ tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SGV, &ins->declaration.register_semantic, 0); -+ break; -+ -+ case VSIR_OP_DCL_OUTPUT_SIV: - tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SIV, &ins->declaration.register_semantic, 0); - break; - -- case VKD3DSIH_DCL_SAMPLER: -+ case VSIR_OP_DCL_SAMPLER: - tpf_dcl_sampler(tpf, ins); - break; - -- case VKD3DSIH_DCL: -- case VKD3DSIH_DCL_RESOURCE_RAW: -- 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: -+ case VSIR_OP_DCL_UAV_STRUCTURED: -+ case VSIR_OP_DCL_UAV_TYPED: - tpf_dcl_texture(tpf, ins); - break; - -- case VKD3DSIH_ADD: -- case VKD3DSIH_ATOMIC_AND: -- case VKD3DSIH_ATOMIC_CMP_STORE: -- case VKD3DSIH_ATOMIC_IADD: -- case VKD3DSIH_ATOMIC_IMAX: -- case VKD3DSIH_ATOMIC_IMIN: -- case VKD3DSIH_ATOMIC_UMAX: -- case VKD3DSIH_ATOMIC_UMIN: -- case VKD3DSIH_ATOMIC_OR: -- case VKD3DSIH_ATOMIC_XOR: -- case VKD3DSIH_AND: -- case VKD3DSIH_BREAK: -- case VKD3DSIH_CASE: -- case VKD3DSIH_CONTINUE: -- case VKD3DSIH_CUT: -- case VKD3DSIH_DEFAULT: -- case VKD3DSIH_DISCARD: -- case VKD3DSIH_DIV: -- case VKD3DSIH_DP2: -- case VKD3DSIH_DP3: -- case VKD3DSIH_DP4: -- case VKD3DSIH_DSX: -- case VKD3DSIH_DSX_COARSE: -- case VKD3DSIH_DSX_FINE: -- case VKD3DSIH_DSY: -- case VKD3DSIH_DSY_COARSE: -- case VKD3DSIH_DSY_FINE: -- case VKD3DSIH_ELSE: -- case VKD3DSIH_EMIT: -- case VKD3DSIH_ENDIF: -- case VKD3DSIH_ENDLOOP: -- case VKD3DSIH_ENDSWITCH: -- case VKD3DSIH_EQO: -- case VKD3DSIH_EXP: -- case VKD3DSIH_F16TOF32: -- case VKD3DSIH_F32TOF16: -- case VKD3DSIH_FRC: -- case VKD3DSIH_FTOI: -- case VKD3DSIH_FTOU: -- case VKD3DSIH_GATHER4: -- case VKD3DSIH_GATHER4_PO: -- case VKD3DSIH_GATHER4_C: -- case VKD3DSIH_GATHER4_PO_C: -- case VKD3DSIH_GEO: -- case VKD3DSIH_HS_CONTROL_POINT_PHASE: -- case VKD3DSIH_HS_FORK_PHASE: -- case VKD3DSIH_IADD: -- case VKD3DSIH_IEQ: -- case VKD3DSIH_IF: -- case VKD3DSIH_IGE: -- case VKD3DSIH_ILT: -- case VKD3DSIH_IMAD: -- case VKD3DSIH_IMAX: -- case VKD3DSIH_IMIN: -- case VKD3DSIH_IMM_ATOMIC_AND: -- case VKD3DSIH_IMM_ATOMIC_CMP_EXCH: -- case VKD3DSIH_IMM_ATOMIC_EXCH: -- case VKD3DSIH_IMM_ATOMIC_IADD: -- case VKD3DSIH_IMM_ATOMIC_IMAX: -- case VKD3DSIH_IMM_ATOMIC_IMIN: -- case VKD3DSIH_IMM_ATOMIC_UMAX: -- case VKD3DSIH_IMM_ATOMIC_UMIN: -- case VKD3DSIH_IMM_ATOMIC_OR: -- case VKD3DSIH_IMM_ATOMIC_XOR: -- case VKD3DSIH_SYNC: -- case VKD3DSIH_IMUL: -- case VKD3DSIH_INE: -- case VKD3DSIH_INEG: -- case VKD3DSIH_ISHL: -- case VKD3DSIH_ISHR: -- case VKD3DSIH_ITOF: -- case VKD3DSIH_LD: -- case VKD3DSIH_LD2DMS: -- case VKD3DSIH_LD_RAW: -- case VKD3DSIH_LD_UAV_TYPED: -- case VKD3DSIH_LOG: -- case VKD3DSIH_LOOP: -- case VKD3DSIH_LTO: -- case VKD3DSIH_MAD: -- case VKD3DSIH_MAX: -- case VKD3DSIH_MIN: -- case VKD3DSIH_MOV: -- case VKD3DSIH_MOVC: -- case VKD3DSIH_MUL: -- case VKD3DSIH_NEU: -- case VKD3DSIH_NOT: -- case VKD3DSIH_OR: -- case VKD3DSIH_RCP: -- case VKD3DSIH_RESINFO: -- case VKD3DSIH_RET: -- case VKD3DSIH_ROUND_NE: -- case VKD3DSIH_ROUND_NI: -- case VKD3DSIH_ROUND_PI: -- case VKD3DSIH_ROUND_Z: -- case VKD3DSIH_RSQ: -- case VKD3DSIH_SAMPLE: -- case VKD3DSIH_SAMPLE_B: -- case VKD3DSIH_SAMPLE_C: -- case VKD3DSIH_SAMPLE_C_LZ: -- case VKD3DSIH_SAMPLE_GRAD: -- case VKD3DSIH_SAMPLE_INFO: -- case VKD3DSIH_SAMPLE_LOD: -- case VKD3DSIH_SINCOS: -- case VKD3DSIH_SQRT: -- case VKD3DSIH_STORE_RAW: -- case VKD3DSIH_STORE_UAV_TYPED: -- case VKD3DSIH_SWITCH: -- case VKD3DSIH_UDIV: -- case VKD3DSIH_UGE: -- case VKD3DSIH_ULT: -- case VKD3DSIH_UMAX: -- case VKD3DSIH_UMIN: -- case VKD3DSIH_USHR: -- case VKD3DSIH_UTOF: -- case VKD3DSIH_XOR: -+ case VSIR_OP_ADD: -+ case VSIR_OP_ATOMIC_AND: -+ case VSIR_OP_ATOMIC_CMP_STORE: -+ case VSIR_OP_ATOMIC_IADD: -+ case VSIR_OP_ATOMIC_IMAX: -+ case VSIR_OP_ATOMIC_IMIN: -+ case VSIR_OP_ATOMIC_UMAX: -+ case VSIR_OP_ATOMIC_UMIN: -+ case VSIR_OP_ATOMIC_OR: -+ case VSIR_OP_ATOMIC_XOR: -+ case VSIR_OP_AND: -+ case VSIR_OP_BREAK: -+ case VSIR_OP_CASE: -+ case VSIR_OP_CONTINUE: -+ case VSIR_OP_CUT: -+ case VSIR_OP_CUT_STREAM: -+ case VSIR_OP_DCL_STREAM: -+ case VSIR_OP_DEFAULT: -+ case VSIR_OP_DISCARD: -+ case VSIR_OP_DIV: -+ case VSIR_OP_DP2: -+ case VSIR_OP_DP3: -+ case VSIR_OP_DP4: -+ case VSIR_OP_DSX: -+ case VSIR_OP_DSX_COARSE: -+ case VSIR_OP_DSX_FINE: -+ case VSIR_OP_DSY: -+ case VSIR_OP_DSY_COARSE: -+ case VSIR_OP_DSY_FINE: -+ case VSIR_OP_ELSE: -+ case VSIR_OP_EMIT: -+ case VSIR_OP_EMIT_STREAM: -+ case VSIR_OP_ENDIF: -+ case VSIR_OP_ENDLOOP: -+ case VSIR_OP_ENDSWITCH: -+ case VSIR_OP_EQO: -+ case VSIR_OP_EXP: -+ case VSIR_OP_F16TOF32: -+ case VSIR_OP_F32TOF16: -+ case VSIR_OP_FRC: -+ case VSIR_OP_FTOI: -+ case VSIR_OP_FTOU: -+ case VSIR_OP_GATHER4: -+ case VSIR_OP_GATHER4_PO: -+ case VSIR_OP_GATHER4_C: -+ case VSIR_OP_GATHER4_PO_C: -+ case VSIR_OP_GEO: -+ case VSIR_OP_HS_CONTROL_POINT_PHASE: -+ case VSIR_OP_HS_FORK_PHASE: -+ case VSIR_OP_IADD: -+ case VSIR_OP_IEQ: -+ case VSIR_OP_IF: -+ case VSIR_OP_IGE: -+ case VSIR_OP_ILT: -+ case VSIR_OP_IMAD: -+ case VSIR_OP_IMAX: -+ case VSIR_OP_IMIN: -+ case VSIR_OP_IMM_ATOMIC_AND: -+ case VSIR_OP_IMM_ATOMIC_CMP_EXCH: -+ case VSIR_OP_IMM_ATOMIC_EXCH: -+ case VSIR_OP_IMM_ATOMIC_IADD: -+ case VSIR_OP_IMM_ATOMIC_IMAX: -+ case VSIR_OP_IMM_ATOMIC_IMIN: -+ case VSIR_OP_IMM_ATOMIC_UMAX: -+ case VSIR_OP_IMM_ATOMIC_UMIN: -+ case VSIR_OP_IMM_ATOMIC_OR: -+ case VSIR_OP_IMM_ATOMIC_XOR: -+ case VSIR_OP_SYNC: -+ case VSIR_OP_IMUL: -+ case VSIR_OP_INE: -+ case VSIR_OP_INEG: -+ case VSIR_OP_ISHL: -+ case VSIR_OP_ISHR: -+ case VSIR_OP_ITOF: -+ case VSIR_OP_LD: -+ case VSIR_OP_LD2DMS: -+ case VSIR_OP_LD_RAW: -+ case VSIR_OP_LD_UAV_TYPED: -+ case VSIR_OP_LOG: -+ case VSIR_OP_LOOP: -+ case VSIR_OP_LTO: -+ case VSIR_OP_MAD: -+ case VSIR_OP_MAX: -+ case VSIR_OP_MIN: -+ case VSIR_OP_MOV: -+ case VSIR_OP_MOVC: -+ case VSIR_OP_MUL: -+ case VSIR_OP_NEU: -+ case VSIR_OP_NOT: -+ case VSIR_OP_OR: -+ case VSIR_OP_RCP: -+ case VSIR_OP_RESINFO: -+ case VSIR_OP_RET: -+ case VSIR_OP_ROUND_NE: -+ case VSIR_OP_ROUND_NI: -+ case VSIR_OP_ROUND_PI: -+ case VSIR_OP_ROUND_Z: -+ case VSIR_OP_RSQ: -+ case VSIR_OP_SAMPLE: -+ case VSIR_OP_SAMPLE_B: -+ case VSIR_OP_SAMPLE_C: -+ case VSIR_OP_SAMPLE_C_LZ: -+ case VSIR_OP_SAMPLE_GRAD: -+ case VSIR_OP_SAMPLE_INFO: -+ case VSIR_OP_SAMPLE_LOD: -+ case VSIR_OP_SINCOS: -+ case VSIR_OP_SQRT: -+ case VSIR_OP_STORE_RAW: -+ case VSIR_OP_STORE_UAV_TYPED: -+ case VSIR_OP_SWITCH: -+ case VSIR_OP_UDIV: -+ case VSIR_OP_UGE: -+ case VSIR_OP_ULT: -+ case VSIR_OP_UMAX: -+ case VSIR_OP_UMIN: -+ case VSIR_OP_USHR: -+ case VSIR_OP_UTOF: -+ case VSIR_OP_XOR: - tpf_simple_instruction(tpf, ins); - break; - -@@ -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..d1992c9d446 100644 +index 5fcc836aae1..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 @@ @@ -25919,2219 +84,8 @@ index f56608940db..d1992c9d446 100644 static inline int char_to_int(char c) { if ('0' <= c && c <= '9') -@@ -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) - { -- if (context->log_level < level) -+ struct vkd3d_string_buffer *messages = &context->messages; -+ size_t pos = messages->content_size; -+ -+ if (!WARN_ON() && context->log_level < level) - return; - - if (location) -@@ -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) -- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: ", -+ vkd3d_string_buffer_printf(messages, "%s:%u:%u: ", - source_name, location->line, location->column); - else -- vkd3d_string_buffer_printf(&context->messages, "%s: ", source_name); -+ vkd3d_string_buffer_printf(messages, "%s: ", source_name); - } -- vkd3d_string_buffer_vprintf(&context->messages, format, args); -- vkd3d_string_buffer_printf(&context->messages, "\n"); -+ vkd3d_string_buffer_vprintf(messages, format, args); -+ vkd3d_string_buffer_printf(messages, "\n"); -+ -+ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); -+ if (context->log_level < level) -+ messages->content_size = pos; - } - - void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, - enum vkd3d_shader_error error, const char *format, va_list args) - { -- if (context->log_level < VKD3D_SHADER_LOG_WARNING) -+ struct vkd3d_string_buffer *messages = &context->messages; -+ size_t pos = messages->content_size; -+ -+ if (!WARN_ON() && context->log_level < VKD3D_SHADER_LOG_WARNING) - return; - - if (location) -@@ -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) -- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: W%04u: ", -+ vkd3d_string_buffer_printf(messages, "%s:%u:%u: W%04u: ", - source_name, location->line, location->column, error); - else -- vkd3d_string_buffer_printf(&context->messages, "%s: W%04u: ", source_name, error); -+ vkd3d_string_buffer_printf(messages, "%s: W%04u: ", source_name, error); - } - else - { -- vkd3d_string_buffer_printf(&context->messages, "W%04u: ", error); -+ vkd3d_string_buffer_printf(messages, "W%04u: ", error); - } -- vkd3d_string_buffer_vprintf(&context->messages, format, args); -- vkd3d_string_buffer_printf(&context->messages, "\n"); -+ vkd3d_string_buffer_vprintf(messages, format, args); -+ vkd3d_string_buffer_printf(messages, "\n"); -+ -+ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); -+ if (context->log_level < VKD3D_SHADER_LOG_WARNING) -+ messages->content_size = pos; - } - - void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, -@@ -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) - { -- if (context->log_level < VKD3D_SHADER_LOG_ERROR) -+ struct vkd3d_string_buffer *messages = &context->messages; -+ size_t pos = messages->content_size; -+ -+ if (!WARN_ON() && context->log_level < VKD3D_SHADER_LOG_ERROR) - return; - - if (location) -@@ -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) -- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: E%04u: ", -+ vkd3d_string_buffer_printf(messages, "%s:%u:%u: E%04u: ", - source_name, location->line, location->column, error); - else -- vkd3d_string_buffer_printf(&context->messages, "%s: E%04u: ", source_name, error); -+ vkd3d_string_buffer_printf(messages, "%s: E%04u: ", source_name, error); - } - else - { -- vkd3d_string_buffer_printf(&context->messages, "E%04u: ", error); -+ vkd3d_string_buffer_printf(messages, "E%04u: ", error); - } -- vkd3d_string_buffer_vprintf(&context->messages, format, args); -- vkd3d_string_buffer_printf(&context->messages, "\n"); -+ vkd3d_string_buffer_vprintf(messages, format, args); -+ vkd3d_string_buffer_printf(messages, "\n"); -+ -+ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); -+ if (context->log_level < VKD3D_SHADER_LOG_ERROR) -+ messages->content_size = pos; - } - - void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, -@@ -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; - -- return (VKD3DSIH_ATOMIC_AND <= opcode && opcode <= VKD3DSIH_ATOMIC_XOR) -- || (VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR) -- || opcode == VKD3DSIH_LD_UAV_TYPED -- || (opcode == VKD3DSIH_LD_RAW && instruction->src[1].reg.type == VKD3DSPR_UAV) -- || (opcode == VKD3DSIH_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV); -+ return (VSIR_OP_ATOMIC_AND <= opcode && opcode <= VSIR_OP_ATOMIC_XOR) -+ || (VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR) -+ || opcode == VSIR_OP_LD_UAV_TYPED -+ || (opcode == VSIR_OP_LD_RAW && instruction->src[1].reg.type == VKD3DSPR_UAV) -+ || (opcode == VSIR_OP_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV); - } - - static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *context, -@@ -1035,7 +1113,7 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in - { - enum vkd3d_shader_opcode opcode = instruction->opcode; - -- return opcode == VKD3DSIH_IMM_ATOMIC_ALLOC || opcode == VKD3DSIH_IMM_ATOMIC_CONSUME; -+ return opcode == VSIR_OP_IMM_ATOMIC_ALLOC || opcode == VSIR_OP_IMM_ATOMIC_CONSUME; - } - - static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_context *context, -@@ -1048,8 +1126,8 @@ static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_ - { - enum vkd3d_shader_opcode opcode = instruction->opcode; - -- return (VKD3DSIH_ATOMIC_AND <= opcode && opcode <= VKD3DSIH_ATOMIC_XOR) -- || (VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR); -+ return (VSIR_OP_ATOMIC_AND <= opcode && opcode <= VSIR_OP_ATOMIC_XOR) -+ || (VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR); - } - - static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context, -@@ -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) - { -- case VKD3DSIH_DCL_CONSTANT_BUFFER: -+ case VSIR_OP_DCL_CONSTANT_BUFFER: - vkd3d_shader_scan_constant_buffer_declaration(context, instruction); - break; -- case VKD3DSIH_DCL_SAMPLER: -+ case VSIR_OP_DCL_SAMPLER: - vkd3d_shader_scan_sampler_declaration(context, instruction); - break; -- case VKD3DSIH_DCL: -+ case VSIR_OP_DCL: - if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE) - break; - -@@ -1276,33 +1388,33 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - break; - } - /* fall through */ -- case VKD3DSIH_DCL_UAV_TYPED: -+ case VSIR_OP_DCL_UAV_TYPED: - vkd3d_shader_scan_typed_resource_declaration(context, instruction); - break; -- case VKD3DSIH_DCL_RESOURCE_RAW: -- case VKD3DSIH_DCL_UAV_RAW: -+ 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 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, VSIR_DATA_U32, 0, - instruction->declaration.structured_resource.byte_stride, false, instruction->flags); - break; -- case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: -+ case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: - context->output_primitive = instruction->declaration.tessellator_output_primitive; - break; -- case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING: -+ case VSIR_OP_DCL_TESSELLATOR_PARTITIONING: - context->partitioning = instruction->declaration.tessellator_partitioning; - break; -- case VKD3DSIH_IF: -- case VKD3DSIH_IFC: -+ case VSIR_OP_IF: -+ case VSIR_OP_IFC: - cf_info = vkd3d_shader_scan_push_cf_info(context); - cf_info->type = VKD3D_SHADER_BLOCK_IF; - cf_info->inside_block = true; - break; -- case VKD3DSIH_ELSE: -+ case VSIR_OP_ELSE: - 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 +1423,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - } - cf_info->inside_block = true; - break; -- case VKD3DSIH_ENDIF: -+ case VSIR_OP_ENDIF: - 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 +1432,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - } - vkd3d_shader_scan_pop_cf_info(context); - break; -- case VKD3DSIH_LOOP: -+ case VSIR_OP_LOOP: - cf_info = vkd3d_shader_scan_push_cf_info(context); - cf_info->type = VKD3D_SHADER_BLOCK_LOOP; - cf_info->inside_block = true; - break; -- case VKD3DSIH_ENDLOOP: -+ case VSIR_OP_ENDLOOP: - 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 +1446,11 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - } - vkd3d_shader_scan_pop_cf_info(context); - break; -- case VKD3DSIH_SWITCH: -+ case VSIR_OP_SWITCH: - cf_info = vkd3d_shader_scan_push_cf_info(context); - cf_info->type = VKD3D_SHADER_BLOCK_SWITCH; - break; -- case VKD3DSIH_ENDSWITCH: -+ case VSIR_OP_ENDSWITCH: - if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) - || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH || cf_info->inside_block) - { -@@ -1348,7 +1460,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - } - vkd3d_shader_scan_pop_cf_info(context); - break; -- case VKD3DSIH_CASE: -+ case VSIR_OP_CASE: - if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) - || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH) - { -@@ -1358,7 +1470,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - } - cf_info->inside_block = true; - break; -- case VKD3DSIH_DEFAULT: -+ case VSIR_OP_DEFAULT: - if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) - || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH) - { -@@ -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; -- case VKD3DSIH_BREAK: -+ case VSIR_OP_BREAK: - 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 +1496,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - } - cf_info->inside_block = false; - break; -- case VKD3DSIH_BREAKP: -+ case VSIR_OP_BREAKP: - 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 +1504,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - return VKD3D_ERROR_INVALID_SHADER; - } - break; -- case VKD3DSIH_CONTINUE: -+ case VSIR_OP_CONTINUE: - 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 +1513,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - } - cf_info->inside_block = false; - break; -- case VKD3DSIH_CONTINUEP: -+ case VSIR_OP_CONTINUEP: - 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 +1521,55 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - return VKD3D_ERROR_INVALID_SHADER; - } - break; -- case VKD3DSIH_RET: -+ case VSIR_OP_RET: - if (context->cf_info_count) - context->cf_info[context->cf_info_count - 1].inside_block = false; - break; -- case VKD3DSIH_TEX: -- 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: -- case VKD3DSIH_TEXM3x2TEX: -- case VKD3DSIH_TEXM3x3SPEC: -- case VKD3DSIH_TEXM3x3TEX: -- case VKD3DSIH_TEXM3x3VSPEC: -- case VKD3DSIH_TEXREG2AR: -- case VKD3DSIH_TEXREG2GB: -- case VKD3DSIH_TEXREG2RGB: -+ case VSIR_OP_TEX: -+ case VSIR_OP_TEXBEM: -+ case VSIR_OP_TEXBEML: -+ case VSIR_OP_TEXDP3TEX: -+ case VSIR_OP_TEXM3x2TEX: -+ case VSIR_OP_TEXM3x3SPEC: -+ case VSIR_OP_TEXM3x3TEX: -+ case VSIR_OP_TEXM3x3VSPEC: -+ case VSIR_OP_TEXREG2AR: -+ case VSIR_OP_TEXREG2GB: -+ case VSIR_OP_TEXREG2RGB: - sampler_reg = &instruction->dst[0].reg; - vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg); - break; -- case VKD3DSIH_GATHER4: -- case VKD3DSIH_GATHER4_C: -- case VKD3DSIH_SAMPLE: -- case VKD3DSIH_SAMPLE_B: -- case VKD3DSIH_SAMPLE_C: -- case VKD3DSIH_SAMPLE_C_LZ: -- case VKD3DSIH_SAMPLE_GRAD: -- case VKD3DSIH_SAMPLE_LOD: -+ case VSIR_OP_GATHER4: -+ case VSIR_OP_GATHER4_C: -+ case VSIR_OP_SAMPLE_B: -+ case VSIR_OP_SAMPLE_C: -+ case VSIR_OP_SAMPLE_C_LZ: -+ case VSIR_OP_SAMPLE_GRAD: -+ case VSIR_OP_SAMPLE_LOD: - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg); - 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); - break; -- case VKD3DSIH_LD: -- case VKD3DSIH_LD2DMS: -+ case VSIR_OP_LD: -+ case VSIR_OP_LD2DMS: - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, NULL); - break; -- case VKD3DSIH_BUFINFO: -- case VKD3DSIH_SAMPLE_INFO: -+ case VSIR_OP_BUFINFO: -+ case VSIR_OP_SAMPLE_INFO: - if (instruction->src[0].reg.type == VKD3DSPR_RESOURCE) - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[0].reg, NULL); - break; -- case VKD3DSIH_LD_RAW: -- case VKD3DSIH_RESINFO: -+ case VSIR_OP_LD_RAW: -+ case VSIR_OP_RESINFO: - if (instruction->src[1].reg.type == VKD3DSPR_RESOURCE) - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, NULL); - break; -- case VKD3DSIH_LD_STRUCTURED: -+ case VSIR_OP_LD_STRUCTURED: - if (instruction->src[2].reg.type == VKD3DSPR_RESOURCE) - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, NULL); - break; -@@ -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); - } -+ else if (compile_info->source_type == VKD3D_SHADER_SOURCE_TX) -+ { -+ ret = tx_parse(compile_info, out, &message_context); -+ } - 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, 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, -+ VKD3D_SHADER_SOURCE_TX, - }; - - TRACE("count %p.\n", count); -@@ -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, - }; - -+ static const enum vkd3d_shader_target_type tx_types[] = -+ { -+ VKD3D_SHADER_TARGET_D3D_ASM, -+ }; -+ - TRACE("source_type %#x, count %p.\n", source_type, count); - - switch (source_type) -@@ -2101,6 +2241,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( - *count = ARRAY_SIZE(fx_types); - return fx_types; - -+ case VKD3D_SHADER_SOURCE_TX: -+ *count = ARRAY_SIZE(tx_types); -+ return tx_types; -+ - 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..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 - VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT = 5042, - VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE = 5043, - VKD3D_SHADER_ERROR_HLSL_MISPLACED_STREAM_OUTPUT = 5044, -+ VKD3D_SHADER_ERROR_HLSL_MISSING_INPUT_PATCH = 5045, - - VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, - VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, -@@ -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 +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, -+ VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT = 8020, - - VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, - VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, -@@ -236,7 +240,7 @@ enum vkd3d_shader_error - VKD3D_SHADER_WARNING_DXIL_UNDEFINED_OPERAND = 8310, - - VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, -- VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001, -+ VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE = 9001, - VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE = 9002, - VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK = 9003, - VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS = 9004, -@@ -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 - { -- VKD3DSIH_ABS, -- VKD3DSIH_ACOS, -- VKD3DSIH_ADD, -- VKD3DSIH_AND, -- VKD3DSIH_ASIN, -- VKD3DSIH_ATAN, -- VKD3DSIH_ATOMIC_AND, -- VKD3DSIH_ATOMIC_CMP_STORE, -- VKD3DSIH_ATOMIC_IADD, -- VKD3DSIH_ATOMIC_IMAX, -- VKD3DSIH_ATOMIC_IMIN, -- VKD3DSIH_ATOMIC_OR, -- VKD3DSIH_ATOMIC_UMAX, -- VKD3DSIH_ATOMIC_UMIN, -- VKD3DSIH_ATOMIC_XOR, -- VKD3DSIH_BEM, -- VKD3DSIH_BFI, -- VKD3DSIH_BFREV, -- VKD3DSIH_BRANCH, -- VKD3DSIH_BREAK, -- VKD3DSIH_BREAKC, -- VKD3DSIH_BREAKP, -- VKD3DSIH_BUFINFO, -- VKD3DSIH_CALL, -- VKD3DSIH_CALLNZ, -- VKD3DSIH_CASE, -- VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, -- VKD3DSIH_CMP, -- VKD3DSIH_CND, -- VKD3DSIH_CONTINUE, -- VKD3DSIH_CONTINUEP, -- VKD3DSIH_COUNTBITS, -- VKD3DSIH_CRS, -- VKD3DSIH_CUT, -- VKD3DSIH_CUT_STREAM, -- VKD3DSIH_DADD, -- VKD3DSIH_DCL, -- VKD3DSIH_DCL_CONSTANT_BUFFER, -- VKD3DSIH_DCL_FUNCTION_BODY, -- VKD3DSIH_DCL_FUNCTION_TABLE, -- VKD3DSIH_DCL_GLOBAL_FLAGS, -- VKD3DSIH_DCL_GS_INSTANCES, -- VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, -- VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, -- VKD3DSIH_DCL_HS_MAX_TESSFACTOR, -- VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, -- VKD3DSIH_DCL_INDEX_RANGE, -- VKD3DSIH_DCL_INDEXABLE_TEMP, -- VKD3DSIH_DCL_INPUT, -- VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, -- VKD3DSIH_DCL_INPUT_PRIMITIVE, -- VKD3DSIH_DCL_INPUT_PS, -- VKD3DSIH_DCL_INPUT_PS_SGV, -- VKD3DSIH_DCL_INPUT_PS_SIV, -- VKD3DSIH_DCL_INPUT_SGV, -- VKD3DSIH_DCL_INPUT_SIV, -- VKD3DSIH_DCL_INTERFACE, -- VKD3DSIH_DCL_OUTPUT, -- VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, -- VKD3DSIH_DCL_OUTPUT_SIV, -- VKD3DSIH_DCL_OUTPUT_TOPOLOGY, -- VKD3DSIH_DCL_RESOURCE_RAW, -- VKD3DSIH_DCL_RESOURCE_STRUCTURED, -- VKD3DSIH_DCL_SAMPLER, -- VKD3DSIH_DCL_STREAM, -- VKD3DSIH_DCL_TEMPS, -- VKD3DSIH_DCL_TESSELLATOR_DOMAIN, -- VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, -- VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, -- VKD3DSIH_DCL_TGSM_RAW, -- VKD3DSIH_DCL_TGSM_STRUCTURED, -- VKD3DSIH_DCL_THREAD_GROUP, -- VKD3DSIH_DCL_UAV_RAW, -- VKD3DSIH_DCL_UAV_STRUCTURED, -- VKD3DSIH_DCL_UAV_TYPED, -- VKD3DSIH_DCL_VERTICES_OUT, -- VKD3DSIH_DDIV, -- VKD3DSIH_DEF, -- VKD3DSIH_DEFAULT, -- VKD3DSIH_DEFB, -- VKD3DSIH_DEFI, -- VKD3DSIH_DEQO, -- VKD3DSIH_DFMA, -- VKD3DSIH_DGEO, -- VKD3DSIH_DISCARD, -- VKD3DSIH_DIV, -- VKD3DSIH_DLT, -- VKD3DSIH_DMAX, -- VKD3DSIH_DMIN, -- VKD3DSIH_DMOV, -- VKD3DSIH_DMOVC, -- VKD3DSIH_DMUL, -- VKD3DSIH_DNE, -- VKD3DSIH_DP2, -- VKD3DSIH_DP2ADD, -- VKD3DSIH_DP3, -- VKD3DSIH_DP4, -- VKD3DSIH_DRCP, -- VKD3DSIH_DST, -- VKD3DSIH_DSX, -- VKD3DSIH_DSX_COARSE, -- VKD3DSIH_DSX_FINE, -- VKD3DSIH_DSY, -- VKD3DSIH_DSY_COARSE, -- VKD3DSIH_DSY_FINE, -- VKD3DSIH_DTOF, -- VKD3DSIH_DTOI, -- VKD3DSIH_DTOU, -- VKD3DSIH_ELSE, -- VKD3DSIH_EMIT, -- VKD3DSIH_EMIT_STREAM, -- VKD3DSIH_ENDIF, -- VKD3DSIH_ENDLOOP, -- VKD3DSIH_ENDREP, -- VKD3DSIH_ENDSWITCH, -- VKD3DSIH_EQO, -- VKD3DSIH_EQU, -- VKD3DSIH_EVAL_CENTROID, -- VKD3DSIH_EVAL_SAMPLE_INDEX, -- VKD3DSIH_EXP, -- VKD3DSIH_EXPP, -- VKD3DSIH_F16TOF32, -- VKD3DSIH_F32TOF16, -- VKD3DSIH_FCALL, -- VKD3DSIH_FIRSTBIT_HI, -- VKD3DSIH_FIRSTBIT_LO, -- VKD3DSIH_FIRSTBIT_SHI, -- VKD3DSIH_FRC, -- VKD3DSIH_FREM, -- VKD3DSIH_FTOD, -- VKD3DSIH_FTOI, -- VKD3DSIH_FTOU, -- VKD3DSIH_GATHER4, -- VKD3DSIH_GATHER4_C, -- VKD3DSIH_GATHER4_C_S, -- VKD3DSIH_GATHER4_PO, -- VKD3DSIH_GATHER4_PO_C, -- VKD3DSIH_GATHER4_PO_C_S, -- VKD3DSIH_GATHER4_PO_S, -- VKD3DSIH_GATHER4_S, -- VKD3DSIH_GEO, -- VKD3DSIH_GEU, -- VKD3DSIH_HCOS, -- VKD3DSIH_HS_CONTROL_POINT_PHASE, -- VKD3DSIH_HS_DECLS, -- VKD3DSIH_HS_FORK_PHASE, -- VKD3DSIH_HS_JOIN_PHASE, -- VKD3DSIH_HSIN, -- VKD3DSIH_HTAN, -- VKD3DSIH_IADD, -- VKD3DSIH_IBFE, -- VKD3DSIH_IDIV, -- VKD3DSIH_IEQ, -- VKD3DSIH_IF, -- VKD3DSIH_IFC, -- VKD3DSIH_IGE, -- VKD3DSIH_ILT, -- VKD3DSIH_IMAD, -- VKD3DSIH_IMAX, -- VKD3DSIH_IMIN, -- VKD3DSIH_IMM_ATOMIC_ALLOC, -- VKD3DSIH_IMM_ATOMIC_AND, -- VKD3DSIH_IMM_ATOMIC_CMP_EXCH, -- VKD3DSIH_IMM_ATOMIC_CONSUME, -- VKD3DSIH_IMM_ATOMIC_EXCH, -- VKD3DSIH_IMM_ATOMIC_IADD, -- VKD3DSIH_IMM_ATOMIC_IMAX, -- VKD3DSIH_IMM_ATOMIC_IMIN, -- VKD3DSIH_IMM_ATOMIC_OR, -- VKD3DSIH_IMM_ATOMIC_UMAX, -- VKD3DSIH_IMM_ATOMIC_UMIN, -- VKD3DSIH_IMM_ATOMIC_XOR, -- VKD3DSIH_IMUL, -- VKD3DSIH_INE, -- VKD3DSIH_INEG, -- VKD3DSIH_ISFINITE, -- VKD3DSIH_ISHL, -- VKD3DSIH_ISHR, -- VKD3DSIH_ISINF, -- VKD3DSIH_ISNAN, -- VKD3DSIH_ITOD, -- VKD3DSIH_ITOF, -- VKD3DSIH_ITOI, -- VKD3DSIH_LABEL, -- VKD3DSIH_LD, -- VKD3DSIH_LD2DMS, -- VKD3DSIH_LD2DMS_S, -- VKD3DSIH_LD_RAW, -- VKD3DSIH_LD_RAW_S, -- VKD3DSIH_LD_S, -- VKD3DSIH_LD_STRUCTURED, -- VKD3DSIH_LD_STRUCTURED_S, -- VKD3DSIH_LD_UAV_TYPED, -- VKD3DSIH_LD_UAV_TYPED_S, -- VKD3DSIH_LIT, -- VKD3DSIH_LOD, -- VKD3DSIH_LOG, -- VKD3DSIH_LOGP, -- VKD3DSIH_LOOP, -- VKD3DSIH_LRP, -- VKD3DSIH_LTO, -- VKD3DSIH_LTU, -- VKD3DSIH_M3x2, -- VKD3DSIH_M3x3, -- VKD3DSIH_M3x4, -- VKD3DSIH_M4x3, -- VKD3DSIH_M4x4, -- VKD3DSIH_MAD, -- VKD3DSIH_MAX, -- VKD3DSIH_MIN, -- VKD3DSIH_MOV, -- VKD3DSIH_MOVA, -- VKD3DSIH_MOVC, -- VKD3DSIH_MSAD, -- VKD3DSIH_MUL, -- VKD3DSIH_NEO, -- VKD3DSIH_NEU, -- VKD3DSIH_NOP, -- VKD3DSIH_NOT, -- VKD3DSIH_NRM, -- VKD3DSIH_OR, -- VKD3DSIH_ORD, -- VKD3DSIH_PHASE, -- VKD3DSIH_PHI, -- VKD3DSIH_POW, -- VKD3DSIH_QUAD_READ_ACROSS_D, -- VKD3DSIH_QUAD_READ_ACROSS_X, -- VKD3DSIH_QUAD_READ_ACROSS_Y, -- VKD3DSIH_QUAD_READ_LANE_AT, -- VKD3DSIH_RCP, -- VKD3DSIH_REP, -- VKD3DSIH_RESINFO, -- VKD3DSIH_RET, -- VKD3DSIH_RETP, -- VKD3DSIH_ROUND_NE, -- VKD3DSIH_ROUND_NI, -- VKD3DSIH_ROUND_PI, -- VKD3DSIH_ROUND_Z, -- VKD3DSIH_RSQ, -- VKD3DSIH_SAMPLE, -- VKD3DSIH_SAMPLE_B, -- VKD3DSIH_SAMPLE_B_CL_S, -- VKD3DSIH_SAMPLE_C, -- VKD3DSIH_SAMPLE_C_CL_S, -- VKD3DSIH_SAMPLE_C_LZ, -- VKD3DSIH_SAMPLE_C_LZ_S, -- VKD3DSIH_SAMPLE_CL_S, -- VKD3DSIH_SAMPLE_GRAD, -- VKD3DSIH_SAMPLE_GRAD_CL_S, -- VKD3DSIH_SAMPLE_INFO, -- VKD3DSIH_SAMPLE_LOD, -- VKD3DSIH_SAMPLE_LOD_S, -- VKD3DSIH_SAMPLE_POS, -- VKD3DSIH_SETP, -- VKD3DSIH_SGE, -- VKD3DSIH_SGN, -- VKD3DSIH_SINCOS, -- VKD3DSIH_SLT, -- VKD3DSIH_SQRT, -- VKD3DSIH_STORE_RAW, -- VKD3DSIH_STORE_STRUCTURED, -- VKD3DSIH_STORE_UAV_TYPED, -- VKD3DSIH_SUB, -- VKD3DSIH_SWAPC, -- VKD3DSIH_SWITCH, -- VKD3DSIH_SWITCH_MONOLITHIC, -- VKD3DSIH_SYNC, -- VKD3DSIH_TAN, -- VKD3DSIH_TEX, -- VKD3DSIH_TEXBEM, -- VKD3DSIH_TEXBEML, -- VKD3DSIH_TEXCOORD, -- VKD3DSIH_TEXDEPTH, -- VKD3DSIH_TEXDP3, -- VKD3DSIH_TEXDP3TEX, -- VKD3DSIH_TEXKILL, -- VKD3DSIH_TEXLDD, -- VKD3DSIH_TEXLDL, -- VKD3DSIH_TEXM3x2DEPTH, -- VKD3DSIH_TEXM3x2PAD, -- VKD3DSIH_TEXM3x2TEX, -- VKD3DSIH_TEXM3x3, -- VKD3DSIH_TEXM3x3DIFF, -- VKD3DSIH_TEXM3x3PAD, -- VKD3DSIH_TEXM3x3SPEC, -- VKD3DSIH_TEXM3x3TEX, -- VKD3DSIH_TEXM3x3VSPEC, -- VKD3DSIH_TEXREG2AR, -- VKD3DSIH_TEXREG2GB, -- VKD3DSIH_TEXREG2RGB, -- VKD3DSIH_UBFE, -- VKD3DSIH_UDIV, -- VKD3DSIH_UGE, -- VKD3DSIH_ULT, -- VKD3DSIH_UMAX, -- VKD3DSIH_UMIN, -- VKD3DSIH_UMUL, -- VKD3DSIH_UNO, -- VKD3DSIH_USHR, -- VKD3DSIH_UTOD, -- VKD3DSIH_UTOF, -- VKD3DSIH_UTOU, -- VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL, -- VKD3DSIH_WAVE_ACTIVE_BALLOT, -- VKD3DSIH_WAVE_ACTIVE_BIT_AND, -- VKD3DSIH_WAVE_ACTIVE_BIT_OR, -- VKD3DSIH_WAVE_ACTIVE_BIT_XOR, -- VKD3DSIH_WAVE_ALL_BIT_COUNT, -- VKD3DSIH_WAVE_ALL_TRUE, -- VKD3DSIH_WAVE_ANY_TRUE, -- VKD3DSIH_WAVE_IS_FIRST_LANE, -- VKD3DSIH_WAVE_OP_ADD, -- VKD3DSIH_WAVE_OP_IMAX, -- VKD3DSIH_WAVE_OP_IMIN, -- VKD3DSIH_WAVE_OP_MAX, -- VKD3DSIH_WAVE_OP_MIN, -- VKD3DSIH_WAVE_OP_MUL, -- VKD3DSIH_WAVE_OP_UMAX, -- VKD3DSIH_WAVE_OP_UMIN, -- VKD3DSIH_WAVE_PREFIX_BIT_COUNT, -- VKD3DSIH_WAVE_READ_LANE_AT, -- VKD3DSIH_WAVE_READ_LANE_FIRST, -- VKD3DSIH_XOR, -- -- VKD3DSIH_INVALID, -- -- VKD3DSIH_COUNT, --}; -+ VSIR_OP_ABS, -+ VSIR_OP_ACOS, -+ VSIR_OP_ADD, -+ VSIR_OP_AND, -+ VSIR_OP_ASIN, -+ VSIR_OP_ATAN, -+ VSIR_OP_ATOMIC_AND, -+ VSIR_OP_ATOMIC_CMP_STORE, -+ VSIR_OP_ATOMIC_IADD, -+ VSIR_OP_ATOMIC_IMAX, -+ VSIR_OP_ATOMIC_IMIN, -+ VSIR_OP_ATOMIC_OR, -+ VSIR_OP_ATOMIC_UMAX, -+ VSIR_OP_ATOMIC_UMIN, -+ VSIR_OP_ATOMIC_XOR, -+ VSIR_OP_BEM, -+ VSIR_OP_BFI, -+ VSIR_OP_BFREV, -+ VSIR_OP_BRANCH, -+ VSIR_OP_BREAK, -+ VSIR_OP_BREAKC, -+ VSIR_OP_BREAKP, -+ VSIR_OP_BUFINFO, -+ VSIR_OP_CALL, -+ VSIR_OP_CALLNZ, -+ VSIR_OP_CASE, -+ VSIR_OP_CHECK_ACCESS_FULLY_MAPPED, -+ VSIR_OP_CMP, -+ VSIR_OP_CND, -+ VSIR_OP_CONTINUE, -+ VSIR_OP_CONTINUEP, -+ VSIR_OP_COS, -+ VSIR_OP_COUNTBITS, -+ VSIR_OP_CRS, -+ VSIR_OP_CUT, -+ VSIR_OP_CUT_STREAM, -+ VSIR_OP_DADD, -+ VSIR_OP_DCL, -+ VSIR_OP_DCL_CONSTANT_BUFFER, -+ VSIR_OP_DCL_FUNCTION_BODY, -+ VSIR_OP_DCL_FUNCTION_TABLE, -+ VSIR_OP_DCL_GLOBAL_FLAGS, -+ VSIR_OP_DCL_GS_INSTANCES, -+ VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, -+ VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, -+ VSIR_OP_DCL_HS_MAX_TESSFACTOR, -+ VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER, -+ VSIR_OP_DCL_INDEX_RANGE, -+ VSIR_OP_DCL_INDEXABLE_TEMP, -+ VSIR_OP_DCL_INPUT, -+ VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT, -+ VSIR_OP_DCL_INPUT_PRIMITIVE, -+ VSIR_OP_DCL_INPUT_PS, -+ VSIR_OP_DCL_INPUT_PS_SGV, -+ VSIR_OP_DCL_INPUT_PS_SIV, -+ VSIR_OP_DCL_INPUT_SGV, -+ VSIR_OP_DCL_INPUT_SIV, -+ VSIR_OP_DCL_INTERFACE, -+ VSIR_OP_DCL_OUTPUT, -+ VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, -+ VSIR_OP_DCL_OUTPUT_SGV, -+ VSIR_OP_DCL_OUTPUT_SIV, -+ VSIR_OP_DCL_OUTPUT_TOPOLOGY, -+ VSIR_OP_DCL_RESOURCE_RAW, -+ VSIR_OP_DCL_RESOURCE_STRUCTURED, -+ VSIR_OP_DCL_SAMPLER, -+ VSIR_OP_DCL_STREAM, -+ VSIR_OP_DCL_TEMPS, -+ VSIR_OP_DCL_TESSELLATOR_DOMAIN, -+ VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, -+ VSIR_OP_DCL_TESSELLATOR_PARTITIONING, -+ VSIR_OP_DCL_TGSM_RAW, -+ VSIR_OP_DCL_TGSM_STRUCTURED, -+ VSIR_OP_DCL_THREAD_GROUP, -+ VSIR_OP_DCL_UAV_RAW, -+ VSIR_OP_DCL_UAV_STRUCTURED, -+ VSIR_OP_DCL_UAV_TYPED, -+ VSIR_OP_DCL_VERTICES_OUT, -+ VSIR_OP_DDIV, -+ VSIR_OP_DEF, -+ VSIR_OP_DEFAULT, -+ VSIR_OP_DEFB, -+ VSIR_OP_DEFI, -+ VSIR_OP_DEQO, -+ VSIR_OP_DFMA, -+ VSIR_OP_DGEO, -+ VSIR_OP_DISCARD, -+ VSIR_OP_DIV, -+ VSIR_OP_DLT, -+ VSIR_OP_DMAX, -+ VSIR_OP_DMIN, -+ VSIR_OP_DMOV, -+ VSIR_OP_DMOVC, -+ VSIR_OP_DMUL, -+ VSIR_OP_DNE, -+ VSIR_OP_DP2, -+ VSIR_OP_DP2ADD, -+ VSIR_OP_DP3, -+ VSIR_OP_DP4, -+ VSIR_OP_DRCP, -+ VSIR_OP_DST, -+ VSIR_OP_DSX, -+ VSIR_OP_DSX_COARSE, -+ VSIR_OP_DSX_FINE, -+ VSIR_OP_DSY, -+ VSIR_OP_DSY_COARSE, -+ VSIR_OP_DSY_FINE, -+ VSIR_OP_DTOF, -+ VSIR_OP_DTOI, -+ VSIR_OP_DTOU, -+ VSIR_OP_ELSE, -+ VSIR_OP_EMIT, -+ VSIR_OP_EMIT_STREAM, -+ VSIR_OP_ENDIF, -+ VSIR_OP_ENDLOOP, -+ VSIR_OP_ENDREP, -+ VSIR_OP_ENDSWITCH, -+ VSIR_OP_EQO, -+ VSIR_OP_EQU, -+ VSIR_OP_EVAL_CENTROID, -+ VSIR_OP_EVAL_SAMPLE_INDEX, -+ VSIR_OP_EXP, -+ VSIR_OP_EXPP, -+ VSIR_OP_F16TOF32, -+ VSIR_OP_F32TOF16, -+ VSIR_OP_FCALL, -+ VSIR_OP_FIRSTBIT_HI, -+ VSIR_OP_FIRSTBIT_LO, -+ VSIR_OP_FIRSTBIT_SHI, -+ VSIR_OP_FRC, -+ VSIR_OP_FREM, -+ VSIR_OP_FTOD, -+ VSIR_OP_FTOI, -+ VSIR_OP_FTOU, -+ VSIR_OP_GATHER4, -+ VSIR_OP_GATHER4_C, -+ VSIR_OP_GATHER4_C_S, -+ VSIR_OP_GATHER4_PO, -+ VSIR_OP_GATHER4_PO_C, -+ VSIR_OP_GATHER4_PO_C_S, -+ VSIR_OP_GATHER4_PO_S, -+ VSIR_OP_GATHER4_S, -+ VSIR_OP_GEO, -+ VSIR_OP_GEU, -+ VSIR_OP_HCOS, -+ VSIR_OP_HS_CONTROL_POINT_PHASE, -+ VSIR_OP_HS_DECLS, -+ VSIR_OP_HS_FORK_PHASE, -+ VSIR_OP_HS_JOIN_PHASE, -+ VSIR_OP_HSIN, -+ VSIR_OP_HTAN, -+ VSIR_OP_IADD, -+ VSIR_OP_IBFE, -+ VSIR_OP_IDIV, -+ VSIR_OP_IEQ, -+ VSIR_OP_IF, -+ VSIR_OP_IFC, -+ VSIR_OP_IGE, -+ VSIR_OP_ILT, -+ VSIR_OP_IMAD, -+ VSIR_OP_IMAX, -+ VSIR_OP_IMIN, -+ VSIR_OP_IMM_ATOMIC_ALLOC, -+ VSIR_OP_IMM_ATOMIC_AND, -+ VSIR_OP_IMM_ATOMIC_CMP_EXCH, -+ VSIR_OP_IMM_ATOMIC_CONSUME, -+ VSIR_OP_IMM_ATOMIC_EXCH, -+ VSIR_OP_IMM_ATOMIC_IADD, -+ VSIR_OP_IMM_ATOMIC_IMAX, -+ VSIR_OP_IMM_ATOMIC_IMIN, -+ VSIR_OP_IMM_ATOMIC_OR, -+ VSIR_OP_IMM_ATOMIC_UMAX, -+ VSIR_OP_IMM_ATOMIC_UMIN, -+ VSIR_OP_IMM_ATOMIC_XOR, -+ VSIR_OP_IMUL, -+ VSIR_OP_IMUL_LOW, -+ VSIR_OP_INE, -+ VSIR_OP_INEG, -+ VSIR_OP_IREM, -+ VSIR_OP_ISFINITE, -+ VSIR_OP_ISHL, -+ VSIR_OP_ISHR, -+ VSIR_OP_ISINF, -+ VSIR_OP_ISNAN, -+ VSIR_OP_ITOD, -+ VSIR_OP_ITOF, -+ VSIR_OP_ITOI, -+ VSIR_OP_LABEL, -+ VSIR_OP_LD, -+ VSIR_OP_LD2DMS, -+ VSIR_OP_LD2DMS_S, -+ VSIR_OP_LD_RAW, -+ VSIR_OP_LD_RAW_S, -+ VSIR_OP_LD_S, -+ VSIR_OP_LD_STRUCTURED, -+ VSIR_OP_LD_STRUCTURED_S, -+ VSIR_OP_LD_UAV_TYPED, -+ VSIR_OP_LD_UAV_TYPED_S, -+ VSIR_OP_LIT, -+ VSIR_OP_LOD, -+ VSIR_OP_LOG, -+ VSIR_OP_LOGP, -+ VSIR_OP_LOOP, -+ VSIR_OP_LRP, -+ VSIR_OP_LTO, -+ VSIR_OP_LTU, -+ VSIR_OP_M3x2, -+ VSIR_OP_M3x3, -+ VSIR_OP_M3x4, -+ VSIR_OP_M4x3, -+ VSIR_OP_M4x4, -+ VSIR_OP_MAD, -+ VSIR_OP_MAX, -+ VSIR_OP_MIN, -+ VSIR_OP_MOV, -+ VSIR_OP_MOVA, -+ VSIR_OP_MOVC, -+ VSIR_OP_MSAD, -+ VSIR_OP_MUL, -+ VSIR_OP_NEO, -+ VSIR_OP_NEU, -+ VSIR_OP_NOP, -+ VSIR_OP_NOT, -+ VSIR_OP_NRM, -+ VSIR_OP_OR, -+ VSIR_OP_ORD, -+ VSIR_OP_PHASE, -+ VSIR_OP_PHI, -+ VSIR_OP_POW, -+ VSIR_OP_QUAD_READ_ACROSS_D, -+ VSIR_OP_QUAD_READ_ACROSS_X, -+ VSIR_OP_QUAD_READ_ACROSS_Y, -+ VSIR_OP_QUAD_READ_LANE_AT, -+ VSIR_OP_RCP, -+ VSIR_OP_REP, -+ VSIR_OP_RESINFO, -+ VSIR_OP_RET, -+ VSIR_OP_RETP, -+ VSIR_OP_ROUND_NE, -+ VSIR_OP_ROUND_NI, -+ VSIR_OP_ROUND_PI, -+ VSIR_OP_ROUND_Z, -+ VSIR_OP_RSQ, -+ VSIR_OP_SAMPLE, -+ VSIR_OP_SAMPLE_B, -+ VSIR_OP_SAMPLE_B_CL_S, -+ VSIR_OP_SAMPLE_C, -+ VSIR_OP_SAMPLE_C_CL_S, -+ VSIR_OP_SAMPLE_C_LZ, -+ VSIR_OP_SAMPLE_C_LZ_S, -+ VSIR_OP_SAMPLE_CL_S, -+ VSIR_OP_SAMPLE_GRAD, -+ VSIR_OP_SAMPLE_GRAD_CL_S, -+ VSIR_OP_SAMPLE_INFO, -+ VSIR_OP_SAMPLE_LOD, -+ VSIR_OP_SAMPLE_LOD_S, -+ VSIR_OP_SAMPLE_POS, -+ VSIR_OP_SETP, -+ VSIR_OP_SGE, -+ VSIR_OP_SGN, -+ VSIR_OP_SIN, -+ VSIR_OP_SINCOS, -+ VSIR_OP_SLT, -+ VSIR_OP_SQRT, -+ VSIR_OP_STORE_RAW, -+ VSIR_OP_STORE_STRUCTURED, -+ VSIR_OP_STORE_UAV_TYPED, -+ VSIR_OP_SUB, -+ VSIR_OP_SWAPC, -+ VSIR_OP_SWITCH, -+ VSIR_OP_SWITCH_MONOLITHIC, -+ VSIR_OP_SYNC, -+ VSIR_OP_TAN, -+ VSIR_OP_TEX, -+ VSIR_OP_TEXBEM, -+ VSIR_OP_TEXBEML, -+ VSIR_OP_TEXCOORD, -+ VSIR_OP_TEXCRD, -+ VSIR_OP_TEXDEPTH, -+ VSIR_OP_TEXDP3, -+ VSIR_OP_TEXDP3TEX, -+ VSIR_OP_TEXKILL, -+ VSIR_OP_TEXLD, -+ VSIR_OP_TEXLDD, -+ VSIR_OP_TEXLDL, -+ VSIR_OP_TEXM3x2DEPTH, -+ VSIR_OP_TEXM3x2PAD, -+ VSIR_OP_TEXM3x2TEX, -+ VSIR_OP_TEXM3x3, -+ VSIR_OP_TEXM3x3DIFF, -+ VSIR_OP_TEXM3x3PAD, -+ VSIR_OP_TEXM3x3SPEC, -+ VSIR_OP_TEXM3x3TEX, -+ VSIR_OP_TEXM3x3VSPEC, -+ VSIR_OP_TEXREG2AR, -+ VSIR_OP_TEXREG2GB, -+ VSIR_OP_TEXREG2RGB, -+ VSIR_OP_UBFE, -+ VSIR_OP_UDIV, -+ VSIR_OP_UDIV_SIMPLE, -+ VSIR_OP_UGE, -+ VSIR_OP_ULT, -+ VSIR_OP_UMAX, -+ VSIR_OP_UMIN, -+ VSIR_OP_UMUL, -+ VSIR_OP_UNO, -+ VSIR_OP_UREM, -+ VSIR_OP_USHR, -+ VSIR_OP_UTOD, -+ VSIR_OP_UTOF, -+ VSIR_OP_UTOU, -+ VSIR_OP_WAVE_ACTIVE_ALL_EQUAL, -+ VSIR_OP_WAVE_ACTIVE_BALLOT, -+ VSIR_OP_WAVE_ACTIVE_BIT_AND, -+ VSIR_OP_WAVE_ACTIVE_BIT_OR, -+ VSIR_OP_WAVE_ACTIVE_BIT_XOR, -+ VSIR_OP_WAVE_ALL_BIT_COUNT, -+ VSIR_OP_WAVE_ALL_TRUE, -+ VSIR_OP_WAVE_ANY_TRUE, -+ VSIR_OP_WAVE_IS_FIRST_LANE, -+ VSIR_OP_WAVE_OP_ADD, -+ VSIR_OP_WAVE_OP_IMAX, -+ VSIR_OP_WAVE_OP_IMIN, -+ VSIR_OP_WAVE_OP_MAX, -+ VSIR_OP_WAVE_OP_MIN, -+ VSIR_OP_WAVE_OP_MUL, -+ VSIR_OP_WAVE_OP_UMAX, -+ VSIR_OP_WAVE_OP_UMIN, -+ VSIR_OP_WAVE_PREFIX_BIT_COUNT, -+ VSIR_OP_WAVE_READ_LANE_AT, -+ VSIR_OP_WAVE_READ_LANE_FIRST, -+ VSIR_OP_XOR, -+ -+ VSIR_OP_INVALID, -+ -+ VSIR_OP_COUNT, -+}; -+ -+const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error); - - enum vkd3d_shader_register_type - { -@@ -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; -- union -+ union vsir_immediate_constant - { - uint32_t immconst_u32[VKD3D_VEC4_SIZE]; - float immconst_f32[VKD3D_VEC4_SIZE]; -@@ -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); - } - --static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg) --{ -- return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR -- && (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_u64[0] : !reg->u.immconst_u32[0]); --} -- - static inline bool register_is_numeric_array(const struct vkd3d_shader_register *reg) - { - return (reg->type == VKD3DSPR_IMMCONSTBUFFER || reg->type == VKD3DSPR_IDXTEMP -@@ -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); -+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); -+int tx_parse(const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); - - void free_dxbc_shader_desc(struct dxbc_shader_desc *desc); - -@@ -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; - } - --enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, -- unsigned int index); -- --static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_shader_sysval_semantic sysval) --{ -- return vkd3d_siv_from_sysval_indexed(sysval, 0); --} -- - static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) - { - unsigned int i; -@@ -1853,6 +1963,8 @@ static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64) - } - } - -+const char *debug_vsir_writemask(unsigned int writemask); -+ - static inline uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32) - { - switch (swizzle32) -@@ -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; - } - -+static inline void vsir_swizzle_set_component(uint32_t *swizzle, unsigned int idx, unsigned int component) -+{ -+ *swizzle &= ~(VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(idx)); -+ *swizzle |= component << VKD3D_SHADER_SWIZZLE_SHIFT(idx); -+} -+ - static inline unsigned int vkd3d_compact_swizzle(uint32_t swizzle, uint32_t write_mask) - { - unsigned int i, compacted_swizzle = 0; diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -index f2b18b665f8..c41f8bae806 100644 +index f2967835b62..f804c1f0c24 100644 --- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c @@ -19,6 +19,8 @@ @@ -28143,355 +97,6 @@ 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 -+++ b/libs/vkd3d/libs/vkd3d/resource.c -@@ -310,6 +310,9 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface) - struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); - unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount); - -+ if (refcount == 1) -+ vkd3d_atomic_increment_u32(&heap->internal_refcount); -+ - TRACE("%p increasing refcount to %u.\n", heap, refcount); - - VKD3D_ASSERT(!heap->is_private); -@@ -342,6 +345,12 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap) - d3d12_device_release(device); - } - -+static void d3d12_heap_decref(struct d3d12_heap *heap) -+{ -+ if (!vkd3d_atomic_decrement_u32(&heap->internal_refcount)) -+ d3d12_heap_destroy(heap); -+} -+ - static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) - { - struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); -@@ -350,18 +359,12 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) - TRACE("%p decreasing refcount to %u.\n", heap, refcount); - - /* A heap must not be destroyed until all contained resources are destroyed. */ -- if (!refcount && !heap->resource_count) -- d3d12_heap_destroy(heap); -+ if (!refcount) -+ d3d12_heap_decref(heap); - - return refcount; - } - --static void d3d12_heap_resource_destroyed(struct d3d12_heap *heap) --{ -- if (!vkd3d_atomic_decrement_u32(&heap->resource_count) && (!heap->refcount || heap->is_private)) -- d3d12_heap_destroy(heap); --} -- - static HRESULT STDMETHODCALLTYPE d3d12_heap_GetPrivateData(ID3D12Heap *iface, - REFGUID guid, UINT *data_size, void *data) - { -@@ -487,7 +490,7 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, - - heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl; - heap->refcount = 1; -- heap->resource_count = 0; -+ heap->internal_refcount = 1; - - heap->is_private = !!resource; - -@@ -555,8 +558,6 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, - heap->device = device; - if (!heap->is_private) - d3d12_device_add_ref(heap->device); -- else -- heap->resource_count = 1; - - if (d3d12_heap_get_memory_property_flags(heap) & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - { -@@ -998,7 +999,7 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12 - d3d12_resource_tile_info_cleanup(resource); - - if (resource->heap) -- d3d12_heap_resource_destroyed(resource->heap); -+ d3d12_heap_decref(resource->heap); - } - - static ULONG d3d12_resource_incref(struct d3d12_resource *resource) -@@ -2200,7 +2201,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device, - { - resource->heap = heap; - resource->heap_offset = heap_offset; -- vkd3d_atomic_increment_u32(&heap->resource_count); -+ vkd3d_atomic_increment_u32(&heap->internal_refcount); - } - else - { -@@ -2491,20 +2492,41 @@ static void descriptor_writes_free_object_refs(struct descriptor_writes *writes, - writes->held_ref_count = 0; - } - -+static enum vkd3d_vk_descriptor_set_index vkd3d_vk_descriptor_set_index_from_vk_descriptor_type( -+ VkDescriptorType type) -+{ -+ static const enum vkd3d_vk_descriptor_set_index table[] = -+ { -+ [VK_DESCRIPTOR_TYPE_SAMPLER] = VKD3D_SET_INDEX_SAMPLER, -+ [VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER] = VKD3D_SET_INDEX_COUNT, -+ [VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE] = VKD3D_SET_INDEX_SAMPLED_IMAGE, -+ [VK_DESCRIPTOR_TYPE_STORAGE_IMAGE] = VKD3D_SET_INDEX_STORAGE_IMAGE, -+ [VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER] = VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER, -+ [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER] = VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER, -+ [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER] = VKD3D_SET_INDEX_UNIFORM_BUFFER, -+ }; -+ -+ VKD3D_ASSERT(type < ARRAY_SIZE(table)); -+ VKD3D_ASSERT(table[type] < VKD3D_SET_INDEX_COUNT); -+ -+ return table[type]; -+} -+ - static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_heap *descriptor_heap, -- uint32_t dst_array_element, struct descriptor_writes *writes, struct d3d12_device *device) -+ uint32_t dst_array_element, struct descriptor_writes *writes, struct d3d12_device *device, -+ VkDescriptorType type) - { - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - struct d3d12_descriptor_heap_vk_set *descriptor_set; -- enum vkd3d_vk_descriptor_set_index set, end; -+ enum vkd3d_vk_descriptor_set_index set; - unsigned int i = writes->count; - -- end = device->vk_info.EXT_mutable_descriptor_type ? VKD3D_SET_INDEX_MUTABLE -- : VKD3D_SET_INDEX_STORAGE_IMAGE; - /* Binding a shader with the wrong null descriptor type works in Windows. - * To support that here we must write one to all applicable Vulkan sets. */ -- for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= end; ++set) -+ for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= VKD3D_SET_INDEX_STORAGE_IMAGE; ++set) - { -+ if (device->vk_info.EXT_mutable_descriptor_type) -+ set = vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(type); - descriptor_set = &descriptor_heap->vk_descriptor_sets[set]; - writes->vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writes->vk_descriptor_writes[i].pNext = NULL; -@@ -2545,6 +2567,8 @@ static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_hea - VK_CALL(vkUpdateDescriptorSets(device->vk_device, i, writes->vk_descriptor_writes, 0, NULL)); - descriptor_writes_free_object_refs(writes, device); - i = 0; -+ if (device->vk_info.EXT_mutable_descriptor_type) -+ break; - } - - writes->count = i; -@@ -2609,7 +2633,7 @@ static void d3d12_desc_write_vk_heap(struct d3d12_descriptor_heap *descriptor_he - break; - } - if (is_null && device->vk_info.EXT_robustness2) -- return d3d12_desc_write_vk_heap_null_descriptor(descriptor_heap, dst_array_element, writes, device); -+ return d3d12_desc_write_vk_heap_null_descriptor(descriptor_heap, dst_array_element, writes, device, type); - - ++i; - if (u.header->magic == VKD3D_DESCRIPTOR_MAGIC_UAV && u.view->v.vk_counter_view) -@@ -4223,17 +4247,6 @@ static const struct ID3D12DescriptorHeapVtbl d3d12_descriptor_heap_vtbl = - d3d12_descriptor_heap_GetGPUDescriptorHandleForHeapStart, - }; - --const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[] = --{ -- VKD3D_SET_INDEX_SAMPLER, -- VKD3D_SET_INDEX_COUNT, -- VKD3D_SET_INDEX_SAMPLED_IMAGE, -- VKD3D_SET_INDEX_STORAGE_IMAGE, -- VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER, -- VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER, -- VKD3D_SET_INDEX_UNIFORM_BUFFER, --}; -- - static HRESULT d3d12_descriptor_heap_create_descriptor_pool(struct d3d12_descriptor_heap *descriptor_heap, - 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..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, - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - struct vkd3d_shader_compile_info compile_info; - struct VkShaderModuleCreateInfo shader_desc; -+ struct vkd3d_shader_dxbc_desc dxbc_desc; - struct vkd3d_shader_code spirv = {0}; -+ char source_name[33]; - VkResult vr; - int ret; - -@@ -2416,6 +2418,16 @@ static HRESULT create_shader_stage(struct d3d12_device *device, - compile_info.log_level = VKD3D_SHADER_LOG_NONE; - compile_info.source_name = NULL; - -+ if ((ret = vkd3d_shader_parse_dxbc(&(struct vkd3d_shader_code){code->pShaderBytecode, code->BytecodeLength}, -+ 0, &dxbc_desc, NULL)) >= 0) -+ { -+ sprintf(source_name, "%08x%08x%08x%08x", dxbc_desc.checksum[0], -+ dxbc_desc.checksum[1], dxbc_desc.checksum[2], dxbc_desc.checksum[3]); -+ vkd3d_shader_free_dxbc(&dxbc_desc); -+ TRACE("Compiling shader \"%s\".\n", source_name); -+ compile_info.source_name = source_name; -+ } -+ - 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 -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -@@ -436,7 +436,7 @@ struct d3d12_heap - { - ID3D12Heap ID3D12Heap_iface; - unsigned int refcount; -- unsigned int resource_count; -+ unsigned int internal_refcount; - - bool is_private; - D3D12_HEAP_DESC desc; -@@ -827,17 +827,6 @@ enum vkd3d_vk_descriptor_set_index - VKD3D_SET_INDEX_COUNT - }; - --extern const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[]; -- --static inline enum vkd3d_vk_descriptor_set_index vkd3d_vk_descriptor_set_index_from_vk_descriptor_type( -- VkDescriptorType type) --{ -- VKD3D_ASSERT(type <= VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); -- VKD3D_ASSERT(vk_descriptor_set_index_table[type] < VKD3D_SET_INDEX_COUNT); -- -- return vk_descriptor_set_index_table[type]; --} -- - struct vkd3d_vk_descriptor_heap_layout - { - VkDescriptorType type; -- 2.50.1 diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch index c4522449..2ec8c690 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch @@ -1,14 +1,12 @@ -From 9385c0987fde1070c8e9e1054c57fa16eeab2c7d Mon Sep 17 00:00:00 2001 +From b2165faef0a403a805b21efd42f8769a1769b78a 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/include/vkd3d_shader.h | 23 ++ 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 + @@ -17,39 +15,16 @@ Subject: [PATCH] Updated vkd3d to 3b41d99fa9e80dda5844738a226f70f14f778c8b. .../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(-) + 14 files changed, 630 insertions(+), 258 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 +index d82869e79ea..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 +@@ -120,6 +120,11 @@ enum vkd3d_shader_structure_type * \since 1.15 */ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_HULL_SHADER_TESSELLATION_INFO, @@ -61,7 +36,7 @@ index 0fd3c67b7e0..a1f85dbbd05 100644 VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), }; -@@ -2281,6 +2287,24 @@ struct vkd3d_shader_scan_hull_shader_tessellation_info +@@ -2282,6 +2287,24 @@ struct vkd3d_shader_scan_hull_shader_tessellation_info enum vkd3d_shader_tessellator_partitioning partitioning; }; @@ -546,19 +521,6 @@ index c448e000cf9..6a12dec14bf 100644 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 @@ -1706,19 +1668,6 @@ index c6e048adb20..88d1160d4e8 100644 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 @@ -1975,68 +1924,6 @@ index e758c16b3d4..b63c5785770 100644 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/0003-Updated-vkd3d-to-d0098b0d5968d1969ec622b91fd360fd0ae.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-d0098b0d5968d1969ec622b91fd360fd0ae.patch new file mode 100644 index 00000000..acfe026d --- /dev/null +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-d0098b0d5968d1969ec622b91fd360fd0ae.patch @@ -0,0 +1,133 @@ +From 5881c4d692d2522ed93d5e39362eda5f0c8e647f Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 23 Aug 2025 07:27:59 +1000 +Subject: [PATCH] Updated vkd3d to d0098b0d5968d1969ec622b91fd360fd0aec2328. + +--- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 9 +-------- + libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 +- + libs/vkd3d/libs/vkd3d-shader/preproc.l | 12 ++---------- + libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c | 7 ++++++- + libs/vkd3d/libs/vkd3d/utils.c | 3 ++- + 5 files changed, 12 insertions(+), 21 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index 5988e7b3a30..acc30b998f6 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -2329,7 +2329,6 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc + struct vkd3d_string_buffer *buffer = gen->buffer; + 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"); + +@@ -2358,13 +2357,7 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc + if (gen->failed) + return VKD3D_ERROR_INVALID_SHADER; + +- if ((code = vkd3d_malloc(buffer->buffer_size))) +- { +- memcpy(code, buffer->buffer, buffer->content_size); +- out->size = buffer->content_size; +- out->code = code; +- } +- else return VKD3D_ERROR_OUT_OF_MEMORY; ++ vkd3d_shader_code_from_string_buffer(out, buffer); + + return VKD3D_OK; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +index 0cdebb8a657..da9f0d39136 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +@@ -346,7 +346,7 @@ while {return KW_WHILE; } + {ANY} {} + + {ANY} { +- return yytext[0]; ++ return (unsigned char)yytext[0]; + } + + %% +diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l +index 5c56fba0229..f9b1d67ac36 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/preproc.l ++++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l +@@ -824,7 +824,6 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, + static const struct vkd3d_shader_preprocess_info default_preprocess_info = {0}; + struct preproc_ctx ctx = {0}; + char *source_name = NULL; +- void *output_code; + unsigned int i; + + vkd3d_string_buffer_init(&ctx.buffer); +@@ -901,16 +900,9 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, + return VKD3D_ERROR_INVALID_SHADER; + } + +- if (!(output_code = vkd3d_malloc(ctx.buffer.content_size))) +- { +- vkd3d_string_buffer_cleanup(&ctx.buffer); +- return VKD3D_ERROR_OUT_OF_MEMORY; +- } +- memcpy(output_code, ctx.buffer.buffer, ctx.buffer.content_size); +- out->size = ctx.buffer.content_size; +- out->code = output_code; + vkd3d_string_buffer_trace(&ctx.buffer); +- vkd3d_string_buffer_cleanup(&ctx.buffer); ++ ++ vkd3d_shader_code_from_string_buffer(out, &ctx.buffer); + return VKD3D_OK; + + fail: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 75b7f9aa769..08450b4cf85 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -2266,6 +2266,7 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info + struct vkd3d_shader_code *out, char **messages) + { + struct vkd3d_shader_message_context message_context; ++ struct shader_dump_data dump_data; + int ret; + + TRACE("compile_info %p, out %p, messages %p.\n", compile_info, out, messages); +@@ -2278,7 +2279,11 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info + + vkd3d_shader_message_context_init(&message_context, compile_info->log_level); + +- ret = preproc_lexer_parse(compile_info, out, &message_context); ++ 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 ((ret = preproc_lexer_parse(compile_info, out, &message_context)) >= 0) ++ vkd3d_shader_dump_shader(&dump_data, out->code, out->size, SHADER_DUMP_TYPE_PREPROC); + + vkd3d_shader_message_context_trace_messages(&message_context); + if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) +diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c +index c2832a61f67..2d0510e5456 100644 +--- a/libs/vkd3d/libs/vkd3d/utils.c ++++ b/libs/vkd3d/libs/vkd3d/utils.c +@@ -703,7 +703,7 @@ const char *debug_vk_extent_3d(VkExtent3D extent) + + const char *debug_vk_queue_flags(VkQueueFlags flags) + { +- char buffer[191]; ++ char buffer[222]; + + buffer[0] = '\0'; + #define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; } +@@ -716,6 +716,7 @@ const char *debug_vk_queue_flags(VkQueueFlags flags) + #define FLAG_TO_STR(f, n) if (flags & f) { strcat(buffer, " | "#n); flags &= ~f; } + FLAG_TO_STR(0x20, VK_QUEUE_VIDEO_DECODE_BIT_KHR) + FLAG_TO_STR(0x40, VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ++ FLAG_TO_STR(0x100, VK_QUEUE_OPTICAL_FLOW_BIT_NV) + #undef FLAG_TO_STR + if (flags) + FIXME("Unrecognized flag(s) %#x.\n", flags); +-- +2.50.1 + diff --git a/staging/upstream-commit b/staging/upstream-commit index 656e456a..4eafd165 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -288a40d05c8cddf62d0b12524a90d2d4f5ce114d +7dcdd7a6549793e8a6469816a5c25226e2d73e9c