diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-39391230d27d58f4e7e8786ba32a0ca133b.patch similarity index 59% rename from patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch rename to patches/vkd3d-latest/0001-Updated-vkd3d-to-39391230d27d58f4e7e8786ba32a0ca133b.patch index a95bbe37..2c458a5d 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-39391230d27d58f4e7e8786ba32a0ca133b.patch @@ -1,55 +1,60 @@ -From cbe5d8ece42a672f12b79eccf708428eddfcdcb4 Mon Sep 17 00:00:00 2001 +From 9aac32c0e09bb62200f552d7971b932f12ef8f4c 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 e69f3da089d472b723b016ef67c04c0f954fa792. +Subject: [PATCH] Updated vkd3d to 39391230d27d58f4e7e8786ba32a0ca133b28fc0. --- - dlls/msado15/tests/msado15.c | 2 +- - libs/vkd3d/include/private/spirv_grammar.h | 561 +--- + libs/vkd3d/Makefile.in | 4 +- + libs/vkd3d/include/private/spirv_grammar.h | 561 +-- libs/vkd3d/include/private/vkd3d_common.h | 22 +- libs/vkd3d/include/private/vkd3d_version.h | 2 +- - libs/vkd3d/include/vkd3d_shader.h | 38 +- + libs/vkd3d/include/vkd3d_shader.h | 176 +- libs/vkd3d/libs/vkd3d-common/blob.c | 1 + - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 64 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 43 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 690 ++--- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 69 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 199 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 1047 +++-- libs/vkd3d/libs/vkd3d-shader/fx.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 74 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 82 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 22 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 161 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 936 +++++-- - .../libs/vkd3d-shader/hlsl_constant_ops.c | 349 ++- - libs/vkd3d/libs/vkd3d-shader/ir.c | 2320 +++++++++++------ - libs/vkd3d/libs/vkd3d-shader/msl.c | 170 +- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 172 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 92 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 38 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.l | 3 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 254 +- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1834 +++++--- + .../libs/vkd3d-shader/hlsl_constant_ops.c | 405 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 3942 ++++++++++++----- + libs/vkd3d/libs/vkd3d-shader/msl.c | 468 +- libs/vkd3d/libs/vkd3d-shader/preproc.l | 13 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 775 +++--- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 57 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 250 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 174 +- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 1335 +++--- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 71 +- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 331 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 207 +- .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 17 +- libs/vkd3d/libs/vkd3d/command.c | 92 +- libs/vkd3d/libs/vkd3d/device.c | 24 +- - libs/vkd3d/libs/vkd3d/state.c | 6 +- + libs/vkd3d/libs/vkd3d/state.c | 8 +- libs/vkd3d/libs/vkd3d/utils.c | 3 +- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 5 +- - 30 files changed, 4257 insertions(+), 2700 deletions(-) + 30 files changed, 7033 insertions(+), 4364 deletions(-) -diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c -index d81ab7da6cf..6529571a60e 100644 ---- a/dlls/msado15/tests/msado15.c -+++ b/dlls/msado15/tests/msado15.c -@@ -2046,8 +2046,8 @@ START_TEST(msado15) - setup_database(); +diff --git a/libs/vkd3d/Makefile.in b/libs/vkd3d/Makefile.in +index 9ad9ed850b6..868f4582380 100644 +--- a/libs/vkd3d/Makefile.in ++++ b/libs/vkd3d/Makefile.in +@@ -7,7 +7,6 @@ EXTRADEFS = \ + -DLIBVKD3D_UTILS_SOURCE - test_Connection(); -- test_Connection_Open(); - test_ConnectionPoint(); -+ test_Connection_Open(); - test_ADORecordsetConstruction(FALSE); - test_ADORecordsetConstruction(TRUE); - test_Fields(); + SOURCES = \ +- config.h \ + libs/vkd3d-common/blob.c \ + libs/vkd3d-common/debug.c \ + libs/vkd3d-common/error.c \ +@@ -40,4 +39,5 @@ SOURCES = \ + libs/vkd3d/resource.c \ + libs/vkd3d/state.c \ + libs/vkd3d/utils.c \ +- libs/vkd3d/vkd3d_main.c ++ libs/vkd3d/vkd3d_main.c \ ++ config.h diff --git a/libs/vkd3d/include/private/spirv_grammar.h b/libs/vkd3d/include/private/spirv_grammar.h index 34cadd9bd58..2aac5a6558c 100644 --- a/libs/vkd3d/include/private/spirv_grammar.h @@ -1089,10 +1094,10 @@ index 0edc4428022..687751d6a5f 100644 -#define VKD3D_VCS_ID " (Wine bundled)" +#define VKD3D_VCS_ID " (git a8ca1f95)" diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index d82869e79ea..3a2f54c8f22 100644 +index d82869e79ea..50bcf6b292b 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -120,6 +120,11 @@ enum vkd3d_shader_structure_type +@@ -120,6 +120,16 @@ enum vkd3d_shader_structure_type * \since 1.15 */ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_HULL_SHADER_TESSELLATION_INFO, @@ -1101,10 +1106,15 @@ index d82869e79ea..3a2f54c8f22 100644 + * \since 1.18 + */ + VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO, ++ /** ++ * The structure is a vkd3d_shader_d3dbc_source_info structure. ++ * \since 1.18 ++ */ ++ VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), }; -@@ -417,10 +422,17 @@ struct vkd3d_shader_code +@@ -417,10 +427,17 @@ struct vkd3d_shader_code { /** * Pointer to the code. Note that textual formats are not null-terminated. @@ -1126,7 +1136,91 @@ index d82869e79ea..3a2f54c8f22 100644 */ const void *code; /** Size of \a code, in bytes. */ -@@ -2282,6 +2294,24 @@ struct vkd3d_shader_scan_hull_shader_tessellation_info +@@ -944,6 +961,83 @@ enum vkd3d_shader_parameter_name + * \since 1.15 + */ + VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE, ++ /** ++ * Bump-mapping matrix. This parameter is used in the evaluation of the ++ * Shader Model 1.x instructions BEM, TEXBEM, and TEXBEML. ++ * ++ * This parameter specifies a 2x2 matrix, packed into a vector in the order ++ * [00, 01, 10, 11], where "01" specifies the component at column 0 and row ++ * 1. These coordinates correspond to the Direct3D notation. ++ * ++ * To use this parameter to implement Direct3D bump mapping, pass the values ++ * of the texture stage states D3DTSS_BUMPENVMAT00, D3DTSS_BUMPENVMAT01, ++ * D3DTSS_BUMPENVMAT10, and D3DTSS_BUMPENVMAT11, in that order. ++ * ++ * These enum values are contiguous and arithmetic may safely be performed ++ * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_[n] is ++ * VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 plus n. ++ * ++ * The data type for each parameter must be ++ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4. ++ * ++ * The default value for each parameter is the zero matrix [0, 0; 0, 0]. ++ * ++ * \since 1.18 ++ */ ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_1, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_2, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_3, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_4, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_5, ++ /** ++ * Bump-mapping luminance scale factor. This parameter is used in the ++ * evaluation of the Shader Model 1.x instruction TEXBEML. ++ * ++ * To use this parameter to implement Direct3D bump mapping, pass the value ++ * of the texture stage state D3DTSS_BUMPENVLSCALE. ++ * ++ * These enum values are contiguous and arithmetic may safely be performed ++ * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_[n] is ++ * VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0 plus n. ++ * ++ * The data type for each parameter must be ++ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32. ++ * ++ * The default value for each parameter is 0.0. ++ * ++ * \since 1.18 ++ */ ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_1, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_2, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_3, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_4, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_5, ++ /** ++ * Bump-mapping luminance offset. This parameter is used in the ++ * evaluation of the Shader Model 1.x instruction TEXBEML. ++ * ++ * To use this parameter to implement Direct3D bump mapping, pass the value ++ * of the texture stage state D3DTSS_BUMPENVLOFFSET. ++ * ++ * These enum values are contiguous and arithmetic may safely be performed ++ * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_[n] is ++ * VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0 plus n. ++ * ++ * The data type for each parameter must be ++ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32. ++ * ++ * The default value for each parameter is 0.0. ++ * ++ * \since 1.18 ++ */ ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_1, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_2, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_3, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_4, ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_5, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME), + }; +@@ -2282,6 +2376,79 @@ struct vkd3d_shader_scan_hull_shader_tessellation_info enum vkd3d_shader_tessellator_partitioning partitioning; }; @@ -1147,10 +1241,73 @@ index d82869e79ea..3a2f54c8f22 100644 + /** The thread group size in the x/y/z direction. */ + unsigned int x, y, z; +}; ++ ++/** ++ * A chained structure containing legacy Direct3D bytecode compilation parameters. ++ * This structure specifies some information about the source environment that ++ * is not specified in the source shader format, but may be necessary for the ++ * target format. ++ * ++ * This structure is optional. ++ * ++ * This structure extends vkd3d_shader_compile_info. ++ * ++ * This structure contains only input parameters. ++ * ++ * \since 1.18 ++ */ ++struct vkd3d_shader_d3dbc_source_info ++{ ++ /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO. */ ++ enum vkd3d_shader_structure_type type; ++ /** Optional pointer to a structure containing further parameters. */ ++ const void *next; ++ ++ /** ++ * The dimension of each texture bound to the shader. ++ * ++ * If this structure is not specified, the dimension for all textures will ++ * be VKD3D_SHADER_RESOURCE_TEXTURE_2D. ++ * ++ * The dimension of textures in this array not used by the shader will be ++ * ignored. ++ * ++ * This field is ignored for shader models 2 and higher. ++ */ ++ enum vkd3d_shader_resource_type texture_dimensions[6]; ++ ++ /** ++ * A mask indicating which samplers should be shadow (i.e. comparison-mode) ++ * samplers. When legacy Direct3D shaders are used with the Direct3D 8 and 9 ++ * APIs, this is implied by the format of the sampled resource; e.g. a ++ * D3DFMT_D24S8 texture implies shadow sampling, while a D3DFMT_A8R8G8B8 ++ * or D3DFMT_INTZ texture does not. ++ * This information is necessary when converting to other formats ++ * (e.g. SPIR-V, GLSL) which specify this in the shader. ++ * ++ * For example, if bit 1 is set (so the value is 0x2), this indicates that ++ * the sampler at bind point 1 (and no others) should be a shadow sampler. ++ * ++ * Bits in this mask corresponding to textures not used by the shader will ++ * be ignored. ++ * ++ * If this structure is not specified, no samplers will be considered to ++ * be shadow samplers. ++ */ ++ uint32_t shadow_samplers; ++}; + /** * Data type of a shader varying, returned as part of struct * vkd3d_shader_signature_element. +@@ -2775,6 +2942,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported + * + * Depending on the source and target types, this function may support the + * following chained structures: ++ * - vkd3d_shader_d3dbc_source_info + * - vkd3d_shader_descriptor_offset_info + * - vkd3d_shader_hlsl_source_info + * - vkd3d_shader_interface_info 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 @@ -1164,10 +1321,22 @@ index f60ef7db769..c2c6ad67804 100644 #include "vkd3d.h" #include "vkd3d_blob.h" diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 6425a8f62d2..6f8fbe84b90 100644 +index 6425a8f62d2..4573cb67fb5 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -390,27 +390,10 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, +@@ -145,11 +145,6 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, en + + static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t atomic_flags) + { +- if (atomic_flags & VKD3DARF_SEQ_CST) +- { +- vkd3d_string_buffer_printf(&compiler->buffer, "_seqCst"); +- atomic_flags &= ~VKD3DARF_SEQ_CST; +- } + if (atomic_flags & VKD3DARF_VOLATILE) + { + vkd3d_string_buffer_printf(&compiler->buffer, "_volatile"); +@@ -390,27 +385,10 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_data_type type) { @@ -1198,7 +1367,7 @@ index 6425a8f62d2..6f8fbe84b90 100644 else vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", compiler->colours.error, type, compiler->colours.reset); -@@ -610,6 +593,18 @@ static void shader_print_uint_literal(struct vkd3d_d3d_asm_compiler *compiler, +@@ -610,6 +588,18 @@ static void shader_print_uint_literal(struct vkd3d_d3d_asm_compiler *compiler, prefix, compiler->colours.literal, i, compiler->colours.reset, suffix); } @@ -1217,7 +1386,7 @@ index 6425a8f62d2..6f8fbe84b90 100644 static void shader_print_uint64_literal(struct vkd3d_d3d_asm_compiler *compiler, const char *prefix, uint64_t i, const char *suffix) { -@@ -810,6 +805,12 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -810,6 +800,12 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const if (reg->dimension == VSIR_DIMENSION_VEC4) shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], ""); } @@ -1230,7 +1399,7 @@ index 6425a8f62d2..6f8fbe84b90 100644 else if (reg->data_type == VSIR_DATA_U64) { shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[0], ""); -@@ -851,7 +852,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -851,7 +847,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const && reg->type != VKD3DSPR_NULL && reg->type != VKD3DSPR_DEPTHOUT) { @@ -1239,7 +1408,7 @@ index 6425a8f62d2..6f8fbe84b90 100644 { bool is_sm_5_1 = vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1); -@@ -879,10 +880,10 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -879,10 +875,10 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const /* For descriptors in sm < 5.1 we move the reg->idx values up one slot * to normalise with 5.1. * Here we should ignore it if it's a descriptor in sm < 5.1. */ @@ -1252,7 +1421,7 @@ index 6425a8f62d2..6f8fbe84b90 100644 shader_print_subscript(compiler, reg->idx[2].offset, reg->idx[2].rel_addr); } } -@@ -974,6 +975,22 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, +@@ -974,6 +970,22 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, vkd3d_string_buffer_printf(buffer, ">%s", suffix); } @@ -1275,7 +1444,7 @@ index 6425a8f62d2..6f8fbe84b90 100644 static void shader_print_write_mask(struct vkd3d_d3d_asm_compiler *compiler, const char *prefix, uint32_t mask, const char *suffix) { -@@ -1528,6 +1545,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1528,6 +1540,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, 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); @@ -1284,18 +1453,22 @@ index 6425a8f62d2..6f8fbe84b90 100644 if (ins->declaration.indexable_temp.alignment) shader_print_uint_literal(compiler, ", align ", ins->declaration.indexable_temp.alignment, ""); diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 751e5578276..fbf9de20278 100644 +index 751e5578276..87a7d48acca 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -246,6 +246,7 @@ struct vkd3d_shader_sm1_parser +@@ -246,6 +246,11 @@ struct vkd3d_shader_sm1_parser bool abort; struct vkd3d_shader_parser p; + struct vsir_program *program; ++ ++ const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info; ++ ++ uint16_t texture_descriptors; struct { -@@ -468,7 +469,7 @@ static bool has_relative_address(uint32_t param) +@@ -468,7 +473,7 @@ static bool has_relative_address(uint32_t param) static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info( const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode) { @@ -1304,7 +1477,7 @@ index 751e5578276..fbf9de20278 100644 const struct vkd3d_sm1_opcode_info *info; unsigned int i = 0; -@@ -542,9 +543,9 @@ static enum vkd3d_shader_register_type parse_register_type( +@@ -542,9 +547,9 @@ static enum vkd3d_shader_register_type parse_register_type( } if (d3dbc_type == VKD3D_SM1_REG_ADDR) @@ -1316,16 +1489,29 @@ index 751e5578276..fbf9de20278 100644 for (unsigned int i = 0; i < ARRAY_SIZE(register_types); ++i) { -@@ -660,7 +661,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp +@@ -658,9 +663,9 @@ static unsigned int make_mask_contiguous(unsigned int mask) + + static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool output, const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval, - unsigned int register_index, bool is_dcl, unsigned int mask) +- unsigned int register_index, bool is_dcl, unsigned int mask) ++ unsigned int register_index, bool is_dcl, unsigned int mask, uint32_t dst_modifiers) { - struct vsir_program *program = sm1->p.program; + struct vsir_program *program = sm1->program; struct shader_signature *signature; struct signature_element *element; -@@ -702,7 +703,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp +@@ -694,7 +699,8 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp + element->mask = make_mask_contiguous(mask); + element->used_mask = is_dcl ? 0 : mask; + if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) +- element->interpolation_mode = VKD3DSIM_LINEAR; ++ element->interpolation_mode = (dst_modifiers & VKD3DSPDM_MSAMPCENTROID) ++ ? VKD3DSIM_LINEAR_CENTROID : VKD3DSIM_LINEAR; + + return true; + } +@@ -702,7 +708,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, unsigned int register_index, unsigned int mask) { @@ -1334,16 +1520,101 @@ index 751e5578276..fbf9de20278 100644 struct shader_signature *signature; struct signature_element *element; -@@ -749,7 +750,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, +@@ -747,16 +753,17 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, + } + static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1, - const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) +- const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) ++ const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask, uint32_t dst_modifiers) { - const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; + const struct vkd3d_shader_version *version = &sm1->program->shader_version; unsigned int register_index = reg->idx_count > 0 ? reg->idx[0].offset : 0; switch (reg->type) -@@ -844,7 +845,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * + { + case VKD3DSPR_TEMP: + if (version->type == VKD3D_SHADER_TYPE_PIXEL && version->major == 1 && !register_index) +- return add_signature_element(sm1, true, "COLOR", 0, VKD3D_SHADER_SV_TARGET, 0, is_dcl, mask); ++ return add_signature_element(sm1, true, "COLOR", 0, VKD3D_SHADER_SV_TARGET, ++ 0, is_dcl, mask, dst_modifiers); + return true; + + case VKD3DSPR_INPUT: +@@ -768,15 +775,15 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * + return true; + } + return add_signature_element(sm1, false, "COLOR", register_index, +- VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask); ++ VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask, dst_modifiers); + + case VKD3DSPR_TEXTURE: + return add_signature_element(sm1, false, "TEXCOORD", register_index, +- VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask); ++ VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask, dst_modifiers); + + case VKD3DSPR_TEXCRDOUT: + return add_signature_element(sm1, true, "TEXCOORD", register_index, +- VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask); ++ VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask, dst_modifiers); + + case VKD3DSPR_OUTPUT: + if (version->type == VKD3D_SHADER_TYPE_VERTEX) +@@ -788,30 +795,30 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * + + case VKD3DSPR_ATTROUT: + return add_signature_element(sm1, true, "COLOR", register_index, +- VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask); ++ VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask, dst_modifiers); + + case VKD3DSPR_COLOROUT: + return add_signature_element(sm1, true, "COLOR", register_index, +- VKD3D_SHADER_SV_TARGET, register_index, is_dcl, mask); ++ VKD3D_SHADER_SV_TARGET, register_index, is_dcl, mask, dst_modifiers); + + case VKD3DSPR_DEPTHOUT: + return add_signature_element(sm1, true, "DEPTH", 0, +- VKD3D_SHADER_SV_DEPTH, register_index, is_dcl, 0x1); ++ VKD3D_SHADER_SV_DEPTH, register_index, is_dcl, 0x1, dst_modifiers); + + case VKD3DSPR_RASTOUT: + switch (register_index) + { + case 0: +- return add_signature_element(sm1, true, "POSITION", 0, +- VKD3D_SHADER_SV_POSITION, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, mask); ++ return add_signature_element(sm1, true, "POSITION", 0, VKD3D_SHADER_SV_POSITION, ++ SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, mask, dst_modifiers); + + case 1: +- return add_signature_element(sm1, true, "FOG", 0, +- VKD3D_SHADER_SV_NONE, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1); ++ return add_signature_element(sm1, true, "FOG", 0, VKD3D_SHADER_SV_NONE, ++ SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1, dst_modifiers); + + case 2: +- return add_signature_element(sm1, true, "PSIZE", 0, +- VKD3D_SHADER_SV_NONE, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1); ++ return add_signature_element(sm1, true, "PSIZE", 0, VKD3D_SHADER_SV_NONE, ++ SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1, dst_modifiers); + + default: + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX, +@@ -824,11 +831,11 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * + { + case 0: + return add_signature_element(sm1, false, "VPOS", 0, +- VKD3D_SHADER_SV_POSITION, register_index, is_dcl, mask); ++ VKD3D_SHADER_SV_POSITION, register_index, is_dcl, mask, dst_modifiers); + + case 1: + return add_signature_element(sm1, false, "VFACE", 0, +- VKD3D_SHADER_SV_IS_FRONT_FACE, register_index, is_dcl, 0x1); ++ VKD3D_SHADER_SV_IS_FRONT_FACE, register_index, is_dcl, 0x1, dst_modifiers); + + default: + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX, +@@ -844,10 +851,11 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_semantic *semantic) { @@ -1352,7 +1623,36 @@ index 751e5578276..fbf9de20278 100644 const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg; enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; unsigned int mask = semantic->resource.reg.write_mask; -@@ -906,7 +907,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, ++ uint32_t modifiers = semantic->resource.reg.modifiers; + bool output; + + static const char sm1_semantic_names[][13] = +@@ -873,11 +881,11 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser * + else if (reg->type == VKD3DSPR_INPUT || reg->type == VKD3DSPR_TEXTURE) + output = false; + else /* vpos and vface don't have a semantic. */ +- return add_signature_element_from_register(sm1, reg, true, mask); ++ return add_signature_element_from_register(sm1, reg, true, mask, modifiers); + + /* sm2 pixel shaders use DCL but don't provide a semantic. */ + if (version->type == VKD3D_SHADER_TYPE_PIXEL && version->major == 2) +- return add_signature_element_from_register(sm1, reg, true, mask); ++ return add_signature_element_from_register(sm1, reg, true, mask, modifiers); + + /* With the exception of vertex POSITION output, none of these are system + * values. Pixel POSITION input is not equivalent to SV_Position; the closer +@@ -886,8 +894,8 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser * + && output && semantic->usage == VKD3D_DECL_USAGE_POSITION) + sysval = VKD3D_SHADER_SV_POSITION; + +- return add_signature_element(sm1, output, sm1_semantic_names[semantic->usage], +- semantic->usage_idx, sysval, reg->idx[0].offset, true, mask); ++ return add_signature_element(sm1, output, sm1_semantic_names[semantic->usage], semantic->usage_idx, sysval, ++ reg->idx[0].offset, true, mask, modifiers); + } + + static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, +@@ -906,7 +914,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def) { @@ -1361,7 +1661,37 @@ index 751e5578276..fbf9de20278 100644 uint32_t register_index = reg->idx[0].offset; switch (reg->type) -@@ -955,7 +956,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, +@@ -931,7 +939,28 @@ static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, + break; + } + +- add_signature_element_from_register(sm1, reg, false, mask); ++ add_signature_element_from_register(sm1, reg, false, mask, 0); ++} ++ ++static void d3dbc_add_combined_sampler_descriptor(struct vkd3d_shader_sm1_parser *d3dbc, ++ unsigned int sampler_idx, enum vkd3d_shader_resource_type resource_type) ++{ ++ struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; ++ const struct vkd3d_shader_d3dbc_source_info *source_info = d3dbc->d3dbc_source_info; ++ struct vsir_program *program = d3dbc->program; ++ struct vkd3d_shader_descriptor_info1 *d; ++ ++ if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, ++ sampler_idx, &range, resource_type, VSIR_DATA_F32)) ++ vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, ++ "Failed to create SRV descriptor for combined sampler %u.", sampler_idx); ++ ++ if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, ++ sampler_idx, &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) ++ vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, ++ "Failed to create sampler descriptor for combined sampler %u.", sampler_idx); ++ else if (source_info && source_info->shadow_samplers & (1u << sampler_idx)) ++ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; + } + + /* Read a parameter token from the input stream, and possibly a relative +@@ -955,7 +984,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, * VS >= 2.0 have relative addressing (with token) * VS >= 1.0 < 2.0 have relative addressing (without token) * The version check below should work in general. */ @@ -1370,7 +1700,7 @@ index 751e5578276..fbf9de20278 100644 { *addr_token = (1u << 31) | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2) -@@ -984,7 +985,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co +@@ -984,7 +1013,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co /* Version 2.0+ shaders may contain address tokens, but fortunately they * have a useful length mask - use it here. Version 1.x shaders contain no * such tokens. */ @@ -1379,7 +1709,7 @@ index 751e5578276..fbf9de20278 100644 { length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; *ptr += length; -@@ -1019,7 +1020,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const +@@ -1019,7 +1048,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const shader_sm1_read_param(sm1, ptr, &token, &addr_token); if (has_relative_address(token)) { @@ -1388,7 +1718,7 @@ index 751e5578276..fbf9de20278 100644 { vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); -@@ -1040,7 +1041,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const +@@ -1040,7 +1069,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const shader_sm1_read_param(sm1, ptr, &token, &addr_token); if (has_relative_address(token)) { @@ -1397,7 +1727,7 @@ index 751e5578276..fbf9de20278 100644 { vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); -@@ -1052,9 +1053,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const +@@ -1052,9 +1081,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const shader_sm1_parse_dst_param(sm1, token, dst_rel_addr, dst_param); if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_POINT_SIZE) @@ -1409,7 +1739,63 @@ index 751e5578276..fbf9de20278 100644 } static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, -@@ -1214,7 +1215,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str +@@ -1098,6 +1127,11 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, + range->first = range->last = semantic->resource.reg.reg.idx[0].offset; + + add_signature_element_from_semantic(sm1, semantic); ++ if (semantic->resource_type) ++ { ++ d3dbc_add_combined_sampler_descriptor(sm1, range->first, semantic->resource_type); ++ sm1->texture_descriptors |= (1u << range->first); ++ } + } + + static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, +@@ -1192,6 +1226,43 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1) + } + } + ++static void d3dbc_update_descriptors(struct vkd3d_shader_sm1_parser *d3dbc, ++ const struct vkd3d_shader_instruction *ins) ++{ ++ enum vkd3d_shader_resource_type type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; ++ const struct vkd3d_shader_d3dbc_source_info *source_info; ++ unsigned int sampler_idx; ++ ++ switch (ins->opcode) ++ { ++ case VSIR_OP_TEX: ++ case VSIR_OP_TEXBEM: ++ case VSIR_OP_TEXBEML: ++ case VSIR_OP_TEXDP3TEX: ++ case VSIR_OP_TEXLD: ++ 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_idx = ins->dst[0].reg.idx[0].offset; ++ if ((d3dbc->texture_descriptors & (1u << sampler_idx))) ++ break; ++ ++ if ((source_info = d3dbc->d3dbc_source_info) ++ && sampler_idx < ARRAY_SIZE(source_info->texture_dimensions)) ++ type = source_info->texture_dimensions[sampler_idx]; ++ d3dbc_add_combined_sampler_descriptor(d3dbc, sampler_idx, type); ++ d3dbc->texture_descriptors |= (1u << sampler_idx); ++ break; ++ ++ default: ++ break; ++ } ++} ++ + static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins) + { + if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags) +@@ -1214,7 +1285,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str { struct vkd3d_shader_src_param *src_params, *predicate; const struct vkd3d_sm1_opcode_info *opcode_info; @@ -1418,7 +1804,26 @@ index 751e5578276..fbf9de20278 100644 unsigned int vsir_dst_count, vsir_src_count; struct vkd3d_shader_dst_param *dst_param; const uint32_t **ptr = &sm1->ptr; -@@ -1446,7 +1447,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st +@@ -1356,6 +1427,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + goto fail; + } + ++ if (program->shader_version.major == 1) ++ d3dbc_update_descriptors(sm1, ins); ++ + shader_sm1_validate_instruction(sm1, ins); + return; + +@@ -1393,6 +1467,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st + uint16_t shader_type; + size_t token_count; + ++ sm1->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO); ++ + token_count = code_size / sizeof(*sm1->start); + + if (token_count < 2) +@@ -1446,7 +1522,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st code_size != ~(size_t)0 ? token_count / 4u + 4 : 16, VSIR_CF_STRUCTURED, normalisation_level)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -1428,18 +1833,49 @@ index 751e5578276..fbf9de20278 100644 sm1->ptr = sm1->start; return VKD3D_OK; -@@ -1504,8 +1506,8 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c - for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) - program->flat_constant_count[i] = get_external_constant_count(&sm1, i); +@@ -1473,6 +1550,7 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c + struct vkd3d_shader_message_context *message_context, struct vsir_program *program) + { + struct vkd3d_shader_sm1_parser sm1 = {0}; ++ struct vkd3d_shader_descriptor_info1 *d; + struct vkd3d_shader_instruction *ins; + unsigned int i; + int ret; +@@ -1501,11 +1579,29 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c + } + } + +- for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) +- program->flat_constant_count[i] = get_external_constant_count(&sm1, i); ++ for (i = 0; i < 3; ++i) ++ { ++ struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; ++ unsigned int size = get_external_constant_count(&sm1, i); - if (sm1.p.failed && ret >= 0) - ret = VKD3D_ERROR_INVALID_SHADER; ++ if (size) ++ { ++ if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ++ i, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) ++ vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, ++ "Failed to create CBV descriptor."); ++ else ++ d->buffer_size = size * 16; ++ } ++ } ++ ++ program->has_descriptor_info = true; ++ ++ if (TRACE_ON()) ++ vsir_program_trace(program); ++ + if (ret >= 0 && sm1.p.status < 0) + ret = sm1.p.status; if (ret < 0) { -@@ -1952,7 +1954,7 @@ static void d3dbc_write_vsir_dcl(struct d3dbc_compiler *d3dbc, const struct vkd3 +@@ -1952,7 +2048,7 @@ static void d3dbc_write_vsir_dcl(struct d3dbc_compiler *d3dbc, const struct vkd3 reg_id = semantic->resource.reg.reg.idx[0].offset; @@ -1448,18 +1884,55 @@ index 751e5578276..fbf9de20278 100644 { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_TYPE, "dcl instruction with register type %u.", semantic->resource.reg.reg.type); -@@ -2148,9 +2150,6 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, - if ((result = vsir_allocate_temp_registers(program, message_context))) +@@ -1988,6 +2084,9 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str + + switch (ins->opcode) + { ++ case VSIR_OP_NOP: ++ break; ++ + case VSIR_OP_DEF: + d3dbc_write_vsir_def(d3dbc, ins); + break; +@@ -2075,11 +2174,11 @@ 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 ((version->type == VKD3D_SHADER_TYPE_PIXEL || output) && !vkd3d_shader_ver_ge(version, 3, 0)) + { +- if (reg.reg.idx[0].offset > SM1_RASTOUT_REGISTER_OFFSET) ++ 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) ++ else if (reg.reg.idx[0].offset >= SM1_COLOR_REGISTER_OFFSET) + reg.reg.idx[0].offset -= SM1_COLOR_REGISTER_OFFSET; + } + } +@@ -2095,6 +2194,8 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, + put_u32(buffer, token); + + reg.write_mask = element->mask; ++ if (element->interpolation_mode == VKD3DSIM_LINEAR_CENTROID) ++ reg.modifiers |= VKD3DSPDM_MSAMPCENTROID; + write_sm1_dst_register(buffer, ®); + } + +@@ -2145,10 +2246,10 @@ 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))) ++ if ((result = vsir_program_optimize(program, config_flags, compile_info, message_context))) return result; - if ((result = vsir_update_dcl_temps(program, message_context))) -- return result; -- ++ if ((result = vsir_allocate_temp_registers(program, message_context))) + return result; + d3dbc.program = program; - d3dbc.message_context = message_context; - switch (version->type) diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index c448e000cf9..f82644d4679 100644 +index c448e000cf9..8d803b91f7a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -45,6 +45,8 @@ static const unsigned int MAX_GS_OUTPUT_STREAMS = 4; @@ -1471,7 +1944,50 @@ index c448e000cf9..f82644d4679 100644 enum bitcode_block_id { BLOCKINFO_BLOCK = 0, -@@ -892,6 +894,8 @@ struct sm6_parser +@@ -645,13 +647,13 @@ enum sm6_value_type + { + VALUE_TYPE_INVALID, + VALUE_TYPE_FUNCTION, +- VALUE_TYPE_DATA, + VALUE_TYPE_HANDLE, + VALUE_TYPE_SSA, + VALUE_TYPE_ICB, + VALUE_TYPE_IDXTEMP, + VALUE_TYPE_GROUPSHAREDMEM, + VALUE_TYPE_CONSTANT, ++ VALUE_TYPE_CONSTANT_ARRAY, + VALUE_TYPE_UNDEFINED, + }; + +@@ -704,6 +706,12 @@ struct sm6_constant_data + union vsir_immediate_constant immconst; + }; + ++struct sm6_constant_array_data ++{ ++ const struct vkd3d_shader_immediate_constant_buffer *icb; ++ const uint64_t *elements; ++}; ++ + struct sm6_value + { + const struct sm6_type *type; +@@ -714,13 +722,13 @@ struct sm6_value + union + { + struct sm6_function_data function; +- const struct vkd3d_shader_immediate_constant_buffer *data; + struct sm6_handle_data handle; + struct sm6_ssa_data ssa; + struct sm6_icb_data icb; + struct sm6_idxtemp_data idxtemp; + struct sm6_groupsharedmem_data groupsharedmem; + struct sm6_constant_data constant; ++ struct sm6_constant_array_data constant_array; + } u; + }; + +@@ -892,6 +900,8 @@ struct sm6_parser const uint32_t *ptr, *start, *end; unsigned int bitpos; @@ -1480,7 +1996,7 @@ index c448e000cf9..f82644d4679 100644 struct dxil_block root_block; struct dxil_block *current_block; -@@ -915,6 +919,7 @@ struct sm6_parser +@@ -915,6 +925,7 @@ struct sm6_parser struct vkd3d_shader_dst_param *input_params; struct vkd3d_shader_dst_param *patch_constant_params; uint32_t io_regs_declared[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)]; @@ -1488,7 +2004,7 @@ index c448e000cf9..f82644d4679 100644 struct sm6_function *functions; size_t function_count; -@@ -976,7 +981,7 @@ static uint32_t sm6_parser_read_uint32(struct sm6_parser *sm6) +@@ -976,7 +987,7 @@ static uint32_t sm6_parser_read_uint32(struct sm6_parser *sm6) { if (sm6_parser_is_end(sm6)) { @@ -1497,7 +2013,7 @@ index c448e000cf9..f82644d4679 100644 return 0; } return *sm6->ptr++; -@@ -994,7 +999,7 @@ static uint32_t sm6_parser_read_bits(struct sm6_parser *sm6, unsigned int length +@@ -994,7 +1005,7 @@ static uint32_t sm6_parser_read_bits(struct sm6_parser *sm6, unsigned int length if (sm6_parser_is_end(sm6)) { @@ -1506,7 +2022,7 @@ index c448e000cf9..f82644d4679 100644 return 0; } -@@ -1006,7 +1011,7 @@ static uint32_t sm6_parser_read_bits(struct sm6_parser *sm6, unsigned int length +@@ -1006,7 +1017,7 @@ static uint32_t sm6_parser_read_bits(struct sm6_parser *sm6, unsigned int length ++sm6->ptr; if (sm6_parser_is_end(sm6) && l < length) { @@ -1515,7 +2031,7 @@ index c448e000cf9..f82644d4679 100644 return bits; } sm6->bitpos = 0; -@@ -1028,7 +1033,7 @@ static uint64_t sm6_parser_read_vbr(struct sm6_parser *sm6, unsigned int length) +@@ -1028,7 +1039,7 @@ static uint64_t sm6_parser_read_vbr(struct sm6_parser *sm6, unsigned int length) if (sm6_parser_is_end(sm6)) { @@ -1524,7 +2040,7 @@ index c448e000cf9..f82644d4679 100644 return 0; } -@@ -1039,9 +1044,10 @@ static uint64_t sm6_parser_read_vbr(struct sm6_parser *sm6, unsigned int length) +@@ -1039,9 +1050,10 @@ static uint64_t sm6_parser_read_vbr(struct sm6_parser *sm6, unsigned int length) bits = sm6_parser_read_bits(sm6, length); result |= (uint64_t)(bits & mask) << shift; shift += length - 1; @@ -1537,7 +2053,7 @@ index c448e000cf9..f82644d4679 100644 return result; } -@@ -1053,7 +1059,7 @@ static void sm6_parser_align_32(struct sm6_parser *sm6) +@@ -1053,7 +1065,7 @@ static void sm6_parser_align_32(struct sm6_parser *sm6) if (sm6_parser_is_end(sm6)) { @@ -1546,7 +2062,7 @@ index c448e000cf9..f82644d4679 100644 return; } -@@ -1144,8 +1150,8 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6) +@@ -1144,8 +1156,8 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6) for (i = 0; i < count; ++i) record->operands[i] = sm6_parser_read_vbr(sm6, 6); @@ -1557,7 +2073,7 @@ index c448e000cf9..f82644d4679 100644 if (ret < 0 || (ret = dxil_block_add_record(block, record)) < 0) vkd3d_free(record); -@@ -1156,25 +1162,25 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6) +@@ -1156,25 +1168,25 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6) static bool sm6_parser_read_literal_operand(struct sm6_parser *sm6, uint64_t context, uint64_t *op) { *op = context; @@ -1587,7 +2103,7 @@ index c448e000cf9..f82644d4679 100644 } static bool sm6_parser_read_blob_operand(struct sm6_parser *sm6, uint64_t context, uint64_t *op) -@@ -1194,7 +1200,7 @@ static enum vkd3d_result dxil_abbrev_init(struct dxil_abbrev *abbrev, unsigned i +@@ -1194,7 +1206,7 @@ static enum vkd3d_result dxil_abbrev_init(struct dxil_abbrev *abbrev, unsigned i abbrev->is_array = false; @@ -1596,7 +2112,7 @@ index c448e000cf9..f82644d4679 100644 { if (sm6_parser_read_bits(sm6, 1)) { -@@ -1247,7 +1253,7 @@ static enum vkd3d_result dxil_abbrev_init(struct dxil_abbrev *abbrev, unsigned i +@@ -1247,7 +1259,7 @@ static enum vkd3d_result dxil_abbrev_init(struct dxil_abbrev *abbrev, unsigned i abbrev->count = count; @@ -1605,7 +2121,7 @@ index c448e000cf9..f82644d4679 100644 } static enum vkd3d_result sm6_parser_add_global_abbrev(struct sm6_parser *sm6) -@@ -1459,7 +1465,7 @@ static enum vkd3d_result dxil_block_read(struct dxil_block *parent, struct sm6_p +@@ -1459,7 +1471,7 @@ static enum vkd3d_result dxil_block_read(struct dxil_block *parent, struct sm6_p } break; } @@ -1614,7 +2130,7 @@ index c448e000cf9..f82644d4679 100644 return VKD3D_ERROR_INVALID_SHADER; } -@@ -1510,8 +1516,8 @@ static enum vkd3d_result dxil_block_init(struct dxil_block *block, const struct +@@ -1510,8 +1522,8 @@ static enum vkd3d_result dxil_block_init(struct dxil_block *block, const struct block->length = sm6_parser_read_uint32(sm6); block->start = sm6->ptr - sm6->start; @@ -1625,7 +2141,43 @@ index c448e000cf9..f82644d4679 100644 if ((block->abbrev_count = sm6_parser_compute_global_abbrev_count_for_block_id(sm6, block->id))) { -@@ -2437,7 +2443,7 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ +@@ -2274,6 +2286,11 @@ static inline bool sm6_value_is_constant(const struct sm6_value *value) + return value->value_type == VALUE_TYPE_CONSTANT; + } + ++static bool sm6_value_is_constant_array(const struct sm6_value *value) ++{ ++ return value->value_type == VALUE_TYPE_CONSTANT_ARRAY; ++} ++ + static bool sm6_value_is_constant_zero(const struct sm6_value *value) + { + if (value->value_type != VALUE_TYPE_CONSTANT) +@@ -2317,11 +2334,6 @@ static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **value + return true; + } + +-static bool sm6_value_is_data(const struct sm6_value *value) +-{ +- return value->value_type == VALUE_TYPE_DATA; +-} +- + static bool sm6_value_is_ssa(const struct sm6_value *value) + { + return value->value_type == VALUE_TYPE_SSA; +@@ -2424,9 +2436,9 @@ static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) + } + + static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins, +- enum vkd3d_shader_opcode handler_idx, const struct sm6_value *resource, struct sm6_parser *sm6) ++ enum vkd3d_shader_opcode opcode, const struct sm6_value *resource, struct sm6_parser *dxil) + { +- vsir_instruction_init(ins, &sm6->p.location, handler_idx); ++ vsir_instruction_init(ins, &dxil->p.location, opcode); + ins->resource_type = resource->u.handle.d->resource_type; + ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; + ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER; +@@ -2437,7 +2449,7 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ { struct vkd3d_shader_src_param *params; @@ -1634,7 +2186,7 @@ index c448e000cf9..f82644d4679 100644 { ERR("Failed to allocate src params.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -@@ -2454,7 +2460,7 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ +@@ -2454,7 +2466,7 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ { struct vkd3d_shader_dst_param *params; @@ -1643,7 +2195,7 @@ index c448e000cf9..f82644d4679 100644 { ERR("Failed to allocate dst params.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -@@ -2473,8 +2479,11 @@ static void register_init_with_id(struct vkd3d_shader_register *reg, +@@ -2473,8 +2485,11 @@ static void register_init_with_id(struct vkd3d_shader_register *reg, reg->idx[0].offset = id; } @@ -1656,7 +2208,7 @@ index c448e000cf9..f82644d4679 100644 if (type->class == TYPE_CLASS_INTEGER) { switch (type->u.width) -@@ -2482,15 +2491,16 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) +@@ -2482,15 +2497,16 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) case 1: return VSIR_DATA_BOOL; case 8: @@ -1678,7 +2230,7 @@ index c448e000cf9..f82644d4679 100644 return VSIR_DATA_U32; } } -@@ -2505,12 +2515,14 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) +@@ -2505,12 +2521,14 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) case 64: return VSIR_DATA_F64; default: @@ -1695,7 +2247,7 @@ index c448e000cf9..f82644d4679 100644 return VSIR_DATA_U32; } -@@ -2572,6 +2584,16 @@ static void register_convert_to_minimum_precision(struct vkd3d_shader_register * +@@ -2572,6 +2590,16 @@ static void register_convert_to_minimum_precision(struct vkd3d_shader_register * } break; @@ -1712,7 +2264,7 @@ index c448e000cf9..f82644d4679 100644 case VSIR_DATA_U16: reg->data_type = VSIR_DATA_U32; reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16; -@@ -2590,14 +2612,14 @@ static void register_convert_to_minimum_precision(struct vkd3d_shader_register * +@@ -2590,14 +2618,14 @@ static void register_convert_to_minimum_precision(struct vkd3d_shader_register * static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, struct sm6_parser *sm6); @@ -1730,7 +2282,7 @@ index c448e000cf9..f82644d4679 100644 switch (value->value_type) { -@@ -2609,21 +2631,21 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str +@@ -2609,21 +2637,21 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str case VALUE_TYPE_ICB: vsir_register_init(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, 2); reg->idx[0].offset = value->u.icb.id; @@ -1755,7 +2307,16 @@ index c448e000cf9..f82644d4679 100644 reg->idx[1].is_in_bounds = value->u.groupsharedmem.index.is_in_bounds; break; -@@ -2720,11 +2742,11 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned +@@ -2640,7 +2668,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + + case VALUE_TYPE_FUNCTION: + case VALUE_TYPE_HANDLE: +- case VALUE_TYPE_DATA: ++ case VALUE_TYPE_CONSTANT_ARRAY: + vkd3d_unreachable(); + } + +@@ -2720,11 +2748,11 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned param->modifiers = VKD3DSPSM_NONE; } @@ -1770,7 +2331,7 @@ index c448e000cf9..f82644d4679 100644 } static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param, -@@ -2756,9 +2778,9 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, +@@ -2756,9 +2784,9 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, } else { @@ -1782,7 +2343,7 @@ index c448e000cf9..f82644d4679 100644 idx->offset = 0; idx->rel_addr = rel_addr; } -@@ -2783,17 +2805,19 @@ static void src_param_init_vector_from_handle(struct sm6_parser *sm6, +@@ -2783,17 +2811,19 @@ static void src_param_init_vector_from_handle(struct sm6_parser *sm6, src_param_init_vector_from_reg(param, ®); } @@ -1807,7 +2368,7 @@ index c448e000cf9..f82644d4679 100644 return true; } -@@ -2805,7 +2829,7 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio +@@ -2805,7 +2835,7 @@ 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); @@ -1816,7 +2377,7 @@ index c448e000cf9..f82644d4679 100644 } static bool instruction_dst_param_init_uint_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) -@@ -2987,8 +3011,7 @@ static bool sm6_value_validate_is_backward_ref(const struct sm6_value *value, st +@@ -2987,8 +3017,7 @@ static bool sm6_value_validate_is_backward_ref(const struct sm6_value *value, st { if (!value->is_back_ref) { @@ -1826,63 +2387,139 @@ index c448e000cf9..f82644d4679 100644 "Forward-referenced pointer declarations are not supported."); return false; } -@@ -3200,8 +3223,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - /* Multidimensional arrays are emitted in flattened form. */ - if (elem_type->class != TYPE_CLASS_INTEGER && elem_type->class != TYPE_CLASS_FLOAT) - { +@@ -3044,7 +3073,7 @@ static bool sm6_value_validate_is_i32(const struct sm6_value *value, struct sm6_ + return true; + } + +-static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx) ++static struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx) + { + if (idx < sm6->value_count) + return &sm6->values[idx]; +@@ -3188,100 +3217,6 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) + return value << 63; + } + +-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. */ +- if (elem_type->class != TYPE_CLASS_INTEGER && elem_type->class != TYPE_CLASS_FLOAT) +- { - FIXME("Unhandled element type %u for data array.\n", elem_type->class); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_NOT_IMPLEMENTED, - "The element data type for an immediate constant buffer is not scalar integer or floating point."); - return VKD3D_ERROR_INVALID_SHADER; - } -@@ -3224,7 +3246,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - "Out of memory allocating an immediate constant buffer of count %u.", count); - return VKD3D_ERROR_OUT_OF_MEMORY; - } +- "The element data type for an immediate constant buffer is not scalar integer or floating point."); +- return VKD3D_ERROR_INVALID_SHADER; +- } +- +- /* Arrays of bool are not used in DXIL. dxc will emit an array of int32 instead if necessary. */ +- if (!(size = elem_type->u.width / CHAR_BIT)) +- { +- WARN("Invalid data type width %u.\n", elem_type->u.width); +- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +- "An immediate constant buffer is declared with boolean elements."); +- return VKD3D_ERROR_INVALID_SHADER; +- } +- size = max(size, sizeof(icb->data[0])); +- count = operands ? type->u.array.count * size / sizeof(icb->data[0]) : 0; +- +- if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count])))) +- { +- ERR("Failed to allocate buffer, count %u.\n", count); +- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +- "Out of memory allocating an immediate constant buffer of count %u.", count); +- return VKD3D_ERROR_OUT_OF_MEMORY; +- } - if (!shader_instruction_array_add_icb(&sm6->p.program->instructions, icb)) -+ if (!vsir_program_add_icb(sm6->program, icb)) - { - ERR("Failed to store icb object.\n"); - vkd3d_free(icb); -@@ -3237,7 +3259,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - dst->u.data = icb; - - icb->register_idx = sm6->icb_count++; +- { +- ERR("Failed to store icb object.\n"); +- vkd3d_free(icb); +- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +- "Out of memory storing an immediate constant buffer object."); +- return VKD3D_ERROR_OUT_OF_MEMORY; +- } +- +- dst->value_type = VALUE_TYPE_DATA; +- dst->u.data = icb; +- +- icb->register_idx = sm6->icb_count++; - icb->data_type = vsir_data_type_from_dxil(elem_type); -+ icb->data_type = vsir_data_type_from_dxil(elem_type, 0, sm6); - icb->element_count = type->u.array.count; - icb->component_count = 1; - icb->is_null = !operands; -@@ -3254,6 +3276,12 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - icb->data_type = VSIR_DATA_F32; - break; +- icb->element_count = type->u.array.count; +- icb->component_count = 1; +- icb->is_null = !operands; +- +- if (!operands) +- return VKD3D_OK; +- +- count = type->u.array.count; +- switch (icb->data_type) +- { +- 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) +@@ -3468,8 +3403,8 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + case CST_CODE_NULL: + if (sm6_type_is_array(type)) + { +- if ((ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) +- return ret; ++ dst->value_type = VALUE_TYPE_CONSTANT_ARRAY; ++ dst->u.constant_array.elements = NULL; + } + else + { +@@ -3529,8 +3464,8 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + if (!dxil_record_validate_operand_count(record, type->u.array.count, type->u.array.count, sm6)) + return VKD3D_ERROR_INVALID_SHADER; -+ case VSIR_DATA_I16: -+ for (i = 0; i < count; ++i) -+ icb->data[i] = (int16_t)operands[i]; -+ icb->data_type = VSIR_DATA_I32; -+ break; -+ - case VSIR_DATA_U16: - for (i = 0; i < count; ++i) - icb->data[i] = (int16_t)operands[i]; -@@ -3261,12 +3289,14 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - break; +- if ((ret = value_allocate_constant_array(dst, type, record->operands, sm6)) < 0) +- return ret; ++ dst->value_type = VALUE_TYPE_CONSTANT_ARRAY; ++ dst->u.constant_array.elements = record->operands; - case VSIR_DATA_F32: -+ case VSIR_DATA_I32: - case VSIR_DATA_U32: - for (i = 0; i < count; ++i) - icb->data[i] = operands[i]; - break; + break; - case VSIR_DATA_F64: -+ case VSIR_DATA_I64: - case VSIR_DATA_U64: - data64 = (uint64_t *)icb->data; - for (i = 0; i < count; ++i) -@@ -3651,26 +3681,19 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al +@@ -3651,26 +3586,19 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al return true; } @@ -1916,7 +2553,7 @@ index c448e000cf9..f82644d4679 100644 return ins; } -@@ -3679,7 +3702,8 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type +@@ -3679,7 +3607,8 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type { struct vkd3d_shader_instruction *ins; @@ -1926,7 +2563,7 @@ index c448e000cf9..f82644d4679 100644 /* The icb value index will be resolved later so forward references can be handled. */ ins->declaration.icb = (void *)(intptr_t)init; dst->value_type = VALUE_TYPE_ICB; -@@ -3690,12 +3714,22 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru +@@ -3690,12 +3619,22 @@ 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) { @@ -1952,7 +2589,7 @@ index c448e000cf9..f82644d4679 100644 ins->declaration.indexable_temp.register_idx = sm6->indexable_temp_count++; ins->declaration.indexable_temp.register_size = count; ins->declaration.indexable_temp.alignment = alignment; -@@ -3715,23 +3749,21 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 +@@ -3715,23 +3654,21 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 struct vkd3d_shader_instruction *ins; unsigned int byte_count; @@ -1980,7 +2617,7 @@ index c448e000cf9..f82644d4679 100644 ins->declaration.tgsm_raw.byte_count = byte_count; /* The initialiser value index will be resolved later when forward references can be handled. */ ins->flags = init; -@@ -3742,7 +3774,8 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str +@@ -3742,7 +3679,8 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str { struct vkd3d_shader_instruction *ins; @@ -1990,7 +2627,7 @@ index c448e000cf9..f82644d4679 100644 dst_param_init(&ins->declaration.tgsm_structured.reg); dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; dst->u.groupsharedmem.id = sm6->tgsm_count++; -@@ -3750,13 +3783,10 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str +@@ -3750,13 +3688,10 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str /* Convert minimum precision types to their 32-bit equivalent. */ if (dst->structure_stride == 2) dst->structure_stride = 4; @@ -2006,7 +2643,7 @@ index c448e000cf9..f82644d4679 100644 ins->declaration.tgsm_structured.alignment = alignment; ins->declaration.tgsm_structured.byte_stride = dst->structure_stride; ins->declaration.tgsm_structured.structure_count = count; -@@ -3781,8 +3811,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ +@@ -3781,8 +3716,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ { if (!sm6_type_is_scalar(type->u.array.elem_type)) { @@ -2016,7 +2653,7 @@ index c448e000cf9..f82644d4679 100644 "Global array variables with nested type class %u are not supported.", type->u.array.elem_type->class); return false; -@@ -3797,8 +3826,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ +@@ -3797,8 +3731,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ } else { @@ -2026,7 +2663,7 @@ index c448e000cf9..f82644d4679 100644 "Global variables of type class %u are not supported.", type->class); return false; } -@@ -3903,14 +3931,13 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ +@@ -3903,33 +3836,141 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ } else { @@ -2043,7 +2680,159 @@ index c448e000cf9..f82644d4679 100644 } static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_initialiser( -@@ -3961,17 +3988,16 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm + size_t index, struct sm6_parser *sm6) + { +- const struct sm6_value *value; ++ struct sm6_value *value; + + VKD3D_ASSERT(index); + --index; +- if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_data(value) && !sm6_value_is_undef(value))) ++ if (!(value = sm6_parser_get_value_safe(sm6, index)) ++ || (!sm6_value_is_constant_array(value) && !sm6_value_is_undef(value))) + { + WARN("Invalid initialiser index %zu.\n", index); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Global variable initialiser value index %zu is invalid.", index); + return NULL; + } +- else if (sm6_value_is_data(value)) ++ else if (sm6_value_is_constant_array(value)) + { +- return value->u.data; ++ const uint64_t *elements = value->u.constant_array.elements; ++ struct vkd3d_shader_immediate_constant_buffer *icb; ++ const struct sm6_array_info *array; ++ const struct sm6_type *elem_type; ++ unsigned int i, size, count; ++ uint64_t *data64; ++ ++ if (value->u.constant_array.icb) ++ return value->u.constant_array.icb; ++ ++ array = &value->type->u.array; ++ elem_type = array->elem_type; ++ /* Multidimensional arrays are emitted in flattened form. */ ++ if (elem_type->class != TYPE_CLASS_INTEGER && elem_type->class != TYPE_CLASS_FLOAT) ++ { ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_NOT_IMPLEMENTED, ++ "The element data type for an immediate constant buffer is not scalar integer or floating point."); ++ return NULL; ++ } ++ ++ /* Arrays of bool are not used in DXIL. dxc will emit an array of int32 instead if necessary. */ ++ if (!(size = elem_type->u.width / CHAR_BIT)) ++ { ++ WARN("Invalid data type width %u.\n", elem_type->u.width); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "An immediate constant buffer is declared with boolean elements."); ++ return NULL; ++ } ++ size = max(size, sizeof(icb->data[0])); ++ count = elements ? array->count * size / sizeof(icb->data[0]) : 0; ++ ++ if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count])))) ++ { ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, ++ "Out of memory allocating an immediate constant buffer of count %u.", count); ++ return NULL; ++ } ++ ++ if (!vsir_program_add_icb(sm6->program, icb)) ++ { ++ vkd3d_free(icb); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, ++ "Out of memory storing an immediate constant buffer object."); ++ return NULL; ++ } ++ ++ count = array->count; ++ icb->register_idx = sm6->icb_count++; ++ icb->data_type = vsir_data_type_from_dxil(elem_type, 0, sm6); ++ icb->element_count = count; ++ icb->component_count = 1; ++ icb->is_null = !elements; ++ value->u.constant_array.icb = icb; ++ ++ if (!elements) ++ return icb; ++ ++ switch (icb->data_type) ++ { ++ case VSIR_DATA_F16: ++ icb->data_type = VSIR_DATA_F32; ++ for (i = 0; i < count; ++i) ++ { ++ icb->data[i] = half_to_float(elements[i]); ++ } ++ break; ++ ++ case VSIR_DATA_I16: ++ icb->data_type = VSIR_DATA_I32; ++ for (i = 0; i < count; ++i) ++ { ++ icb->data[i] = (int16_t)elements[i]; ++ } ++ break; ++ ++ case VSIR_DATA_U16: ++ icb->data_type = VSIR_DATA_U32; ++ for (i = 0; i < count; ++i) ++ { ++ icb->data[i] = (int16_t)elements[i]; ++ } ++ break; ++ ++ case VSIR_DATA_F32: ++ case VSIR_DATA_I32: ++ case VSIR_DATA_U32: ++ for (i = 0; i < count; ++i) ++ { ++ icb->data[i] = elements[i]; ++ } ++ break; ++ ++ case VSIR_DATA_F64: ++ case VSIR_DATA_I64: ++ case VSIR_DATA_U64: ++ data64 = (uint64_t *)icb->data; ++ for (i = 0; i < count; ++i) ++ { ++ data64[i] = elements[i]; ++ } ++ break; ++ ++ default: ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Invalid array of type %u.", icb->data_type); ++ return NULL; ++ } ++ ++ return icb; + } + /* In VSIR, initialisation with undefined values of objects is implied, not explicit. */ + return NULL; +@@ -3943,15 +3984,16 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm + return false; + + --index; +- if (!(value = sm6_parser_get_value_safe(sm6, index)) +- || (!sm6_value_is_data(value) && !sm6_value_is_constant(value) && !sm6_value_is_undef(value))) ++ if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_constant_array(value) ++ && !sm6_value_is_constant(value) && !sm6_value_is_undef(value))) + { + WARN("Invalid initialiser index %zu.\n", index); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "TGSM initialiser value index %zu is invalid.", index); + return false; + } +- else if ((sm6_value_is_data(value) && value->u.data->is_null) || sm6_value_is_constant_zero(value)) ++ else if ((sm6_value_is_constant_array(value) && !value->u.constant_array.elements) ++ || sm6_value_is_constant_zero(value)) + { + return true; + } +@@ -3961,17 +4003,16 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm return false; } @@ -2064,7 +2853,7 @@ index c448e000cf9..f82644d4679 100644 struct vkd3d_shader_instruction *ins; const struct dxil_record *record; enum vkd3d_result ret; -@@ -3980,10 +4006,6 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) +@@ -3980,10 +4021,6 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) sm6->p.location.line = block->id; sm6->p.location.column = 0; @@ -2075,7 +2864,7 @@ index c448e000cf9..f82644d4679 100644 for (i = 0; i < block->record_count; ++i) { sm6->p.location.column = i; -@@ -4001,7 +4023,10 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) +@@ -4001,7 +4038,10 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) case MODULE_CODE_GLOBALVAR: if (!sm6_parser_declare_global(sm6, record)) @@ -2087,7 +2876,7 @@ index c448e000cf9..f82644d4679 100644 break; case MODULE_CODE_VERSION: -@@ -4009,8 +4034,7 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) +@@ -4009,8 +4049,7 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) return VKD3D_ERROR_INVALID_SHADER; if ((version = record->operands[0]) != 1) { @@ -2097,7 +2886,7 @@ index c448e000cf9..f82644d4679 100644 "Bitcode format version %#"PRIx64" is unsupported.", version); return VKD3D_ERROR_INVALID_SHADER; } -@@ -4088,7 +4112,9 @@ static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_par +@@ -4088,7 +4127,9 @@ static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_par unsigned int i; for (i = 0; i < count; ++i) @@ -2108,7 +2897,7 @@ index c448e000cf9..f82644d4679 100644 } static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( -@@ -4125,7 +4151,7 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( +@@ -4125,7 +4166,7 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) { @@ -2117,7 +2906,7 @@ index c448e000cf9..f82644d4679 100644 enum vkd3d_shader_register_type io_reg_type; bool is_patch_constant, is_control_point; struct vkd3d_shader_dst_param *param; -@@ -4175,7 +4201,10 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade +@@ -4175,7 +4216,10 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade if (is_control_point) { if (reg_type == VKD3DSPR_OUTPUT) @@ -2129,7 +2918,7 @@ index c448e000cf9..f82644d4679 100644 param->reg.idx[count++].offset = 0; } -@@ -4190,7 +4219,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade +@@ -4190,7 +4234,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) { @@ -2138,7 +2927,7 @@ index c448e000cf9..f82644d4679 100644 { vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, "Failed to allocate output parameters."); -@@ -4204,7 +4233,7 @@ static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct +@@ -4204,7 +4248,7 @@ static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature) { @@ -2147,7 +2936,7 @@ index c448e000cf9..f82644d4679 100644 { vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, "Failed to allocate input parameters."); -@@ -4219,9 +4248,9 @@ static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct +@@ -4219,9 +4263,9 @@ static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct static int sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6, const struct shader_signature *patch_constant_signature) { @@ -2159,7 +2948,7 @@ index c448e000cf9..f82644d4679 100644 patch_constant_signature->element_count))) { vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -@@ -4310,8 +4339,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec +@@ -4310,8 +4354,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec WARN("Ignoring in_alloca flag.\n"); if (!(packed_operands & ALLOCA_FLAG_EXPLICIT_TYPE)) { @@ -2169,7 +2958,7 @@ index c448e000cf9..f82644d4679 100644 "Implicit result type for ALLOCA instructions is not supported."); return; } -@@ -4347,8 +4375,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec +@@ -4347,8 +4390,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec /* A size of 1 means one instance of type[0], i.e. one array. */ if (sm6_value_get_constant_uint(size, sm6) != 1) { @@ -2179,7 +2968,7 @@ index c448e000cf9..f82644d4679 100644 "ALLOCA instruction allocation sizes other than 1 are not supported."); return; } -@@ -4410,7 +4437,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ +@@ -4410,7 +4452,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ || !sm6_value_validate_is_backward_ref(ptr, sm6)) return; @@ -2188,7 +2977,7 @@ index c448e000cf9..f82644d4679 100644 if (reg.type != VKD3DSPR_GROUPSHAREDMEM) { -@@ -4430,8 +4457,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ +@@ -4430,8 +4472,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VSIR_OP_INVALID) { @@ -2198,7 +2987,25 @@ index c448e000cf9..f82644d4679 100644 "Operation %"PRIu64" for an atomicrmw instruction is unhandled.", code); return; } -@@ -4466,12 +4492,12 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ +@@ -4441,6 +4482,8 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ + /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */ + if ((code = record->operands[i++]) != ORDERING_SEQCST) + FIXME("Unhandled atomic ordering %"PRIu64".\n", code); ++ else ++ WARN("Ignoring atomic ordering %"PRIu64".\n", code); + + if ((code = record->operands[i]) != 1) + WARN("Ignoring synchronisation scope %"PRIu64".\n", code); +@@ -4458,7 +4501,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ + + ins = state->ins; + vsir_instruction_init(ins, &sm6->p.location, op); +- ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST; ++ ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0; + + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +@@ -4466,12 +4509,12 @@ 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); @@ -2213,7 +3020,35 @@ index c448e000cf9..f82644d4679 100644 dst_param_init(&dst_params[0]); dst_params[1].reg = reg; -@@ -4559,8 +4585,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty +@@ -4483,7 +4526,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ + } + + static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, +- const struct sm6_type *type_b, struct sm6_parser *sm6) ++ const struct sm6_type *type_b, struct sm6_parser *sm6, enum vkd3d_shader_opcode *aux_opcode) + { + bool is_int = sm6_type_is_bool_i16_i32_i64(type_a); + bool is_double = sm6_type_is_double(type_a); +@@ -4506,12 +4549,17 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty + "Type mismatch in binary operation arguments."); + } + ++ *aux_opcode = VSIR_OP_NOP; ++ + switch (code) + { + case BINOP_ADD: ++ op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD); ++ is_valid = !is_bool; ++ break; + case BINOP_SUB: +- /* NEG is applied later for subtraction. */ + op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD); ++ *aux_opcode = is_int ? VSIR_OP_INEG : VSIR_OP_NEG; + is_valid = !is_bool; + break; + case BINOP_AND: +@@ -4559,8 +4607,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty is_valid = is_int; break; default: @@ -2223,35 +3058,103 @@ index c448e000cf9..f82644d4679 100644 "Binary operation %#"PRIx64" is unhandled.", code); return VSIR_OP_INVALID; } -@@ -4581,6 +4606,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco +@@ -4576,10 +4623,12 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty + } + + static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_record *record, +- struct vkd3d_shader_instruction *ins, struct sm6_value *dst) ++ struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) + { ++ enum vkd3d_shader_opcode opcode, aux_opcode; struct vkd3d_shader_src_param *src_params; - enum vkd3d_shader_opcode handler_idx; +- enum vkd3d_shader_opcode handler_idx; ++ struct vkd3d_shader_dst_param *dst_params; ++ uint32_t type_flags = 0, aux_id = 0; const struct sm6_value *a, *b; -+ uint32_t type_flags = 0; uint64_t code, flags; bool silence_warning; - unsigned int i = 0; -@@ -4622,6 +4648,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco +@@ -4596,15 +4645,34 @@ 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)) == VSIR_OP_INVALID) ++ if ((opcode = map_binary_op(code, a->type, b->type, sm6, &aux_opcode)) == VSIR_OP_INVALID) + return; + +- vsir_instruction_init(ins, &sm6->p.location, handler_idx); ++ if (aux_opcode != VSIR_OP_NOP) ++ { ++ vsir_instruction_init(ins, &sm6->p.location, aux_opcode); ++ ++ if (!(dst_params = instruction_dst_params_alloc(ins, 1, sm6)) ++ || !(src_params = instruction_src_params_alloc(ins, 1, sm6))) ++ return; ++ ++ aux_id = sm6_parser_alloc_ssa_id(sm6); ++ ++ src_param_init_from_value(&src_params[0], b, DXIL_TYPE_SIGNED, sm6); ++ ++ dst_param_init(&dst_params[0]); ++ register_init_with_id(&dst_params[0].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id); ++ ++ ++ins; ++ ++code_block->instruction_count; ++ } ++ ++ vsir_instruction_init(ins, &sm6->p.location, opcode); + + flags = (record->operand_count > i) ? record->operands[i] : 0; + silence_warning = false; + +- switch (handler_idx) ++ switch (opcode) + { + case VSIR_OP_ADD: + case VSIR_OP_MUL: +@@ -4621,11 +4689,13 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + case VSIR_OP_ISHL: silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP)); break; ++ case VSIR_OP_IDIV: ++ case VSIR_OP_IREM: case VSIR_OP_ISHR: + type_flags |= DXIL_TYPE_SIGNED; + /* fall through */ case VSIR_OP_USHR: - case VSIR_OP_IDIV: +- case VSIR_OP_IDIV: case VSIR_OP_UDIV_SIMPLE: -@@ -4646,8 +4674,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco +- case VSIR_OP_IREM: + case VSIR_OP_UREM: + silence_warning = !(flags & ~PEB_EXACT); + break; +@@ -4646,21 +4716,29 @@ 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, sm6); - src_param_init_from_value(&src_params[1], b, sm6); +- if (code == BINOP_SUB) +- src_params[1].modifiers = VKD3DSPSM_NEG; ++ + src_param_init_from_value(&src_params[0], a, type_flags, sm6); -+ src_param_init_from_value(&src_params[1], b, type_flags, sm6); - if (code == BINOP_SUB) - src_params[1].modifiers = VKD3DSPSM_NEG; ++ ++ if (aux_opcode == VSIR_OP_NOP) ++ { ++ src_param_init_from_value(&src_params[1], b, type_flags, sm6); ++ } ++ else ++ { ++ src_param_init(&src_params[1]); ++ register_init_with_id(&src_params[1].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id); ++ } -@@ -4660,7 +4688,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + dst->type = a->type; + +- if (handler_idx == VSIR_OP_ISHL || handler_idx == VSIR_OP_ISHR || handler_idx == VSIR_OP_USHR) ++ if (opcode == VSIR_OP_ISHL || opcode == VSIR_OP_ISHR || opcode == VSIR_OP_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; } @@ -2260,7 +3163,7 @@ index c448e000cf9..f82644d4679 100644 } static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index, -@@ -4710,7 +4738,7 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record +@@ -4710,7 +4788,7 @@ 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; @@ -2269,7 +3172,7 @@ index c448e000cf9..f82644d4679 100644 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); } -@@ -4781,7 +4809,9 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st +@@ -4781,7 +4859,9 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st unsigned int i; for (i = 0; i < component_count; ++i) @@ -2280,7 +3183,7 @@ index c448e000cf9..f82644d4679 100644 return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); } -@@ -4797,11 +4827,11 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s +@@ -4797,11 +4877,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; @@ -2294,7 +3197,7 @@ index c448e000cf9..f82644d4679 100644 return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); } -@@ -4822,7 +4852,7 @@ static void sm6_parser_emit_dx_void(struct sm6_parser *sm6, enum dx_intrinsic_op +@@ -4822,7 +4902,7 @@ static void sm6_parser_emit_dx_void(struct sm6_parser *sm6, enum dx_intrinsic_op { struct vkd3d_shader_instruction *ins = state->ins; vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_void_op(op)); @@ -2303,7 +3206,7 @@ index c448e000cf9..f82644d4679 100644 } static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) -@@ -4919,13 +4949,16 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o +@@ -4919,13 +4999,16 @@ 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; @@ -2323,7 +3226,7 @@ index c448e000cf9..f82644d4679 100644 switch (op) { case DX_FMAX: -@@ -4933,8 +4966,10 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co +@@ -4933,8 +5016,10 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co case DX_FMIN: return type->u.width == 64 ? VSIR_OP_DMIN : VSIR_OP_MIN; case DX_IMAX: @@ -2334,7 +3237,7 @@ index c448e000cf9..f82644d4679 100644 return VSIR_OP_IMIN; case DX_QUAD_READ_LANE_AT: return VSIR_OP_QUAD_READ_LANE_AT; -@@ -4954,14 +4989,15 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -4954,14 +5039,15 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ { struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_params; @@ -2354,7 +3257,7 @@ index c448e000cf9..f82644d4679 100644 } static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6) -@@ -4990,8 +5026,7 @@ static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *oper +@@ -4990,8 +5076,7 @@ static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *oper return VSIR_OP_IMM_ATOMIC_XOR; /* DXIL currently doesn't use SUB and NAND. */ default: @@ -2364,7 +3267,29 @@ index c448e000cf9..f82644d4679 100644 "Operation %"PRIu64" for an atomic binop instruction is unhandled.", code); return VSIR_OP_INVALID; } -@@ -5030,7 +5065,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr +@@ -5006,18 +5091,18 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr + unsigned int i, coord_idx, coord_count = 1; + struct vkd3d_shader_dst_param *dst_params; + struct vkd3d_shader_src_param *src_params; +- enum vkd3d_shader_opcode handler_idx; + struct vkd3d_shader_instruction *ins; + const struct sm6_value *resource; + struct vkd3d_shader_register reg; ++ enum vkd3d_shader_opcode opcode; + + resource = operands[0]; + if (!sm6_value_validate_is_handle(resource, sm6)) + return; + + if (is_cmp_xchg) +- handler_idx = VSIR_OP_IMM_ATOMIC_CMP_EXCH; +- else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID) ++ opcode = VSIR_OP_IMM_ATOMIC_CMP_EXCH; ++ else if ((opcode = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID) + return; + + coord_idx = 2 - is_cmp_xchg; +@@ -5030,7 +5115,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr } else { @@ -2373,7 +3298,21 @@ index c448e000cf9..f82644d4679 100644 } for (i = coord_idx + coord_count; i < coord_idx + 3; ++i) -@@ -5051,14 +5086,14 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr +@@ -5039,26 +5124,26 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr + { + WARN("Ignoring unexpected operand.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, +- "Ignoring an unexpected defined operand value for atomic instruction %u.", handler_idx); ++ "Ignoring an unexpected defined operand value for atomic instruction %u.", opcode); + break; + } + } + + ins = state->ins; +- vsir_instruction_init(ins, &sm6->p.location, handler_idx); ++ vsir_instruction_init(ins, &sm6->p.location, opcode); + + if (!(src_params = instruction_src_params_alloc(ins, 2 + is_cmp_xchg, sm6))) return; src_param_init_vector_from_reg(&src_params[0], ®); if (is_cmp_xchg) @@ -2391,7 +3330,7 @@ index c448e000cf9..f82644d4679 100644 dst_param_init(&dst_params[1]); sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); } -@@ -5099,8 +5134,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu +@@ -5099,8 +5184,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu if (!sm6_value_is_constant(operands[1])) { @@ -2401,7 +3340,7 @@ index c448e000cf9..f82644d4679 100644 "A dynamic update value for a UAV counter operation is not supported."); return; } -@@ -5118,7 +5152,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu +@@ -5118,7 +5202,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu return; src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); @@ -2410,7 +3349,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5152,7 +5186,7 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int +@@ -5152,7 +5236,7 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int src_param_init_scalar(&src_params[1], !clamp); src_param_init_vector_from_handle(sm6, &src_params[2], &sampler->u.handle); @@ -2419,7 +3358,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5180,7 +5214,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr +@@ -5180,7 +5264,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr type = sm6_type_get_scalar_type(dst->type, 0); VKD3D_ASSERT(type); @@ -2428,17 +3367,29 @@ index c448e000cf9..f82644d4679 100644 if (data_type_is_64_bit(src_param->reg.data_type)) src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); else -@@ -5198,7 +5232,8 @@ static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_s - if (!bitmap_is_set(sm6->io_regs_declared, reg_type)) +@@ -5189,16 +5273,17 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr + 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, ++static void sm6_parser_dcl_register_builtin(struct sm6_parser *dxil, enum vkd3d_shader_opcode opcode, + 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; + +- if (!bitmap_is_set(sm6->io_regs_declared, reg_type)) ++ if (!bitmap_is_set(dxil->io_regs_declared, reg_type)) { - bitmap_set(sm6->io_regs_declared, reg_type); +- bitmap_set(sm6->io_regs_declared, reg_type); - ins = sm6_parser_add_instruction(sm6, handler_idx); -+ if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) ++ bitmap_set(dxil->io_regs_declared, reg_type); ++ if (!(ins = sm6_parser_add_instruction(dxil, opcode))) + return; dst_param = &ins->declaration.dst; vsir_register_init(&dst_param->reg, reg_type, data_type, 0); dst_param_init_vector(dst_param, component_count); -@@ -5220,7 +5255,7 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, struct +@@ -5220,7 +5305,7 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, struct src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param_init(src_param); @@ -2447,7 +3398,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_coverage(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5323,7 +5358,7 @@ static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic +@@ -5323,7 +5408,7 @@ static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DISCARD); if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) @@ -2456,7 +3407,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5350,7 +5385,7 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i +@@ -5350,7 +5435,7 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param_init_scalar(src_param, component_idx); @@ -2465,7 +3416,40 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5392,7 +5427,7 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc +@@ -5359,21 +5444,21 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc + struct vkd3d_shader_src_param *src_params; + struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_register regs[2]; +- enum vkd3d_shader_opcode handler_idx; ++ enum vkd3d_shader_opcode opcode; + unsigned int component_count; + + switch (op) + { + case DX_DOT2: +- handler_idx = VSIR_OP_DP2; ++ opcode = VSIR_OP_DP2; + component_count = 2; + break; + case DX_DOT3: +- handler_idx = VSIR_OP_DP3; ++ opcode = VSIR_OP_DP3; + component_count = 3; + break; + case DX_DOT4: +- handler_idx = VSIR_OP_DP4; ++ opcode = VSIR_OP_DP4; + component_count = 4; + break; + default: +@@ -5386,13 +5471,13 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc + return; + + ins = state->ins; +- vsir_instruction_init(ins, &sm6->p.location, handler_idx); ++ vsir_instruction_init(ins, &sm6->p.location, opcode); + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; src_param_init_vector_from_reg(&src_params[0], ®s[0]); src_param_init_vector_from_reg(&src_params[1], ®s[1]); @@ -2474,7 +3458,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5407,7 +5442,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri +@@ -5407,7 +5492,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri row_index = sm6_value_get_constant_uint(operands[0], sm6); column_index = sm6_value_get_constant_uint(operands[2], sm6); @@ -2483,7 +3467,7 @@ index c448e000cf9..f82644d4679 100644 if (row_index >= signature->element_count) { WARN("Invalid row index %u.\n", row_index); -@@ -5437,9 +5472,9 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri +@@ -5437,9 +5522,9 @@ 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) @@ -2495,20 +3479,24 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5451,10 +5486,10 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op - vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); +@@ -5448,13 +5533,12 @@ 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, VSIR_OP_MOV); ++ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_ABS); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0], sm6); +- src_param->modifiers = VKD3DSPSM_ABS; + src_param_init_from_value(src_param, operands[0], 0, sm6); - src_param->modifiers = VKD3DSPSM_ABS; - instruction_dst_param_init_ssa_scalar(ins, sm6); + instruction_dst_param_init_ssa_scalar(ins, 0, sm6); } static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5494,7 +5529,7 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i +@@ -5494,7 +5578,7 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i component_idx = sm6_value_get_constant_uint(operands[0], sm6); src_param_init_scalar(src_param, component_idx); @@ -2517,7 +3505,7 @@ index c448e000cf9..f82644d4679 100644 } static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, const struct sm6_type *type) -@@ -5524,9 +5559,11 @@ static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opco +@@ -5524,9 +5608,11 @@ 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) @@ -2531,7 +3519,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5554,7 +5591,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in +@@ -5554,7 +5640,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in if (is_texture) { ins->flags = VKD3DSI_RESINFO_UINT; @@ -2540,7 +3528,7 @@ index c448e000cf9..f82644d4679 100644 component_count = VKD3D_VEC4_SIZE; if (resource_kind_is_multisampled(resource_kind)) -@@ -5627,9 +5664,11 @@ static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsi +@@ -5627,9 +5713,11 @@ 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) @@ -2554,7 +3542,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5638,7 +5677,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin +@@ -5638,7 +5726,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT; bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT; struct vkd3d_shader_instruction *ins = state->ins; @@ -2563,7 +3551,7 @@ index c448e000cf9..f82644d4679 100644 unsigned int count, row_index, column_index; const struct vkd3d_shader_dst_param *params; struct vkd3d_shader_src_param *src_param; -@@ -5697,7 +5736,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin +@@ -5697,7 +5785,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin register_index_address_init(&src_param->reg.idx[count], operands[3], sm6); } @@ -2572,7 +3560,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5717,7 +5756,7 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri +@@ -5717,7 +5805,7 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri src_params[0].reg = reg; src_param_init_vector(&src_params[0], 2); @@ -2581,7 +3569,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_output_control_point_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5768,9 +5807,9 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic +@@ -5768,9 +5856,9 @@ 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; @@ -2593,7 +3581,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5915,7 +5954,7 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri +@@ -5915,7 +6003,7 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; @@ -2602,7 +3590,7 @@ index c448e000cf9..f82644d4679 100644 if (!sm6_value_is_undef(operands[2])) { /* Constant zero would be ok, but is not worth checking for unless it shows up. */ -@@ -5980,7 +6019,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr +@@ -5980,7 +6068,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; @@ -2611,7 +3599,7 @@ index c448e000cf9..f82644d4679 100644 if (!sm6_value_is_undef(operands[2])) { /* Constant zero would have no effect, but is not worth checking for unless it shows up. */ -@@ -6010,7 +6049,7 @@ static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_ +@@ -6010,7 +6098,7 @@ static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_ src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param_init(src_param); @@ -2620,7 +3608,7 @@ index c448e000cf9..f82644d4679 100644 ins->dst->reg.data_type = VSIR_DATA_U32; } -@@ -6035,14 +6074,14 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in +@@ -6035,14 +6123,14 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in if (op == DX_TEX2DMS_GET_SAMPLE_POS) { src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); @@ -2637,7 +3625,7 @@ index c448e000cf9..f82644d4679 100644 } instruction_dst_param_init_ssa_vector(ins, 2, sm6); -@@ -6104,7 +6143,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -6104,7 +6192,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ 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); @@ -2646,7 +3634,7 @@ index c448e000cf9..f82644d4679 100644 break; case DX_SAMPLE_C: clamp_idx = 10; -@@ -6113,7 +6152,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -6113,7 +6201,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ 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); @@ -2655,7 +3643,7 @@ index c448e000cf9..f82644d4679 100644 component_count = 1; break; case DX_SAMPLE_GRAD: -@@ -6148,7 +6187,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -6148,7 +6236,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -2664,7 +3652,7 @@ index c448e000cf9..f82644d4679 100644 struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; unsigned int element_idx; -@@ -6170,7 +6209,7 @@ static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intr +@@ -6170,7 +6258,7 @@ static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intr src_param->reg = sm6->input_params[element_idx].reg; src_param_init(src_param); @@ -2673,19 +3661,24 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -6182,9 +6221,9 @@ static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsi - vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); +@@ -6179,13 +6267,12 @@ 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, VSIR_OP_MOV); ++ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SATURATE); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0], sm6); + src_param_init_from_value(src_param, operands[0], 0, sm6); - if (instruction_dst_param_init_ssa_scalar(ins, sm6)) -+ if (instruction_dst_param_init_ssa_scalar(ins, 0, sm6)) - ins->dst->modifiers = VKD3DSPDM_SATURATE; +- ins->dst->modifiers = VKD3DSPDM_SATURATE; ++ instruction_dst_param_init_ssa_scalar(ins, 0, sm6); } -@@ -6197,7 +6236,7 @@ static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intr + static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -6197,7 +6284,7 @@ static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intr vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -2694,7 +3687,7 @@ index c448e000cf9..f82644d4679 100644 instruction_dst_param_init_ssa_vector(ins, 2, sm6); } -@@ -6207,7 +6246,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr +@@ -6207,7 +6294,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr { bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT; struct vkd3d_shader_instruction *ins = state->ins; @@ -2703,7 +3696,17 @@ index c448e000cf9..f82644d4679 100644 struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_dst_param *dst_param; const struct shader_signature *signature; -@@ -6263,7 +6302,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr +@@ -6227,8 +6314,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr + return; + } + e = &signature->elements[row_index]; +- if (!e->sysval_semantic) +- column_index += vsir_write_mask_get_component_idx(e->mask); ++ column_index += vsir_write_mask_get_component_idx(e->mask); + + if (column_index >= VKD3D_VEC4_SIZE) + { +@@ -6263,7 +6349,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr } if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) @@ -2712,7 +3715,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -6309,7 +6348,7 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in +@@ -6309,7 +6395,7 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in 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; @@ -2721,7 +3724,7 @@ index c448e000cf9..f82644d4679 100644 } src_param_init_vector_from_reg(&src_params[0], &coord); -@@ -6372,7 +6411,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr +@@ -6372,7 +6458,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) @@ -2730,7 +3733,7 @@ index c448e000cf9..f82644d4679 100644 instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); } -@@ -6436,7 +6475,7 @@ static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum d +@@ -6436,7 +6522,7 @@ static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum d vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_WAVE_ACTIVE_BALLOT); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -2739,7 +3742,7 @@ index c448e000cf9..f82644d4679 100644 instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); } -@@ -6476,9 +6515,9 @@ static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_i +@@ -6476,9 +6562,9 @@ static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_i if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -2751,7 +3754,7 @@ index c448e000cf9..f82644d4679 100644 } static enum vkd3d_shader_opcode sm6_dx_map_wave_op(enum dxil_wave_op_kind op, bool is_signed, bool is_float, -@@ -6527,9 +6566,9 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic +@@ -6527,9 +6613,9 @@ 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; @@ -2763,7 +3766,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -6918,14 +6957,15 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor +@@ -6918,14 +7004,15 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); } @@ -2781,7 +3784,7 @@ index c448e000cf9..f82644d4679 100644 from_int = sm6_type_is_integer(from); to_int = sm6_type_is_integer(to); from_fp = sm6_type_is_floating_point(from); -@@ -6934,15 +6974,13 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ +@@ -6934,15 +7021,13 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ /* NOTE: DXIL currently doesn't use vectors here. */ if ((!from_int && !from_fp) || (!to_int && !to_fp)) { @@ -2799,7 +3802,7 @@ index c448e000cf9..f82644d4679 100644 "Cast to/from an 8-bit type is not implemented."); return VSIR_OP_INVALID; } -@@ -6982,6 +7020,7 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ +@@ -6982,6 +7067,7 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ case CAST_SITOFP: op = VSIR_OP_ITOF; is_valid = from_int && to_fp; @@ -2807,7 +3810,7 @@ index c448e000cf9..f82644d4679 100644 break; case CAST_FPTRUNC: -@@ -7000,16 +7039,14 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ +@@ -7000,16 +7086,14 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ break; default: @@ -2826,7 +3829,7 @@ index c448e000cf9..f82644d4679 100644 "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 VSIR_OP_INVALID; -@@ -7032,22 +7069,23 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ +@@ -7032,22 +7116,23 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ return op; } @@ -2855,7 +3858,7 @@ index c448e000cf9..f82644d4679 100644 return; dst->type = type; -@@ -7060,28 +7098,28 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor +@@ -7060,35 +7145,36 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor return; } @@ -2891,15 +3894,16 @@ index c448e000cf9..f82644d4679 100644 src_param->reg.data_type = ins->dst[0].reg.data_type; } -@@ -7089,6 +7127,7 @@ struct sm6_cmp_info + struct sm6_cmp_info { - enum vkd3d_shader_opcode handler_idx; +- enum vkd3d_shader_opcode handler_idx; ++ enum vkd3d_shader_opcode opcode; bool src_swap; + uint32_t type_flags; }; static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) -@@ -7118,10 +7157,10 @@ static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) +@@ -7118,10 +7204,10 @@ static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) [ICMP_UGE] = {VSIR_OP_UGE}, [ICMP_ULT] = {VSIR_OP_ULT}, [ICMP_ULE] = {VSIR_OP_UGE, true}, @@ -2914,7 +3918,25 @@ index c448e000cf9..f82644d4679 100644 }; return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL; -@@ -7222,10 +7261,10 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor +@@ -7188,7 +7274,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 == VSIR_OP_INVALID) ++ if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->opcode || cmp->opcode == VSIR_OP_INVALID) + { + FIXME("Unhandled operation %"PRIu64".\n", code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -7196,7 +7282,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor + return; + } + +- vsir_instruction_init(ins, &sm6->p.location, cmp->handler_idx); ++ vsir_instruction_init(ins, &sm6->p.location, cmp->opcode); + + flags = (record->operand_count > i) ? record->operands[i] : 0; + silence_warning = false; +@@ -7222,10 +7308,10 @@ 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; @@ -2928,7 +3950,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -7245,7 +7284,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re +@@ -7245,7 +7331,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re || !sm6_value_validate_is_backward_ref(ptr, sm6)) return; @@ -2937,7 +3959,22 @@ index c448e000cf9..f82644d4679 100644 if (reg.type != VKD3DSPR_GROUPSHAREDMEM) { -@@ -7300,14 +7339,14 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re +@@ -7288,6 +7374,8 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re + /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */ + if (success_ordering != ORDERING_SEQCST) + FIXME("Unhandled success ordering %"PRIu64".\n", success_ordering); ++ else ++ WARN("Ignoring success ordering %"PRIu64".\n", success_ordering); + if (success_ordering != failure_ordering) + FIXME("Unhandled failure ordering %"PRIu64".\n", failure_ordering); + +@@ -7295,19 +7383,19 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re + FIXME("Ignoring weak cmpxchg.\n"); + + 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; ++ ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0; + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; src_param_make_constant_uint(&src_params[0], 0); @@ -2955,7 +3992,7 @@ index c448e000cf9..f82644d4679 100644 dst_param_init(&dst_params[0]); dst_params[1].reg = reg; dst_param_init(&dst_params[1]); -@@ -7366,10 +7405,10 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil +@@ -7366,10 +7454,10 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -2968,7 +4005,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -7515,7 +7554,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor +@@ -7515,7 +7603,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor if (record->operands[i]) WARN("Ignoring volatile modifier.\n"); @@ -2977,7 +4014,7 @@ index c448e000cf9..f82644d4679 100644 if (ptr->structure_stride) { -@@ -7530,7 +7569,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor +@@ -7530,7 +7618,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); @@ -2986,7 +4023,7 @@ index c448e000cf9..f82644d4679 100644 src_params[2].reg.alignment = alignment; /* The offset is already in src_params[0]. */ src_params[2].reg.idx_count = 1; -@@ -7544,11 +7583,11 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor +@@ -7544,11 +7632,11 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor return; if (operand_count > 1) src_param_make_constant_uint(&src_params[0], 0); @@ -3000,7 +4037,7 @@ index c448e000cf9..f82644d4679 100644 } static int phi_incoming_compare(const void *a, const void *b) -@@ -7702,7 +7741,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco +@@ -7702,7 +7790,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco if (record->operands[i]) WARN("Ignoring volatile modifier.\n"); @@ -3009,7 +4046,7 @@ index c448e000cf9..f82644d4679 100644 if (ptr->structure_stride) { -@@ -7717,7 +7756,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco +@@ -7717,7 +7805,7 @@ 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); @@ -3018,7 +4055,7 @@ index c448e000cf9..f82644d4679 100644 } else { -@@ -7728,7 +7767,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco +@@ -7728,7 +7816,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco return; if (operand_count > 1) src_param_make_constant_uint(&src_params[0], 0); @@ -3027,7 +4064,7 @@ index c448e000cf9..f82644d4679 100644 } dst_param = instruction_dst_params_alloc(ins, 1, sm6); -@@ -7778,7 +7817,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec +@@ -7778,7 +7866,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec return; } @@ -3036,7 +4073,7 @@ index c448e000cf9..f82644d4679 100644 terminator->type = TERMINATOR_SWITCH; terminator->case_count = record->operand_count / 2u; -@@ -7854,9 +7893,11 @@ static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_re +@@ -7854,9 +7942,11 @@ static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_re if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; for (i = 0; i < 3; ++i) @@ -3050,7 +4087,7 @@ index c448e000cf9..f82644d4679 100644 } static bool sm6_metadata_value_is_node(const struct sm6_metadata_value *m) -@@ -8195,7 +8236,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun +@@ -8195,7 +8285,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun 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."); } @@ -3059,7 +4096,7 @@ index c448e000cf9..f82644d4679 100644 } } } -@@ -8206,7 +8247,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun +@@ -8206,7 +8296,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, struct sm6_function *function) { @@ -3068,7 +4105,16 @@ index c448e000cf9..f82644d4679 100644 struct vkd3d_shader_instruction *ins; size_t i, block_idx, block_count; const struct dxil_record *record; -@@ -8355,8 +8396,8 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const +@@ -8301,7 +8391,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const + break; + } + case FUNC_CODE_INST_BINOP: +- sm6_parser_emit_binop(sm6, record, ins, dst); ++ sm6_parser_emit_binop(sm6, record, code_block, ins, dst); + break; + case FUNC_CODE_INST_BR: + sm6_parser_emit_br(sm6, record, function, code_block, ins); +@@ -8355,8 +8445,8 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; } @@ -3079,7 +4125,7 @@ index c448e000cf9..f82644d4679 100644 if (record->attachment) metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6); -@@ -8403,18 +8444,26 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ +@@ -8403,18 +8493,26 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ case TERMINATOR_UNCOND_BR: if (!block->terminator.true_block) return; @@ -3108,7 +4154,7 @@ index c448e000cf9..f82644d4679 100644 src_param_init(&src_params[0]); src_params[0].reg = block->terminator.conditional_reg; vsir_src_param_init_label(&src_params[1], block->terminator.true_block->id); -@@ -8422,9 +8471,13 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ +@@ -8422,9 +8520,13 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ break; case TERMINATOR_SWITCH: @@ -3123,7 +4169,7 @@ index c448e000cf9..f82644d4679 100644 src_param_init(&src_params[0]); src_params[0].reg = block->terminator.conditional_reg; /* TODO: emit the merge block id. */ -@@ -8438,7 +8491,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ +@@ -8438,7 +8540,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ switch_case = &block->terminator.cases[i]; if (!(case_block = switch_case->block)) { @@ -3132,7 +4178,7 @@ index c448e000cf9..f82644d4679 100644 continue; } if (switch_case->is_default) -@@ -8491,11 +8544,18 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser +@@ -8491,11 +8593,18 @@ 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; @@ -3152,7 +4198,7 @@ index c448e000cf9..f82644d4679 100644 for (j = 0; j < incoming_count; ++j) { -@@ -8507,11 +8567,11 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser +@@ -8507,11 +8616,11 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser if (incoming_block) vsir_src_param_init_label(&src_params[index + 1], incoming_block->id); else @@ -3166,7 +4212,7 @@ index c448e000cf9..f82644d4679 100644 } } -@@ -8577,42 +8637,45 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) +@@ -8577,42 +8686,45 @@ 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; @@ -3229,7 +4275,18 @@ index c448e000cf9..f82644d4679 100644 } static bool sm6_parser_allocate_named_metadata(struct sm6_parser *sm6) -@@ -9510,8 +9573,8 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, +@@ -8813,8 +8925,8 @@ static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const + if (!(value = sm6_parser_get_value_safe(sm6, value_idx))) + return VKD3D_ERROR_INVALID_SHADER; + +- if (!sm6_value_is_constant(value) && !sm6_value_is_undef(value) && !sm6_value_is_data(value) +- && !sm6_value_is_function_dcl(value)) ++ if (!sm6_value_is_constant(value) && !sm6_value_is_undef(value) ++ && !sm6_value_is_constant_array(value) && !sm6_value_is_function_dcl(value)) + { + WARN("Value at index %u is not a constant or a function declaration.\n", value_idx); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA, +@@ -9510,8 +9622,8 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins; const struct sm6_metadata_node *node; const struct sm6_metadata_value *m; @@ -3239,7 +4296,7 @@ index c448e000cf9..f82644d4679 100644 unsigned int i; for (i = 0; i < descriptor_node->operand_count; ++i) -@@ -9560,42 +9623,41 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, +@@ -9560,42 +9672,41 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; } @@ -3294,7 +4351,7 @@ index c448e000cf9..f82644d4679 100644 } static enum vkd3d_result sm6_parser_resources_init(struct sm6_parser *sm6) -@@ -9711,7 +9773,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const +@@ -9711,7 +9822,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const { unsigned int i, j, column_count, operand_count, index; const struct sm6_metadata_node *node, *element_node; @@ -3303,7 +4360,7 @@ index c448e000cf9..f82644d4679 100644 struct signature_element *elements, *e; unsigned int values[10]; bool native_16bit; -@@ -9930,7 +9992,7 @@ invalid: +@@ -9930,7 +10041,7 @@ invalid: static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m, enum vkd3d_tessellator_domain tessellator_domain) { @@ -3312,7 +4369,7 @@ index c448e000cf9..f82644d4679 100644 enum vkd3d_result ret; if (!sm6_metadata_value_is_node(m)) -@@ -9953,6 +10015,14 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons +@@ -9953,6 +10064,14 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons &program->patch_constant_signature, tessellator_domain, false)) < 0) return ret; @@ -3327,7 +4384,7 @@ index c448e000cf9..f82644d4679 100644 if ((ret = sm6_parser_init_input_signature(sm6, &program->input_signature)) < 0) return ret; -@@ -9983,14 +10053,15 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm +@@ -9983,14 +10102,15 @@ 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; @@ -3346,7 +4403,7 @@ index c448e000cf9..f82644d4679 100644 const struct sm6_metadata_node *node; struct vkd3d_shader_instruction *ins; unsigned int group_sizes[3]; -@@ -10040,11 +10111,12 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co +@@ -10040,30 +10160,33 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co } } @@ -3361,27 +4418,33 @@ index c448e000cf9..f82644d4679 100644 return VKD3D_OK; } -@@ -10053,7 +10125,8 @@ static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_ + +-static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, unsigned int count) ++static void sm6_parser_emit_dcl_count(struct sm6_parser *dxil, enum vkd3d_shader_opcode opcode, unsigned int count) { struct vkd3d_shader_instruction *ins; - ins = sm6_parser_add_instruction(sm6, handler_idx); -+ if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) ++ if (!(ins = sm6_parser_add_instruction(dxil, opcode))) + return; ins->declaration.count = count; } -@@ -10063,7 +10136,8 @@ static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *sm6, +-static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *sm6, +- enum vkd3d_shader_opcode handler_idx, enum vkd3d_primitive_type primitive_type, ++static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *dxil, ++ enum vkd3d_shader_opcode opcode, enum vkd3d_primitive_type primitive_type, + unsigned int patch_vertex_count) { struct vkd3d_shader_instruction *ins; - ins = sm6_parser_add_instruction(sm6, handler_idx); -+ if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) ++ if (!(ins = sm6_parser_add_instruction(dxil, opcode))) + return; ins->declaration.primitive_type.type = primitive_type; ins->declaration.primitive_type.patch_vertex_count = patch_vertex_count; } -@@ -10080,9 +10154,10 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, +@@ -10080,9 +10203,10 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, "Domain shader tessellator domain %u is unhandled.", tessellator_domain); } @@ -3394,7 +4457,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, -@@ -10108,10 +10183,11 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, +@@ -10108,10 +10232,11 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, "Hull shader tessellator partitioning %u is unhandled.", tessellator_partitioning); } @@ -3408,7 +4471,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *sm6, -@@ -10126,10 +10202,11 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * +@@ -10126,10 +10251,11 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * "Hull shader tessellator output primitive %u is unhandled.", primitive); } @@ -3422,7 +4485,7 @@ index c448e000cf9..f82644d4679 100644 } static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, struct sm6_metadata_value *m) -@@ -10153,7 +10230,8 @@ static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, +@@ -10153,7 +10279,8 @@ static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, "Hull shader max tessellation factor %f is invalid.", max_tessellation_factor); } @@ -3432,7 +4495,7 @@ index c448e000cf9..f82644d4679 100644 ins->declaration.max_tessellation_factor = max_tessellation_factor; } -@@ -10241,8 +10319,8 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -10241,8 +10368,8 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s } sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); @@ -3443,7 +4506,7 @@ index c448e000cf9..f82644d4679 100644 i = operands[1]; /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */ -@@ -10253,7 +10331,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -10253,7 +10380,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s "Geometry shader output vertex count %u is invalid.", i); } sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_VERTICES_OUT, i); @@ -3452,7 +4515,7 @@ index c448e000cf9..f82644d4679 100644 if (operands[2] > 1) { -@@ -10271,7 +10349,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -10271,7 +10398,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s output_primitive = VKD3D_PT_TRIANGLELIST; } sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); @@ -3461,7 +4524,7 @@ index c448e000cf9..f82644d4679 100644 i = operands[4]; if (!i || i > MAX_GS_INSTANCE_COUNT) -@@ -10326,7 +10404,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa +@@ -10326,7 +10453,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]); sm6_parser_validate_control_point_count(sm6, operands[1], true, "Domain shader input"); @@ -3470,7 +4533,7 @@ index c448e000cf9..f82644d4679 100644 return operands[0]; } -@@ -10334,7 +10412,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa +@@ -10334,7 +10461,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m) { @@ -3479,7 +4542,7 @@ index c448e000cf9..f82644d4679 100644 const struct sm6_metadata_node *node; unsigned int operands[6] = {0}; unsigned int i; -@@ -10633,7 +10711,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10633,7 +10760,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro { size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size; const struct vkd3d_shader_location location = {.source_name = compile_info->source_name}; @@ -3487,7 +4550,7 @@ index c448e000cf9..f82644d4679 100644 uint32_t version_token, dxil_version, token_count, magic; const uint32_t *byte_code = dxbc_desc->byte_code; unsigned int chunk_offset, chunk_size; -@@ -10727,9 +10804,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10727,9 +10853,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro if (!vsir_program_init(program, compile_info, &version, (count + (count >> 2)) / 2u + 10, VSIR_CF_BLOCKS, VSIR_NORMALISED_SM6)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -3499,7 +4562,7 @@ index c448e000cf9..f82644d4679 100644 switch (program->shader_version.type) { -@@ -10746,9 +10824,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10746,9 +10873,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro break; } @@ -3509,7 +4572,7 @@ index c448e000cf9..f82644d4679 100644 program->features = dxbc_desc->features; memset(dxbc_desc, 0, sizeof(*dxbc_desc)); -@@ -10890,15 +10965,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10890,15 +11014,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro goto fail; } @@ -3525,7 +4588,7 @@ index c448e000cf9..f82644d4679 100644 program->ssa_count = sm6->ssa_next_id; if (!(fn = sm6_parser_get_function(sm6, sm6->entry_point))) -@@ -10949,15 +11015,13 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10949,15 +11064,13 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro dxil_block_destroy(&sm6->root_block); @@ -3558,9 +4621,18 @@ index 676c501bb08..a14346a45d2 100644 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..b2679beff9f 100644 +index dfe0a40ddf0..4d7505d8740 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -280,7 +280,7 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, + break; + + case VKD3DSPR_THREADID: +- vkd3d_string_buffer_printf(buffer, "gl_GlobalInvocationID"); ++ vkd3d_string_buffer_printf(buffer, "uvec4(gl_GlobalInvocationID, 0)"); + break; + + case VKD3DSPR_IDXTEMP: @@ -288,6 +288,14 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, shader_glsl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); break; @@ -3576,7 +4648,122 @@ index dfe0a40ddf0..b2679beff9f 100644 default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled register type %#x.", reg->type); -@@ -792,7 +800,7 @@ static void shader_glsl_print_texel_offset(struct vkd3d_string_buffer *buffer, s +@@ -384,7 +392,7 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd + 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; ++ struct vkd3d_string_buffer *register_name; + enum vsir_data_type src_data_type; + unsigned int size; + +@@ -401,39 +409,11 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd + + shader_glsl_print_register_name(register_name, gen, reg); + +- if (!vsir_src->modifiers) +- str = buffer; +- else +- str = vkd3d_string_buffer_get(&gen->string_buffers); +- + size = reg->dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; +- shader_glsl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, size); ++ shader_glsl_print_bitcast(buffer, gen, register_name->buffer, data_type, src_data_type, size); + if (reg->dimension == VSIR_DIMENSION_VEC4) +- shader_glsl_print_swizzle(str, vsir_src->swizzle, mask); +- +- switch (vsir_src->modifiers) +- { +- case VKD3DSPSM_NONE: +- break; +- case VKD3DSPSM_NEG: +- vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); +- break; +- 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); +- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); +- break; +- } ++ shader_glsl_print_swizzle(buffer, vsir_src->swizzle, mask); + +- if (str != buffer) +- vkd3d_string_buffer_release(&gen->string_buffers, str); + vkd3d_string_buffer_release(&gen->string_buffers, register_name); + } + +@@ -495,23 +475,14 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g + 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); +- if (modifiers & ~VKD3DSPDM_SATURATE) +- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled destination modifier(s) %#x.", modifiers); + + shader_glsl_print_indent(buffer, gen->indent); + vkd3d_string_buffer_printf(buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer); +- if (modifiers & VKD3DSPDM_SATURATE) +- vkd3d_string_buffer_printf(buffer, "clamp("); + + switch (data_type) + { +@@ -520,6 +491,8 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g + "Internal compiler error: Unhandled destination register data type %#x.", data_type); + /* fall through */ + case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: + close = false; + break; + case VSIR_DATA_I32: +@@ -534,8 +507,6 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g + + if (close) + vkd3d_string_buffer_printf(buffer, ")"); +- if (modifiers & VKD3DSPDM_SATURATE) +- vkd3d_string_buffer_printf(buffer, ", 0.0, 1.0)"); + vkd3d_string_buffer_printf(buffer, ";\n"); + } + +@@ -611,6 +582,21 @@ static void shader_glsl_dot(struct vkd3d_glsl_generator *gen, + glsl_dst_cleanup(&dst, &gen->string_buffers); + } + ++static void shader_glsl_saturate(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ struct glsl_src src; ++ struct glsl_dst dst; ++ uint32_t mask; ++ ++ mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); ++ glsl_src_init(&src, gen, &ins->src[0], mask); ++ ++ shader_glsl_print_assignment(gen, &dst, "clamp(%s, 0.0, 1.0)", src.str->buffer); ++ ++ glsl_src_cleanup(&src, &gen->string_buffers); ++ glsl_dst_cleanup(&dst, &gen->string_buffers); ++} ++ + static void shader_glsl_intrinsic(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_instruction *ins, const char *op) + { +@@ -792,7 +778,7 @@ static void shader_glsl_print_texel_offset(struct vkd3d_string_buffer *buffer, s static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { @@ -3585,7 +4772,7 @@ index dfe0a40ddf0..b2679beff9f 100644 const struct glsl_resource_type_info *resource_type_info; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; -@@ -800,11 +808,9 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ +@@ -800,11 +786,9 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ enum vsir_data_type data_type; struct glsl_src coord; struct glsl_dst dst; @@ -3599,7 +4786,7 @@ index dfe0a40ddf0..b2679beff9f 100644 if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, -@@ -831,20 +837,22 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ +@@ -831,20 +815,22 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) { @@ -3626,7 +4813,7 @@ index dfe0a40ddf0..b2679beff9f 100644 shader_glsl_print_combined_sampler_name(fetch, gen, resource_idx, resource_space, VKD3D_SHADER_DUMMY_SAMPLER_INDEX, 0); vkd3d_string_buffer_printf(fetch, ", %s", coord.str->buffer); -@@ -860,6 +868,11 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ +@@ -860,6 +846,11 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ else shader_glsl_print_src(fetch, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, ins->src[2].reg.data_type); } @@ -3638,7 +4825,50 @@ index dfe0a40ddf0..b2679beff9f 100644 vkd3d_string_buffer_printf(fetch, ")"); shader_glsl_print_swizzle(fetch, ins->src[1].swizzle, ins->dst[0].write_mask); -@@ -1281,6 +1294,13 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st +@@ -1227,25 +1218,33 @@ static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d + + static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) + { ++ struct vkd3d_string_buffer *src1, *src2; + unsigned int component_count; +- struct glsl_src src[3]; ++ struct glsl_src src[1]; + struct glsl_dst dst; + uint32_t mask; + ++ /* Sadly, mix() in unextended GLSL 4.40 can only select between ++ * floating-point sources. The earliest version able to select between ++ * integer sources is version 4.50; the same functionality is also ++ * provided by the EXT_shader_integer_mix extension. */ ++ + mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); + glsl_src_init(&src[0], gen, &ins->src[0], mask); +- glsl_src_init(&src[1], gen, &ins->src[1], mask); +- glsl_src_init(&src[2], gen, &ins->src[2], mask); ++ src1 = vkd3d_string_buffer_get(&gen->string_buffers); ++ src2 = vkd3d_string_buffer_get(&gen->string_buffers); ++ shader_glsl_print_src(src1, gen, &ins->src[1], mask, VSIR_DATA_F32); ++ shader_glsl_print_src(src2, gen, &ins->src[2], mask, VSIR_DATA_F32); + + if ((component_count = vsir_write_mask_component_count(mask)) > 1) +- shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bvec%u(%s))", +- src[2].str->buffer, src[1].str->buffer, component_count, src[0].str->buffer); ++ shader_glsl_print_assignment_ext(gen, &dst, VSIR_DATA_F32, "mix(%s, %s, bvec%u(%s))", ++ src2->buffer, src1->buffer, component_count, src[0].str->buffer); + else +- shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bool(%s))", +- src[2].str->buffer, src[1].str->buffer, src[0].str->buffer); ++ shader_glsl_print_assignment_ext(gen, &dst, VSIR_DATA_F32, "mix(%s, %s, bool(%s))", ++ src2->buffer, src1->buffer, src[0].str->buffer); + +- glsl_src_cleanup(&src[2], &gen->string_buffers); +- glsl_src_cleanup(&src[1], &gen->string_buffers); ++ vkd3d_string_buffer_release(&gen->string_buffers, src2); ++ vkd3d_string_buffer_release(&gen->string_buffers, src1); + glsl_src_cleanup(&src[0], &gen->string_buffers); + glsl_dst_cleanup(&dst, &gen->string_buffers); + } +@@ -1281,6 +1280,13 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_VertexID, 0, 0, 0))"); break; @@ -3652,7 +4882,7 @@ index dfe0a40ddf0..b2679beff9f 100644 case VKD3D_SHADER_SV_IS_FRONT_FACE: if (version->type != VKD3D_SHADER_TYPE_PIXEL) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -@@ -1429,6 +1449,12 @@ static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen) +@@ -1429,6 +1435,12 @@ static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen) shader_glsl_print_write_mask(buffer, e->mask); vkd3d_string_buffer_printf(buffer, ";\n"); } @@ -3665,7 +4895,17 @@ index dfe0a40ddf0..b2679beff9f 100644 } static void shader_glsl_ret(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) -@@ -1475,6 +1501,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, +@@ -1459,6 +1471,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + + switch (ins->opcode) + { ++ case VSIR_OP_ABS: ++ shader_glsl_intrinsic(gen, ins, "abs"); ++ break; + case VSIR_OP_ADD: + case VSIR_OP_IADD: + shader_glsl_binop(gen, ins, "+"); +@@ -1475,6 +1490,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VSIR_OP_CONTINUE: shader_glsl_continue(gen); break; @@ -3675,7 +4915,7 @@ index dfe0a40ddf0..b2679beff9f 100644 case VSIR_OP_DCL_INDEXABLE_TEMP: shader_glsl_dcl_indexable_temp(gen, ins); break; -@@ -1495,6 +1524,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, +@@ -1495,6 +1513,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VSIR_OP_DP4: shader_glsl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); break; @@ -3688,7 +4928,7 @@ index dfe0a40ddf0..b2679beff9f 100644 case VSIR_OP_ELSE: shader_glsl_else(gen, ins); break; -@@ -1531,6 +1566,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, +@@ -1531,6 +1555,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, break; case VSIR_OP_GEO: case VSIR_OP_IGE: @@ -3696,17 +4936,28 @@ index dfe0a40ddf0..b2679beff9f 100644 shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); break; case VSIR_OP_IF: -@@ -1620,6 +1656,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, +@@ -1561,6 +1586,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + shader_glsl_relop(gen, ins, "!=", "notEqual"); + break; + case VSIR_OP_INEG: ++ case VSIR_OP_NEG: + shader_glsl_unary_op(gen, ins, "-"); + break; + case VSIR_OP_ISHL: +@@ -1620,6 +1646,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VSIR_OP_RSQ: shader_glsl_intrinsic(gen, ins, "inversesqrt"); break; ++ case VSIR_OP_SATURATE: ++ shader_glsl_saturate(gen, ins); ++ break; + case VSIR_OP_SIN: + shader_glsl_intrinsic(gen, ins, "sin"); + break; case VSIR_OP_SQRT: shader_glsl_intrinsic(gen, ins, "sqrt"); break; -@@ -1629,6 +1668,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, +@@ -1629,6 +1661,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VSIR_OP_SWITCH: shader_glsl_switch(gen, ins); break; @@ -3719,7 +4970,7 @@ index dfe0a40ddf0..b2679beff9f 100644 case VSIR_OP_XOR: shader_glsl_binop(gen, ins, "^"); break; -@@ -2318,6 +2363,8 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) +@@ -2318,6 +2356,8 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) vkd3d_string_buffer_printf(buffer, "vec4 %s_in[%u];\n", gen->prefix, gen->limits.input_count); if (gen->limits.output_count) vkd3d_string_buffer_printf(buffer, "vec4 %s_out[%u];\n", gen->prefix, gen->limits.output_count); @@ -3728,7 +4979,7 @@ index dfe0a40ddf0..b2679beff9f 100644 if (program->temp_count) vkd3d_string_buffer_printf(buffer, "vec4 r[%u];\n", program->temp_count); vkd3d_string_buffer_printf(buffer, "\n"); -@@ -2328,7 +2375,6 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc +@@ -2328,7 +2368,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; @@ -3736,7 +4987,7 @@ index dfe0a40ddf0..b2679beff9f 100644 MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); -@@ -2357,13 +2403,7 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc +@@ -2357,13 +2396,7 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc if (gen->failed) return VKD3D_ERROR_INVALID_SHADER; @@ -3751,8 +5002,16 @@ index dfe0a40ddf0..b2679beff9f 100644 return VKD3D_OK; } +@@ -2449,6 +2482,7 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, + + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); ++ VKD3D_ASSERT(program->has_no_modifiers); + + vkd3d_glsl_generator_init(&generator, program, compile_info, + combined_sampler_info, message_context); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 62335086e20..ec1e27d9496 100644 +index 62335086e20..1de17e2b551 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -393,6 +393,11 @@ bool hlsl_type_is_signed_integer(const struct hlsl_type *type) @@ -3767,7 +5026,20 @@ index 62335086e20..ec1e27d9496 100644 bool hlsl_type_is_integer(const struct hlsl_type *type) { VKD3D_ASSERT(hlsl_is_numeric_type(type)); -@@ -1809,6 +1814,76 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v +@@ -1732,6 +1737,12 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t + return &c->node; + } + ++struct hlsl_ir_node *hlsl_block_add_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc) ++{ ++ return append_new_instr(ctx, block, hlsl_new_constant(ctx, type, value, loc)); ++} ++ + struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc) + { + struct hlsl_constant_value value; +@@ -1809,6 +1820,76 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); } @@ -3844,7 +5116,21 @@ index 62335086e20..ec1e27d9496 100644 static struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) -@@ -3654,8 +3729,11 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) +@@ -2130,11 +2211,11 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, + return &store->node; + } + +-void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, ++struct hlsl_ir_node *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, uint32_t writemask, const struct vkd3d_shader_location *loc) + { +- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc)); ++ return 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, +@@ -3654,8 +3735,11 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_BIT_NOT] = "~", [HLSL_OP1_CAST] = "cast", [HLSL_OP1_CEIL] = "ceil", @@ -3856,7 +5142,7 @@ index 62335086e20..ec1e27d9496 100644 [HLSL_OP1_DSX] = "dsx", [HLSL_OP1_DSX_COARSE] = "dsx_coarse", [HLSL_OP1_DSX_FINE] = "dsx_fine", -@@ -3665,6 +3743,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) +@@ -3665,6 +3749,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_EXP2] = "exp2", [HLSL_OP1_F16TOF32] = "f16tof32", [HLSL_OP1_F32TOF16] = "f32tof16", @@ -3864,7 +5150,7 @@ index 62335086e20..ec1e27d9496 100644 [HLSL_OP1_FLOOR] = "floor", [HLSL_OP1_FRACT] = "fract", [HLSL_OP1_ISINF] = "isinf", -@@ -3718,8 +3797,9 @@ static void dump_ir_expr(struct vkd3d_string_buffer *buffer, const struct hlsl_i +@@ -3718,8 +3803,9 @@ static void dump_ir_expr(struct vkd3d_string_buffer *buffer, const struct hlsl_i vkd3d_string_buffer_printf(buffer, "%s (", debug_hlsl_expr_op(expr->op)); for (i = 0; i < HLSL_MAX_OPERANDS && expr->operands[i].node; ++i) { @@ -3876,7 +5162,7 @@ index 62335086e20..ec1e27d9496 100644 vkd3d_string_buffer_printf(buffer, ")"); } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index d67f820fe8b..8dbfd062177 100644 +index d67f820fe8b..75027f83e33 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -233,6 +233,9 @@ struct hlsl_type @@ -3889,7 +5175,24 @@ index d67f820fe8b..8dbfd062177 100644 bool is_typedef; uint32_t is_minimum_precision : 1; -@@ -715,8 +718,11 @@ enum hlsl_ir_expr_op +@@ -245,6 +248,7 @@ struct hlsl_semantic + const char *name; + uint32_t index; + uint32_t stream_index; ++ uint32_t modifiers; + + /* Name exactly as it appears in the sources. */ + const char *raw_name; +@@ -530,6 +534,8 @@ struct hlsl_ir_var + struct + { + bool used; ++ bool uav_read; ++ bool uav_atomics; + enum hlsl_sampler_dim sampler_dim; + struct vkd3d_shader_location first_sampler_dim_loc; + } *objects_usage[HLSL_REGSET_LAST_OBJECT + 1]; +@@ -715,8 +721,11 @@ enum hlsl_ir_expr_op HLSL_OP1_BIT_NOT, HLSL_OP1_CAST, HLSL_OP1_CEIL, @@ -3901,7 +5204,7 @@ index d67f820fe8b..8dbfd062177 100644 HLSL_OP1_DSX, HLSL_OP1_DSX_COARSE, HLSL_OP1_DSX_FINE, -@@ -726,6 +732,7 @@ enum hlsl_ir_expr_op +@@ -726,6 +735,7 @@ enum hlsl_ir_expr_op HLSL_OP1_EXP2, HLSL_OP1_F16TOF32, HLSL_OP1_F32TOF16, @@ -3909,7 +5212,7 @@ index d67f820fe8b..8dbfd062177 100644 HLSL_OP1_FLOOR, HLSL_OP1_FRACT, HLSL_OP1_ISINF, -@@ -1184,8 +1191,8 @@ struct hlsl_ctx +@@ -1184,8 +1194,8 @@ struct hlsl_ctx } constant_defs; /* 'c' registers where the constants expected by SM2 sincos are stored. */ struct hlsl_reg d3dsincosconst1, d3dsincosconst2; @@ -3920,7 +5223,7 @@ index d67f820fe8b..8dbfd062177 100644 /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ -@@ -1541,6 +1548,12 @@ static inline bool hlsl_var_has_buffer_offset_register_reservation(struct hlsl_c +@@ -1541,6 +1551,12 @@ static inline bool hlsl_var_has_buffer_offset_register_reservation(struct hlsl_c return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer; } @@ -3933,7 +5236,25 @@ index d67f820fe8b..8dbfd062177 100644 char *hlsl_sprintf_alloc(struct hlsl_ctx *ctx, const char *fmt, ...) VKD3D_PRINTF_FUNC(2, 3); const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); -@@ -1693,6 +1706,9 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, +@@ -1563,6 +1579,8 @@ struct hlsl_ir_node *hlsl_block_add_binary_expr(struct hlsl_ctx *ctx, struct hls + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2); + struct hlsl_ir_node *hlsl_block_add_cast(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_node *arg, struct hlsl_type *type, const struct vkd3d_shader_location *loc); ++struct hlsl_ir_node *hlsl_block_add_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc); +@@ -1585,7 +1603,7 @@ void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block, + unsigned int unroll_limit, const struct vkd3d_shader_location *loc); + 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); +-void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, ++struct hlsl_ir_node *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, 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, +@@ -1693,6 +1711,9 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct hlsl_ir_node *arg3); @@ -3943,7 +5264,7 @@ index d67f820fe8b..8dbfd062177 100644 void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var); struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, -@@ -1779,10 +1795,10 @@ bool hlsl_type_is_integer(const struct hlsl_type *type); +@@ -1779,10 +1800,10 @@ bool hlsl_type_is_integer(const struct hlsl_type *type); bool hlsl_type_is_floating_point(const struct hlsl_type *type); bool hlsl_type_is_row_major(const struct hlsl_type *type); bool hlsl_type_is_signed_integer(const struct hlsl_type *type); @@ -3955,11 +5276,36 @@ index d67f820fe8b..8dbfd062177 100644 bool hlsl_type_is_minimum_precision(const struct hlsl_type *type); bool hlsl_type_is_resource(const struct hlsl_type *type); bool hlsl_type_is_shader(const struct hlsl_type *type); +@@ -1814,10 +1835,13 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl + struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); + + bool hlsl_copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block); +-bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); +-bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); ++struct hlsl_ir_node *hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block); ++struct hlsl_ir_node *hlsl_fold_constant_identities(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block); + bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); +-bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); ++struct hlsl_ir_node *hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block); + bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), + struct hlsl_block *block, void *context); + diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -index 0cdebb8a657..da9f0d39136 100644 +index 0cdebb8a657..c41d807cca1 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; } +@@ -83,7 +83,6 @@ ComputeShader {return KW_COMPUTESHADER; } + compile {return KW_COMPILE; } + CompileShader {return KW_COMPILESHADER; } + const {return KW_CONST; } +-ConstructGSWithSO {return KW_CONSTRUCTGSWITHSO; } + continue {return KW_CONTINUE; } + DepthStencilState {return KW_DEPTHSTENCILSTATE; } + DepthStencilView {return KW_DEPTHSTENCILVIEW; } +@@ -346,7 +345,7 @@ while {return KW_WHILE; } {ANY} {} {ANY} { @@ -3969,10 +5315,91 @@ index 0cdebb8a657..da9f0d39136 100644 %% diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 024d96c5663..d3004d7cc8a 100644 +index 024d96c5663..8ec963c8656 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -3181,6 +3181,20 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, +@@ -614,10 +614,6 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx + if (!(ret.string = vkd3d_strdup(string->string))) + return ret; + } +- else if (node->type == HLSL_IR_STRING_CONSTANT) +- { +- hlsl_fixme(ctx, &node->loc, "Evaluate string constants as static expressions."); +- } + else + { + hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, +@@ -1082,7 +1078,7 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, + field->loc = v->loc; + field->name = v->name; + field->semantic = v->semantic; +- field->storage_modifiers = modifiers; ++ field->storage_modifiers = modifiers | v->semantic.modifiers; + if (v->initializer.args_count) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Illegal initializer on a struct field."); +@@ -1211,16 +1207,17 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i + static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters *parameters, + struct parse_parameter *param, const struct vkd3d_shader_location *loc) + { ++ uint32_t modifiers = param->modifiers | param->semantic.modifiers; + struct hlsl_ir_var *var; + + if (param->type->class == HLSL_CLASS_MATRIX) + VKD3D_ASSERT(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); + +- if ((param->modifiers & HLSL_STORAGE_OUT) && (param->modifiers & HLSL_STORAGE_UNIFORM)) ++ if ((modifiers & HLSL_STORAGE_OUT) && (modifiers & HLSL_STORAGE_UNIFORM)) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Parameter '%s' is declared as both \"out\" and \"uniform\".", param->name); + +- if ((param->modifiers & HLSL_STORAGE_OUT) && !(param->modifiers & HLSL_STORAGE_IN) ++ if ((modifiers & HLSL_STORAGE_OUT) && !(modifiers & HLSL_STORAGE_IN) + && (param->type->modifiers & HLSL_MODIFIER_CONST)) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Parameter '%s' is declared as both \"out\" and \"const\".", param->name); +@@ -1234,14 +1231,14 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, + "Missing default value for parameter '%s'.", param->name); + +- if (param->initializer.args_count && (param->modifiers & HLSL_STORAGE_OUT)) ++ if (param->initializer.args_count && (modifiers & HLSL_STORAGE_OUT)) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Output parameter '%s' has a default value.", param->name); + + if (hlsl_get_stream_output_type(param->type)) + check_invalid_stream_output_object(ctx, param->type, param->name, loc); + +- if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers, ++ if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, modifiers, + ¶m->reg_reservation))) + return false; + var->is_param = 1; +@@ -2408,10 +2405,10 @@ static void check_invalid_object_fields(struct hlsl_ctx *ctx, const struct hlsl_ + + static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) + { ++ uint32_t modifiers = v->modifiers | v->semantic.modifiers; + struct hlsl_type *basic_type = v->basic_type; + struct hlsl_ir_function_decl *func; + struct hlsl_semantic new_semantic; +- uint32_t modifiers = v->modifiers; + bool unbounded_res_array = false; + bool constant_buffer = false; + struct hlsl_ir_var *var; +@@ -3041,10 +3038,7 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, + if (!param->default_values[j].string) + { + value.u[0] = param->default_values[j].number; +- if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) +- return NULL; +- hlsl_block_add_instr(args->instrs, comp); +- ++ comp = hlsl_block_add_constant(ctx, args->instrs, type, &value, loc); + hlsl_block_add_store_component(ctx, args->instrs, ¶m_deref, j, comp); + } + } +@@ -3181,6 +3175,20 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, return true; } @@ -3993,7 +5420,7 @@ index 024d96c5663..d3004d7cc8a 100644 static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -3579,6 +3593,20 @@ static bool intrinsic_cosh(struct hlsl_ctx *ctx, +@@ -3579,6 +3587,20 @@ static bool intrinsic_cosh(struct hlsl_ctx *ctx, return write_cosh_or_sinh(ctx, params, loc, false); } @@ -4014,7 +5441,7 @@ index 024d96c5663..d3004d7cc8a 100644 static bool intrinsic_cross(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -3925,6 +3953,76 @@ static bool intrinsic_f32tof16(struct hlsl_ctx *ctx, +@@ -3925,6 +3947,69 @@ static bool intrinsic_f32tof16(struct hlsl_ctx *ctx, return add_expr(ctx, params->instrs, HLSL_OP1_F32TOF16, operands, type, loc); } @@ -4024,7 +5451,6 @@ index 024d96c5663..d3004d7cc8a 100644 + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *type = params->args[0]->data_type; + struct hlsl_ir_node *c, *clz, *eq, *xor; -+ struct hlsl_constant_value v; + + if (hlsl_version_lt(ctx, 4, 0)) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, @@ -4046,20 +5472,14 @@ index 024d96c5663..d3004d7cc8a 100644 + if (hlsl_version_lt(ctx, 5, 0)) + return add_expr(ctx, params->instrs, HLSL_OP1_FIND_MSB, operands, type, loc); + -+ v.u[0].u = 0x1f; -+ if (!(c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &v, loc))) -+ return false; -+ hlsl_block_add_instr(params->instrs, c); ++ c = hlsl_block_add_uint_constant(ctx, params->instrs, 0x1f, loc); + + if (!(clz = add_expr(ctx, params->instrs, HLSL_OP1_CLZ, operands, type, loc))) + return false; + if (!(xor = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_BIT_XOR, c, clz, loc))) + return false; + -+ v.u[0].i = -1; -+ if (!(c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &v, loc))) -+ return false; -+ hlsl_block_add_instr(params->instrs, c); ++ c = hlsl_block_add_uint_constant(ctx, params->instrs, ~0u, loc); + + if (!(eq = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_EQUAL, clz, c, loc))) + return false; @@ -4091,7 +5511,18 @@ index 024d96c5663..d3004d7cc8a 100644 static bool intrinsic_floor(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -3983,6 +4081,53 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, +@@ -3948,9 +4033,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer + if (!(div = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, x, y, loc))) + return false; + +- if (!(zero = hlsl_new_constant(ctx, div->data_type, &zero_value, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, zero); ++ zero = hlsl_block_add_constant(ctx, params->instrs, div->data_type, &zero_value, loc); + + if (!(abs = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, div, loc))) + return false; +@@ -3983,6 +4066,53 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); } @@ -4145,7 +5576,19 @@ index 024d96c5663..d3004d7cc8a 100644 static bool intrinsic_fwidth(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -4701,7 +4846,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -4499,9 +4629,8 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, + struct hlsl_type *int_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_INT, + arg->data_type->e.numeric.dimx, arg->data_type->e.numeric.dimy); + +- if (!(zero = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, arg->data_type->e.numeric.type), &zero_value, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, zero); ++ zero = hlsl_block_add_constant(ctx, params->instrs, ++ hlsl_get_scalar_type(ctx, arg->data_type->e.numeric.type), &zero_value, loc); + + /* Check if 0 < arg, cast bool to int */ + +@@ -4701,7 +4830,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * } if (!strcmp(name, "tex2Dbias") @@ -4155,7 +5598,7 @@ index 024d96c5663..d3004d7cc8a 100644 { struct hlsl_ir_node *lod, *c; -@@ -4853,6 +4999,12 @@ static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, +@@ -4853,6 +4983,12 @@ static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, return intrinsic_tex(ctx, params, loc, "texCUBE", HLSL_SAMPLER_DIM_CUBE); } @@ -4168,7 +5611,39 @@ index 024d96c5663..d3004d7cc8a 100644 static bool intrinsic_texCUBEgrad(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -5263,6 +5415,7 @@ intrinsic_functions[] = +@@ -5184,6 +5320,23 @@ static bool intrinsic_AllMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, + | VKD3DSSF_GROUP_SHARED_MEMORY | VKD3DSSF_THREAD_GROUP, loc); + } + ++static bool intrinsic_ConstructGSWithSO(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *compile; ++ ++ if (params->args_count != 2 && params->args_count != 6) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Wrong number of arguments to ConstructGSWithSO(): expected 2 or 6, but got %u.", params->args_count); ++ ++ if (!(compile = hlsl_new_compile(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, ++ NULL, params->args, params->args_count, params->instrs, loc))) ++ return false; ++ ++ hlsl_block_add_instr(params->instrs, compile); ++ return true; ++} ++ + static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -5233,6 +5386,7 @@ intrinsic_functions[] = + /* Note: these entries should be kept in alphabetical order. */ + {"AllMemoryBarrier", 0, true, intrinsic_AllMemoryBarrier}, + {"AllMemoryBarrierWithGroupSync", 0, true, intrinsic_AllMemoryBarrierWithGroupSync}, ++ {"ConstructGSWithSO", -1, false, intrinsic_ConstructGSWithSO}, + {"D3DCOLORtoUBYTE4", 1, true, intrinsic_d3dcolor_to_ubyte4}, + {"DeviceMemoryBarrier", 0, true, intrinsic_DeviceMemoryBarrier}, + {"DeviceMemoryBarrierWithGroupSync", 0, true, intrinsic_DeviceMemoryBarrierWithGroupSync}, +@@ -5263,6 +5417,7 @@ intrinsic_functions[] = {"clip", 1, true, intrinsic_clip}, {"cos", 1, true, intrinsic_cos}, {"cosh", 1, true, intrinsic_cosh}, @@ -4176,7 +5651,7 @@ index 024d96c5663..d3004d7cc8a 100644 {"cross", 2, true, intrinsic_cross}, {"ddx", 1, true, intrinsic_ddx}, {"ddx_coarse", 1, true, intrinsic_ddx_coarse}, -@@ -5280,9 +5433,12 @@ intrinsic_functions[] = +@@ -5280,9 +5435,12 @@ intrinsic_functions[] = {"f16tof32", 1, true, intrinsic_f16tof32}, {"f32tof16", 1, true, intrinsic_f32tof16}, {"faceforward", 3, true, intrinsic_faceforward}, @@ -4189,7 +5664,7 @@ index 024d96c5663..d3004d7cc8a 100644 {"fwidth", 1, true, intrinsic_fwidth}, {"isinf", 1, true, intrinsic_isinf}, {"ldexp", 2, true, intrinsic_ldexp}, -@@ -5327,6 +5483,7 @@ intrinsic_functions[] = +@@ -5327,6 +5485,7 @@ intrinsic_functions[] = {"tex3Dgrad", 4, false, intrinsic_tex3Dgrad}, {"tex3Dproj", 2, false, intrinsic_tex3Dproj}, {"texCUBE", -1, false, intrinsic_texCUBE}, @@ -4197,7 +5672,82 @@ index 024d96c5663..d3004d7cc8a 100644 {"texCUBEgrad", 4, false, intrinsic_texCUBEgrad}, {"texCUBEproj", 2, false, intrinsic_texCUBEproj}, {"transpose", 1, true, intrinsic_transpose}, -@@ -8059,7 +8216,7 @@ resource_format: +@@ -5471,36 +5630,6 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha + return make_block(ctx, compile); + } + +-static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, +- struct parse_initializer *args, const struct vkd3d_shader_location *loc) +-{ +- struct hlsl_ir_node *compile; +- +- switch (compile_type) +- { +- case HLSL_COMPILE_TYPE_COMPILE: +- vkd3d_unreachable(); +- +- case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO: +- if (args->args_count != 2 && args->args_count != 6) +- { +- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, +- "Wrong number of arguments to ConstructGSWithSO: expected 2 or 6, but got %u.", +- args->args_count); +- } +- break; +- } +- +- if (!(compile = hlsl_new_compile(ctx, compile_type, NULL, args->args, args->args_count, args->instrs, loc))) +- { +- free_parse_initializer(args); +- return NULL; +- } +- +- free_parse_initializer(args); +- return make_block(ctx, compile); +-} +- + static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, + struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -6781,7 +6910,6 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + %token KW_COMPILESHADER + %token KW_COMPUTESHADER + %token KW_CONST +-%token KW_CONSTRUCTGSWITHSO + %token KW_CONTINUE + %token KW_DEFAULT + %token KW_DEPTHSTENCILSTATE +@@ -7690,15 +7818,28 @@ colon_attributes: + semantic: + ':' any_identifier + { ++ static const char *centroid_suffix = "_centroid"; ++ uint32_t modifiers = 0; ++ size_t len; + char *p; + + if (!($$.raw_name = hlsl_strdup(ctx, $2))) + YYABORT; + +- for (p = $2 + strlen($2); p > $2 && isdigit(p[-1]); --p) ++ len = strlen($2); ++ if (ascii_strncasecmp($2, "sv_", 3) ++ && len > strlen(centroid_suffix) ++ && !ascii_strcasecmp($2 + (len - strlen(centroid_suffix)), centroid_suffix)) ++ { ++ modifiers = HLSL_STORAGE_CENTROID; ++ len -= strlen(centroid_suffix); ++ } ++ ++ for (p = $2 + len; p > $2 && isdigit(p[-1]); --p) + ; + $$.name = $2; + $$.index = atoi(p); ++ $$.modifiers = modifiers; + $$.reported_missing = false; + $$.reported_duplicated_output_next_index = 0; + $$.reported_duplicated_input_incompatible_next_index = 0; +@@ -8059,7 +8200,7 @@ resource_format: { uint32_t modifiers = $1; @@ -4206,8 +5756,20 @@ index 024d96c5663..d3004d7cc8a 100644 YYABORT; } +@@ -9282,11 +9423,6 @@ primary_expr: + vkd3d_free($3); + vkd3d_free($5); + } +- | KW_CONSTRUCTGSWITHSO '(' func_arguments ')' +- { +- if (!($$ = add_compile_variant(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, &$3, &@1))) +- YYABORT; +- } + | var_identifier '(' func_arguments ')' + { + if (!($$ = add_call(ctx, $1, &$3, &@1))) diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 0b3dee4d2ce..2138c3776a7 100644 +index 0b3dee4d2ce..9048214923b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -175,12 +175,29 @@ static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) @@ -4258,17 +5820,1560 @@ index 0b3dee4d2ce..2138c3776a7 100644 idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); break; -@@ -5029,8 +5038,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node +@@ -917,18 +926,17 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, + return progress; + } + +-typedef bool (*PFN_lower_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *); ++typedef struct hlsl_ir_node *(*PFN_replace_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *); + +-static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++static bool call_replace_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { +- PFN_lower_func func = context; ++ struct hlsl_ir_node *replacement; ++ PFN_replace_func func = context; + struct hlsl_block block; + + hlsl_block_init(&block); +- if (func(ctx, instr, &block)) ++ if ((replacement = func(ctx, instr, &block))) + { +- struct hlsl_ir_node *replacement = LIST_ENTRY(list_tail(&block.instrs), struct hlsl_ir_node, entry); +- + list_move_before(&instr->entry, &block.instrs); + hlsl_replace_node(instr, replacement); + return true; +@@ -940,12 +948,17 @@ static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, vo + } + } + +-/* Specific form of transform_ir() for passes which convert a single instruction +- * to a block of one or more instructions. This helper takes care of setting up +- * the block and calling hlsl_replace_node_with_block(). */ +-static bool lower_ir(struct hlsl_ctx *ctx, PFN_lower_func func, struct hlsl_block *block) ++/* Specific form of transform_ir() for passes which replace a single instruction ++ * with another instruction. This includes passes which lower an instruction ++ * to one or more new instructions, and passes which fold away a redundant ++ * instruction. ++ * ++ * New instructions should be added to "block", and the replacement instruction ++ * should be returned. If the instruction should be left alone, NULL should be ++ * returned instead. */ ++static bool replace_ir(struct hlsl_ctx *ctx, PFN_replace_func func, struct hlsl_block *block) + { +- return hlsl_transform_ir(ctx, call_lower_func, block, func); ++ return hlsl_transform_ir(ctx, call_replace_func, block, func); + } + + static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -1286,7 +1299,8 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h + return hlsl_block_add_simple_load(ctx, block, coords, loc); + } + +-static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_complex_casts(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + unsigned int src_comp_count, dst_comp_count; + struct hlsl_type *src_type, *dst_type; +@@ -1297,17 +1311,17 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + unsigned int dst_idx; + if (instr->type != HLSL_IR_EXPR) - return false; +- return false; ++ return NULL; + + if (hlsl_ir_expr(instr)->op != HLSL_OP1_CAST) +- return false; ++ return NULL; + + arg = hlsl_ir_expr(instr)->operands[0].node; + dst_type = instr->data_type; + src_type = arg->data_type; + + if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR) +- return false; ++ return NULL; + + src_comp_count = hlsl_type_component_count(src_type); + dst_comp_count = hlsl_type_component_count(dst_type); +@@ -1323,7 +1337,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + } + + if (!(var = hlsl_new_synthetic_var(ctx, "cast", dst_type, &instr->loc))) +- return false; ++ return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (dst_idx = 0; dst_idx < dst_comp_count; ++dst_idx) +@@ -1354,8 +1368,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + hlsl_block_add_store_component(ctx, block, &var_deref, dst_idx, cast); + } + +- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); +- return true; ++ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); + } + + /* hlsl_ir_swizzle nodes that directly point to a matrix value are only a parse-time construct that +@@ -1363,7 +1376,8 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + * an assignment or as a value made from different components of the matrix. The former cases should + * have already been split into several separate assignments, but the latter are lowered by this + * pass. */ +-static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_matrix_swizzles(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_swizzle *swizzle; + struct hlsl_deref var_deref; +@@ -1372,14 +1386,14 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + unsigned int k, i; + + if (instr->type != HLSL_IR_SWIZZLE) +- return false; ++ return NULL; + swizzle = hlsl_ir_swizzle(instr); + matrix_type = swizzle->val.node->data_type; + if (matrix_type->class != HLSL_CLASS_MATRIX) +- return false; ++ return NULL; + + if (!(var = hlsl_new_synthetic_var(ctx, "matrix-swizzle", instr->data_type, &instr->loc))) +- return false; ++ return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (i = 0; i < instr->data_type->e.numeric.dimx; ++i) +@@ -1392,8 +1406,7 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + hlsl_block_add_store_component(ctx, block, &var_deref, i, load); + } + +- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); +- return true; ++ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); + } + + /* hlsl_ir_index nodes are a parse-time construct used to represent array indexing and struct +@@ -1402,7 +1415,8 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + * For the latter case, this pass takes care of lowering hlsl_ir_indexes into individual + * hlsl_ir_loads, or individual hlsl_ir_resource_loads, in case the indexing is a + * resource access. */ +-static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_index_loads(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_deref var_deref; + struct hlsl_ir_index *index; +@@ -1411,7 +1425,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + struct hlsl_ir_var *var; + + if (instr->type != HLSL_IR_INDEX) +- return false; ++ return NULL; + index = hlsl_ir_index(instr); + val = index->val.node; + +@@ -1426,14 +1440,13 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count); + + if (!(coords = add_zero_mipmap_level(ctx, block, coords, &instr->loc))) +- return false; ++ return NULL; + + params.type = HLSL_RESOURCE_LOAD; + params.resource = val; + params.coords = coords; + params.format = val->data_type->e.resource.format; +- hlsl_block_add_resource_load(ctx, block, ¶ms, &instr->loc); +- return true; ++ return hlsl_block_add_resource_load(ctx, block, ¶ms, &instr->loc); + } + + if (val->type == HLSL_IR_RESOURCE_LOAD) +@@ -1450,7 +1463,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + struct hlsl_deref row_deref; + + if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) +- return false; ++ return NULL; + hlsl_init_simple_deref_from_var(&row_deref, var); + + for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i) +@@ -1479,7 +1492,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node); + } + +- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); ++ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); + } + else + { +@@ -1497,14 +1510,13 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + appended_load->node.data_type = type; + + hlsl_block_add_instr(block, &appended_load->node); ++ return &appended_load->node; + } +- +- return true; + } + } + + if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc))) +- return false; ++ return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var); + + hlsl_block_add_simple_store(ctx, block, var, val); +@@ -1518,7 +1530,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + VKD3D_ASSERT(!hlsl_type_is_row_major(mat->data_type)); + + if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) +- return false; ++ return NULL; + hlsl_init_simple_deref_from_var(&row_deref, var); + + for (i = 0; i < mat->data_type->e.numeric.dimx; ++i) +@@ -1528,37 +1540,34 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc); + + if (!(load = hlsl_new_load_index(ctx, &var_deref, c, &instr->loc))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, &load->node); + + if (!(load = hlsl_new_load_index(ctx, &load->src, index->idx.node, &instr->loc))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, &load->node); + + hlsl_block_add_store_index(ctx, block, &row_deref, c, &load->node, 0, &instr->loc); + } + +- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); +- } +- else +- { +- hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc); ++ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); + } +- return true; ++ ++ return hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc); + } + + /* Lower casts from vec1 to vecN to swizzles. */ +-static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + const struct hlsl_type *src_type, *dst_type; + struct hlsl_type *dst_scalar_type; + struct hlsl_ir_expr *cast; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + cast = hlsl_ir_expr(instr); + if (cast->op != HLSL_OP1_CAST) +- return false; ++ return NULL; + src_type = cast->operands[0].node->data_type; + dst_type = cast->node.data_type; + +@@ -1572,17 +1581,17 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s + new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_scalar_type, &cast->node.loc); + + if (dst_type->e.numeric.dimx != 1) +- hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), ++ return hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), + dst_type->e.numeric.dimx, new_cast, &cast->node.loc); + +- return true; ++ return new_cast; + } + +- return false; ++ return NULL; + } + + /* 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) ++static struct hlsl_ir_node *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; +@@ -1590,29 +1599,28 @@ static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s + struct hlsl_deref *deref; + + if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type)) +- return false; ++ return NULL; + load = hlsl_ir_load(instr); + deref = &load->src; + + if (!deref->var->is_tgsm) +- return false; ++ return NULL; + + if (deref->path_len) + { + hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM."); +- return false; ++ return NULL; + } + + 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; ++ return hlsl_block_add_resource_load(ctx, block, ¶ms, loc); + } + + /* 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) ++static struct hlsl_ir_node *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; +@@ -1620,26 +1628,24 @@ static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + struct hlsl_deref *deref; + + if (instr->type != HLSL_IR_STORE) +- return false; ++ return NULL; + store = hlsl_ir_store(instr); + deref = &store->lhs; + + if (!deref->var->is_tgsm) +- return false; ++ return NULL; + + if (deref->path_len) + { + hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM."); +- return false; ++ return NULL; + } + + 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, ++ return 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 +@@ -3558,7 +3564,8 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + return false; + } + +-static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++static struct hlsl_ir_node *fold_redundant_casts(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + if (instr->type == HLSL_IR_EXPR) + { +@@ -3567,20 +3574,17 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + const struct hlsl_type *src_type; + + if (expr->op != HLSL_OP1_CAST) +- return false; ++ return NULL; + + src_type = expr->operands[0].node->data_type; + + if (hlsl_types_are_equal(src_type, dst_type) + || (src_type->e.numeric.type == dst_type->e.numeric.type + && hlsl_is_vec1(src_type) && hlsl_is_vec1(dst_type))) +- { +- hlsl_replace_node(&expr->node, expr->operands[0].node); +- return true; +- } ++ return expr->operands[0].node; + } + +- return false; ++ return NULL; + } + + /* Copy an element of a complex variable. Helper for +@@ -3815,17 +3819,18 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return true; + } + +-static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_narrowing_casts(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + const struct hlsl_type *src_type, *dst_type; + struct hlsl_type *dst_vector_type; + struct hlsl_ir_expr *cast; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + cast = hlsl_ir_expr(instr); + if (cast->op != HLSL_OP1_CAST) +- return false; ++ return NULL; + src_type = cast->operands[0].node->data_type; + dst_type = cast->node.data_type; + +@@ -3838,65 +3843,58 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + /* We need to preserve the cast since it might be doing more than just + * narrowing the vector. */ + new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc); +- hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W), ++ return hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W), + dst_type->e.numeric.dimx, new_cast, &cast->node.loc); +- return true; + } + +- return false; ++ return NULL; + } + +-static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++static struct hlsl_ir_node *fold_swizzle_chains(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_node *next_instr; + + if (instr->type != HLSL_IR_SWIZZLE) +- return false; ++ return NULL; + swizzle = hlsl_ir_swizzle(instr); + + next_instr = swizzle->val.node; + + if (next_instr->type == HLSL_IR_SWIZZLE) + { +- struct hlsl_ir_node *new_swizzle; + uint32_t combined_swizzle; + + combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->u.vector, + swizzle->u.vector, instr->data_type->e.numeric.dimx); + next_instr = hlsl_ir_swizzle(next_instr)->val.node; + +- if (!(new_swizzle = hlsl_new_swizzle(ctx, combined_swizzle, +- instr->data_type->e.numeric.dimx, next_instr, &instr->loc))) +- return false; +- +- list_add_before(&instr->entry, &new_swizzle->entry); +- hlsl_replace_node(instr, new_swizzle); +- return true; ++ return hlsl_block_add_swizzle(ctx, block, combined_swizzle, ++ instr->data_type->e.numeric.dimx, next_instr, &instr->loc); + } + +- return false; ++ return NULL; + } + +-static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++static struct hlsl_ir_node *fold_trivial_swizzles(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_swizzle *swizzle; + unsigned int i; + + if (instr->type != HLSL_IR_SWIZZLE) +- return false; ++ return NULL; + swizzle = hlsl_ir_swizzle(instr); + + if (instr->data_type->e.numeric.dimx != swizzle->val.node->data_type->e.numeric.dimx) +- return false; ++ return NULL; + + for (i = 0; i < instr->data_type->e.numeric.dimx; ++i) + if (hlsl_swizzle_get_component(swizzle->u.vector, i) != i) +- return false; +- +- hlsl_replace_node(instr, swizzle->val.node); ++ return NULL; + +- return true; ++ return swizzle->val.node; + } + + static bool remove_trivial_conditional_branches(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -4019,7 +4017,8 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + return true; + } + +-static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *idx; + struct hlsl_deref *deref; +@@ -4027,13 +4026,13 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir + unsigned int i; + + if (instr->type != HLSL_IR_LOAD) +- return false; ++ return NULL; + + deref = &hlsl_ir_load(instr)->src; + VKD3D_ASSERT(deref->var); + + if (deref->path_len == 0) +- return false; ++ return NULL; + + type = deref->var->data_type; + for (i = 0; i < deref->path_len - 1; ++i) +@@ -4050,7 +4049,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir + enum hlsl_ir_expr_op op; + + if (!(vector_load = hlsl_new_load_parent(ctx, deref, &instr->loc))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, &vector_load->node); + + swizzle = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc); +@@ -4059,9 +4058,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir + value.u[1].u = 1; + value.u[2].u = 2; + value.u[3].u = 3; +- if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, c); ++ c = hlsl_block_add_constant(ctx, block, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc); + + operands[0] = swizzle; + operands[1] = c; +@@ -4077,14 +4074,14 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir + * LOGIC_OR + LOGIC_AND. */ + operands[0] = &vector_load->node; + operands[1] = eq; +- hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc); +- return true; ++ return hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc); + } + +- return false; ++ return NULL; + } + +-static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *idx; + struct hlsl_deref *deref; +@@ -4092,13 +4089,13 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc + unsigned int i; + + if (instr->type != HLSL_IR_STORE) +- return false; ++ return NULL; + + deref = &hlsl_ir_store(instr)->lhs; + VKD3D_ASSERT(deref->var); + + if (deref->path_len == 0) +- return false; ++ return NULL; + + type = deref->var->data_type; + for (i = 0; i < deref->path_len - 1; ++i) +@@ -4113,7 +4110,7 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc + hlsl_fixme(ctx, &instr->loc, "Non-constant vector addressing on store. Unrolling may be missing."); + } + +- return false; ++ return NULL; + } + + static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) +@@ -4127,8 +4124,8 @@ static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const s + * This is achieved through a synthetic variable. The non-constant index is compared for equality + * with every possible value it can have within the array bounds, and the ternary operator is used + * to update the value of the synthetic var when the equality check passes. */ +-static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +- struct hlsl_block *block) ++static struct hlsl_ir_node *lower_nonconstant_array_loads(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_constant_value zero_value = {0}; + struct hlsl_ir_node *cut_index, *zero; +@@ -4140,15 +4137,15 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n + bool row_major; + + if (instr->type != HLSL_IR_LOAD) +- return false; ++ return NULL; + load = hlsl_ir_load(instr); + deref = &load->src; + + if (deref->path_len == 0) +- return false; ++ return NULL; + + if (deref_supports_sm1_indirect_addressing(ctx, deref)) +- return false; ++ return NULL; + + for (i = deref->path_len - 1; ; --i) + { +@@ -4159,7 +4156,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n + } + + if (i == 0) +- return false; ++ return NULL; + } + + cut_index = deref->path[i_cut].node; +@@ -4171,12 +4168,9 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n + VKD3D_ASSERT(cut_type->class == HLSL_CLASS_ARRAY || row_major); + + if (!(var = hlsl_new_synthetic_var(ctx, row_major ? "row_major-load" : "array-load", instr->data_type, &instr->loc))) +- return false; +- +- if (!(zero = hlsl_new_constant(ctx, instr->data_type, &zero_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, zero); ++ return NULL; + ++ zero = hlsl_block_add_constant(ctx, block, instr->data_type, &zero_value, &instr->loc); + hlsl_block_add_simple_store(ctx, block, var, zero); + + TRACE("Lowering non-constant %s load on variable '%s'.\n", row_major ? "row_major" : "array", deref->var->name); +@@ -4200,7 +4194,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n + var_load = hlsl_block_add_simple_load(ctx, block, var, &cut_index->loc); + + if (!hlsl_copy_deref(ctx, &deref_copy, deref)) +- return false; ++ return NULL; + hlsl_src_remove(&deref_copy.path[i_cut]); + hlsl_src_from_node(&deref_copy.path[i_cut], const_i); + specific_load = hlsl_block_add_load_index(ctx, block, &deref_copy, NULL, &cut_index->loc); +@@ -4214,8 +4208,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n + hlsl_block_add_simple_store(ctx, block, var, ternary); + } + +- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); +- return true; ++ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); + } + + static struct hlsl_type *clone_texture_array_as_combined_sampler_array(struct hlsl_ctx *ctx, struct hlsl_type *type) +@@ -4486,31 +4479,30 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx) + } + + /* Turn CAST to int or uint into TRUNC + REINTERPRET */ +-static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_casts_to_int(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; + struct hlsl_ir_node *arg, *trunc; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_CAST) +- return false; ++ return NULL; + + arg = expr->operands[0].node; + if (!hlsl_type_is_integer(instr->data_type) || instr->data_type->e.numeric.type == HLSL_TYPE_BOOL) +- return false; ++ return NULL; + if (!hlsl_type_is_floating_point(arg->data_type)) +- return false; ++ return NULL; + + trunc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_TRUNC, arg, &instr->loc); + + memset(operands, 0, sizeof(operands)); + operands[0] = trunc; +- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); +- +- return true; ++ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); + } + + /* Turn TRUNC into: +@@ -4524,16 +4516,16 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + * where the comparisons in the extra term are performed using CMP or SLT + * depending on whether this is a pixel or vertex shader, respectively. + */ +-static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg, *res; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_TRUNC) +- return false; ++ return NULL; + + arg = expr->operands[0].node; + +@@ -4543,31 +4535,27 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + struct hlsl_constant_value zero_value, one_value; + + memset(&zero_value, 0, sizeof(zero_value)); +- if (!(zero = hlsl_new_constant(ctx, arg->data_type, &zero_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, zero); ++ zero = hlsl_block_add_constant(ctx, block, arg->data_type, &zero_value, &instr->loc); + + one_value.u[0].f = 1.0; + one_value.u[1].f = 1.0; + one_value.u[2].f = 1.0; + one_value.u[3].f = 1.0; +- if (!(one = hlsl_new_constant(ctx, arg->data_type, &one_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, one); ++ one = hlsl_block_add_constant(ctx, block, arg->data_type, &one_value, &instr->loc); + + fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); + neg_fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, fract, &instr->loc); + + if (!(has_fract = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, neg_fract, zero, one))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, has_fract); + + if (!(extra = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, arg, zero, has_fract))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, extra); + + floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract); +- res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra); ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra); + } + else + { +@@ -4581,11 +4569,10 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract); + + if (!(res = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, is_neg, has_fract, floor))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, res); ++ return res; + } +- +- return true; + } + + /* Lower modulus using: +@@ -4593,7 +4580,8 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + * mod(x, y) = x - trunc(x / y) * y; + * + */ +-static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_int_modulus_sm1(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *div, *trunc, *mul, *neg, *operands[2], *ret; + struct hlsl_type *float_type; +@@ -4601,15 +4589,15 @@ static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + bool is_float; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP2_MOD) +- return false; ++ return NULL; + + is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT + || instr->data_type->e.numeric.type == HLSL_TYPE_HALF; + if (is_float) +- return false; ++ return NULL; + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); + + for (unsigned int i = 0; i < 2; ++i) +@@ -4622,13 +4610,11 @@ static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, trunc, operands[1]); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul, &instr->loc); + ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, operands[0], neg); +- hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); +- +- return true; ++ return hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); + } + + /* Lower DIV to RCP + MUL. */ +-static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *rcp, *ret, *operands[2]; + struct hlsl_type *float_type; +@@ -4636,10 +4622,10 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str + bool is_float; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP2_DIV) +- return false; ++ return NULL; + + is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT + || instr->data_type->e.numeric.type == HLSL_TYPE_HALF; +@@ -4656,42 +4642,40 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str + ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, operands[0], rcp); + if (!is_float) + ret = hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); +- +- return true; ++ return ret; + } + + /* Lower SQRT to RSQ + RCP. */ +-static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_expr *expr; + struct hlsl_ir_node *rsq; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_SQRT) +- return false; ++ return NULL; + + rsq = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RSQ, expr->operands[0].node, &instr->loc); +- hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc); +- return true; ++ return hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc); + } + + /* Lower DP2 to MUL + ADD */ +-static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg1, *arg2, *mul, *add_x, *add_y; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_DOT) +- return false; ++ return NULL; + if (arg1->data_type->e.numeric.dimx != 2) +- return false; ++ return NULL; + + if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) + { +@@ -4701,7 +4685,7 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + operands[1] = arg2; + operands[2] = hlsl_block_add_float_constant(ctx, block, 0.0f, &expr->node.loc); + +- hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc); ++ return hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc); + } + else + { +@@ -4711,32 +4695,29 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + instr->data_type->e.numeric.dimx, mul, &expr->node.loc); + add_y = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(Y, Y, Y, Y), + instr->data_type->e.numeric.dimx, mul, &expr->node.loc); +- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); + } +- +- return true; + } + + /* Lower ABS to MAX */ +-static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg, *neg; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + arg = expr->operands[0].node; + if (expr->op != HLSL_OP1_ABS) +- return false; ++ return NULL; + + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); +- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg); +- return true; ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg); + } + + /* Lower ROUND using FRC, ROUND(x) -> ((x + 0.5) - FRC(x + 0.5)). */ +-static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg, *neg, *sum, *frc, *half; + struct hlsl_type *type = instr->data_type; +@@ -4745,69 +4726,64 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + + expr = hlsl_ir_expr(instr); + arg = expr->operands[0].node; + if (expr->op != HLSL_OP1_ROUND) +- return false; ++ return NULL; + + component_count = hlsl_type_component_count(type); + for (i = 0; i < component_count; ++i) + half_value.u[i].f = 0.5f; +- if (!(half = hlsl_new_constant(ctx, type, &half_value, &expr->node.loc))) +- return false; +- hlsl_block_add_instr(block, half); ++ half = hlsl_block_add_constant(ctx, block, type, &half_value, &expr->node.loc); + + sum = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, half); + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, sum, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc); +- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg); +- return true; ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg); + } + + /* Lower CEIL to FRC */ +-static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg, *neg, *frc; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + + expr = hlsl_ir_expr(instr); + arg = expr->operands[0].node; + if (expr->op != HLSL_OP1_CEIL) +- return false; ++ return NULL; + + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, neg, &instr->loc); +- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg); +- return true; ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg); + } + + /* Lower FLOOR to FRC */ +-static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg, *neg, *frc; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + + expr = hlsl_ir_expr(instr); + arg = expr->operands[0].node; + if (expr->op != HLSL_OP1_FLOOR) +- return false; ++ return NULL; + + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc); +- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg); +- return true; ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg); + } + + /* Lower SIN/COS to SINCOS for SM1. */ +-static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg, *half, *two_pi, *reciprocal_two_pi, *neg_pi; + struct hlsl_constant_value half_value, two_pi_value, reciprocal_two_pi_value, neg_pi_value; +@@ -4819,7 +4795,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + int i; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + + if (expr->op == HLSL_OP1_SIN) +@@ -4827,7 +4803,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + else if (expr->op == HLSL_OP1_COS) + op = HLSL_OP1_COS_REDUCED; + else +- return false; ++ return NULL; + + arg = expr->operands[0].node; + type = arg->data_type; +@@ -4841,27 +4817,22 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + neg_pi_value.u[i].f = -M_PI; + } + +- if (!(half = hlsl_new_constant(ctx, type, &half_value, &instr->loc)) +- || !(two_pi = hlsl_new_constant(ctx, type, &two_pi_value, &instr->loc)) +- || !(reciprocal_two_pi = hlsl_new_constant(ctx, type, &reciprocal_two_pi_value, &instr->loc)) +- || !(neg_pi = hlsl_new_constant(ctx, type, &neg_pi_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, half); +- hlsl_block_add_instr(block, two_pi); +- hlsl_block_add_instr(block, reciprocal_two_pi); +- hlsl_block_add_instr(block, neg_pi); ++ half = hlsl_block_add_constant(ctx, block, type, &half_value, &instr->loc); ++ two_pi = hlsl_block_add_constant(ctx, block, type, &two_pi_value, &instr->loc); ++ reciprocal_two_pi = hlsl_block_add_constant(ctx, block, type, &reciprocal_two_pi_value, &instr->loc); ++ neg_pi = hlsl_block_add_constant(ctx, block, type, &neg_pi_value, &instr->loc); + + if (!(mad = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, arg, reciprocal_two_pi, half))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, mad); + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mad, &instr->loc); + if (!(reduced = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, frc, two_pi, neg_pi))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, reduced); + + if (type->e.numeric.dimx == 1) + { +- sincos = hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc); ++ return hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc); + } + else + { +@@ -4877,7 +4848,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + } + + if (!(var = hlsl_new_synthetic_var(ctx, "sincos", type, &instr->loc))) +- return false; ++ return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (i = 0; i < type->e.numeric.dimx; ++i) +@@ -4886,13 +4857,11 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + hlsl_block_add_store_component(ctx, block, &var_deref, i, sincos); + } + +- hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc); ++ return hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc); + } +- +- return true; + } + +-static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg, *arg_cast, *neg, *one, *sub; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; +@@ -4901,10 +4870,10 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_LOGIC_NOT) +- return false; ++ return NULL; + + arg = expr->operands[0].node; + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->e.numeric.dimx); +@@ -4920,20 +4889,16 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st + one_value.u[1].f = 1.0; + one_value.u[2].f = 1.0; + one_value.u[3].f = 1.0; +- if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, one); +- ++ one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); + sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg); + + memset(operands, 0, sizeof(operands)); + operands[0] = sub; +- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); +- return true; ++ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); + } + + /* Lower TERNARY to CMP for SM1. */ +-static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *cond, *first, *second, *float_cond, *neg; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; +@@ -4941,11 +4906,11 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + struct hlsl_type *type; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP3_TERNARY) +- return false; ++ return NULL; + + cond = expr->operands[0].node; + first = expr->operands[1].node; +@@ -4954,7 +4919,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + if (cond->data_type->class > HLSL_CLASS_VECTOR || instr->data_type->class > HLSL_CLASS_VECTOR) + { + hlsl_fixme(ctx, &instr->loc, "Lower ternary of type other than scalar or vector."); +- return false; ++ return NULL; + } + + VKD3D_ASSERT(cond->data_type->e.numeric.type == HLSL_TYPE_BOOL); +@@ -4968,8 +4933,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + operands[0] = neg; + operands[1] = second; + operands[2] = first; +- hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc); +- return true; ++ return hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc); + } + + static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -5017,7 +4981,7 @@ static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node * + return true; + } + +-static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, ++static struct hlsl_ir_node *lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + struct hlsl_block *block) + { + struct hlsl_ir_node *arg1, *arg1_cast, *arg2, *arg2_cast, *slt, *res; +@@ -5027,11 +4991,10 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + bool negate = false; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP2_EQUAL && expr->op != HLSL_OP2_NEQUAL && expr->op != HLSL_OP2_LESS - && expr->op != HLSL_OP2_GEQUAL) +- return false; + if (!hlsl_is_comparison_op(expr->op)) - return false; ++ return NULL; arg1 = expr->operands[0].node; -@@ -5906,11 +5914,13 @@ static void mark_vars_usage(struct hlsl_ctx *ctx) + arg2 = expr->operands[1].node; +@@ -5087,10 +5050,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + one_value.u[1].f = 1.0; + one_value.u[2].f = 1.0; + one_value.u[3].f = 1.0; +- if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, one); +- ++ one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); + slt_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); + res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, slt_neg); + } +@@ -5103,8 +5063,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + * and casts to BOOL have already been lowered to "!= 0". */ + memset(operands, 0, sizeof(operands)); + operands[0] = res; +- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); +- return true; ++ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); + } + + /* Intended to be used for SM1-SM3, lowers SLT instructions (only available in vertex shaders) to +@@ -5115,7 +5074,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + * = ((x - y) >= 0) ? 0.0 : 1.0 + * = CMP(x - y, 0.0, 1.0) + */ +-static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg1, *arg2, *arg1_cast, *arg2_cast, *neg, *sub, *zero, *one, *cmp; + struct hlsl_constant_value zero_value, one_value; +@@ -5123,10 +5082,10 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP2_SLT) +- return false; ++ return NULL; + + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; +@@ -5138,24 +5097,19 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg1_cast, neg); + + memset(&zero_value, 0, sizeof(zero_value)); +- if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, zero); ++ zero = hlsl_block_add_constant(ctx, block, float_type, &zero_value, &instr->loc); + + one_value.u[0].f = 1.0; + one_value.u[1].f = 1.0; + one_value.u[2].f = 1.0; + one_value.u[3].f = 1.0; +- if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, one); ++ one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); + + if (!(cmp = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, sub, zero, one))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, cmp); +- +- return true; +-} ++ return cmp; ++} + + /* Intended to be used for SM1-SM3, lowers CMP instructions (only available in pixel shaders) to + * SLT instructions (only available in vertex shaders). +@@ -5165,7 +5119,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + * = z * ((x < 0) ? 1.0 : 0.0) + y * ((x < 0) ? 0.0 : 1.0) + * = z * SLT(x, 0.0) + y * (1 - SLT(x, 0.0)) + */ +-static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *args[3], *args_cast[3], *slt, *neg_slt, *sub, *zero, *one, *mul1, *mul2; + struct hlsl_constant_value zero_value, one_value; +@@ -5174,10 +5128,10 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP3_CMP) +- return false; ++ return NULL; + + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); + +@@ -5188,28 +5142,24 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + } + + memset(&zero_value, 0, sizeof(zero_value)); +- if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, zero); ++ zero = hlsl_block_add_constant(ctx, block, float_type, &zero_value, &instr->loc); + + one_value.u[0].f = 1.0; + one_value.u[1].f = 1.0; + one_value.u[2].f = 1.0; + one_value.u[3].f = 1.0; +- if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, one); ++ one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); + + slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, args_cast[0], zero); + mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[2], slt); + neg_slt = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); + sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg_slt); + mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[1], sub); +- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2); +- return true; ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2); + } + +-static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_casts_to_bool(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_type *type = instr->data_type, *arg_type; + static const struct hlsl_constant_value zero_value; +@@ -5217,28 +5167,23 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_CAST) +- return false; ++ return NULL; + arg_type = expr->operands[0].node->data_type; + if (type->class > HLSL_CLASS_VECTOR || arg_type->class > HLSL_CLASS_VECTOR) +- return false; ++ return NULL; + if (type->e.numeric.type != HLSL_TYPE_BOOL) +- return false; ++ return NULL; + + /* Narrowing casts should have already been lowered. */ + VKD3D_ASSERT(type->e.numeric.dimx == arg_type->e.numeric.dimx); + +- zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc); +- if (!zero) +- return false; +- hlsl_block_add_instr(block, zero); +- ++ zero = hlsl_block_add_constant(ctx, block, arg_type, &zero_value, &instr->loc); + neq = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_NEQUAL, expr->operands[0].node, zero); + neq->data_type = expr->node.data_type; +- +- return true; ++ return neq; + } + + struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *instrs, +@@ -5262,7 +5207,8 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc + return hlsl_block_add_expr(ctx, instrs, HLSL_OP3_TERNARY, operands, if_true->data_type, &condition->loc); + } + +-static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_int_division_sm4(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; + struct hlsl_type *type = instr->data_type, *utype; +@@ -5271,26 +5217,23 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_DIV) +- return false; ++ return NULL; + if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) +- return false; ++ return NULL; + if (type->e.numeric.type != HLSL_TYPE_INT) +- return false; ++ return NULL; + utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); + + xor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_XOR, arg1, arg2); + + for (i = 0; i < type->e.numeric.dimx; ++i) + high_bit_value.u[i].u = 0x80000000; +- if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, high_bit); +- ++ high_bit = hlsl_block_add_constant(ctx, block, type, &high_bit_value, &instr->loc); + and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, xor, high_bit); + abs1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg1, &instr->loc); + cast1 = hlsl_block_add_cast(ctx, block, abs1, utype, &instr->loc); +@@ -5302,7 +5245,8 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + return hlsl_add_conditional(ctx, block, and, neg, cast3); + } + +-static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_int_modulus_sm4(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; + struct hlsl_type *type = instr->data_type, *utype; +@@ -5311,24 +5255,21 @@ static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_MOD) +- return false; ++ return NULL; + if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) +- return false; ++ return NULL; + if (type->e.numeric.type != HLSL_TYPE_INT) +- return false; ++ return NULL; + utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); + + for (i = 0; i < type->e.numeric.dimx; ++i) + high_bit_value.u[i].u = 0x80000000; +- if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, high_bit); +- ++ high_bit = hlsl_block_add_constant(ctx, block, type, &high_bit_value, &instr->loc); + and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, arg1, high_bit); + abs1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg1, &instr->loc); + cast1 = hlsl_block_add_cast(ctx, block, abs1, utype, &instr->loc); +@@ -5340,31 +5281,30 @@ static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + return hlsl_add_conditional(ctx, block, and, neg, cast3); + } + +-static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_type *type = instr->data_type; + struct hlsl_ir_node *arg, *neg; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + + if (expr->op != HLSL_OP1_ABS) +- return false; ++ return NULL; + if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) +- return false; ++ return NULL; + if (type->e.numeric.type != HLSL_TYPE_INT) +- return false; ++ return NULL; + + arg = expr->operands[0].node; + + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); +- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg); +- return true; ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg); + } + +-static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg1, *arg2, *mult, *comps[4] = {0}, *res; + struct hlsl_type *type = instr->data_type; +@@ -5373,11 +5313,11 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + bool is_bool; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + + if (expr->op != HLSL_OP2_DOT) +- return false; ++ return NULL; + + if (hlsl_type_is_integer(type)) + { +@@ -5399,14 +5339,14 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + res = comps[0]; + for (i = 1; i < dimx; ++i) + res = hlsl_block_add_binary_expr(ctx, block, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]); +- +- return true; ++ return res; + } + +- return false; ++ return NULL; + } + +-static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_float_modulus(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one; + struct hlsl_type *type = instr->data_type, *btype; +@@ -5415,16 +5355,16 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_MOD) +- return false; ++ return NULL; + if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) +- return false; ++ return NULL; + if (type->e.numeric.type != HLSL_TYPE_FLOAT) +- return false; ++ return NULL; + btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); + + mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, arg2, arg1); +@@ -5438,15 +5378,11 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + + for (i = 0; i < type->e.numeric.dimx; ++i) + one_value.u[i].f = 1.0f; +- if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, one); +- ++ one = hlsl_block_add_constant(ctx, block, type, &one_value, &instr->loc); + div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond); + mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1); + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc); +- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); +- return true; ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); + } + + static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -5468,9 +5404,7 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + hlsl_block_init(&block); + + arg_type = jump->condition.node->data_type; +- if (!(zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(&block, zero); ++ zero = hlsl_block_add_constant(ctx, &block, arg_type, &zero_value, &instr->loc); + + operands[0] = jump->condition.node; + operands[1] = zero; +@@ -5478,9 +5412,8 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + arg_type->e.numeric.dimx, arg_type->e.numeric.dimy); + cmp = hlsl_block_add_expr(ctx, &block, HLSL_OP2_LESS, operands, cmp_type, &instr->loc); + +- if (!(bool_false = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc))) +- return false; +- hlsl_block_add_instr(&block, bool_false); ++ bool_false = hlsl_block_add_constant(ctx, &block, ++ hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc); + + or = bool_false; + +@@ -5906,11 +5839,13 @@ static void mark_vars_usage(struct hlsl_ctx *ctx) struct register_allocator { @@ -4283,7 +7388,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 /* Two allocations with different mode can't share the same register. */ int mode; -@@ -5920,11 +5930,7 @@ struct register_allocator +@@ -5920,11 +5855,7 @@ struct register_allocator } *allocations; size_t count, capacity; @@ -4296,7 +7401,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 uint32_t reg_count; /* Special flag so allocations that can share registers prioritize those -@@ -5936,7 +5942,7 @@ struct register_allocator +@@ -5936,7 +5867,7 @@ struct register_allocator }; static unsigned int get_available_writemask(const struct register_allocator *allocator, @@ -4305,7 +7410,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { unsigned int writemask = VKD3DSP_WRITEMASK_ALL; size_t i; -@@ -5945,12 +5951,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all +@@ -5945,12 +5876,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all { const struct allocation *allocation = &allocator->allocations[i]; @@ -4319,7 +7424,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { writemask &= ~allocation->writemask; if (allocation->mode != mode) -@@ -5967,7 +5968,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all +@@ -5967,7 +5893,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all } static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *allocator, uint32_t reg_idx, @@ -4328,7 +7433,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { struct allocation *allocation; -@@ -5978,8 +5979,6 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a +@@ -5978,8 +5904,6 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a allocation = &allocator->allocations[allocator->count++]; allocation->reg = reg_idx; allocation->writemask = writemask; @@ -4337,7 +7442,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 allocation->mode = mode; allocation->vip = vip; -@@ -5998,8 +5997,7 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a +@@ -5998,8 +5922,7 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a * 'vip' can be used so that no new allocations can be made in the given register * unless they are 'vip' as well. */ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_allocator *allocator, @@ -4347,7 +7452,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { struct hlsl_reg ret = {.allocation_size = 1, .allocated = true}; unsigned int required_size = force_align ? 4 : reg_size; -@@ -6012,62 +6010,34 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a +@@ -6012,62 +5935,34 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a { for (uint32_t reg_idx = 0; reg_idx < allocator->reg_count; ++reg_idx) { @@ -4417,7 +7522,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { unsigned int last_reg_mask = (1u << (reg_size % 4)) - 1; unsigned int writemask; -@@ -6075,18 +6045,18 @@ static bool is_range_available(const struct register_allocator *allocator, unsig +@@ -6075,18 +5970,18 @@ static bool is_range_available(const struct register_allocator *allocator, unsig for (i = 0; i < (reg_size / 4); ++i) { @@ -4440,7 +7545,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { struct hlsl_reg ret = {0}; uint32_t reg_idx; -@@ -6094,35 +6064,33 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo +@@ -6094,35 +5989,33 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo for (reg_idx = 0;; ++reg_idx) { @@ -4484,7 +7589,64 @@ index 0b3dee4d2ce..2138c3776a7 100644 } static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type) -@@ -6287,10 +6255,9 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) +@@ -6199,7 +6092,7 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls + return false; + } + +-static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) ++static void register_deref_usage(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) + { + struct hlsl_ir_var *var = deref->var; + enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); +@@ -6247,18 +6140,43 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + } + + case HLSL_IR_RESOURCE_LOAD: +- register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->resource); +- if (hlsl_ir_resource_load(instr)->sampler.var) +- register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->sampler); ++ { ++ const struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); ++ ++ register_deref_usage(ctx, &load->resource); ++ if (load->sampler.var) ++ register_deref_usage(ctx, &load->sampler); ++ ++ if (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS) ++ { ++ unsigned int index; ++ ++ hlsl_regset_index_from_deref(ctx, &load->resource, HLSL_REGSET_UAVS, &index); ++ load->resource.var->objects_usage[HLSL_REGSET_UAVS][index].uav_read = true; ++ } + break; ++ } + + case HLSL_IR_RESOURCE_STORE: + register_deref_usage(ctx, &hlsl_ir_resource_store(instr)->resource); + break; + + case HLSL_IR_INTERLOCKED: +- register_deref_usage(ctx, &hlsl_ir_interlocked(instr)->dst); ++ { ++ const struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr); ++ ++ register_deref_usage(ctx, &interlocked->dst); ++ ++ if (hlsl_deref_get_regset(ctx, &interlocked->dst) == HLSL_REGSET_UAVS) ++ { ++ unsigned int index; ++ ++ hlsl_regset_index_from_deref(ctx, &interlocked->dst, HLSL_REGSET_UAVS, &index); ++ interlocked->dst.var->objects_usage[HLSL_REGSET_UAVS][index].uav_read = true; ++ interlocked->dst.var->objects_usage[HLSL_REGSET_UAVS][index].uav_atomics = true; ++ } + break; ++ } + + default: + break; +@@ -6287,10 +6205,9 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) } } @@ -4497,7 +7659,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 bool is_per_component = false; if (instr->reg.allocated || !instr->last_read) -@@ -6302,12 +6269,10 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, +@@ -6302,12 +6219,10 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, { case HLSL_OP1_COS_REDUCED: dst_writemask = VKD3DSP_WRITEMASK_0; @@ -4510,7 +7672,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 break; case HLSL_OP1_EXP2: -@@ -6329,12 +6294,22 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, +@@ -6329,12 +6244,22 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); @@ -4538,7 +7700,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 else { instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx); -@@ -6344,40 +6319,46 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, +@@ -6344,40 +6269,46 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, instr->reg.id = ctx->ssa_count++; } @@ -4601,7 +7763,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { struct hlsl_ir_node *instr; -@@ -6387,15 +6368,15 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, +@@ -6387,15 +6318,15 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, if (ctx->profile->major_version >= 4 && instr->type == HLSL_IR_CONSTANT) continue; @@ -4620,7 +7782,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 break; } -@@ -6404,21 +6385,21 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, +@@ -6404,21 +6335,21 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_load *load = hlsl_ir_load(instr); /* We need to at least allocate a variable for undefs. * FIXME: We should probably find a way to remove them instead. */ @@ -4645,7 +7807,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 break; } -@@ -6429,7 +6410,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, +@@ -6429,7 +6360,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) { @@ -4654,7 +7816,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 } break; } -@@ -6553,8 +6534,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, +@@ -6553,8 +6484,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, break; } @@ -4664,7 +7826,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type)); for (unsigned int x = 0, i = 0; x < 4; ++x) -@@ -6651,16 +6631,14 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -6651,16 +6581,14 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl { type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); @@ -4683,7 +7845,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 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); -@@ -6674,8 +6652,7 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -6674,8 +6602,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_block *body) { @@ -4693,7 +7855,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 struct hlsl_ir_var *var; sort_uniforms_by_bind_count(ctx, HLSL_REGSET_NUMERIC); -@@ -6698,15 +6675,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo +@@ -6698,15 +6625,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo { if (i < bind_count) { @@ -4712,7 +7874,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 } var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; -@@ -6730,8 +6706,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo +@@ -6730,8 +6656,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo if (!var->regs[HLSL_REGSET_NUMERIC].allocated) { @@ -4722,7 +7884,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 TRACE("Allocated %s to %s.\n", var->name, debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); } -@@ -6748,12 +6723,13 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo +@@ -6748,12 +6673,13 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo * 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. */ @@ -4738,7 +7900,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 /* Reset variable temp register allocations. */ LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) { -@@ -6771,25 +6747,13 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block +@@ -6771,29 +6697,17 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block { if (var->is_output_semantic) { @@ -4765,10 +7927,36 @@ index 0b3dee4d2ce..2138c3776a7 100644 + allocate_temp_registers_recurse(ctx, body); } - static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, -@@ -6928,9 +6892,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var - if (special_interpolation) - mode = VKD3DSIM_NONE; +-static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, +- unsigned int storage_modifiers) ++static enum vkd3d_shader_interpolation_mode get_interpolation_mode(const struct vkd3d_shader_version *version, ++ struct hlsl_type *type, unsigned int storage_modifiers) + { + unsigned int i; + +@@ -6815,6 +6729,9 @@ static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hl + + VKD3D_ASSERT(hlsl_is_numeric_type(type)); + ++ if (version->major < 4) ++ storage_modifiers &= HLSL_STORAGE_LINEAR | HLSL_STORAGE_CENTROID; ++ + if ((storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) + || base_type_get_semantic_equivalent(type->e.numeric.type) == HLSL_TYPE_UINT) + return VKD3DSIM_CONSTANT; +@@ -6921,16 +6838,14 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var + { + unsigned int component_count = is_primitive + ? var->data_type->e.array.type->e.numeric.dimx : var->data_type->e.numeric.dimx; +- int mode = (ctx->profile->major_version < 4) +- ? 0 : sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); + unsigned int reg_size = optimize ? component_count : 4; ++ int mode = VKD3DSIM_NONE; + +- if (special_interpolation) +- mode = VKD3DSIM_NONE; ++ if (version.major >= 4 && !special_interpolation) ++ mode = get_interpolation_mode(&version, var->data_type, var->storage_modifiers); - var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX, + var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, @@ -4777,7 +7965,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 TRACE("Allocated %s to %s (mode %d).\n", var->name, debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode); -@@ -6945,11 +6908,17 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *seman +@@ -6945,11 +6860,17 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *seman bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; struct hlsl_ir_var *var; @@ -4795,8 +7983,12 @@ index 0b3dee4d2ce..2138c3776a7 100644 LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { -@@ -8266,6 +8235,282 @@ void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) - lower_ir(ctx, lower_index_loads, body); +@@ -8263,9 +8184,255 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod + + void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) + { +- lower_ir(ctx, lower_index_loads, body); ++ replace_ir(ctx, lower_index_loads, body); } +static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op) @@ -4983,22 +8175,21 @@ index 0b3dee4d2ce..2138c3776a7 100644 + return NULL; +} + -+static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++static struct hlsl_ir_node *fold_conditional_identities(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_ir_node *c, *x, *y, *res_x, *res_y; -+ struct hlsl_ir_node *res = NULL; + struct hlsl_ir_expr *expr, *ec; -+ struct hlsl_block block; + + if (instr->type != HLSL_IR_EXPR) -+ return false; ++ return NULL; + + if (instr->data_type->class > HLSL_CLASS_VECTOR) -+ return false; ++ return NULL; + + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP3_TERNARY) -+ return false; ++ return NULL; + + c = expr->operands[0].node; + x = expr->operands[1].node; @@ -5006,88 +8197,158 @@ index 0b3dee4d2ce..2138c3776a7 100644 + + VKD3D_ASSERT(c->data_type->e.numeric.type == HLSL_TYPE_BOOL); + ++ /* c ? x : x -> x */ + if (nodes_are_equivalent(x, y)) -+ { -+ /* c ? x : x -> x */ -+ hlsl_replace_node(instr, x); -+ return true; -+ } ++ return x; + + if (c->type == HLSL_IR_CONSTANT) + { ++ /* false ? x : y -> y */ + if (hlsl_constant_is_zero(hlsl_ir_constant(c))) -+ { -+ /* false ? x : y -> y */ -+ hlsl_replace_node(instr, y); -+ return true; -+ } ++ return y; + ++ /* true ? x : y -> x */ + if (hlsl_constant_is_one(hlsl_ir_constant(c))) -+ { -+ /* true ? x : y -> x */ -+ hlsl_replace_node(instr, x); -+ return true; -+ } ++ return x; + } + -+ hlsl_block_init(&block); -+ + if (x->type == HLSL_IR_CONSTANT && y->type == HLSL_IR_CONSTANT + && hlsl_types_are_equal(c->data_type, x->data_type) + && hlsl_types_are_equal(c->data_type, y->data_type)) + { ++ /* c ? true : false -> c */ + if (hlsl_constant_is_one(hlsl_ir_constant(x)) && hlsl_constant_is_zero(hlsl_ir_constant(y))) -+ { -+ /* c ? true : false -> c */ -+ res = c; -+ goto done; -+ } ++ return c; + ++ /* c ? false : true -> !c */ + if (hlsl_constant_is_zero(hlsl_ir_constant(x)) && hlsl_constant_is_one(hlsl_ir_constant(y))) -+ { -+ /* c ? false : true -> !c */ -+ res = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); -+ goto done; -+ } ++ return hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); + } + ++ /* !c ? x : y -> c ? y : x */ + ec = c->type == HLSL_IR_EXPR ? hlsl_ir_expr(c) : NULL; + if (ec && ec->op == HLSL_OP1_LOGIC_NOT) -+ { -+ /* !c ? x : y -> c ? y : x */ -+ res = hlsl_add_conditional(ctx, &block, ec->operands[0].node, y, x); -+ goto done; -+ } ++ return hlsl_add_conditional(ctx, block, ec->operands[0].node, y, x); + -+ res_x = evaluate_conditionals_recurse(ctx, &block, c, true, x, &instr->loc); -+ res_y = evaluate_conditionals_recurse(ctx, &block, c, false, y, &instr->loc); ++ res_x = evaluate_conditionals_recurse(ctx, block, c, true, x, &instr->loc); ++ res_y = evaluate_conditionals_recurse(ctx, block, c, false, y, &instr->loc); + if (res_x || res_y) -+ res = hlsl_add_conditional(ctx, &block, c, res_x ? res_x : x, res_y ? res_y : y); ++ return hlsl_add_conditional(ctx, block, c, res_x ? res_x : x, res_y ? res_y : y); + -+done: -+ if (res) -+ { -+ list_move_before(&instr->entry, &block.instrs); -+ hlsl_replace_node(instr, res); -+ return true; -+ } -+ -+ hlsl_block_cleanup(&block); -+ return false; ++ return NULL; +} static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) { -@@ -8275,6 +8520,8 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) - { - progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL); -+ progress |= hlsl_transform_ir(ctx, fold_unary_identities, block, NULL); -+ progress |= hlsl_transform_ir(ctx, fold_conditional_identities, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); +@@ -8273,10 +8440,12 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) -@@ -8448,6 +8695,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + do + { +- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); ++ progress = replace_ir(ctx, hlsl_fold_constant_exprs, block); + progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL); +- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); +- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); ++ progress |= hlsl_transform_ir(ctx, fold_unary_identities, block, NULL); ++ progress |= replace_ir(ctx, fold_conditional_identities, block); ++ progress |= replace_ir(ctx, hlsl_fold_constant_identities, block); ++ progress |= replace_ir(ctx, hlsl_fold_constant_swizzles, block); + + any_progress |= progress; + } while (progress); +@@ -8288,27 +8457,27 @@ static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *bod + { + bool progress; + +- hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); ++ replace_ir(ctx, fold_redundant_casts, body); + do + { + progress = simplify_exprs(ctx, body); + progress |= hlsl_copy_propagation_execute(ctx, body); +- progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); +- progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); ++ progress |= replace_ir(ctx, fold_swizzle_chains, body); ++ progress |= replace_ir(ctx, fold_trivial_swizzles, body); + progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); + } while (progress); +- hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); ++ replace_ir(ctx, fold_redundant_casts, body); + } + + void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) + { + bool progress; + +- lower_ir(ctx, lower_complex_casts, body); +- lower_ir(ctx, lower_matrix_swizzles, body); ++ replace_ir(ctx, lower_complex_casts, body); ++ replace_ir(ctx, lower_matrix_swizzles, body); + +- lower_ir(ctx, lower_broadcasts, body); +- while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL)); ++ replace_ir(ctx, lower_broadcasts, body); ++ while (replace_ir(ctx, fold_redundant_casts, body)); + do + { + progress = hlsl_transform_ir(ctx, split_array_copies, body, NULL); +@@ -8317,16 +8486,16 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) + while (progress); + hlsl_transform_ir(ctx, split_matrix_copies, body, NULL); + +- lower_ir(ctx, lower_narrowing_casts, body); +- lower_ir(ctx, lower_int_dot, body); ++ replace_ir(ctx, lower_narrowing_casts, body); ++ replace_ir(ctx, lower_int_dot, body); + if (hlsl_version_ge(ctx, 4, 0)) + { +- lower_ir(ctx, lower_int_modulus_sm4, body); +- lower_ir(ctx, lower_int_division_sm4, body); ++ replace_ir(ctx, lower_int_modulus_sm4, body); ++ replace_ir(ctx, lower_int_division_sm4, body); + } +- lower_ir(ctx, lower_int_abs, body); +- lower_ir(ctx, lower_casts_to_bool, body); +- lower_ir(ctx, lower_float_modulus, body); ++ replace_ir(ctx, lower_int_abs, body); ++ replace_ir(ctx, lower_casts_to_bool, body); ++ replace_ir(ctx, lower_float_modulus, body); + + hlsl_run_folding_passes(ctx, body); + } +@@ -8335,6 +8504,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + struct shader_signature *signature, bool output, struct hlsl_ir_var *var) + { + enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_VOID; ++ enum vkd3d_shader_interpolation_mode interpolation_mode = VKD3DSIM_NONE; + bool is_primitive = hlsl_type_is_primitive_array(var->data_type); + enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; + unsigned int register_index, mask, use_mask; +@@ -8342,6 +8512,9 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + enum vkd3d_shader_register_type type; + struct signature_element *element; + ++ if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) ++ interpolation_mode = get_interpolation_mode(&program->shader_version, var->data_type, var->storage_modifiers); ++ + if (hlsl_version_ge(ctx, 4, 0)) + { + struct vkd3d_string_buffer *string; +@@ -8421,6 +8594,13 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + || (type == VKD3DSPR_INPUT && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)) + register_index += SM1_COLOR_REGISTER_OFFSET; + } ++ ++ if (interpolation_mode == VKD3DSIM_LINEAR_CENTROID ++ && (vkd3d_shader_ver_ge(&program->shader_version, 3, 0) || type != VKD3DSPR_TEXTURE)) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, ++ "The centroid interpolation mode is not supported by the '%s' semantic.", var->semantic.name); ++ } + } + else + { +@@ -8448,6 +8628,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog if (!ascii_strcasecmp(var->semantic.name, "PSIZE") && output && program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX) { @@ -5095,7 +8356,22 @@ index 0b3dee4d2ce..2138c3776a7 100644 if (var->data_type->e.numeric.dimx > 1) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "PSIZE output must have only 1 component in this shader model."); -@@ -8570,9 +8818,8 @@ static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, c +@@ -8487,13 +8668,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + element->register_count = 1; + element->mask = mask; + element->used_mask = use_mask; +- if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) +- { +- if (program->shader_version.major >= 4) +- element->interpolation_mode = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); +- else +- element->interpolation_mode = VKD3DSIM_LINEAR; +- } ++ element->interpolation_mode = interpolation_mode; + + switch (var->data_type->e.numeric.type) + { +@@ -8570,9 +8745,8 @@ static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, c case HLSL_TYPE_DOUBLE: return VSIR_DATA_F64; case HLSL_TYPE_FLOAT: @@ -5106,7 +8382,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 case HLSL_TYPE_INT: return VSIR_DATA_I32; case HLSL_TYPE_UINT: -@@ -8703,7 +8950,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, +@@ -8703,7 +8877,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, semantic->resource_type = resource_type; dst_param = &semantic->resource.reg; @@ -5115,7 +8391,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 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; -@@ -8784,6 +9031,7 @@ static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src +@@ -8784,6 +8958,7 @@ static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src } src->reg.dimension = VSIR_DIMENSION_VEC4; @@ -5123,7 +8399,34 @@ index 0b3dee4d2ce..2138c3776a7 100644 for (i = 0, j = 0; i < 4; ++i) { if ((map_writemask & (1u << i)) && (j < width)) -@@ -9467,8 +9715,6 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8885,6 +9060,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p + reg->type = VKD3DSPR_RESOURCE; + reg->dimension = VSIR_DIMENSION_VEC4; + reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id; ++ if (vkd3d_shader_ver_le(version, 5, 0)) ++ reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); + 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; +@@ -8896,6 +9073,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p + reg->type = VKD3DSPR_UAV; + reg->dimension = VSIR_DIMENSION_VEC4; + reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id; ++ if (vkd3d_shader_ver_le(version, 5, 0)) ++ reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); + 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; +@@ -8907,6 +9086,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p + reg->type = VKD3DSPR_SAMPLER; + reg->dimension = VSIR_DIMENSION_NONE; + reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id; ++ if (vkd3d_shader_ver_le(version, 5, 0)) ++ reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); + 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; +@@ -9467,8 +9648,6 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break; case HLSL_OP3_CMP: @@ -5132,14 +8435,8 @@ index 0b3dee4d2ce..2138c3776a7 100644 generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_CMP, 0, 0, true); break; -@@ -9930,10 +10176,14 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co - struct hlsl_ir_function_decl *func, struct list *semantic_vars, - struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) - { -+ struct hlsl_ir_var *var; +@@ -9933,7 +10112,8 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co struct hlsl_block block; -+ struct hlsl_reg *reg; -+ unsigned int *count; program->ssa_count = 0; - program->temp_count = allocate_temp_registers(ctx, body, semantic_vars); @@ -5148,27 +8445,24 @@ index 0b3dee4d2ce..2138c3776a7 100644 if (ctx->result) return; -@@ -9944,7 +10194,19 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co - +@@ -9945,6 +10125,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co sm1_generate_vsir_block(ctx, body, program); -+ count = &program->flat_constant_count[VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER]; -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ if (!var->is_uniform) -+ continue; -+ -+ if (!(reg = &var->regs[HLSL_REGSET_NUMERIC])->allocation_size) -+ continue; -+ -+ *count = max(*count, reg->id + reg->allocation_size); -+ } program->ssa_count = ctx->ssa_count; + program->temp_count = ctx->temp_count; if (ctx->result) return; -@@ -10795,11 +11057,32 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -10539,7 +10720,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs + dst_param->write_mask = write_mask; + + if (var->is_input_semantic && version->type == VKD3D_SHADER_TYPE_PIXEL) +- ins->flags = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); ++ ins->flags = get_interpolation_mode(version, var->data_type, var->storage_modifiers); + } + + static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_program *program, +@@ -10795,11 +10976,32 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_PI, 0, 0, true); return true; @@ -5201,7 +8495,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 case HLSL_OP1_DSX: VKD3D_ASSERT(type_is_float(dst_type)); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX, 0, 0, true); -@@ -11437,6 +11720,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, +@@ -11437,6 +11639,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, const struct vkd3d_shader_version *version = &program->shader_version; const struct hlsl_ir_node *sample_index = load->sample_index.node; const struct hlsl_ir_node *texel_offset = load->texel_offset.node; @@ -5209,7 +8503,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 const struct hlsl_ir_node *coords = load->coords.node; unsigned int coords_writemask = VKD3DSP_WRITEMASK_ALL; const struct hlsl_deref *resource = &load->resource; -@@ -11444,20 +11728,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, +@@ -11444,20 +11647,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim = load->sampling_dim; bool tgsm = load->resource.var->is_tgsm; struct vkd3d_shader_instruction *ins; @@ -5232,7 +8526,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 if (!tgsm) { -@@ -11468,15 +11747,19 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, +@@ -11468,15 +11666,19 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); return false; } @@ -5254,7 +8548,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 return false; if (texel_offset && !sm4_generate_vsir_validate_texel_offset_aoffimmi(texel_offset)) -@@ -11504,10 +11787,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, +@@ -11504,10 +11706,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, coords_writemask); if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, @@ -5272,7 +8566,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { if (sample_index->type == HLSL_IR_CONSTANT) vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, -@@ -12093,16 +12381,15 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se +@@ -12093,16 +12300,15 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se struct hlsl_block block = {0}; struct hlsl_scope *scope; struct hlsl_ir_var *var; @@ -5291,7 +8585,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 hlsl_block_init(&block); -@@ -12113,8 +12400,8 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se +@@ -12113,8 +12319,8 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se sm4_generate_vsir_instr_dcl_semantic(ctx, program, var, &block, &var->loc); } @@ -5302,7 +8596,16 @@ index 0b3dee4d2ce..2138c3776a7 100644 LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) { -@@ -12427,7 +12714,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, +@@ -12243,7 +12449,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un + extern_resources[*count].component_type = component_type; + + extern_resources[*count].regset = regset; +- extern_resources[*count].id = var->regs[regset].id; ++ extern_resources[*count].id = var->regs[regset].id + regset_offset; + extern_resources[*count].space = var->regs[regset].space; + extern_resources[*count].index = var->regs[regset].index + regset_offset; + extern_resources[*count].bind_count = 1; +@@ -12427,7 +12633,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, return; } @@ -5311,7 +8614,36 @@ index 0b3dee4d2ce..2138c3776a7 100644 src_param = &ins->declaration.cb.src; vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 0); -@@ -12592,6 +12879,9 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, +@@ -12478,16 +12684,16 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, + ins->declaration.sampler.range.last = array_last; + ins->declaration.sampler.range.space = resource->space; + +- src_param->reg.idx[0].offset = resource->id; ++ src_param->reg.idx[0].offset = resource->id + i; + src_param->reg.idx[1].offset = array_first; + src_param->reg.idx[2].offset = array_last; + src_param->reg.idx_count = 3; + } + } + +-static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const struct hlsl_type *type) ++static enum vkd3d_shader_resource_type get_vsir_resource_type(enum hlsl_sampler_dim sampler_dim) + { +- switch (type->sampler_dim) ++ switch (sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + return VKD3D_SHADER_RESOURCE_TEXTURE_1D; +@@ -12516,7 +12722,7 @@ static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const + } + } + +-static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) ++static enum vsir_data_type get_vsir_resource_data_type(const struct hlsl_type *type) + { + const struct hlsl_type *format = type->e.resource.format; + +@@ -12592,6 +12798,9 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, { switch (component_type->sampler_dim) { @@ -5321,7 +8653,22 @@ index 0b3dee4d2ce..2138c3776a7 100644 case HLSL_SAMPLER_DIM_RAW_BUFFER: opcode = VSIR_OP_DCL_RESOURCE_RAW; break; -@@ -12647,7 +12937,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, +@@ -12633,13 +12842,11 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + vsir_resource->range.last = array_last; + vsir_resource->range.space = resource->space; + +- vsir_resource->reg.reg.idx[0].offset = resource->id; ++ vsir_resource->reg.reg.idx[0].offset = resource->id + i; + 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 (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + { + ins->raw = true; +@@ -12647,13 +12854,15 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) { ins->structured = true; @@ -5330,7 +8677,16 @@ index 0b3dee4d2ce..2138c3776a7 100644 ins->declaration.structured_resource.byte_stride = ins->resource_stride; } else -@@ -12784,6 +13074,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, + { ++ ins->declaration.semantic.resource_type = get_vsir_resource_type(resource->component_type->sampler_dim); ++ + for (unsigned int j = 0; j < 4; ++j) +- ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); ++ ins->declaration.semantic.resource_data_type[j] = get_vsir_resource_data_type(component_type); + + if (multisampled) + ins->declaration.semantic.sample_count = component_type->sample_count; +@@ -12784,6 +12993,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, } program->ssa_count = 0; @@ -5338,15 +8694,149 @@ index 0b3dee4d2ce..2138c3776a7 100644 if (version->type == VKD3D_SHADER_TYPE_HULL) generate_vsir_add_program_instruction(ctx, program, -@@ -12801,6 +13092,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, +@@ -12801,6 +13011,141 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, generate_vsir_scan_global_flags(ctx, program, semantic_vars, func); program->ssa_count = ctx->ssa_count; + program->temp_count = ctx->temp_count; ++} ++ ++static void generate_vsir_descriptors_for_var(struct hlsl_ctx *ctx, struct vsir_program *program, ++ const struct hlsl_ir_var *var, enum hlsl_regset r, enum vkd3d_shader_descriptor_type type) ++{ ++ unsigned int component_count = hlsl_type_component_count(var->data_type); ++ ++ for (unsigned int k = 0; k < component_count; ++k) ++ { ++ const struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k); ++ struct vkd3d_shader_register_range range; ++ struct vkd3d_shader_descriptor_info1 *d; ++ unsigned int regset_offset; ++ enum hlsl_regset regset; ++ uint32_t id; ++ ++ if (!hlsl_type_is_resource(component_type)) ++ continue; ++ regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); ++ if (regset != r) ++ continue; ++ if (regset_offset > var->regs[r].allocation_size) ++ continue; ++ ++ if (!var->objects_usage[r][regset_offset].used) ++ continue; ++ ++ id = var->regs[r].id + regset_offset; ++ range.space = var->regs[r].space; ++ range.first = var->regs[r].index + regset_offset; ++ /* FIXME: 5.1 arrays. */ ++ range.last = var->regs[r].index + regset_offset; ++ ++ if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) ++ { ++ if (!(d = vsir_program_add_descriptor(program, type, id, ++ &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) ++ return; ++ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) ++ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; ++ } ++ else ++ { ++ if (component_type->class == HLSL_CLASS_SAMPLER) ++ d = vsir_program_add_descriptor(program, type, id, &range, ++ get_vsir_resource_type(var->objects_usage[r][regset_offset].sampler_dim), VSIR_DATA_F32); ++ else ++ d = vsir_program_add_descriptor(program, type, id, &range, ++ get_vsir_resource_type(component_type->sampler_dim), ++ get_vsir_resource_data_type(component_type)); ++ if (!d) ++ return; ++ ++ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) ++ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; ++ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ d->structure_stride = hlsl_type_get_packed_size(component_type->e.resource.format); ++ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS ++ || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) ++ d->sample_count = component_type->sample_count; ++ ++ if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV && component_type->e.resource.rasteriser_ordered) ++ d->uav_flags |= VKD3DSUF_RASTERISER_ORDERED_VIEW; ++ ++ if (var->objects_usage[r][regset_offset].uav_read) ++ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ; ++ if (var->objects_usage[r][regset_offset].uav_atomics) ++ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS; ++ } ++ } ++} ++ ++static void generate_vsir_descriptors(struct hlsl_ctx *ctx, struct vsir_program *program) ++{ ++ struct vkd3d_shader_register_range range; ++ struct vkd3d_shader_descriptor_info1 *d; ++ const struct hlsl_ir_var *var; ++ ++ if (program->shader_version.major < 4) ++ { ++ uint32_t flat_constant_count = 0; ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ const struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC]; ++ ++ if (var->is_uniform && reg->allocation_size) ++ flat_constant_count = max(flat_constant_count, reg->id + reg->allocation_size); ++ ++ generate_vsir_descriptors_for_var(ctx, program, var, ++ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER); ++ generate_vsir_descriptors_for_var(ctx, program, var, ++ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV); ++ } ++ ++ if (flat_constant_count) ++ { ++ range.space = 0; ++ range.first = range.last = VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER; ++ if ((d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ++ range.first, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) ++ d->buffer_size = flat_constant_count * 16; ++ } ++ } ++ else ++ { ++ struct hlsl_buffer *buffer; ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ generate_vsir_descriptors_for_var(ctx, program, var, ++ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER); ++ generate_vsir_descriptors_for_var(ctx, program, var, ++ HLSL_REGSET_TEXTURES, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV); ++ generate_vsir_descriptors_for_var(ctx, program, var, ++ HLSL_REGSET_UAVS, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV); ++ } ++ ++ LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) ++ { ++ if (!buffer->reg.allocated) ++ continue; ++ ++ range.space = buffer->reg.space; ++ range.first = buffer->reg.index; ++ /* FIXME: 5.1 arrays. */ ++ range.last = buffer->reg.index; ++ if ((d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ++ buffer->reg.id, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) ++ d->buffer_size = align(buffer->size, 4) * sizeof(float); ++ } ++ } ++ ++ program->has_descriptor_info = true; } /* For some reason, for matrices, values from default value initializers end -@@ -12915,14 +13207,16 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) +@@ -12915,14 +13260,16 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) { @@ -5365,7 +8855,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 default: break; } -@@ -12998,7 +13292,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) +@@ -12998,7 +13345,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) vkd3d_unreachable(); } @@ -5375,7 +8865,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 { const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type); const char *name = array_type->name ? array_type->name : ""; -@@ -13007,7 +13302,10 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -13007,7 +13355,10 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b size_t name_offset = 0; size_t i; @@ -5387,7 +8877,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 return; if (profile->major_version >= 5) -@@ -13029,7 +13327,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -13029,7 +13380,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b continue; field->name_bytecode_offset = put_string(buffer, field->name); @@ -5396,7 +8886,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 ++field_count; } -@@ -13038,15 +13336,29 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -13038,15 +13389,29 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b for (i = 0; i < array_type->e.record.field_count; ++i) { struct hlsl_struct_field *field = &array_type->e.record.fields[i]; @@ -5429,7 +8919,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type))); put_u32(buffer, vkd3d_make_u32(array_size, field_count)); put_u32(buffer, fields_offset); -@@ -13054,7 +13366,11 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -13054,7 +13419,11 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b else { VKD3D_ASSERT(array_type->class <= HLSL_CLASS_LAST_NUMERIC); @@ -5442,7 +8932,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 put_u32(buffer, vkd3d_make_u32(array_type->e.numeric.dimy, array_type->e.numeric.dimx)); put_u32(buffer, vkd3d_make_u32(array_size, 0)); put_u32(buffer, 1); -@@ -13073,9 +13389,9 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -13073,9 +13442,9 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef) { uint32_t binding_desc_size = (hlsl_version_ge(ctx, 5, 1) ? 10 : 8) * sizeof(uint32_t); @@ -5454,7 +8944,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 const struct hlsl_profile_info *profile = ctx->profile; struct vkd3d_bytecode_buffer buffer = {0}; struct extern_resource *extern_resources; -@@ -13097,10 +13413,20 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -13097,10 +13466,20 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated) @@ -5477,7 +8967,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 cbuffer_position = put_u32(&buffer, 0); put_u32(&buffer, extern_resources_count); resource_position = put_u32(&buffer, 0); -@@ -13141,12 +13467,19 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -13141,12 +13520,19 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd put_u32(&buffer, sm4_resource_type(resource->component_type)); if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS) { @@ -5499,7 +8989,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 } else { -@@ -13175,8 +13508,8 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -13175,8 +13561,8 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd /* Buffers. */ @@ -5510,7 +9000,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { unsigned int var_count = 0; -@@ -13198,6 +13531,24 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -13198,6 +13584,24 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_CT_CBUFFER : D3D_CT_TBUFFER); } @@ -5535,7 +9025,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 i = 0; LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { -@@ -13205,7 +13556,18 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -13205,7 +13609,18 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd continue; string_offset = put_string(&buffer, cbuffer->name); @@ -5555,7 +9045,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 } i = 0; -@@ -13216,7 +13578,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -13216,7 +13631,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd if (!cbuffer->reg.allocated) continue; @@ -5564,7 +9054,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { -@@ -13255,7 +13617,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -13255,7 +13670,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd string_offset = put_string(&buffer, var->name); set_u32(&buffer, var_offset, string_offset); @@ -5573,7 +9063,7 @@ index 0b3dee4d2ce..2138c3776a7 100644 set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset); if (var->default_values) -@@ -13298,6 +13660,42 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -13298,6 +13713,42 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd } } @@ -5616,11 +9106,23 @@ index 0b3dee4d2ce..2138c3776a7 100644 creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL)); set_u32(&buffer, creator_position, creator_offset); -@@ -13720,6 +14118,102 @@ static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -13466,8 +13917,8 @@ static void loop_unrolling_simplify(struct hlsl_ctx *ctx, struct hlsl_block *blo + current_index = index_instructions(block, *index); + progress |= copy_propagation_transform_block(ctx, block, state); + +- progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, block, NULL); +- progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, block, NULL); ++ progress |= replace_ir(ctx, fold_swizzle_chains, block); ++ progress |= replace_ir(ctx, fold_trivial_swizzles, block); + progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, block, NULL); + } while (progress); + +@@ -13720,7 +14171,99 @@ static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc hlsl_transform_ir(ctx, resolve_loops, block, NULL); } -+static bool lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +-static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +{ + struct hlsl_ir_function_decl *func; + struct hlsl_ir_node *call, *rhs; @@ -5639,33 +9141,31 @@ index 0b3dee4d2ce..2138c3776a7 100644 + "}\n"; + + if (node->type != HLSL_IR_EXPR) -+ return false; ++ return NULL; + + expr = hlsl_ir_expr(node); + if (expr->op != HLSL_OP1_COUNTBITS) -+ return false; ++ return NULL; + + rhs = expr->operands[0].node; + if (!(body = hlsl_sprintf_alloc(ctx, template, hlsl_type_component_count(rhs->data_type)))) -+ return false; ++ return NULL; + func = hlsl_compile_internal_function(ctx, "countbits", body); + vkd3d_free(body); + if (!func) -+ return false; ++ return NULL; + + lhs = func->parameters.vars[0]; + hlsl_block_add_simple_store(ctx, block, lhs, rhs); + + if (!(call = hlsl_new_call(ctx, func, &node->loc))) -+ return false; ++ return NULL; + hlsl_block_add_instr(block, call); + -+ hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -+ -+ return true; ++ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); +} + -+static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +{ + struct hlsl_ir_function_decl *func; + struct hlsl_ir_node *call, *rhs; @@ -5690,11 +9190,11 @@ index 0b3dee4d2ce..2138c3776a7 100644 + "}\n"; + + if (node->type != HLSL_IR_EXPR) -+ return false; ++ return NULL; + + expr = hlsl_ir_expr(node); + if (expr->op != HLSL_OP1_CTZ) -+ return false; ++ return NULL; + + rhs = expr->operands[0].node; + if (!(body = hlsl_sprintf_alloc(ctx, template, hlsl_type_component_count(rhs->data_type)))) @@ -5702,28 +9202,96 @@ index 0b3dee4d2ce..2138c3776a7 100644 + func = hlsl_compile_internal_function(ctx, "ctz", body); + vkd3d_free(body); + if (!func) -+ return false; ++ return NULL; + + lhs = func->parameters.vars[0]; + hlsl_block_add_simple_store(ctx, block, lhs, rhs); + + if (!(call = hlsl_new_call(ctx, func, &node->loc))) -+ return false; ++ return NULL; + hlsl_block_add_instr(block, call); + -+ hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -+ -+ return true; ++ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); +} + - static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { struct hlsl_ir_function_decl *func; -@@ -13862,6 +14356,69 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru - return true; + struct hlsl_ir_node *call, *rhs; +@@ -13775,29 +14318,28 @@ static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru + expr = hlsl_ir_expr(node); + + if (expr->op != HLSL_OP1_F16TOF32) +- return false; ++ return NULL; + + rhs = expr->operands[0].node; + component_count = hlsl_type_component_count(rhs->data_type); + + if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) +- return false; ++ return NULL; + + if (!(func = hlsl_compile_internal_function(ctx, "soft_f16tof32", body))) +- return false; ++ return NULL; + + lhs = func->parameters.vars[0]; + hlsl_block_add_simple_store(ctx, block, lhs, rhs); + + if (!(call = hlsl_new_call(ctx, func, &node->loc))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, call); + +- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); +- return true; ++ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); } -+static bool lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +-static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) + { + struct hlsl_ir_function_decl *func; + struct hlsl_ir_node *call, *rhs; +@@ -13835,34 +14377,94 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru + "}\n"; + + if (node->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + + expr = hlsl_ir_expr(node); + + if (expr->op != HLSL_OP1_F32TOF16) +- return false; ++ return NULL; + + rhs = expr->operands[0].node; + component_count = hlsl_type_component_count(rhs->data_type); + + if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) +- return false; ++ return NULL; + + if (!(func = hlsl_compile_internal_function(ctx, "soft_f32tof16", body))) +- return false; ++ return NULL; + + lhs = func->parameters.vars[0]; + hlsl_block_add_simple_store(ctx, block, lhs, rhs); + + if (!(call = hlsl_new_call(ctx, func, &node->loc))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, call); + +- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); +- return true; ++ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); ++} ++ ++static struct hlsl_ir_node *lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +{ + struct hlsl_ir_function_decl *func; + struct hlsl_ir_node *call, *rhs; @@ -5760,49 +9328,202 @@ index 0b3dee4d2ce..2138c3776a7 100644 + "}\n"; + + if (node->type != HLSL_IR_EXPR) -+ return false; ++ return NULL; + + expr = hlsl_ir_expr(node); + if (expr->op != HLSL_OP1_FIND_MSB) -+ return false; ++ return NULL; + + rhs = expr->operands[0].node; + if (!(body = hlsl_sprintf_alloc(ctx, template, rhs->data_type->name, hlsl_type_component_count(rhs->data_type)))) -+ return false; ++ return NULL; + func = hlsl_compile_internal_function(ctx, "find_msb", body); + vkd3d_free(body); + if (!func) -+ return false; ++ return NULL; + + lhs = func->parameters.vars[0]; + hlsl_block_add_simple_store(ctx, block, lhs, rhs); + + if (!(call = hlsl_new_call(ctx, func, &node->loc))) -+ return false; ++ return NULL; + hlsl_block_add_instr(block, call); + -+ hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -+ -+ return true; -+} -+ - static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) ++ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); + } + +-static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) ++static struct hlsl_ir_node *lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { struct hlsl_ir_function_decl *func; -@@ -13978,8 +14535,11 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v + struct hlsl_ir_node *call, *rhs; +@@ -13907,12 +14509,12 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct + "}"; + + if (node->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + + expr = hlsl_ir_expr(node); + + if (expr->op != HLSL_OP1_ISINF) +- return false; ++ return NULL; + + rhs = expr->operands[0].node; + +@@ -13927,19 +14529,18 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct + + component_count = hlsl_type_component_count(rhs->data_type); + if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) +- return false; ++ return NULL; + + if (!(func = hlsl_compile_internal_function(ctx, "isinf", body))) +- return false; ++ return NULL; + + hlsl_block_add_simple_store(ctx, block, func->parameters.vars[0], rhs); + + if (!(call = hlsl_new_call(ctx, func, &node->loc))) +- return false; ++ return NULL; + hlsl_block_add_instr(block, call); + +- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); +- return true; ++ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); + } + + static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *body, +@@ -13978,22 +14579,25 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v if (hlsl_version_ge(ctx, 4, 0) && hlsl_version_lt(ctx, 5, 0)) { -+ lower_ir(ctx, lower_countbits, body); -+ lower_ir(ctx, lower_ctz, body); - lower_ir(ctx, lower_f16tof32, body); - lower_ir(ctx, lower_f32tof16, body); -+ lower_ir(ctx, lower_find_msb, body); +- lower_ir(ctx, lower_f16tof32, body); +- lower_ir(ctx, lower_f32tof16, body); ++ replace_ir(ctx, lower_countbits, body); ++ replace_ir(ctx, lower_ctz, body); ++ replace_ir(ctx, lower_f16tof32, body); ++ replace_ir(ctx, lower_f32tof16, body); ++ replace_ir(ctx, lower_find_msb, body); } - lower_ir(ctx, lower_isinf, body); +- lower_ir(ctx, lower_isinf, body); ++ replace_ir(ctx, lower_isinf, body); + + lower_return(ctx, entry_func, body, false); + + while (hlsl_transform_ir(ctx, lower_calls, body, NULL)); + +- lower_ir(ctx, lower_complex_casts, body); +- lower_ir(ctx, lower_matrix_swizzles, body); +- lower_ir(ctx, lower_index_loads, body); ++ replace_ir(ctx, lower_complex_casts, body); ++ replace_ir(ctx, lower_matrix_swizzles, body); ++ replace_ir(ctx, lower_index_loads, body); + +- lower_ir(ctx, lower_tgsm_loads, body); +- lower_ir(ctx, lower_tgsm_stores, body); ++ replace_ir(ctx, lower_tgsm_loads, body); ++ replace_ir(ctx, lower_tgsm_stores, body); + + if (entry_func->return_var) + { +@@ -14166,9 +14770,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v + remove_unreachable_code(ctx, body); + hlsl_transform_ir(ctx, normalize_switch_cases, body, NULL); + +- lower_ir(ctx, lower_nonconstant_vector_derefs, body); +- lower_ir(ctx, lower_casts_to_bool, body); +- lower_ir(ctx, lower_int_dot, body); ++ replace_ir(ctx, lower_nonconstant_vector_derefs, body); ++ replace_ir(ctx, lower_casts_to_bool, body); ++ replace_ir(ctx, lower_int_dot, body); + + if (hlsl_version_lt(ctx, 4, 0)) + hlsl_transform_ir(ctx, lower_separate_samples, body, NULL); +@@ -14180,8 +14784,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v + progress = vectorize_exprs(ctx, body); + 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); ++ progress |= replace_ir(ctx, fold_swizzle_chains, body); ++ progress |= replace_ir(ctx, fold_trivial_swizzles, body); + progress |= vectorize_stores(ctx, body); + } while (progress); + +@@ -14209,37 +14813,37 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v + + if (profile->major_version < 4) + { +- while (lower_ir(ctx, lower_nonconstant_array_loads, body)); ++ while (replace_ir(ctx, lower_nonconstant_array_loads, body)); + +- lower_ir(ctx, lower_ternary, body); +- lower_ir(ctx, lower_int_modulus_sm1, body); +- lower_ir(ctx, lower_division, body); ++ replace_ir(ctx, lower_ternary, body); ++ replace_ir(ctx, lower_int_modulus_sm1, body); ++ replace_ir(ctx, lower_division, body); + /* Constants casted to float must be folded, and new casts to bool also need to be lowered. */ +- hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); +- lower_ir(ctx, lower_casts_to_bool, body); +- +- lower_ir(ctx, lower_casts_to_int, body); +- lower_ir(ctx, lower_trunc, body); +- lower_ir(ctx, lower_sqrt, body); +- lower_ir(ctx, lower_dot, body); +- lower_ir(ctx, lower_round, body); +- lower_ir(ctx, lower_ceil, body); +- lower_ir(ctx, lower_floor, body); +- lower_ir(ctx, lower_trig, body); +- lower_ir(ctx, lower_comparison_operators, body); +- lower_ir(ctx, lower_logic_not, body); ++ replace_ir(ctx, hlsl_fold_constant_exprs, body); ++ replace_ir(ctx, lower_casts_to_bool, body); ++ ++ replace_ir(ctx, lower_casts_to_int, body); ++ replace_ir(ctx, lower_trunc, body); ++ replace_ir(ctx, lower_sqrt, body); ++ replace_ir(ctx, lower_dot, body); ++ replace_ir(ctx, lower_round, body); ++ replace_ir(ctx, lower_ceil, body); ++ replace_ir(ctx, lower_floor, body); ++ replace_ir(ctx, lower_trig, body); ++ replace_ir(ctx, lower_comparison_operators, body); ++ replace_ir(ctx, lower_logic_not, body); + if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) +- lower_ir(ctx, lower_slt, body); ++ replace_ir(ctx, lower_slt, body); + else +- lower_ir(ctx, lower_cmp, body); ++ replace_ir(ctx, lower_cmp, body); + } + + if (profile->major_version < 2) + { +- lower_ir(ctx, lower_abs, body); ++ replace_ir(ctx, lower_abs, body); + } + +- lower_ir(ctx, validate_nonconstant_vector_store_derefs, body); ++ replace_ir(ctx, validate_nonconstant_vector_store_derefs, body); + + hlsl_run_folding_passes(ctx, body); + +@@ -14357,6 +14961,8 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info + if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL) + generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars); + ++ generate_vsir_descriptors(ctx, program); ++ + if (program->shader_version.major < 4) + sm1_generate_ctab(ctx, reflection_data); + else diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -index d339a06e6c7..7b3b0470d5d 100644 +index d339a06e6c7..1c44e5fa37a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c @@ -250,6 +250,118 @@ static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, @@ -6055,6 +9776,20 @@ index d339a06e6c7..7b3b0470d5d 100644 static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { +@@ -1212,11 +1434,11 @@ static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c + return true; + } + +-bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++struct hlsl_ir_node *hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL; + struct hlsl_constant_value res = {0}; +- struct hlsl_ir_node *res_node; + struct hlsl_ir_expr *expr; + unsigned int i; + bool success; @@ -1263,6 +1485,22 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_ceil(ctx, &res, instr->data_type, arg1); break; @@ -6115,10 +9850,19 @@ index d339a06e6c7..7b3b0470d5d 100644 case HLSL_OP3_TERNARY: success = fold_ternary(ctx, &res, instr->data_type, arg1, arg2, arg3); break; -@@ -1393,76 +1647,9 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - return success; - } +@@ -1384,103 +1638,32 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + } + if (success) +- { +- if (!(res_node = hlsl_new_constant(ctx, instr->data_type, &res, &instr->loc))) +- return false; +- list_add_before(&expr->node.entry, &res_node->entry); +- hlsl_replace_node(&expr->node, res_node); +- } +- return success; +-} +- -static bool constant_is_zero(struct hlsl_ir_constant *const_arg) -{ - struct hlsl_type *data_type = const_arg->node.data_type; @@ -6170,7 +9914,8 @@ index d339a06e6c7..7b3b0470d5d 100644 - if (const_arg->value.u[k].d != 1.0) - return false; - break; -- ++ return hlsl_block_add_constant(ctx, block, instr->data_type, &res, &instr->loc); + - case HLSL_TYPE_UINT: - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: @@ -6185,45 +9930,83 @@ index d339a06e6c7..7b3b0470d5d 100644 - } - } - return true; --} -- - bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++ return NULL; + } + +-bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++struct hlsl_ir_node *hlsl_fold_constant_identities(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) { + static const struct hlsl_constant_value zero; struct hlsl_ir_constant *const_arg = NULL; struct hlsl_ir_node *mut_arg = NULL; - struct hlsl_ir_node *res_node; -@@ -1502,29 +1689,40 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in +- struct hlsl_ir_node *res_node; + struct hlsl_ir_expr *expr; + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) +- return false; ++ return NULL; + expr = hlsl_ir_expr(instr); + + if (instr->data_type->class > HLSL_CLASS_VECTOR) +- return false; ++ return NULL; + + /* Verify that the expression has two operands. */ + for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) + { + if (!!expr->operands[i].node != (i < 2)) +- return false; ++ return NULL; + } + + if (expr->operands[0].node->type == HLSL_IR_CONSTANT) +@@ -1495,46 +1678,48 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + } + else + { +- return false; ++ return NULL; + } + +- res_node = NULL; switch (expr->op) { case HLSL_OP2_ADD: - if (constant_is_zero(const_arg)) +- res_node = mut_arg; + if (hlsl_constant_is_zero(const_arg)) - res_node = mut_arg; ++ return mut_arg; break; case HLSL_OP2_MUL: - if (constant_is_one(const_arg)) +- res_node = mut_arg; + if (hlsl_constant_is_one(const_arg)) - res_node = mut_arg; ++ return mut_arg; break; case HLSL_OP2_LOGIC_AND: - if (constant_is_zero(const_arg)) -+ if (hlsl_constant_is_zero(const_arg)) - res_node = &const_arg->node; +- res_node = &const_arg->node; - else if (constant_is_one(const_arg)) +- res_node = mut_arg; ++ if (hlsl_constant_is_zero(const_arg)) ++ return &const_arg->node; + else if (hlsl_constant_is_one(const_arg)) - res_node = mut_arg; ++ return mut_arg; break; case HLSL_OP2_LOGIC_OR: - if (constant_is_zero(const_arg)) -+ if (hlsl_constant_is_zero(const_arg)) - res_node = mut_arg; +- res_node = mut_arg; - else if (constant_is_one(const_arg)) +- res_node = &const_arg->node; ++ if (hlsl_constant_is_zero(const_arg)) ++ return mut_arg; + else if (hlsl_constant_is_one(const_arg)) - res_node = &const_arg->node; ++ return &const_arg->node; break; + case HLSL_OP2_LESS: @@ -6232,15 +10015,23 @@ index d339a06e6c7..7b3b0470d5d 100644 + || expr->operands[1].node->type != HLSL_IR_CONSTANT + || !hlsl_constant_is_zero(hlsl_ir_constant(expr->operands[1].node))) + break; -+ if (!(res_node = hlsl_new_constant(ctx, instr->data_type, &zero, &instr->loc))) -+ break; -+ list_add_before(&expr->node.entry, &res_node->entry); -+ break; ++ return hlsl_block_add_constant(ctx, block, instr->data_type, &zero, &instr->loc); + default: break; } -@@ -1649,6 +1847,9 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + +- if (res_node) +- { +- hlsl_replace_node(&expr->node, res_node); +- return true; +- } +- return false; ++ return NULL; + } + + static bool is_op_associative(enum hlsl_ir_expr_op op, enum hlsl_base_type type) +@@ -1649,6 +1834,9 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst if (instr->data_type->class > HLSL_CLASS_VECTOR) return false; @@ -6250,15 +10041,50 @@ index d339a06e6c7..7b3b0470d5d 100644 hlsl_block_init(&block); arg1 = expr->operands[0].node; +@@ -1760,28 +1948,23 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + return progress; + } + +-bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++struct hlsl_ir_node *hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, ++ struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_constant_value value; + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_constant *src; +- struct hlsl_ir_node *dst; + unsigned int i; + + if (instr->type != HLSL_IR_SWIZZLE) +- return false; ++ return NULL; + swizzle = hlsl_ir_swizzle(instr); + if (swizzle->val.node->type != HLSL_IR_CONSTANT) +- return false; ++ return NULL; + src = hlsl_ir_constant(swizzle->val.node); + + for (i = 0; i < swizzle->node.data_type->e.numeric.dimx; ++i) + value.u[i] = src->value.u[hlsl_swizzle_get_component(swizzle->u.vector, i)]; + +- if (!(dst = hlsl_new_constant(ctx, instr->data_type, &value, &instr->loc))) +- return false; +- +- list_add_before(&swizzle->node.entry, &dst->entry); +- hlsl_replace_node(&swizzle->node, dst); +- return true; ++ return hlsl_block_add_constant(ctx, block, instr->data_type, &value, &instr->loc); + } diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 23e059a3490..453b79c75d2 100644 +index 23e059a3490..5b1d0449a64 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -27,8 +27,54 @@ struct vsir_transformation_context +@@ -27,8 +27,55 @@ struct vsir_transformation_context uint64_t config_flags; const struct vkd3d_shader_compile_info *compile_info; struct vkd3d_shader_message_context *message_context; + struct vkd3d_shader_location null_location; ++ bool progress; +}; + +static void vsir_transformation_context_init(struct vsir_transformation_context *ctx, @@ -6309,7 +10135,23 @@ index 23e059a3490..453b79c75d2 100644 const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) { static const char * const names[] = -@@ -373,6 +419,177 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) +@@ -252,6 +299,7 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) + [VSIR_OP_MOVC ] = "movc", + [VSIR_OP_MSAD ] = "msad", + [VSIR_OP_MUL ] = "mul", ++ [VSIR_OP_NEG ] = "neg", + [VSIR_OP_NEO ] = "ne_ord", + [VSIR_OP_NEU ] = "ne", + [VSIR_OP_NOP ] = "nop", +@@ -290,6 +338,7 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) + [VSIR_OP_SAMPLE_LOD ] = "sample_l", + [VSIR_OP_SAMPLE_LOD_S ] = "sample_l_s", + [VSIR_OP_SAMPLE_POS ] = "sample_pos", ++ [VSIR_OP_SATURATE ] = "saturate", + [VSIR_OP_SETP ] = "setp", + [VSIR_OP_SGE ] = "sge", + [VSIR_OP_SGN ] = "sgn", +@@ -373,6 +422,177 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) return error; } @@ -6487,7 +10329,7 @@ index 23e059a3490..453b79c75d2 100644 static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) { -@@ -444,6 +661,11 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c +@@ -444,6 +664,11 @@ 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; @@ -6499,7 +10341,7 @@ index 23e059a3490..453b79c75d2 100644 if (!shader_instruction_array_init(&program->instructions, reserve)) { if (program->free_parameters) -@@ -471,6 +693,13 @@ void vsir_program_cleanup(struct vsir_program *program) +@@ -471,6 +696,13 @@ void vsir_program_cleanup(struct vsir_program *program) shader_signature_cleanup(&program->output_signature); shader_signature_cleanup(&program->patch_constant_signature); vkd3d_shader_free_scan_descriptor_info1(&program->descriptors); @@ -6513,7 +10355,46 @@ index 23e059a3490..453b79c75d2 100644 } const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( -@@ -796,16 +1025,15 @@ static void dst_param_init_output(struct vkd3d_shader_dst_param *dst, +@@ -517,6 +749,38 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature, + return false; + } + ++struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program, ++ enum vkd3d_shader_descriptor_type type, unsigned int register_id, ++ const struct vkd3d_shader_register_range *range, ++ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type) ++{ ++ struct vkd3d_shader_scan_descriptor_info1 *info = &program->descriptors; ++ struct vkd3d_shader_descriptor_info1 *d; ++ ++ if (!info) ++ return NULL; ++ ++ if (!vkd3d_array_reserve((void **)&info->descriptors, &program->descriptors_size, ++ info->descriptor_count + 1, sizeof(*info->descriptors))) ++ { ++ ERR("Failed to allocate descriptor info.\n"); ++ return NULL; ++ } ++ ++ d = &info->descriptors[info->descriptor_count]; ++ memset(d, 0, sizeof(*d)); ++ d->type = type; ++ d->register_id = register_id; ++ d->register_space = range->space; ++ d->register_index = range->first; ++ d->resource_type = resource_type; ++ d->resource_data_type = resource_data_type; ++ d->count = (range->last == ~0u) ? ~0u : range->last - range->first + 1; ++ ++info->descriptor_count; ++ ++ return d; ++} ++ + const char *debug_vsir_writemask(unsigned int writemask) + { + static const char components[] = {'x', 'y', 'z', 'w'}; +@@ -796,16 +1060,15 @@ static void dst_param_init_output(struct vkd3d_shader_dst_param *dst, dst->write_mask = write_mask; } @@ -6538,7 +10419,7 @@ index 23e059a3490..453b79c75d2 100644 } bool vsir_instruction_init_with_params(struct vsir_program *program, -@@ -857,11 +1085,19 @@ static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instr +@@ -857,11 +1120,19 @@ static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instr || opcode == VSIR_OP_HS_DECLS; } @@ -6561,7 +10442,21 @@ index 23e059a3490..453b79c75d2 100644 } static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, -@@ -1069,6 +1305,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program +@@ -952,11 +1223,12 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra + 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; ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; + + 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); ++ ins2->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + } + + for (k = 0; k < ins->src_count; ++k) +@@ -1069,6 +1341,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program ins->src[1].reg.u.immconst_f32[1] = 0.0f; ins->src[1].reg.u.immconst_f32[2] = 0.0f; ins->src[1].reg.u.immconst_f32[3] = 0.0f; @@ -6569,16 +10464,228 @@ index 23e059a3490..453b79c75d2 100644 /* tmp.x = tmp.x || tmp.y */ /* tmp.x = tmp.x || tmp.z */ -@@ -1422,7 +1659,7 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr +@@ -1120,7 +1393,7 @@ 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 vsir_program_iterator *it, unsigned int *tmp_idx) ++ struct vsir_program_iterator *it) + { + struct vkd3d_shader_instruction *mad, *mul_ins, *add_ins; + struct vkd3d_shader_dst_param *mul_dst; +@@ -1133,9 +1406,6 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro + if (!vsir_program_iterator_insert_after(it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- if (*tmp_idx == ~0u) +- *tmp_idx = program->temp_count++; +- + mul_ins = vsir_program_iterator_current(it); + add_ins = vsir_program_iterator_next(it); + +@@ -1150,14 +1420,9 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro + mul_dst = mul_ins->dst; + *add_ins->dst = *mul_dst; + +- mul_dst->modifiers = 0; +- vsir_register_init(&mul_dst->reg, VKD3DSPR_TEMP, mul_ins->src[0].reg.data_type, 1); +- mul_dst->reg.dimension = add_ins->dst->reg.dimension; +- mul_dst->reg.idx[0].offset = *tmp_idx; ++ dst_param_init_ssa(mul_dst, program->ssa_count, mul_ins->src[0].reg.data_type, VSIR_DIMENSION_VEC4); ++ src_param_init_ssa(&add_ins->src[0], program->ssa_count++, mul_ins->src[0].reg.data_type, VSIR_DIMENSION_VEC4); + +- add_ins->src[0].reg = mul_dst->reg; +- add_ins->src[0].swizzle = vsir_swizzle_from_writemask(mul_dst->write_mask); +- add_ins->src[0].modifiers = 0; + add_ins->src[1] = mul_ins->src[2]; + + return VKD3D_OK; +@@ -1184,8 +1449,8 @@ static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program, + static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, + struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) + { ++ unsigned int count = 3, src0_id, src1_id, divisor_id; + struct vkd3d_shader_instruction *udiv, *ins, *mov; +- unsigned int count = 2; + + udiv = vsir_program_iterator_current(it); + +@@ -1199,9 +1464,9 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, + } + + if (udiv->dst[0].reg.type != VKD3DSPR_NULL) +- ++count; ++ count += 2; + if (udiv->dst[1].reg.type != VKD3DSPR_NULL) +- ++count; ++ count += 2; + + if (!vsir_program_iterator_insert_after(it, count)) + return VKD3D_ERROR_OUT_OF_MEMORY; +@@ -1213,14 +1478,33 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, + 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); ++ src0_id = program->ssa_count++; ++ dst_param_init_ssa(&mov->dst[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); + + 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[1]; +- dst_param_init_ssa(&mov->dst[0], program->ssa_count + 1, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ src1_id = program->ssa_count++; ++ dst_param_init_ssa(&mov->dst[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ ++ mov = vsir_program_iterator_next(it); ++ if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOVC, 1, 3))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ src_param_init_ssa(&mov->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ src_param_init_ssa(&mov->src[1], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ vsir_register_init(&mov->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); ++ mov->src[2].reg.dimension = udiv->src[1].reg.dimension; ++ mov->src[2].reg.u.immconst_u32[0] = 1; ++ mov->src[2].reg.u.immconst_u32[1] = 1; ++ mov->src[2].reg.u.immconst_u32[2] = 1; ++ mov->src[2].reg.u.immconst_u32[3] = 1; ++ if (mov->src[2].reg.dimension == VSIR_DIMENSION_VEC4) ++ mov->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ divisor_id = program->ssa_count++; ++ dst_param_init_ssa(&mov->dst[0], divisor_id, mov->src[1].reg.data_type, mov->src[1].reg.dimension); + + if (udiv->dst[0].reg.type != VKD3DSPR_NULL) + { +@@ -1231,11 +1515,30 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, + + 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); ++ src_param_init_ssa(&ins->src[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); ++ src_param_init_ssa(&ins->src[1], divisor_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ dst_param_init_ssa(&ins->dst[0], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ ++ /* Like its TPF equivalent, division by zero is well-defined for ++ * VSIR_OP_UDIV, and returns UINT_MAX. Division by zero is undefined ++ * for VSIR_OP_UDIV_SIMPLE and VSIR_OP_UREM, so handle it here. */ ++ ins = vsir_program_iterator_next(it); ++ if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_MOVC, 1, 3))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ src_param_init_ssa(&ins->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ src_param_init_ssa(&ins->src[1], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ vsir_register_init(&ins->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); ++ ins->src[2].reg.dimension = udiv->src[1].reg.dimension; ++ ins->src[2].reg.u.immconst_u32[0] = UINT_MAX; ++ ins->src[2].reg.u.immconst_u32[1] = UINT_MAX; ++ ins->src[2].reg.u.immconst_u32[2] = UINT_MAX; ++ ins->src[2].reg.u.immconst_u32[3] = UINT_MAX; ++ if (ins->src[2].reg.dimension == VSIR_DIMENSION_VEC4) ++ ins->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; + ins->dst[0] = udiv->dst[0]; ++ ++ ++program->ssa_count; + } + + if (udiv->dst[1].reg.type != VKD3DSPR_NULL) +@@ -1247,15 +1550,30 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, + + 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); ++ src_param_init_ssa(&ins->src[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); ++ src_param_init_ssa(&ins->src[1], divisor_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ dst_param_init_ssa(&ins->dst[0], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ ++ ins = vsir_program_iterator_next(it); ++ if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_MOVC, 1, 3))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ src_param_init_ssa(&ins->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ src_param_init_ssa(&ins->src[1], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); ++ vsir_register_init(&ins->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); ++ ins->src[2].reg.dimension = udiv->src[1].reg.dimension; ++ ins->src[2].reg.u.immconst_u32[0] = UINT_MAX; ++ ins->src[2].reg.u.immconst_u32[1] = UINT_MAX; ++ ins->src[2].reg.u.immconst_u32[2] = UINT_MAX; ++ ins->src[2].reg.u.immconst_u32[3] = UINT_MAX; ++ if (ins->src[2].reg.dimension == VSIR_DIMENSION_VEC4) ++ ins->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; + ins->dst[0] = udiv->dst[1]; ++ ++ ++program->ssa_count; + } + + vkd3d_shader_instruction_make_nop(udiv); +- program->ssa_count += 2; + + return VKD3D_OK; + } +@@ -1410,7 +1728,8 @@ static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program, + 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; ++ const struct vkd3d_shader_descriptor_info1 *sampler; ++ unsigned int idx = ins->dst[0].reg.idx[0].offset; + struct vkd3d_shader_src_param *srcs; + + /* texld DST, t# -> sample DST, t#, resource#, sampler# */ +@@ -1422,7 +1741,7 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr return VKD3D_ERROR_NOT_IMPLEMENTED; } - if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3))) -+ if (!(srcs = vsir_program_get_src_params(program, 3))) ++ if (!(srcs = vsir_program_get_src_params(program, 4))) return VKD3D_ERROR_OUT_OF_MEMORY; /* Note we run before I/O normalization. */ -@@ -1498,7 +1735,7 @@ static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program, +@@ -1430,9 +1749,26 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr + 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; ++ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); ++ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) ++ { ++ enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2); ++ ++ ins->opcode = VSIR_OP_SAMPLE_C; ++ ins->src = srcs; ++ ins->src_count = 4; ++ ++ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ++ srcs[3] = srcs[0]; ++ srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref); ++ } ++ else ++ { ++ ins->opcode = VSIR_OP_SAMPLE; ++ ins->src = srcs; ++ ins->src_count = 3; ++ } + + return VKD3D_OK; + } +@@ -1492,20 +1828,35 @@ static enum vkd3d_result vsir_program_lower_texldp(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) + { ++ const struct vkd3d_shader_descriptor_info1 *sampler; + unsigned int idx = tex->src[1].reg.idx[0].offset; + struct vkd3d_shader_src_param *srcs; + VKD3D_ASSERT(tex->src[1].reg.idx_count == 1); VKD3D_ASSERT(!tex->src[1].reg.idx[0].rel_addr); @@ -6587,7 +10694,29 @@ index 23e059a3490..453b79c75d2 100644 return VKD3D_ERROR_OUT_OF_MEMORY; srcs[0] = tex->src[0]; -@@ -1541,7 +1778,7 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, + vsir_src_param_init_resource(&srcs[1], idx, idx); + vsir_src_param_init_sampler(&srcs[2], idx, idx); + +- if (!tex->flags) ++ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); ++ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) ++ { ++ enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2); ++ ++ tex->opcode = VSIR_OP_SAMPLE_C; ++ tex->src = srcs; ++ tex->src_count = 4; ++ ++ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ++ srcs[3] = srcs[0]; ++ srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref); ++ } ++ else if (!tex->flags) + { + tex->opcode = VSIR_OP_SAMPLE; + tex->src = srcs; +@@ -1541,7 +1892,7 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, VKD3D_ASSERT(texldd->src[1].reg.idx_count == 1); VKD3D_ASSERT(!texldd->src[1].reg.idx[0].rel_addr); @@ -6596,7 +10725,7 @@ index 23e059a3490..453b79c75d2 100644 return VKD3D_ERROR_OUT_OF_MEMORY; srcs[0] = texldd->src[0]; -@@ -1567,7 +1804,7 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, +@@ -1567,7 +1918,7 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, VKD3D_ASSERT(texldl->src[1].reg.idx_count == 1); VKD3D_ASSERT(!texldl->src[1].reg.idx[0].rel_addr); @@ -6605,12 +10734,16 @@ index 23e059a3490..453b79c75d2 100644 return VKD3D_ERROR_OUT_OF_MEMORY; srcs[0] = texldl->src[0]; -@@ -1585,6 +1822,64 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, +@@ -1585,211 +1936,380 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, 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) +static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *ins) -+{ + { +- switch (ins->declaration.dst.reg.type) ++ const struct vkd3d_shader_descriptor_info1 *sampler; + unsigned int idx = ins->dst[0].reg.idx[0].offset; + struct vkd3d_shader_src_param *srcs; + @@ -6620,7 +10753,7 @@ index 23e059a3490..453b79c75d2 100644 + /* We run before I/O normalization. */ + VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6); + -+ if (!(srcs = vsir_program_get_src_params(program, 3))) ++ if (!(srcs = vsir_program_get_src_params(program, 4))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); @@ -6631,22 +10764,88 @@ index 23e059a3490..453b79c75d2 100644 + 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; -+} -+ ++ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); ++ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) + { +- case VKD3DSPR_INPUT: +- case VKD3DSPR_OUTPUT: +- case VKD3DSPR_PATCHCONST: +- case VKD3DSPR_INCONTROLPOINT: +- case VKD3DSPR_OUTCONTROLPOINT: +- break; ++ ins->opcode = VSIR_OP_SAMPLE_C; ++ ins->src = srcs; ++ ins->src_count = 4; + +- case VKD3DSPR_PRIMID: +- case VKD3DSPR_FORKINSTID: +- case VKD3DSPR_JOININSTID: +- case VKD3DSPR_THREADID: +- case VKD3DSPR_THREADGROUPID: +- case VKD3DSPR_LOCALTHREADID: +- case VKD3DSPR_LOCALTHREADINDEX: +- case VKD3DSPR_COVERAGE: +- case VKD3DSPR_TESSCOORD: +- case VKD3DSPR_OUTPOINTID: +- case VKD3DSPR_GSINSTID: +- case VKD3DSPR_WAVELANECOUNT: +- case VKD3DSPR_WAVELANEINDEX: +- bitmap_set(program->io_dcls, ins->declaration.dst.reg.type); +- break; ++ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + +- default: +- vkd3d_shader_error(ctx->message_context, &ins->location, +- VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, +- "Internal compiler error: invalid register type %#x for DCL_INPUT.", +- ins->declaration.dst.reg.type); +- return VKD3D_ERROR; ++ srcs[3] = srcs[0]; ++ srcs[3].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); ++ } ++ else ++ { ++ ins->opcode = VSIR_OP_SAMPLE; ++ ins->src = srcs; ++ ins->src_count = 3; + } + + return VKD3D_OK; + } + +-static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *program, +- struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) +static enum vkd3d_result vsir_program_lower_texcoord(struct vsir_program *program, + struct vkd3d_shader_instruction *ins) -+{ + { +- switch (ins->declaration.dst.reg.type) +- { +- case VKD3DSPR_INPUT: +- case VKD3DSPR_OUTPUT: +- case VKD3DSPR_PATCHCONST: +- case VKD3DSPR_INCONTROLPOINT: +- case VKD3DSPR_OUTCONTROLPOINT: +- break; + unsigned int idx = ins->dst[0].reg.idx[0].offset; + struct vkd3d_shader_src_param *srcs; -+ -+ /* texcoord t# -> mov_sat t#, t# + +- case VKD3DSPR_DEPTHOUT: +- case VKD3DSPR_SAMPLEMASK: +- case VKD3DSPR_DEPTHOUTGE: +- case VKD3DSPR_DEPTHOUTLE: +- case VKD3DSPR_OUTSTENCILREF: +- bitmap_set(program->io_dcls, ins->declaration.dst.reg.type); +- break; ++ /* texcoord t# -> saturate t#, t# + * Note that the t# destination will subsequently be turned into a temp. */ -+ + +- default: +- vkd3d_shader_error(ctx->message_context, &ins->location, +- VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, +- "Internal compiler error: invalid register type %#x for DCL_OUTPUT.", +- ins->declaration.dst.reg.type); +- return VKD3D_ERROR; +- } + /* We run before I/O normalization. */ + VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6); + @@ -6658,95 +10857,290 @@ index 23e059a3490..453b79c75d2 100644 + srcs[0].reg.dimension = VSIR_DIMENSION_VEC4; + srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + -+ ins->dst[0].modifiers |= VKD3DSPDM_SATURATE; -+ -+ ins->opcode = VSIR_OP_MOV; ++ ins->opcode = VSIR_OP_SATURATE; + ins->src = srcs; + ins->src_count = 1; + + return VKD3D_OK; + } + +-static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_program *program, +- struct vsir_transformation_context *ctx) ++static struct vkd3d_shader_instruction *generate_bump_coords(struct vsir_program *program, ++ struct vsir_program_iterator *it, uint32_t idx, const struct vkd3d_shader_src_param *coords, ++ const struct vkd3d_shader_src_param *perturbation, const struct vkd3d_shader_location *loc) + { +- 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; ++ uint32_t ssa_temp, ssa_coords; + +- for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ /* We generate the following code: ++ * ++ * mad srTMP.xy, PERTURBATION.xx, BUMP_MATRIX#.xy, COORDS.xy ++ * mad srCOORDS.xy, PERTURBATION.yy, BUMP_MATRIX#.zw, srTMP.xy ++ */ ++ ++ ssa_temp = program->ssa_count++; ++ ssa_coords = program->ssa_count++; ++ ++ ins = vsir_program_iterator_current(it); ++ if (!vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAD, 1, 3)) ++ return false; ++ dst_param_init_ssa_float4(&ins->dst[0], ssa_temp); ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; ++ ins->src[0] = *perturbation; ++ ins->src[0].swizzle = vsir_combine_swizzles(perturbation->swizzle, VKD3D_SHADER_SWIZZLE(X, X, X, X)); ++ src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 + idx, VSIR_DATA_F32); ++ ins->src[2] = *coords; ++ ++ ins = vsir_program_iterator_next(it); ++ if (!vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAD, 1, 3)) ++ return false; ++ dst_param_init_ssa_float4(&ins->dst[0], ssa_coords); ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; ++ ins->src[0] = *perturbation; ++ ins->src[0].swizzle = vsir_combine_swizzles(perturbation->swizzle, VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y)); ++ src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 + idx, VSIR_DATA_F32); ++ ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(Z, W, W, W); ++ src_param_init_ssa_float4(&ins->src[2], ssa_temp); ++ ins->src[2].swizzle = VKD3D_SHADER_SWIZZLE(X, Y, Y, Y); ++ ++ return ins; ++} ++ ++static enum vkd3d_result vsir_program_lower_bem(struct vsir_program *program, struct vsir_program_iterator *it) ++{ ++ struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); ++ const struct vkd3d_shader_location location = ins->location; ++ const struct vkd3d_shader_src_param *src = ins->src; ++ const struct vkd3d_shader_dst_param *dst = ins->dst; ++ ++ /* bem DST.xy, SRC0, SRC1 ++ * -> ++ * mad srTMP.xy, SRC1.xx, BUMP_MATRIX#.xy, SRC0.xy ++ * mad DST.xy, SRC1.yy, BUMP_MATRIX#.zw, srTMP.xy */ ++ ++ if (!vsir_program_iterator_insert_after(it, 1)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ if (!(ins = generate_bump_coords(program, it, dst[0].reg.idx[0].offset, &src[0], &src[1], &location))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ ins->dst[0] = dst[0]; ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_lower_texbem(struct vsir_program *program, ++ struct vsir_program_iterator *it, struct vkd3d_shader_message_context *message_context) ++{ ++ struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); ++ const struct vkd3d_shader_location location = ins->location; ++ const struct vkd3d_shader_descriptor_info1 *descriptor; ++ const struct vkd3d_shader_src_param *src = ins->src; ++ bool is_texbeml = (ins->opcode == VSIR_OP_TEXBEML); ++ unsigned int idx = ins->dst[0].reg.idx[0].offset; ++ uint32_t ssa_coords, ssa_luminance, ssa_sample; ++ struct vkd3d_shader_src_param orig_coords; ++ ++ /* texbem t#, SRC ++ * -> ++ * bem srCOORDS.xy, t#, SRC ++ * texld t#, srCOORDS ++ * -> ++ * mad srTMP.xy, SRC.xx, BUMP_MATRIX#.xy, t#.xy ++ * mad srCOORDS.xy, SRC.yy, BUMP_MATRIX#.zw, srTMP.xy ++ * sample t#, srCOORDS, resource#, sampler# ++ * ++ * Luminance then adds: ++ * ++ * mad srLUM.x, SRC.z, BUMP_LUMINANCE_SCALE#, BUMP_LUMINANCE_OFFSET# ++ * mul t#, t#, srLUM.xxxx ++ * ++ * Note that the t# destination will subsequently be turned into a temp. */ ++ ++ descriptor = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); ++ if (descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) + { +- enum vkd3d_result ret; ++ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Unhandled TEXBEM(L) with a comparison sampler."); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } + +- switch (ins->opcode) +- { +- case VSIR_OP_TEXCRD: +- ret = vsir_program_lower_texcrd(program, ins, message_context); +- break; ++ descriptor = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, idx); ++ if (descriptor->resource_type != VKD3D_SHADER_RESOURCE_TEXTURE_2D) ++ { ++ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Unhandled TEXBEM(L) with resource dimension %#x.", descriptor->resource_type); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } + +- 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; ++ if (!vsir_program_iterator_insert_after(it, is_texbeml ? 4 : 2)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; + +- default: +- ret = VKD3D_OK; +- break; +- } ++ vsir_src_param_init(&orig_coords, VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); ++ orig_coords.reg.idx[0].offset = idx; ++ orig_coords.reg.dimension = VSIR_DIMENSION_VEC4; ++ orig_coords.swizzle = VKD3D_SHADER_NO_SWIZZLE; + +- if (ret < 0) +- return ret; ++ if (!(ins = generate_bump_coords(program, it, idx, &orig_coords, &src[0], &location))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ssa_coords = ins->dst[0].reg.idx[0].offset; ++ ++ ins = vsir_program_iterator_next(it); ++ if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_SAMPLE, 1, 3)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); ++ ins->dst[0].reg.idx[0].offset = idx; ++ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; ++ src_param_init_ssa_float4(&ins->src[0], ssa_coords); ++ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, Y, Y, Y); ++ vsir_src_param_init_resource(&ins->src[1], idx, idx); ++ vsir_src_param_init_sampler(&ins->src[2], idx, idx); ++ ++ if (is_texbeml) ++ { ++ enum vkd3d_shader_swizzle_component z = vsir_swizzle_get_component(src[0].swizzle, 2); ++ ++ ssa_sample = program->ssa_count++; ++ ssa_luminance = program->ssa_count++; ++ ++ /* Replace t# destination of the SAMPLE instruction with an SSA value. */ ++ dst_param_init_ssa_float4(&ins->dst[0], ssa_sample); ++ ++ ins = vsir_program_iterator_next(it); ++ if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_MAD, 1, 3)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ dst_param_init_ssa_float4(&ins->dst[0], ssa_luminance); ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; ++ ins->src[0] = src[0]; ++ ins->src[0].swizzle = vkd3d_shader_create_swizzle(z, z, z, z); ++ src_param_init_parameter(&ins->src[1], ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0 + idx, VSIR_DATA_F32); ++ src_param_init_parameter(&ins->src[2], ++ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0 + idx, VSIR_DATA_F32); ++ ++ ins = vsir_program_iterator_next(it); ++ if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_MUL, 1, 2)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); ++ ins->dst[0].reg.idx[0].offset = idx; ++ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; ++ src_param_init_ssa_float4(&ins->src[0], ssa_sample); ++ src_param_init_ssa_float4(&ins->src[1], ssa_luminance); ++ ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ } ++ 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) ++{ ++ switch (ins->declaration.dst.reg.type) ++ { ++ case VKD3DSPR_INPUT: ++ case VKD3DSPR_OUTPUT: ++ case VKD3DSPR_PATCHCONST: ++ case VKD3DSPR_INCONTROLPOINT: ++ case VKD3DSPR_OUTCONTROLPOINT: ++ break; ++ ++ case VKD3DSPR_PRIMID: ++ case VKD3DSPR_FORKINSTID: ++ case VKD3DSPR_JOININSTID: ++ case VKD3DSPR_THREADID: ++ case VKD3DSPR_THREADGROUPID: ++ case VKD3DSPR_LOCALTHREADID: ++ case VKD3DSPR_LOCALTHREADINDEX: ++ case VKD3DSPR_COVERAGE: ++ case VKD3DSPR_TESSCOORD: ++ case VKD3DSPR_OUTPOINTID: ++ case VKD3DSPR_GSINSTID: ++ case VKD3DSPR_WAVELANECOUNT: ++ case VKD3DSPR_WAVELANEINDEX: ++ bitmap_set(program->io_dcls, ins->declaration.dst.reg.type); ++ break; ++ ++ default: ++ vkd3d_shader_error(ctx->message_context, &ins->location, ++ VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, ++ "Internal compiler error: invalid register type %#x for DCL_INPUT.", ++ ins->declaration.dst.reg.type); ++ return VKD3D_ERROR; + } + + return VKD3D_OK; + } + +-static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, ++static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *program, ++ struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) ++{ ++ switch (ins->declaration.dst.reg.type) ++ { ++ case VKD3DSPR_INPUT: ++ case VKD3DSPR_OUTPUT: ++ case VKD3DSPR_PATCHCONST: ++ case VKD3DSPR_INCONTROLPOINT: ++ case VKD3DSPR_OUTCONTROLPOINT: ++ break; ++ ++ case VKD3DSPR_DEPTHOUT: ++ case VKD3DSPR_SAMPLEMASK: ++ case VKD3DSPR_DEPTHOUTGE: ++ case VKD3DSPR_DEPTHOUTLE: ++ case VKD3DSPR_OUTSTENCILREF: ++ bitmap_set(program->io_dcls, ins->declaration.dst.reg.type); ++ break; ++ ++ default: ++ vkd3d_shader_error(ctx->message_context, &ins->location, ++ VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, ++ "Internal compiler error: invalid register type %#x for DCL_OUTPUT.", ++ ins->declaration.dst.reg.type); ++ return VKD3D_ERROR; ++ } + + 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) - { -@@ -1669,10 +1964,31 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr - - switch (ins->opcode) - { -+ case VSIR_OP_IFC: -+ ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context); -+ break; -+ -+ case VSIR_OP_SINCOS: -+ ret = vsir_program_lower_sm1_sincos(program, &it); -+ break; -+ -+ case VSIR_OP_TEXCOORD: -+ if ((ret = vsir_program_lower_texcoord(program, ins)) < 0) -+ return ret; -+ break; -+ - case VSIR_OP_TEXCRD: - ret = vsir_program_lower_texcrd(program, ins, message_context); - break; - -+ case VSIR_OP_TEXKILL: -+ ret = vsir_program_lower_texkill(program, &it, &tmp_idx); -+ break; -+ -+ case VSIR_OP_TEX: -+ ret = vsir_program_lower_tex(program, ins); -+ break; -+ - case VSIR_OP_TEXLD: - if (program->shader_version.major == 1) - ret = vsir_program_lower_texld_sm1(program, ins, message_context); -@@ -1682,6 +1998,34 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr - ret = vsir_program_lower_texld(program, ins, message_context); - break; - -+ case VSIR_OP_TEXLDD: -+ ret = vsir_program_lower_texldd(program, ins); -+ break; -+ -+ case VSIR_OP_TEXLDL: -+ ret = vsir_program_lower_texldl(program, ins); -+ break; -+ -+ case VSIR_OP_TEXBEM: -+ case VSIR_OP_TEXBEML: -+ 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 \"%s\" (%#x).", -+ vsir_opcode_get_name(ins->opcode, ""), ins->opcode); -+ return VKD3D_ERROR_NOT_IMPLEMENTED; -+ - default: - ret = VKD3D_OK; - break; -@@ -1698,7 +2042,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr ++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_message_context *message_context = ctx->message_context; struct vkd3d_shader_instruction *ins; unsigned int tmp_idx = ~0u; - enum vkd3d_result ret; -@@ -1707,16 +2050,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr +- enum vkd3d_result ret; + + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { ++ enum vkd3d_result ret; ++ switch (ins->opcode) { - case VSIR_OP_IFC: @@ -6757,75 +11151,349 @@ index 23e059a3490..453b79c75d2 100644 - case VSIR_OP_TEXKILL: - if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0) - return ret; -- break; -- - case VSIR_OP_MAD: - if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) - return ret; -@@ -1725,6 +2058,8 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - case VSIR_OP_DCL: - case VSIR_OP_DCL_CONSTANT_BUFFER: - case VSIR_OP_DCL_GLOBAL_FLAGS: -+ case VSIR_OP_DCL_INPUT_PRIMITIVE: -+ case VSIR_OP_DCL_OUTPUT_TOPOLOGY: - case VSIR_OP_DCL_SAMPLER: - case VSIR_OP_DCL_TEMPS: - case VSIR_OP_DCL_TESSELLATOR_DOMAIN: -@@ -1765,51 +2100,67 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr ++ case VSIR_OP_BEM: ++ ret = vsir_program_lower_bem(program, &it); break; - case VSIR_OP_SINCOS: +- case VSIR_OP_MAD: +- if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) +- return ret; ++ case VSIR_OP_IFC: ++ ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context); + break; + +- 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); ++ case VSIR_OP_SINCOS: ++ ret = vsir_program_lower_sm1_sincos(program, &it); + break; + +- case VSIR_OP_DCL_INPUT: +- vsir_program_lower_dcl_input(program, ins, ctx); +- vkd3d_shader_instruction_make_nop(ins); ++ case VSIR_OP_TEXBEM: ++ case VSIR_OP_TEXBEML: ++ ret = vsir_program_lower_texbem(program, &it, message_context); + break; + +- case VSIR_OP_DCL_OUTPUT: +- vsir_program_lower_dcl_output(program, ins, ctx); +- vkd3d_shader_instruction_make_nop(ins); ++ case VSIR_OP_TEXCOORD: ++ if ((ret = vsir_program_lower_texcoord(program, ins)) < 0) ++ return ret; + break; + +- 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); ++ case VSIR_OP_TEXCRD: ++ ret = vsir_program_lower_texcrd(program, ins, message_context); + break; + +- case VSIR_OP_IMUL: +- case VSIR_OP_UMUL: +- if ((ret = vsir_program_lower_imul(program, ins, ctx)) < 0) +- return ret; ++ case VSIR_OP_TEXKILL: ++ ret = vsir_program_lower_texkill(program, &it, &tmp_idx); + break; + +- case VSIR_OP_UDIV: +- if ((ret = vsir_program_lower_udiv(program, &it, ctx)) < 0) +- return ret; ++ case VSIR_OP_TEX: ++ ret = vsir_program_lower_tex(program, ins); + break; + +- case VSIR_OP_SINCOS: - if (ins->dst_count == 1) - { - if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0) - return ret; - } -- else ++ 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 - { - if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) - return ret; - } -- break; -- -- case VSIR_OP_TEXLDD: -- if ((ret = vsir_program_lower_texldd(program, ins)) < 0) -+ if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) - return ret; ++ ret = vsir_program_lower_texld(program, ins, message_context); break; -- case VSIR_OP_TEXLDL: + case VSIR_OP_TEXLDD: +- if ((ret = vsir_program_lower_texldd(program, ins)) < 0) +- return ret; ++ ret = vsir_program_lower_texldd(program, ins); + break; + + case VSIR_OP_TEXLDL: - if ((ret = vsir_program_lower_texldl(program, ins)) < 0) - return ret; -+ default: ++ ret = vsir_program_lower_texldl(program, ins); 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 \"%s\" (%#x).", -- vsir_opcode_get_name(ins->opcode, ""), ins->opcode); -- return VKD3D_ERROR_NOT_IMPLEMENTED; + case VSIR_OP_TEXDEPTH: + case VSIR_OP_TEXDP3: + case VSIR_OP_TEXDP3TEX: +@@ -1809,63 +2329,318 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + return VKD3D_ERROR_NOT_IMPLEMENTED; + + default: ++ ret = VKD3D_OK; + break; + } ++ ++ if (ret < 0) ++ return ret; + } + + 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, ++static enum vkd3d_result vsir_program_lower_modifiers(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; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), new_it; ++ struct vkd3d_shader_instruction *ins, *new_ins; ++ enum vkd3d_result ret = VKD3D_OK; ++ unsigned int i, j; + +- ins = vsir_program_iterator_tail(&it); +- if (ins && ins->opcode == VSIR_OP_RET) +- return VKD3D_OK; ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ for (i = 0; i < ins->src_count; ++i) ++ { ++ enum vkd3d_shader_opcode new_opcodes[2] = {VSIR_OP_NOP, VSIR_OP_NOP}; ++ struct vkd3d_shader_src_param *src = &ins->src[i]; + +- if (!(ins = vsir_program_append(program))) +- return VKD3D_ERROR_OUT_OF_MEMORY; +- vsir_instruction_init(ins, &no_loc, VSIR_OP_RET); ++ switch (src->modifiers) ++ { ++ case VKD3DSPSM_NONE: ++ continue; + +- return VKD3D_OK; +-} ++ case VKD3DSPSM_ABS: ++ new_opcodes[0] = VSIR_OP_ABS; ++ break; + +-/* ps_1_* outputs color in r0. Add an instruction to copy that to oC0. +- * We don't need to modify the signature since it already contains COLOR. */ +-static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program *program, +- struct vsir_transformation_context *ctx) +-{ +- struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); +- struct vkd3d_shader_instruction *ins; +- struct vkd3d_shader_location loc; ++ case VKD3DSPSM_NEG: ++ new_opcodes[0] = data_type_is_integer(src->reg.data_type) ? VSIR_OP_INEG : VSIR_OP_NEG; ++ break; + +- if (!(ins = vsir_program_iterator_tail(&it))) +- return VKD3D_OK; +- loc = ins->location; ++ case VKD3DSPSM_ABSNEG: ++ new_opcodes[0] = VSIR_OP_ABS; ++ new_opcodes[1] = VSIR_OP_NEG; ++ break; + +- 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; ++ default: ++ vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Aborting due to unimplemented feature: Source modifier %#x.", src->modifiers); ++ ret = VKD3D_ERROR_NOT_IMPLEMENTED; ++ continue; ++ } ++ ++ for (j = 0; j < 2 && new_opcodes[j] != VSIR_OP_NOP; ++j) ++ { ++ if (!(new_ins = vsir_program_iterator_insert_before(&it, &new_it, 1))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ins = vsir_program_iterator_current(&it); ++ ++ if (!vsir_instruction_init_with_params(program, new_ins, &ins->location, new_opcodes[j], 1, 1)) ++ { ++ vkd3d_shader_instruction_make_nop(new_ins); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ ++ new_ins->src[0] = *src; ++ new_ins->src[0].modifiers = VKD3DSPSM_NONE; ++ ++ dst_param_init_ssa(&new_ins->dst[0], program->ssa_count, src->reg.data_type, src->reg.dimension); ++ src_param_init_ssa(src, program->ssa_count, src->reg.data_type, src->reg.dimension); ++ ++ if (data_type_is_64_bit(src->reg.data_type)) ++ { ++ new_ins->dst[0].write_mask = vsir_write_mask_64_from_32(new_ins->dst[0].write_mask); ++ src->swizzle = vsir_swizzle_64_from_32(src->swizzle); ++ } ++ ++ ++program->ssa_count; ++ } ++ } ++ ++ for (i = 0; i < ins->dst_count; ++i) ++ { ++ struct vkd3d_shader_dst_param *dst = &ins->dst[i]; ++ ++ /* It is always legitimate to ignore _pp. */ ++ dst->modifiers &= ~VKD3DSPDM_PARTIALPRECISION; ++ ++ if (dst->modifiers & ~VKD3DSPDM_SATURATE) ++ { ++ vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Aborting due to unimplemented feature: Destination modifier %#x.", dst->modifiers); ++ ret = VKD3D_ERROR_NOT_IMPLEMENTED; ++ continue; ++ } ++ ++ if (dst->modifiers & VKD3DSPDM_SATURATE) ++ { ++ if (!vsir_program_iterator_insert_after(&it, 1)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ new_ins = vsir_program_iterator_next(&it); ++ ins = vsir_program_iterator_prev(&it); ++ ++ if (!vsir_instruction_init_with_params(program, new_ins, &ins->location, VSIR_OP_SATURATE, 1, 1)) ++ { ++ vkd3d_shader_instruction_make_nop(new_ins); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ ++ new_ins->dst[0] = *dst; ++ new_ins->dst[0].modifiers &= ~VKD3DSPDM_SATURATE; ++ ++ dst_param_init_ssa(dst, program->ssa_count, dst->reg.data_type, dst->reg.dimension); ++ src_param_init_ssa(&new_ins->src[0], program->ssa_count, dst->reg.data_type, dst->reg.dimension); ++ ++ if (data_type_is_64_bit(dst->reg.data_type)) ++ { ++ dst->write_mask = vsir_write_mask_64_from_32(dst->write_mask); ++ new_ins->src[0].swizzle = vsir_swizzle_64_from_32(new_ins->src[0].swizzle); ++ } ++ ++ ++program->ssa_count; ++ } ++ } ++ } ++ ++ program->has_no_modifiers = true; ++ ++ return ret; ++} ++ ++static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; ++ enum vkd3d_result ret; ++ ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ switch (ins->opcode) ++ { ++ case VSIR_OP_MAD: ++ if ((ret = vsir_program_lower_precise_mad(program, &it)) < 0) ++ return ret; ++ break; ++ ++ case VSIR_OP_DCL: ++ case VSIR_OP_DCL_CONSTANT_BUFFER: ++ case VSIR_OP_DCL_GLOBAL_FLAGS: ++ case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: ++ case VSIR_OP_DCL_INPUT_PRIMITIVE: ++ case VSIR_OP_DCL_OUTPUT_TOPOLOGY: ++ 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 VSIR_OP_DCL_INPUT: ++ vsir_program_lower_dcl_input(program, ins, ctx); ++ vkd3d_shader_instruction_make_nop(ins); ++ break; ++ ++ case VSIR_OP_DCL_OUTPUT: ++ vsir_program_lower_dcl_output(program, ins, ctx); ++ vkd3d_shader_instruction_make_nop(ins); ++ break; ++ ++ 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 VSIR_OP_IMUL: ++ case VSIR_OP_UMUL: ++ if ((ret = vsir_program_lower_imul(program, ins, ctx)) < 0) ++ return ret; ++ break; ++ ++ case VSIR_OP_UDIV: ++ if ((ret = vsir_program_lower_udiv(program, &it, ctx)) < 0) ++ return ret; ++ break; ++ ++ case VSIR_OP_SINCOS: ++ if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) ++ return ret; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ + return VKD3D_OK; +} - -- default: -- break; ++ +/* 1.0-1.3 pixel shaders allow writing t# registers, at which point they + * effectively behave like normal r# temps. Convert them to r# registers. + * t# registers which are read before being written contain TEXCOORD varyings, @@ -6875,34 +11543,72 @@ index 23e059a3490..453b79c75d2 100644 + dst->reg.type = VKD3DSPR_TEMP; + dst->reg.idx[0].offset += texture_temp_idx; + } - } - } - -@@ -1823,16 +2174,19 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -- static const struct vkd3d_shader_location no_loc; - struct vkd3d_shader_instruction *ins; ++ } ++ } ++ ++ 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, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_location loc; - -- ins = vsir_program_iterator_tail(&it); -- if (ins && ins->opcode == VSIR_OP_RET) ++ + if (!(ins = vsir_program_iterator_tail(&it))) + loc = ctx->null_location; + else if (ins->opcode == VSIR_OP_RET) - return VKD3D_OK; ++ return VKD3D_OK; + else + loc = ins->location; - - if (!(ins = vsir_program_append(program))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- vsir_instruction_init(ins, &no_loc, VSIR_OP_RET); ++ ++ if (!(ins = vsir_program_append(program))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; + vsir_instruction_init(ins, &loc, VSIR_OP_RET); ++ ++ return VKD3D_OK; ++} ++ ++/* ps_1_* outputs color in r0. Add an instruction to copy that to oC0. ++ * We don't need to modify the signature since it already contains COLOR. */ ++static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_location loc; ++ ++ /* Note we run before I/O normalization. */ ++ VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM4); ++ ++ if (!(ins = vsir_program_iterator_tail(&it))) ++ return VKD3D_OK; ++ loc = ins->location; ++ ++ if (!(ins = vsir_program_append(program))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_SATURATE, 1, 1)) ++ { ++ vsir_instruction_init(ins, &loc, VSIR_OP_NOP); ++ return VKD3D_ERROR_OUT_OF_MEMORY; + } + + src_param_init_temp_float4(&ins->src[0], 0); + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; +- /* Note we run before I/O normalization. */ + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_COLOROUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = 0; + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; +- ins->dst[0].modifiers = VKD3DSPDM_SATURATE; return VKD3D_OK; } -@@ -1923,7 +2277,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra +@@ -1923,7 +2698,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra struct vsir_transformation_context *ctx) { struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); @@ -6911,7 +11617,7 @@ index 23e059a3490..453b79c75d2 100644 struct vkd3d_shader_instruction *ins; unsigned int i; -@@ -1937,21 +2291,23 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra +@@ -1937,21 +2712,23 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) @@ -6939,7 +11645,7 @@ index 23e059a3490..453b79c75d2 100644 for (i = 0; i < 4; ++i) ins->src[0].reg.u.immconst_f32[i] = 1.0f; return VKD3D_OK; -@@ -2162,10 +2518,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program +@@ -2162,10 +2939,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program continue; loc = ins->location; @@ -6951,7 +11657,7 @@ index 23e059a3490..453b79c75d2 100644 for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) { -@@ -2175,6 +2529,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program +@@ -2175,6 +2950,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask); vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; @@ -6959,7 +11665,7 @@ index 23e059a3490..453b79c75d2 100644 ins = vsir_program_iterator_next(&it); } } -@@ -2200,8 +2555,6 @@ struct hull_flattener +@@ -2200,8 +2976,6 @@ struct hull_flattener { struct vsir_program *program; @@ -6968,7 +11674,7 @@ index 23e059a3490..453b79c75d2 100644 enum vkd3d_shader_opcode phase; struct vkd3d_shader_location last_ret_location; unsigned int *ssa_map; -@@ -2213,68 +2566,6 @@ static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flat +@@ -2213,68 +2987,6 @@ static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flat return flattener->phase == VSIR_OP_HS_FORK_PHASE || flattener->phase == VSIR_OP_HS_JOIN_PHASE; } @@ -7037,7 +11743,7 @@ index 23e059a3490..453b79c75d2 100644 static void flattener_fixup_ssa_register(struct hull_flattener *normaliser, struct vkd3d_shader_register *reg, unsigned int instance_id) { -@@ -2337,54 +2628,110 @@ static void flattener_fixup_registers(struct hull_flattener *normaliser, +@@ -2337,85 +3049,131 @@ static void flattener_fixup_registers(struct hull_flattener *normaliser, flattener_fixup_register_indices(normaliser, &ins->dst[i].reg, instance_id); } @@ -7069,21 +11775,6 @@ index 23e059a3490..453b79c75d2 100644 + /* Make a copy of the non-dcl instructions for each instance. */ + dst_it = first_it; + for (i = 1; i < instance_count; ++i) -+ { -+ src_it = *it; -+ for (j = 0; j < instruction_count; ++j) -+ { -+ src_ins = vsir_program_iterator_current(&src_it); -+ if (!vsir_program_iterator_clone_instruction(normaliser->program, &dst_it, src_ins)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ vsir_program_iterator_next(&dst_it); -+ vsir_program_iterator_next(&src_it); -+ } -+ } -+ /* Replace each reference to the instance id with a constant instance id. */ -+ *it = first_it; -+ for (i = 0; i < instance_count; ++i) { - loc = &locations->locations[i - 1]; - j = loc->index + loc->instruction_count; @@ -7092,38 +11783,15 @@ index 23e059a3490..453b79c75d2 100644 - end = j; - count -= (loc->instance_count - 1) * loc->instruction_count; - loc->index += count; -+ if (i) -+ memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); -+ -+ for (j = 0; j < instruction_count; ++j) -+ { -+ ins = vsir_program_iterator_current(it); -+ flattener_fixup_registers(normaliser, ins, i); -+ vsir_program_iterator_next(it); -+ } - } - +- } +- - for (i = 0, count = 0; i < locations->count; ++i) -+ return VKD3D_OK; -+} -+ -+static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser) -+{ -+ struct vsir_program_iterator it = vsir_program_iterator(&normaliser->program->instructions); -+ struct vsir_program_iterator phase_body_it; -+ struct vkd3d_shader_instruction *ins; -+ bool b, phase_body_it_valid = false; -+ unsigned int instruction_count = 0; -+ unsigned int instance_count = 0; -+ enum vkd3d_result res; -+ -+ normaliser->phase = VSIR_OP_INVALID; -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { +- { - loc = &locations->locations[i]; - /* Make a copy of the non-dcl instructions for each instance. */ - for (j = 1; j < loc->instance_count; ++j) -+ if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE) ++ src_it = *it; ++ for (j = 0; j < instruction_count; ++j) { - for (k = 0; k < loc->instruction_count; ++k) - { @@ -7131,6 +11799,69 @@ index 23e059a3490..453b79c75d2 100644 - loc->index + loc->instruction_count * j + k, loc->index + k)) - return VKD3D_ERROR_OUT_OF_MEMORY; - } ++ src_ins = vsir_program_iterator_current(&src_it); ++ if (!vsir_program_iterator_clone_instruction(normaliser->program, &dst_it, src_ins)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ vsir_program_iterator_next(&dst_it); ++ vsir_program_iterator_next(&src_it); + } +- /* 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)); ++ } ++ /* Replace each reference to the instance id with a constant instance id. */ ++ *it = first_it; ++ for (i = 0; i < instance_count; ++i) ++ { ++ if (i) ++ memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); + +- for (k = 0; k < loc->instruction_count; ++k) +- flattener_fixup_registers(normaliser, +- &instructions->elements[loc->index + loc->instruction_count * j + k], j); ++ for (j = 0; j < instruction_count; ++j) ++ { ++ ins = vsir_program_iterator_current(it); ++ flattener_fixup_registers(normaliser, ins, i); ++ vsir_program_iterator_next(it); + } + } + + return VKD3D_OK; + } + +-static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, +- struct vsir_transformation_context *ctx) ++static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser) + { +- struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); +- struct shader_phase_location_array locations; +- struct hull_flattener flattener = {program}; ++ struct vsir_program_iterator it = vsir_program_iterator(&normaliser->program->instructions); ++ struct vsir_program_iterator phase_body_it; + struct vkd3d_shader_instruction *ins; +- enum vkd3d_result result = VKD3D_OK; +- unsigned int i; ++ bool b, phase_body_it_valid = false; ++ unsigned int instruction_count = 0; ++ unsigned int instance_count = 0; ++ enum vkd3d_result res; + +- 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) ++ normaliser->phase = VSIR_OP_INVALID; ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations); +- } +- bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID); +- bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID); ++ 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. */ + phase_body_it_valid = false; @@ -7141,14 +11872,10 @@ index 23e059a3490..453b79c75d2 100644 + if (b) + vkd3d_shader_instruction_make_nop(ins); + continue; - } -- /* Replace each reference to the instance id with a constant instance id. */ -- for (j = 0; j < loc->instance_count; ++j) ++ } + else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT + || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) - { -- if (j != 0) -- memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); ++ { + instance_count = ins->declaration.count + !ins->declaration.count; + vkd3d_shader_instruction_make_nop(ins); + ++instruction_count; @@ -7164,10 +11891,7 @@ index 23e059a3490..453b79c75d2 100644 + phase_body_it = it; + instruction_count = 0; + } - -- for (k = 0; k < loc->instruction_count; ++k) -- flattener_fixup_registers(normaliser, -- &instructions->elements[loc->index + loc->instruction_count * j + k], j); ++ + if (ins->opcode == VSIR_OP_RET) + { + normaliser->last_ret_location = ins->location; @@ -7181,30 +11905,23 @@ index 23e059a3490..453b79c75d2 100644 + else + { + ++instruction_count; - } - } ++ } ++ } ++ ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct hull_flattener flattener = {program}; ++ struct vkd3d_shader_instruction *ins; ++ enum vkd3d_result result = VKD3D_OK; ++ ++ bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID); ++ bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID); -@@ -2394,19 +2741,10 @@ 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 vsir_program_iterator it = vsir_program_iterator(&program->instructions); -- struct shader_phase_location_array locations; - struct hull_flattener flattener = {program}; - struct vkd3d_shader_instruction *ins; - enum vkd3d_result result = VKD3D_OK; -- unsigned int i; - -- flattener.phase = VSIR_OP_INVALID; -- 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); - -@@ -2414,8 +2752,7 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro + 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; @@ -7214,7 +11931,7 @@ index 23e059a3490..453b79c75d2 100644 vkd3d_free(flattener.ssa_map); flattener.ssa_map = NULL; -@@ -2434,7 +2771,7 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro +@@ -2434,7 +3192,7 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro struct control_point_normaliser { @@ -7223,7 +11940,7 @@ index 23e059a3490..453b79c75d2 100644 enum vkd3d_shader_opcode phase; struct vkd3d_shader_src_param *outpointid_param; }; -@@ -2446,20 +2783,15 @@ static bool control_point_normaliser_is_in_control_point_phase(const struct cont +@@ -2446,20 +3204,15 @@ static bool control_point_normaliser_is_in_control_point_phase(const struct cont struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_program *program) { @@ -7245,7 +11962,7 @@ index 23e059a3490..453b79c75d2 100644 return rel_addr; } -@@ -2481,8 +2813,8 @@ static void shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param +@@ -2481,8 +3234,8 @@ static void shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param } static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser, @@ -7256,7 +11973,7 @@ index 23e059a3490..453b79c75d2 100644 { struct vkd3d_shader_instruction *ins; const struct signature_element *e; -@@ -2491,17 +2823,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p +@@ -2491,17 +3244,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p for (i = 0; i < s->element_count; ++i) count += !!s->elements[i].used_mask; @@ -7276,7 +11993,7 @@ index 23e059a3490..453b79c75d2 100644 for (i = 0; i < s->element_count; ++i) { -@@ -2510,9 +2836,9 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p +@@ -2510,9 +3257,9 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p continue; vsir_instruction_init(ins, location, VSIR_OP_MOV); @@ -7288,7 +12005,7 @@ index 23e059a3490..453b79c75d2 100644 ins->src_count = 1; if (!ins->dst || ! ins->src) -@@ -2521,6 +2847,8 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p +@@ -2521,6 +3268,8 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p return VKD3D_ERROR_OUT_OF_MEMORY; } @@ -7297,7 +12014,7 @@ index 23e059a3490..453b79c75d2 100644 vsir_dst_param_init_io(&ins->dst[0], VKD3DSPR_OUTPUT, e, 2); ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->dst[0].reg.idx[0].offset = 0; -@@ -2533,7 +2861,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p +@@ -2533,7 +3282,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p ins->src[0].reg.idx[0].rel_addr = normaliser->outpointid_param; ins->src[0].reg.idx[1].offset = e->register_index; @@ -7306,7 +12023,7 @@ index 23e059a3490..453b79c75d2 100644 } vsir_instruction_init(ins, location, VSIR_OP_RET); -@@ -2565,8 +2893,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -2565,8 +3314,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i ERR("Failed to allocate src param.\n"); return VKD3D_ERROR_OUT_OF_MEMORY; } @@ -7317,7 +12034,7 @@ index 23e059a3490..453b79c75d2 100644 normaliser.phase = VSIR_OP_INVALID; for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -@@ -2598,16 +2926,14 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -2598,16 +3347,14 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i input_control_point_count = ins->declaration.count; break; case VSIR_OP_HS_CONTROL_POINT_PHASE: @@ -7336,7 +12053,7 @@ index 23e059a3490..453b79c75d2 100644 program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; return ret; default: -@@ -2615,7 +2941,6 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -2615,7 +3362,6 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i } } @@ -7344,7 +12061,7 @@ index 23e059a3490..453b79c75d2 100644 program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; return VKD3D_OK; } -@@ -2641,12 +2966,7 @@ struct io_normaliser +@@ -2641,12 +3387,7 @@ struct io_normaliser struct shader_signature *output_signature; struct shader_signature *patch_constant_signature; @@ -7357,7 +12074,7 @@ index 23e059a3490..453b79c75d2 100644 struct vkd3d_shader_dst_param *input_dcl_params[MAX_REG_OUTPUT]; struct vkd3d_shader_dst_param *output_dcl_params[MAX_REG_OUTPUT]; -@@ -3268,9 +3588,6 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program +@@ -3268,9 +4009,6 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program { switch (ins->opcode) { @@ -7367,7 +12084,7 @@ index 23e059a3490..453b79c75d2 100644 case VSIR_OP_DCL_INDEX_RANGE: if ((ret = io_normaliser_add_index_range(&normaliser, ins)) < 0) return ret; -@@ -3355,6 +3672,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par +@@ -3355,6 +4093,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par { enum vkd3d_shader_d3dbc_constant_register set; struct vkd3d_shader_src_param *rel_addr; @@ -7375,7 +12092,7 @@ index 23e059a3490..453b79c75d2 100644 uint32_t index; size_t i, j; -@@ -3369,7 +3687,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par +@@ -3369,7 +4108,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par param->reg.idx_count = 0; param->reg.dimension = VSIR_DIMENSION_VEC4; for (j = 0; j < 4; ++j) @@ -7388,7 +12105,7 @@ index 23e059a3490..453b79c75d2 100644 return; } } -@@ -3521,6 +3843,17 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog +@@ -3521,6 +4264,17 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog return VKD3D_OK; } @@ -7406,7 +12123,7 @@ index 23e059a3490..453b79c75d2 100644 struct cf_flattener_if_info { struct vkd3d_shader_src_param *false_param; -@@ -3544,7 +3877,7 @@ struct cf_flattener_switch_case +@@ -3544,7 +4298,7 @@ struct cf_flattener_switch_case struct cf_flattener_switch_info { @@ -7415,7 +12132,7 @@ index 23e059a3490..453b79c75d2 100644 const struct vkd3d_shader_src_param *condition; unsigned int id; unsigned int merge_block_id; -@@ -3579,9 +3912,7 @@ struct cf_flattener +@@ -3579,9 +4333,7 @@ struct cf_flattener struct vkd3d_shader_location location; enum vkd3d_result status; @@ -7426,31 +12143,34 @@ index 23e059a3490..453b79c75d2 100644 unsigned int block_id; const char **block_names; -@@ -3604,18 +3935,6 @@ static void cf_flattener_set_error(struct cf_flattener *flattener, enum vkd3d_re +@@ -3604,16 +4356,17 @@ static void cf_flattener_set_error(struct cf_flattener *flattener, enum vkd3d_re flattener->status = error; } -static struct vkd3d_shader_instruction *cf_flattener_require_space(struct cf_flattener *flattener, size_t count) --{ ++static struct vkd3d_shader_instruction *cf_flattener_instruction_append(struct cf_flattener *flattener) + { - if (!vkd3d_array_reserve((void **)&flattener->instructions, &flattener->instruction_capacity, - flattener->instruction_count + count, sizeof(*flattener->instructions))) -- { -- ERR("Failed to allocate instructions.\n"); -- cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); -- return NULL; -- } ++ struct vkd3d_shader_instruction *ins; ++ ++ if (!(ins = shader_instruction_array_append(&flattener->instructions))) + { + ERR("Failed to allocate instructions.\n"); + cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); + return NULL; + } - return &flattener->instructions[flattener->instruction_count]; --} -- ++ return ins; + } + static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, - const struct vkd3d_shader_instruction *instruction) - { -@@ -3624,11 +3943,10 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, +@@ -3624,11 +4377,10 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, if (instruction->opcode == VSIR_OP_NOP) return true; - if (!(dst_ins = cf_flattener_require_space(flattener, 1))) -+ if (!(dst_ins = shader_instruction_array_append(&flattener->instructions))) ++ if (!(dst_ins = cf_flattener_instruction_append(flattener))) return false; *dst_ins = *instruction; @@ -7458,12 +12178,12 @@ index 23e059a3490..453b79c75d2 100644 return true; } -@@ -3656,12 +3974,13 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int +@@ -3656,12 +4408,13 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int { struct vkd3d_shader_instruction *ins; - if (!(ins = cf_flattener_require_space(flattener, 1))) -+ if (!(ins = shader_instruction_array_append(&flattener->instructions))) ++ if (!(ins = cf_flattener_instruction_append(flattener))) return; - if (vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->program)) - ++flattener->instruction_count; @@ -7476,12 +12196,12 @@ index 23e059a3490..453b79c75d2 100644 } /* For conditional branches, this returns the false target branch parameter. */ -@@ -3673,14 +3992,17 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten +@@ -3673,14 +4426,17 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten struct vkd3d_shader_src_param *src_params, *false_branch_param; struct vkd3d_shader_instruction *ins; - if (!(ins = cf_flattener_require_space(flattener, 1))) -+ if (!(ins = shader_instruction_array_append(&flattener->instructions))) ++ if (!(ins = cf_flattener_instruction_append(flattener))) return NULL; vsir_instruction_init(ins, &flattener->location, VSIR_OP_BRANCH); @@ -7495,7 +12215,7 @@ index 23e059a3490..453b79c75d2 100644 src_params[0] = *condition; if (flags == VKD3D_SHADER_CONDITIONAL_OP_Z) { -@@ -3701,7 +4023,10 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten +@@ -3701,7 +4457,10 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten else { if (!(src_params = instruction_src_params_alloc(ins, merge_block_id ? 3 : 1, flattener))) @@ -7506,7 +12226,7 @@ index 23e059a3490..453b79c75d2 100644 vsir_src_param_init_label(&src_params[0], true_id); if (merge_block_id) { -@@ -3713,8 +4038,6 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten +@@ -3713,8 +4472,6 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten false_branch_param = NULL; } @@ -7515,21 +12235,17 @@ index 23e059a3490..453b79c75d2 100644 return false_branch_param; } -@@ -3820,8 +4143,12 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -3820,9 +4577,6 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL; after_declarations_section = is_hull_shader; - if (!cf_flattener_require_space(flattener, instructions->count + 1)) -+ if (!shader_instruction_array_reserve(&flattener->instructions, instructions->count + 1)) -+ { -+ ERR("Failed to allocate instructions.\n"); -+ cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); - return VKD3D_ERROR_OUT_OF_MEMORY; -+ } - +- return VKD3D_ERROR_OUT_OF_MEMORY; +- it = vsir_program_iterator(instructions); for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it)) -@@ -3961,13 +4288,14 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte + { +@@ -3961,13 +4715,14 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte merge_block_id = cf_flattener_alloc_block_id(flattener); @@ -7547,7 +12263,7 @@ index 23e059a3490..453b79c75d2 100644 cf_info->u.switch_.id = flattener->switch_id; cf_info->u.switch_.merge_block_id = merge_block_id; -@@ -4000,8 +4328,12 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte +@@ -4000,8 +4755,12 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte /* The SWITCH instruction is completed when the endswitch * instruction is processed because we do not know the number * of case statements or the default block id in advance.*/ @@ -7562,7 +12278,7 @@ index 23e059a3490..453b79c75d2 100644 { vkd3d_free(cf_info->u.switch_.cases); return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -4162,18 +4494,17 @@ static enum vkd3d_result vsir_program_flatten_control_flow_constructs(struct vsi +@@ -4162,18 +4921,17 @@ static enum vkd3d_result vsir_program_flatten_control_flow_constructs(struct vsi VKD3D_ASSERT(program->cf_type == VSIR_CF_STRUCTURED); @@ -7585,7 +12301,7 @@ index 23e059a3490..453b79c75d2 100644 } vkd3d_free(flattener.control_flow_info); -@@ -4190,17 +4521,6 @@ static unsigned int label_from_src_param(const struct vkd3d_shader_src_param *pa +@@ -4190,17 +4948,6 @@ static unsigned int label_from_src_param(const struct vkd3d_shader_src_param *pa return param->reg.idx[0].offset; } @@ -7603,7 +12319,7 @@ index 23e059a3490..453b79c75d2 100644 /* A record represents replacing a jump from block `switch_label' to * block `target_label' with a jump from block `if_label' to block * `target_label'. */ -@@ -4233,39 +4553,40 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -4233,39 +4980,40 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs struct vsir_transformation_context *ctx) { unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label; @@ -7654,7 +12370,7 @@ index 23e059a3490..453b79c75d2 100644 continue; } -@@ -4276,17 +4597,18 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -4276,32 +5024,33 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs * just have to jump to the default label. */ if (case_count == 0) { @@ -7675,25 +12391,26 @@ index 23e059a3490..453b79c75d2 100644 } - if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3 * case_count - 1)) -+ if (!shader_instruction_array_reserve(&instructions, instructions.count + 3 * case_count - 1)) - goto fail; - +- goto fail; +- if_label = current_label; -@@ -4295,13 +4617,15 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs + + for (j = 0; j < case_count; ++j) { 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, VSIR_OP_IEQ, 1, 2)) -+ dst_ins = shader_instruction_array_append(&instructions); -+ if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_IEQ, 1, 2)) -+ { -+ vkd3d_shader_instruction_make_nop(dst_ins); ++ if (!(dst_ins = shader_instruction_array_append(&instructions))) goto fail; - dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count); - instructions[ins_count].src[0] = ins->src[0]; - instructions[ins_count].src[1] = ins->src[3 + 2 * j]; - ++ins_count; ++ if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_IEQ, 1, 2)) ++ { ++ vkd3d_shader_instruction_make_nop(dst_ins); ++ goto fail; + } + dst_param_init_ssa_bool(&dst_ins->dst[0], ssa_count); + dst_ins->src[0] = ins->src[0]; @@ -7701,13 +12418,14 @@ index 23e059a3490..453b79c75d2 100644 /* For all cases except the last one we fall through to * the following case; the last one has to jump to the -@@ -4311,13 +4635,15 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -4311,13 +5060,16 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs else fallthrough_label = block_count + 1; - if (!vsir_instruction_init_with_params(program, &instructions[ins_count], - &ins->location, VSIR_OP_BRANCH, 0, 3)) -+ dst_ins = shader_instruction_array_append(&instructions); ++ if (!(dst_ins = shader_instruction_array_append(&instructions))) ++ goto fail; + if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_BRANCH, 0, 3)) + { + vkd3d_shader_instruction_make_nop(dst_ins); @@ -7723,13 +12441,14 @@ index 23e059a3490..453b79c75d2 100644 ++ssa_count; -@@ -4333,29 +4659,28 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs +@@ -4333,29 +5085,29 @@ 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, VSIR_OP_LABEL, 0, 1)) -+ dst_ins = shader_instruction_array_append(&instructions); ++ if (!(dst_ins = shader_instruction_array_append(&instructions))) ++ goto fail; + if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_LABEL, 0, 1)) + { + vkd3d_shader_instruction_make_nop(dst_ins); @@ -7761,7 +12480,7 @@ index 23e059a3490..453b79c75d2 100644 vkd3d_free(block_map); return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -4422,15 +4747,14 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl +@@ -4422,16 +5174,15 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl vkd3d_free(block_info); } @@ -7777,14 +12496,16 @@ index 23e059a3490..453b79c75d2 100644 + struct vsir_program_iterator it_begin = *it; struct ssas_to_temps_alloc alloc = {0}; struct vkd3d_shader_instruction *ins; -+ size_t phi_count, incoming_count; unsigned int current_label = 0; ++ size_t phi_count; VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); -@@ -4446,14 +4770,31 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ + +@@ -4445,15 +5196,31 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ + goto fail; phi_count = 0; - incoming_count = 0; +- incoming_count = 0; - for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) { @@ -7816,29 +12537,39 @@ index 23e059a3490..453b79c75d2 100644 ++phi_count; temp_idx = alloc.next_temp_idx++; -@@ -4487,12 +4828,15 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ +@@ -4477,8 +5244,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ + incoming->dst = ins->dst; + + alloc.table[ins->dst->reg.idx[0].offset] = temp_idx; +- +- ++incoming_count; + } + + materialize_ssas_to_temps_process_reg(program, &alloc, &ins->dst->reg); +@@ -4487,12 +5252,13 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ if (!phi_count) goto done; - if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count)) -+ if (!shader_instruction_array_reserve(&program->instructions, program->instructions.count + incoming_count)) - goto fail; +- goto fail; ++ *it = it_begin; - for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -+ *it = it_begin; -+ + for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) { struct vkd3d_shader_instruction *mov_ins; ++ struct vkd3d_shader_location loc; + bool finish = false; size_t j; for (j = 0; j < ins->dst_count; ++j) -@@ -4511,33 +4855,44 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ +@@ -4511,33 +5277,46 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ case VSIR_OP_SWITCH_MONOLITHIC: info = &block_info[current_label - 1]; -+ mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count); ++ loc = ins->location; ++ if (!(mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count))) ++ goto fail; + VKD3D_ASSERT(mov_ins); + for (j = 0; j < info->incoming_count; ++j) @@ -7846,7 +12577,8 @@ index 23e059a3490..453b79c75d2 100644 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, VSIR_OP_MOV, 1, 0)) +- if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VSIR_OP_MOV, 1, 0)) ++ if (!vsir_instruction_init_with_params(program, mov_ins, &loc, VSIR_OP_MOV, 1, 0)) + { + vkd3d_shader_instruction_make_nop(mov_ins); goto fail; @@ -7886,7 +12618,7 @@ index 23e059a3490..453b79c75d2 100644 program->temp_count = alloc.next_temp_idx; done: ssas_to_temps_block_info_cleanup(block_info, program->block_count); -@@ -4546,13 +4901,51 @@ done: +@@ -4546,13 +5325,51 @@ done: return VKD3D_OK; fail: @@ -7939,7 +12671,7 @@ index 23e059a3490..453b79c75d2 100644 struct vsir_block_list { struct vsir_block **blocks; -@@ -4607,7 +5000,7 @@ struct vsir_block +@@ -4607,7 +5424,7 @@ struct vsir_block * LABEL that introduces the block. `end' points to the terminator * instruction (either BRANCH or RET). They can coincide, meaning * that the block is empty. */ @@ -7948,7 +12680,7 @@ index 23e059a3490..453b79c75d2 100644 struct vsir_block_list predecessors, successors; uint32_t *dominates; }; -@@ -4790,8 +5183,8 @@ static void vsir_cfg_structure_cleanup(struct vsir_cfg_structure *structure) +@@ -4790,8 +5607,8 @@ static void vsir_cfg_structure_cleanup(struct vsir_cfg_structure *structure) struct vsir_cfg_emit_target { @@ -7959,7 +12691,7 @@ index 23e059a3490..453b79c75d2 100644 unsigned int jump_target_temp_idx; unsigned int temp_count; }; -@@ -4800,8 +5193,8 @@ struct vsir_cfg +@@ -4800,8 +5617,8 @@ struct vsir_cfg { struct vkd3d_shader_message_context *message_context; struct vsir_program *program; @@ -7970,7 +12702,7 @@ index 23e059a3490..453b79c75d2 100644 struct vsir_block *blocks; struct vsir_block *entry; size_t block_count; -@@ -4926,19 +5319,21 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg) +@@ -4926,19 +5743,21 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg) for (i = 0; i < cfg->block_count; ++i) { struct vsir_block *block = &cfg->blocks[i]; @@ -7994,7 +12726,7 @@ index 23e059a3490..453b79c75d2 100644 break; default: -@@ -5046,19 +5441,20 @@ static void vsir_cfg_dump_structured_program(struct vsir_cfg *cfg) +@@ -5046,19 +5865,20 @@ static void vsir_cfg_dump_structured_program(struct vsir_cfg *cfg) } static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program *program, @@ -8019,7 +12751,7 @@ index 23e059a3490..453b79c75d2 100644 vsir_block_list_init(&cfg->order); -@@ -5068,12 +5464,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program +@@ -5068,12 +5888,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program if (TRACE_ON()) vkd3d_string_buffer_init(&cfg->debug_buffer); @@ -8034,7 +12766,7 @@ index 23e059a3490..453b79c75d2 100644 { case VSIR_OP_PHI: case VSIR_OP_SWITCH_MONOLITHIC: -@@ -5081,7 +5476,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program +@@ -5081,7 +5900,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program case VSIR_OP_LABEL: { @@ -8043,7 +12775,7 @@ index 23e059a3490..453b79c75d2 100644 VKD3D_ASSERT(!current_block); VKD3D_ASSERT(label > 0); -@@ -5090,16 +5485,18 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program +@@ -5090,16 +5909,18 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program VKD3D_ASSERT(current_block->label == 0); if ((ret = vsir_block_init(current_block, label, program->block_count)) < 0) goto fail; @@ -8064,7 +12796,7 @@ index 23e059a3490..453b79c75d2 100644 current_block = NULL; break; -@@ -5118,33 +5515,36 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program +@@ -5118,33 +5939,36 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program break; } @@ -8108,7 +12840,7 @@ index 23e059a3490..453b79c75d2 100644 goto fail; } break; -@@ -5328,8 +5728,10 @@ static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg) +@@ -5328,8 +6152,10 @@ static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg) if (cfg->loops_by_header[header->label - 1] != SIZE_MAX) { @@ -8120,7 +12852,7 @@ index 23e059a3490..453b79c75d2 100644 "Block %u is header to more than one loop, this is not implemented.", header->label); return VKD3D_ERROR_NOT_IMPLEMENTED; } -@@ -5411,8 +5813,10 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) +@@ -5411,8 +6237,10 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) if (in_degrees[i] == 0 && block != cfg->entry) { @@ -8132,7 +12864,7 @@ index 23e059a3490..453b79c75d2 100644 "Block %u is unreachable from the entry point.", block->label); ret = VKD3D_ERROR_INVALID_SHADER; goto fail; -@@ -5421,8 +5825,10 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) +@@ -5421,8 +6249,10 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) if (in_degrees[cfg->entry->label - 1] != 0) { @@ -8144,7 +12876,7 @@ index 23e059a3490..453b79c75d2 100644 "The entry point block has %u incoming forward edges.", in_degrees[cfg->entry->label - 1]); ret = VKD3D_ERROR_INVALID_SHADER; goto fail; -@@ -5524,9 +5930,11 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) +@@ -5524,9 +6354,11 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) if (cfg->order.count != cfg->block_count) { @@ -8157,7 +12889,7 @@ index 23e059a3490..453b79c75d2 100644 "The control flow graph is not reducible."); ret = VKD3D_ERROR_INVALID_SHADER; goto fail; -@@ -5785,6 +6193,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -5785,6 +6617,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) { struct vsir_block *block = cfg->order.blocks[i]; struct vsir_cfg_structure *structure; @@ -8165,7 +12897,7 @@ index 23e059a3490..453b79c75d2 100644 VKD3D_ASSERT(stack_depth > 0); -@@ -5810,16 +6219,17 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -5810,16 +6643,17 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) structure->u.block = block; /* Generate between zero and two jump instructions. */ @@ -8186,7 +12918,7 @@ index 23e059a3490..453b79c75d2 100644 struct vsir_block *successor = &cfg->blocks[target - 1]; vsir_cfg_compute_edge_action(cfg, block, successor, &action_true); -@@ -5827,12 +6237,12 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -5827,12 +6661,12 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) } else { @@ -8201,7 +12933,7 @@ index 23e059a3490..453b79c75d2 100644 successor = &cfg->blocks[target - 1]; vsir_cfg_compute_edge_action(cfg, block, successor, &action_false); -@@ -5884,7 +6294,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -5884,7 +6718,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) goto fail; structure->u.jump.type = action_true.jump_type; structure->u.jump.target = action_true.target; @@ -8210,42 +12942,34 @@ index 23e059a3490..453b79c75d2 100644 structure->u.jump.invert_condition = invert_condition; } -@@ -6369,15 +6779,28 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_block(struct vsir_cfg *cfg +@@ -6369,15 +7203,19 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_block(struct vsir_cfg *cfg struct vsir_block *block) { struct vsir_cfg_emit_target *target = cfg->target; + struct vkd3d_shader_instruction *ins, *end, *dst; + struct vsir_program_iterator it; -+ size_t ins_count = 0; - if (!reserve_instructions(&target->instructions, &target->ins_capacity, - target->ins_count + (block->end - block->begin))) - return VKD3D_ERROR_OUT_OF_MEMORY; +- +- memcpy(&target->instructions[target->ins_count], block->begin, +- (char *)block->end - (char *)block->begin); + it = block->begin; + end = vsir_program_iterator_current(&block->end); -- memcpy(&target->instructions[target->ins_count], block->begin, -- (char *)block->end - (char *)block->begin); -+ for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) -+ { -+ ++ins_count; -+ } -+ -+ if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + ins_count)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; - - target->ins_count += block->end - block->begin; -+ it = block->begin; + for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) + { -+ dst = shader_instruction_array_append(&target->instructions); ++ if (!(dst = shader_instruction_array_append(&target->instructions))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; + VKD3D_ASSERT(dst); + *dst = *ins; + } return VKD3D_OK; } -@@ -6387,20 +6810,22 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, +@@ -6387,20 +7225,20 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, { struct vsir_cfg_emit_target *target = cfg->target; const struct vkd3d_shader_location no_loc = {0}; @@ -8263,22 +12987,22 @@ index 23e059a3490..453b79c75d2 100644 return ret; - if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 5)) -+ if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 5)) ++ if (!(ins = shader_instruction_array_append(&target->instructions))) return VKD3D_ERROR_OUT_OF_MEMORY; - +- - vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDLOOP); -+ ins = shader_instruction_array_append(&target->instructions); + vsir_instruction_init(ins, &no_loc, VSIR_OP_ENDLOOP); /* Add a trampoline to implement multilevel jumping depending on the stored * jump_target value. */ -@@ -6414,44 +6839,50 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, +@@ -6414,44 +7252,53 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, * we have to reach an outer loop, so we keep breaking. */ const unsigned int inner_break_target = loop->idx << 1; - if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VSIR_OP_IEQ, 1, 2)) -+ ins = shader_instruction_array_append(&target->instructions); ++ if (!(ins = shader_instruction_array_append(&target->instructions))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; + if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_IEQ, 1, 2)) + { + vkd3d_shader_instruction_make_nop(ins); @@ -8297,11 +13021,12 @@ index 23e059a3490..453b79c75d2 100644 - if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VSIR_OP_CONTINUEP, 0, 1)) -+ ins = shader_instruction_array_append(&target->instructions); ++ if (!(ins = shader_instruction_array_append(&target->instructions))) + return VKD3D_ERROR_OUT_OF_MEMORY; + if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_CONTINUEP, 0, 1)) + { + vkd3d_shader_instruction_make_nop(ins); - return VKD3D_ERROR_OUT_OF_MEMORY; ++ return VKD3D_ERROR_OUT_OF_MEMORY; + } - src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count); @@ -8331,14 +13056,15 @@ index 23e059a3490..453b79c75d2 100644 - if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VSIR_OP_BREAKP, 0, 1)) -+ ins = shader_instruction_array_append(&target->instructions); -+ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_BREAKP, 0, 1)) -+ { -+ vkd3d_shader_instruction_make_nop(ins); ++ if (!(ins = shader_instruction_array_append(&target->instructions))) return VKD3D_ERROR_OUT_OF_MEMORY; - target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z; - - src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count); ++ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_BREAKP, 0, 1)) ++ { ++ vkd3d_shader_instruction_make_nop(ins); ++ return VKD3D_ERROR_OUT_OF_MEMORY; + } + ins->flags |= VKD3D_SHADER_CONDITIONAL_OP_Z; @@ -8348,7 +13074,7 @@ index 23e059a3490..453b79c75d2 100644 } return VKD3D_OK; -@@ -6462,40 +6893,40 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg +@@ -6462,40 +7309,40 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg { struct vsir_cfg_emit_target *target = cfg->target; const struct vkd3d_shader_location no_loc = {0}; @@ -8401,7 +13127,7 @@ index 23e059a3490..453b79c75d2 100644 return VKD3D_OK; } -@@ -6508,6 +6939,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, +@@ -6508,6 +7355,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, /* Encode the jump target as the loop index plus a bit to remember whether * we're breaking or continue-ing. */ unsigned int jump_target = jump->target << 1; @@ -8409,23 +13135,23 @@ index 23e059a3490..453b79c75d2 100644 enum vkd3d_shader_opcode opcode; switch (jump->type) -@@ -6538,32 +6970,34 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, +@@ -6538,32 +7386,33 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, vkd3d_unreachable(); } - if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 2)) -+ if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - +- return VKD3D_ERROR_OUT_OF_MEMORY; +- if (jump->needs_launcher) { - if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VSIR_OP_MOV, 1, 1)) -+ ins = shader_instruction_array_append(&target->instructions); ++ if (!(ins = shader_instruction_array_append(&target->instructions))) + return VKD3D_ERROR_OUT_OF_MEMORY; + if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_MOV, 1, 1)) + { + vkd3d_shader_instruction_make_nop(ins); - return VKD3D_ERROR_OUT_OF_MEMORY; ++ return VKD3D_ERROR_OUT_OF_MEMORY; + } - dst_param_init_temp_uint(&target->instructions[target->ins_count].dst[0], target->jump_target_temp_idx); @@ -8438,7 +13164,8 @@ index 23e059a3490..453b79c75d2 100644 - if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, opcode, 0, !!jump->condition)) -+ ins = shader_instruction_array_append(&target->instructions); ++ if (!(ins = shader_instruction_array_append(&target->instructions))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; + if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, opcode, 0, !!jump->condition)) + { + vkd3d_shader_instruction_make_nop(ins); @@ -8457,7 +13184,7 @@ index 23e059a3490..453b79c75d2 100644 return VKD3D_OK; } -@@ -6616,13 +7050,13 @@ static enum vkd3d_result vsir_cfg_emit_structured_program(struct vsir_cfg *cfg) +@@ -6616,13 +7465,13 @@ static enum vkd3d_result vsir_cfg_emit_structured_program(struct vsir_cfg *cfg) } static enum vkd3d_result vsir_program_structurize_function(struct vsir_program *program, @@ -8474,7 +13201,7 @@ index 23e059a3490..453b79c75d2 100644 return ret; vsir_cfg_compute_dominators(&cfg); -@@ -6653,32 +7087,31 @@ out: +@@ -6653,32 +7502,31 @@ out: static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, struct vsir_transformation_context *ctx) { @@ -8514,7 +13241,7 @@ index 23e059a3490..453b79c75d2 100644 break; case VSIR_OP_HS_CONTROL_POINT_PHASE: -@@ -6686,33 +7119,33 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, +@@ -6686,33 +7534,33 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, 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); @@ -8560,7 +13287,7 @@ index 23e059a3490..453b79c75d2 100644 return ret; } -@@ -6742,8 +7175,10 @@ static void register_map_undominated_use(struct vkd3d_shader_register *reg, stru +@@ -6742,8 +7590,10 @@ static void register_map_undominated_use(struct vkd3d_shader_register *reg, stru static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct vsir_cfg *cfg) { struct vsir_program *program = cfg->program; @@ -8571,7 +13298,7 @@ index 23e059a3490..453b79c75d2 100644 unsigned int j; size_t i; -@@ -6761,12 +7196,13 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v +@@ -6761,12 +7611,13 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v for (i = 0; i < cfg->block_count; ++i) { struct vsir_block *block = &cfg->blocks[i]; @@ -8587,7 +13314,7 @@ index 23e059a3490..453b79c75d2 100644 { for (j = 0; j < ins->dst_count; ++j) { -@@ -6779,12 +7215,13 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v +@@ -6779,12 +7630,13 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v for (i = 0; i < cfg->block_count; ++i) { struct vsir_block *block = &cfg->blocks[i]; @@ -8603,7 +13330,7 @@ index 23e059a3490..453b79c75d2 100644 { for (j = 0; j < ins->src_count; ++j) register_map_undominated_use(&ins->src[j].reg, &alloc, block, origin_blocks); -@@ -6796,10 +7233,10 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v +@@ -6796,10 +7648,10 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v TRACE("Emitting temps for %u values with undominated usage.\n", alloc.next_temp_idx - program->temp_count); @@ -8617,7 +13344,7 @@ index 23e059a3490..453b79c75d2 100644 for (j = 0; j < ins->dst_count; ++j) materialize_ssas_to_temps_process_reg(program, &alloc, &ins->dst[j].reg); -@@ -6815,14 +7252,13 @@ done: +@@ -6815,14 +7667,13 @@ done: return VKD3D_OK; } @@ -8635,7 +13362,7 @@ index 23e059a3490..453b79c75d2 100644 return ret; vsir_cfg_compute_dominators(&cfg); -@@ -6837,25 +7273,23 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_f +@@ -6837,25 +7688,23 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_f static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program, struct vsir_transformation_context *ctx) { @@ -8665,7 +13392,7 @@ index 23e059a3490..453b79c75d2 100644 break; case VSIR_OP_HS_CONTROL_POINT_PHASE: -@@ -6863,14 +7297,14 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru +@@ -6863,14 +7712,14 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru 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); @@ -8683,7 +13410,7 @@ index 23e059a3490..453b79c75d2 100644 break; } } -@@ -6881,7 +7315,6 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru +@@ -6881,7 +7730,6 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru static bool use_flat_interpolation(const struct vsir_program *program, struct vkd3d_shader_message_context *message_context, bool *flat) { @@ -8691,7 +13418,7 @@ index 23e059a3490..453b79c75d2 100644 const struct vkd3d_shader_parameter1 *parameter; *flat = false; -@@ -6891,13 +7324,13 @@ static bool use_flat_interpolation(const struct vsir_program *program, +@@ -6891,13 +7739,13 @@ static bool use_flat_interpolation(const struct vsir_program *program, if (parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { @@ -8707,7 +13434,7 @@ index 23e059a3490..453b79c75d2 100644 "Invalid flat interpolation parameter data type %#x.", parameter->data_type); return false; } -@@ -6938,7 +7371,6 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6938,7 +7786,6 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; @@ -8715,7 +13442,7 @@ index 23e059a3490..453b79c75d2 100644 struct vkd3d_shader_instruction *ins; static const struct -@@ -6959,10 +7391,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6959,10 +7806,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER) { @@ -8727,7 +13454,7 @@ index 23e059a3490..453b79c75d2 100644 vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; -@@ -6972,10 +7402,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6972,10 +7817,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr return VKD3D_OK; } @@ -8739,7 +13466,7 @@ index 23e059a3490..453b79c75d2 100644 switch (ref->data_type) { -@@ -6994,7 +7422,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6994,7 +7837,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr break; case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4: @@ -8748,7 +13475,7 @@ index 23e059a3490..453b79c75d2 100644 "Alpha test reference data type must be a single component."); return VKD3D_ERROR_INVALID_ARGUMENT; -@@ -7036,7 +7464,6 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro +@@ -7036,7 +7879,6 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro 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; @@ -8756,7 +13483,7 @@ index 23e059a3490..453b79c75d2 100644 enum vkd3d_shader_comparison_func compare_func; struct vkd3d_shader_instruction *ins; int ret; -@@ -7054,13 +7481,13 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro +@@ -7054,13 +7896,13 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro if (func->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { @@ -8772,7 +13499,7 @@ index 23e059a3490..453b79c75d2 100644 "Invalid alpha test function parameter data type %#x.", func->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } -@@ -7117,10 +7544,8 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog +@@ -7117,10 +7959,8 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog struct vkd3d_shader_instruction *ins; unsigned int output_idx = 0; @@ -8784,7 +13511,7 @@ index 23e059a3490..453b79c75d2 100644 for (unsigned int i = 0; i < 8; ++i) { -@@ -7166,7 +7591,6 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr +@@ -7166,7 +8006,6 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; const struct vkd3d_shader_parameter1 *mask_parameter = NULL; uint32_t position_signature_idx, position_temp, mask; @@ -8792,7 +13519,7 @@ index 23e059a3490..453b79c75d2 100644 struct signature_element *clip_element; struct vkd3d_shader_instruction *ins; unsigned int plane_count; -@@ -7188,13 +7612,13 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr +@@ -7188,13 +8027,13 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr if (mask_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { @@ -8808,7 +13535,7 @@ index 23e059a3490..453b79c75d2 100644 "Invalid clip plane mask parameter data type %#x.", mask_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } -@@ -7207,7 +7631,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr +@@ -7207,7 +8046,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr { if (signature->elements[i].sysval_semantic == VKD3D_SHADER_SV_CLIP_DISTANCE) { @@ -8817,7 +13544,7 @@ index 23e059a3490..453b79c75d2 100644 "Clip planes cannot be used if the shader writes clip distance."); return VKD3D_ERROR_INVALID_ARGUMENT; } -@@ -7215,7 +7639,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr +@@ -7215,7 +8054,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr if (!vsir_signature_find_sysval(signature, VKD3D_SHADER_SV_POSITION, 0, &position_signature_idx)) { @@ -8826,7 +13553,7 @@ index 23e059a3490..453b79c75d2 100644 "Shader does not write position."); return VKD3D_ERROR_INVALID_SHADER; } -@@ -7288,10 +7712,8 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr +@@ -7288,10 +8127,8 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; struct vkd3d_shader_instruction *ins; @@ -8838,7 +13565,7 @@ index 23e059a3490..453b79c75d2 100644 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); -@@ -7307,7 +7729,6 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro +@@ -7307,7 +8144,6 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro { struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); const struct vkd3d_shader_parameter1 *size_parameter = NULL; @@ -8846,7 +13573,7 @@ index 23e059a3490..453b79c75d2 100644 struct vkd3d_shader_instruction *ins; if (program->has_point_size) -@@ -7329,7 +7750,7 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro +@@ -7329,7 +8165,7 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro if (size_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) { @@ -8855,7 +13582,7 @@ index 23e059a3490..453b79c75d2 100644 "Invalid point size parameter data type %#x.", size_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } -@@ -7356,7 +7777,6 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra +@@ -7356,7 +8192,6 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra { const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL; struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); @@ -8863,7 +13590,7 @@ index 23e059a3490..453b79c75d2 100644 struct vkd3d_shader_instruction *ins; if (!program->has_point_size) -@@ -7380,14 +7800,14 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra +@@ -7380,14 +8215,14 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra if (min_parameter && min_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) { @@ -8880,7 +13607,7 @@ index 23e059a3490..453b79c75d2 100644 "Invalid maximum point size parameter data type %#x.", max_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } -@@ -7530,7 +7950,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr +@@ -7530,7 +8365,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr { struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2; const struct vkd3d_shader_parameter1 *sprite_parameter = NULL; @@ -8889,7 +13616,7 @@ index 23e059a3490..453b79c75d2 100644 struct vkd3d_shader_instruction *ins; bool used_texcoord = false; unsigned int coord_temp; -@@ -7552,13 +7972,13 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr +@@ -7552,13 +8387,13 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr if (sprite_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { @@ -8905,7 +13632,7 @@ index 23e059a3490..453b79c75d2 100644 "Invalid point sprite parameter data type %#x.", sprite_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } -@@ -7578,7 +7998,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr +@@ -7578,7 +8413,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) @@ -8916,7 +13643,7 @@ index 23e059a3490..453b79c75d2 100644 } it2 = it; -@@ -7613,12 +8036,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr +@@ -7613,12 +8451,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr if (used_texcoord) { @@ -8931,7 +13658,7 @@ index 23e059a3490..453b79c75d2 100644 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, VSIR_DATA_F32, 0); -@@ -7626,11 +8047,12 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr +@@ -7626,11 +8462,12 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ins = vsir_program_iterator_next(&it); @@ -8945,7 +13672,7 @@ index 23e059a3490..453b79c75d2 100644 vsir_program_iterator_next(&it); program->has_point_coord = true; -@@ -7668,15 +8090,12 @@ static enum vkd3d_result vsir_program_add_fog_input(struct vsir_program *program +@@ -7668,66 +8505,63 @@ static enum vkd3d_result vsir_program_add_fog_input(struct vsir_program *program } static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *program, @@ -8962,84 +13689,116 @@ index 23e059a3490..453b79c75d2 100644 uint32_t ssa_factor = program->ssa_count++; - size_t pos = ret - instructions->elements; - struct vkd3d_shader_instruction *ins; - uint32_t ssa_temp, ssa_temp2; +- uint32_t ssa_temp, ssa_temp2; ++ uint32_t ssa_temp, ssa_temp2, ssa_temp3; switch (mode) -@@ -7687,16 +8106,11 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * add sr0, FOG_END, -vFOG.x - * mul_sat srFACTOR, sr0, FOG_SCALE + { + case VKD3D_SHADER_FOG_FRAGMENT_LINEAR: + /* We generate the following code: + * +- * add sr0, FOG_END, -vFOG.x +- * mul_sat srFACTOR, sr0, FOG_SCALE ++ * neg sr0, vFOG.x ++ * add sr1, FOG_END, sr0 ++ * mul srFACTOR, sr1, FOG_SCALE */ - if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - - *ret_pos = pos + 4; ssa_temp = program->ssa_count++; ++ ssa_temp2 = program->ssa_count++; - ins = &program->instructions.elements[pos]; -- ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); ++ dst_param_init_ssa_float(&ins->dst[0], ssa_temp); ++ vsir_src_param_init(&ins->src[0], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); ++ ins->src[0].reg.idx[0].offset = fog_signature_idx; ++ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); +- dst_param_init_ssa_float(&ins->dst[0], ssa_temp); ++ dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); -@@ -7705,12 +8119,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); - ins->src[1].modifiers = VKD3DSPSM_NEG; +- 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; ++ src_param_init_ssa_float(&ins->src[1], ssa_temp); + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_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); +- ins->dst[0].modifiers = VKD3DSPDM_SATURATE; +- src_param_init_ssa_float(&ins->src[0], ssa_temp); ++ src_param_init_ssa_float(&ins->src[0], ssa_temp2); src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); + ins = vsir_program_iterator_next(it); + break; case VKD3D_SHADER_FOG_FRAGMENT_EXP: -@@ -7719,16 +8136,11 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + /* We generate the following code: + * * mul sr0, FOG_SCALE, vFOG.x - * exp_sat srFACTOR, -sr0 +- * exp_sat srFACTOR, -sr0 ++ * neg sr1, sr0 ++ * exp srFACTOR, sr1 */ - if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - - *ret_pos = pos + 4; ssa_temp = program->ssa_count++; - -- ins = &program->instructions.elements[pos]; - +- ins = &program->instructions.elements[pos]; ++ ssa_temp2 = program->ssa_count++; + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); -@@ -7736,12 +8148,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -7736,12 +8570,17 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins->src[1].reg.idx[0].offset = fog_signature_idx; ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; +- dst_param_init_ssa_float(&ins->dst[0], ssa_factor); +- ins->dst[0].modifiers = VKD3DSPDM_SATURATE; ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); ++ dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); src_param_init_ssa_float(&ins->src[0], ssa_temp); - ins->src[0].modifiers = VKD3DSPSM_NEG; +- ins->src[0].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); ++ ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); ++ dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ++ src_param_init_ssa_float(&ins->src[0], ssa_temp2); + ins = vsir_program_iterator_next(it); break; case VKD3D_SHADER_FOG_FRAGMENT_EXP2: -@@ -7751,17 +8165,12 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -7749,18 +8588,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * + * mul sr0, FOG_SCALE, vFOG.x * mul sr1, sr0, sr0 - * exp_sat srFACTOR, -sr1 +- * exp_sat srFACTOR, -sr1 ++ * neg sr2, sr1 ++ * exp srFACTOR, sr2 */ - if (!shader_instruction_array_insert_at(&program->instructions, pos, 5)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 5))) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 8))) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - @@ -9047,13 +13806,13 @@ index 23e059a3490..453b79c75d2 100644 ssa_temp = program->ssa_count++; ssa_temp2 = program->ssa_count++; - -- ins = &program->instructions.elements[pos]; - +- ins = &program->instructions.elements[pos]; ++ ssa_temp3 = program->ssa_count++; + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); -@@ -7769,17 +8178,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -7769,17 +8605,23 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins->src[1].reg.idx[0].offset = fog_signature_idx; ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); @@ -9067,39 +13826,70 @@ index 23e059a3490..453b79c75d2 100644 + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; +- dst_param_init_ssa_float(&ins->dst[0], ssa_factor); +- ins->dst[0].modifiers = VKD3DSPDM_SATURATE; ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); ++ dst_param_init_ssa_float(&ins->dst[0], ssa_temp3); src_param_init_ssa_float(&ins->src[0], ssa_temp2); - ins->src[0].modifiers = VKD3DSPSM_NEG; +- ins->src[0].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); ++ ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); ++ dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ++ src_param_init_ssa_float(&ins->src[0], ssa_temp3); + ins = vsir_program_iterator_next(it); break; default: -@@ -7792,18 +8204,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * mad oC0, sr0, srFACTOR, FOG_COLOUR +@@ -7788,22 +8630,38 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + + /* We generate the following code: + * +- * add sr0, FRAG_COLOUR, -FOG_COLOUR +- * mad oC0, sr0, srFACTOR, FOG_COLOUR ++ * neg sr0, FOG_COLOUR ++ * add sr1, FRAG_COLOUR, sr0 ++ * saturate sr2, srFACTOR ++ * mad oC0, sr1, sr2, FOG_COLOUR */ ++ ssa_temp = program->ssa_count++; ++ ssa_temp2 = program->ssa_count++; ++ ssa_temp3 = program->ssa_count++; - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_ADD, 1, 2); +- dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); ++ dst_param_init_ssa_float4(&ins->dst[0], ssa_temp); ++ src_param_init_parameter_vec4(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); ++ ins = vsir_program_iterator_next(it); ++ + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); - dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); ++ dst_param_init_ssa_float4(&ins->dst[0], ssa_temp2); src_param_init_temp_float4(&ins->src[0], colour_temp); - src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); - ins->src[1].modifiers = VKD3DSPSM_NEG; +- src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); +- ins->src[1].modifiers = VKD3DSPSM_NEG; ++ src_param_init_ssa_float4(&ins->src[1], ssa_temp); ++ ins = vsir_program_iterator_next(it); ++ ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_SATURATE, 1, 1); ++ dst_param_init_ssa_float(&ins->dst[0], ssa_temp3); ++ src_param_init_ssa_float(&ins->src[0], ssa_factor); + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MAD, 1, 3); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MAD, 1, 3); dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, program->output_signature.elements[colour_signature_idx].mask); - src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); - src_param_init_ssa_float(&ins->src[1], ssa_factor); +- src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); +- src_param_init_ssa_float(&ins->src[1], ssa_factor); ++ src_param_init_ssa_float4(&ins->src[0], ssa_temp2); ++ src_param_init_ssa_float(&ins->src[1], ssa_temp3); src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); + ins = vsir_program_iterator_next(it); return VKD3D_OK; } -@@ -7811,14 +8225,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -7811,14 +8669,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *program, struct vsir_transformation_context *ctx) { @@ -9115,7 +13905,7 @@ index 23e059a3490..453b79c75d2 100644 int ret; if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) -@@ -7832,13 +8245,13 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p +@@ -7832,13 +8689,13 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p if (mode_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { @@ -9131,7 +13921,7 @@ index 23e059a3490..453b79c75d2 100644 "Invalid fog fragment mode parameter data type %#x.", mode_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } -@@ -7859,19 +8272,16 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p +@@ -7859,19 +8716,16 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p * through the whole shader and convert it to a temp. */ colour_temp = program->temp_count++; @@ -9154,7 +13944,7 @@ index 23e059a3490..453b79c75d2 100644 continue; } -@@ -7927,21 +8337,16 @@ static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *progra +@@ -7927,21 +8781,16 @@ static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *progra return VKD3D_OK; } @@ -9180,7 +13970,7 @@ index 23e059a3490..453b79c75d2 100644 /* Write the fog output. */ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -@@ -7951,26 +8356,26 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr +@@ -7951,26 +8800,26 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); else /* Position or specular W. */ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); @@ -9211,7 +14001,7 @@ index 23e059a3490..453b79c75d2 100644 enum vkd3d_shader_fog_source source; const struct signature_element *e; -@@ -7982,13 +8387,13 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro +@@ -7982,13 +8831,13 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { @@ -9227,7 +14017,7 @@ index 23e059a3490..453b79c75d2 100644 "Invalid fog source parameter data type %#x.", source_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } -@@ -8010,7 +8415,7 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro +@@ -8010,7 +8859,7 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro if (!vsir_signature_find_sysval(&program->output_signature, VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx)) { @@ -9236,7 +14026,7 @@ index 23e059a3490..453b79c75d2 100644 VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position."); return VKD3D_ERROR_INVALID_SHADER; } -@@ -8027,22 +8432,18 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro +@@ -8027,22 +8876,18 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro /* Insert a fog write before each ret, and convert either specular or * position output to a temp. */ @@ -9262,25 +14052,50 @@ index 23e059a3490..453b79c75d2 100644 continue; } -@@ -8450,7 +8851,7 @@ struct liveness_tracker +@@ -8158,6 +9003,7 @@ static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src + case VSIR_OP_MOVC: + case VSIR_OP_MSAD: /* FIXME: Is this correct? */ + case VSIR_OP_MUL: ++ case VSIR_OP_NEG: + case VSIR_OP_NEO: + case VSIR_OP_NEU: + case VSIR_OP_NOT: +@@ -8174,6 +9020,7 @@ static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src + case VSIR_OP_ROUND_PI: + case VSIR_OP_ROUND_Z: + case VSIR_OP_RSQ: ++ case VSIR_OP_SATURATE: + case VSIR_OP_SETP: + case VSIR_OP_SGE: + case VSIR_OP_SGN: +@@ -8449,8 +9296,8 @@ struct liveness_tracker + bool written; bool fixed_mask; uint8_t mask; - unsigned int first_write, last_access; +- unsigned int first_write, last_access; - } *ssa_regs; ++ unsigned int first_write, last_access, last_read; + } *ssa_regs, *temp_regs; }; static void liveness_track_src(struct liveness_tracker *tracker, -@@ -8464,6 +8865,8 @@ static void liveness_track_src(struct liveness_tracker *tracker, +@@ -8463,7 +9310,15 @@ static void liveness_track_src(struct liveness_tracker *tracker, + } if (src->reg.type == VKD3DSPR_SSA) ++ { ++ tracker->ssa_regs[src->reg.idx[0].offset].last_read = index; tracker->ssa_regs[src->reg.idx[0].offset].last_access = index; ++ } + else if (src->reg.type == VKD3DSPR_TEMP) ++ { ++ tracker->temp_regs[src->reg.idx[0].offset].last_read = index; + tracker->temp_regs[src->reg.idx[0].offset].last_access = index; ++ } } static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_shader_dst_param *dst, -@@ -8479,6 +8882,8 @@ static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_sh +@@ -8479,6 +9334,8 @@ static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_sh if (dst->reg.type == VKD3DSPR_SSA) reg = &tracker->ssa_regs[dst->reg.idx[0].offset]; @@ -9289,7 +14104,7 @@ index 23e059a3490..453b79c75d2 100644 else return; -@@ -8565,20 +8970,22 @@ static void liveness_tracker_cleanup(struct liveness_tracker *tracker) +@@ -8565,20 +9422,22 @@ static void liveness_tracker_cleanup(struct liveness_tracker *tracker) static enum vkd3d_result track_liveness(struct vsir_program *program, struct liveness_tracker *tracker) { @@ -9316,7 +14131,7 @@ index 23e059a3490..453b79c75d2 100644 if (ins->opcode == VSIR_OP_LOOP || ins->opcode == VSIR_OP_REP) { if (!loop_depth++) -@@ -8604,8 +9011,7 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv +@@ -8604,8 +9463,7 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv * 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 @@ -9326,10 +14141,13 @@ index 23e059a3490..453b79c75d2 100644 for (unsigned int j = 0; j < program->ssa_count; ++j) { struct liveness_tracker_reg *reg = &tracker->ssa_regs[j]; -@@ -8615,6 +9021,16 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv +@@ -8614,6 +9472,20 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv + reg->first_write = loop_start; if (reg->last_access < i) reg->last_access = i; - } ++ if (reg->last_read < i) ++ reg->last_read = i; ++ } + + for (unsigned int j = 0; j < program->temp_count; ++j) + { @@ -9339,11 +14157,12 @@ index 23e059a3490..453b79c75d2 100644 + reg->first_write = loop_start; + if (reg->last_access < i) + reg->last_access = i; -+ } ++ if (reg->last_read < i) ++ reg->last_read = i; + } } } - -@@ -8632,74 +9048,19 @@ struct temp_allocator +@@ -8632,75 +9504,21 @@ struct temp_allocator struct vkd3d_shader_message_context *message_context; struct temp_allocator_reg { @@ -9352,9 +14171,18 @@ index 23e059a3490..453b79c75d2 100644 uint32_t temp_id; - } *ssa_regs; - size_t allocated_ssa_count; -- enum vkd3d_result result; --}; -- ++ enum vkd3d_shader_register_type type; ++ unsigned int idx; ++ bool force_first; ++ bool fixed_mask; ++ } *ssa_regs, *temp_regs; ++ size_t ssa_count, temp_count; ++ unsigned int new_temp_count; + enum vkd3d_result result; ++ uint8_t *current_allocation; ++ bool ps_1_x; + }; + -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) -{ @@ -9416,20 +14244,11 @@ index 23e059a3490..453b79c75d2 100644 - } - } -} -+ enum vkd3d_shader_register_type type; -+ unsigned int idx; -+ bool force_first; -+ } *ssa_regs, *temp_regs; -+ size_t ssa_count, temp_count; -+ unsigned int new_temp_count; -+ enum vkd3d_result result; -+ uint8_t *current_allocation; -+ bool ps_1_x; -+}; - +- static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3d_shader_src_param *src) { -@@ -8713,6 +9074,8 @@ static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3 + struct temp_allocator_reg *reg; +@@ -8713,12 +9531,17 @@ static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3 if (src->reg.type == VKD3DSPR_SSA) reg = &allocator->ssa_regs[src->reg.idx[0].offset]; @@ -9438,7 +14257,16 @@ index 23e059a3490..453b79c75d2 100644 else return; -@@ -8792,6 +9155,7 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, + src->reg.type = VKD3DSPR_TEMP; + src->reg.dimension = VSIR_DIMENSION_VEC4; + src->reg.idx[0].offset = reg->temp_id; ++ ++ if (reg->fixed_mask) ++ return; + src->swizzle = vsir_combine_swizzles(vsir_swizzle_from_writemask(reg->allocated_mask), src->swizzle); + } + +@@ -8792,6 +9615,7 @@ 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; @@ -9446,7 +14274,7 @@ index 23e059a3490..453b79c75d2 100644 for (unsigned int k = 0; k < dst->reg.idx_count; ++k) { -@@ -8801,15 +9165,18 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, +@@ -8801,15 +9625,27 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, if (dst->reg.type == VKD3DSPR_SSA) reg = &allocator->ssa_regs[dst->reg.idx[0].offset]; @@ -9459,7 +14287,16 @@ index 23e059a3490..453b79c75d2 100644 dst->reg.dimension = VSIR_DIMENSION_VEC4; dst->reg.idx[0].offset = reg->temp_id; - if (reg->allocated_mask != dst->write_mask) ++ ++ if (reg->fixed_mask) ++ { ++ VKD3D_ASSERT((reg->allocated_mask & dst->write_mask) == dst->write_mask); ++ return; ++ } ++ + remapped_mask = vsir_combine_write_masks(reg->allocated_mask, dst->write_mask); ++ VKD3D_ASSERT(vkd3d_popcount(remapped_mask) == vkd3d_popcount(dst->write_mask)); ++ + if (dst->write_mask != remapped_mask) { - dst->write_mask = reg->allocated_mask; @@ -9467,7 +14304,7 @@ index 23e059a3490..453b79c75d2 100644 if (vsir_opcode_is_double(ins->opcode)) { -@@ -8825,58 +9192,324 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, +@@ -8825,58 +9661,326 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, if (vsir_src_is_masked(ins->opcode, i)) { if (src->reg.type == VKD3DSPR_IMMCONST) @@ -9533,6 +14370,7 @@ index 23e059a3490..453b79c75d2 100644 + { + reg->temp_id = i; + reg->allocated_mask = liveness_reg->mask; ++ reg->fixed_mask = true; + current_allocation[i] |= reg->allocated_mask; + allocator->new_temp_count = max(allocator->new_temp_count, i + 1); + TRACE("Allocated r%u%s for %s (liveness %u-%u).\n", @@ -9559,6 +14397,7 @@ index 23e059a3490..453b79c75d2 100644 + + reg->temp_id = i; + reg->allocated_mask = vsir_combine_write_masks(available_mask, mask); ++ reg->fixed_mask = false; + current_allocation[i] |= reg->allocated_mask; + allocator->new_temp_count = max(allocator->new_temp_count, i + 1); + TRACE("Allocated r%u%s for %s (liveness %u-%u).\n", @@ -9813,7 +14652,7 @@ index 23e059a3490..453b79c75d2 100644 /* 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) -@@ -8886,9 +9519,11 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, +@@ -8886,9 +9990,11 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, } program->ssa_count = 0; @@ -9825,7 +14664,7 @@ index 23e059a3490..453b79c75d2 100644 return allocator.result; } -@@ -8902,11 +9537,17 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, +@@ -8902,11 +10008,17 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, struct vkd3d_shader_message_context *message_context) { @@ -9845,7 +14684,7 @@ index 23e059a3490..453b79c75d2 100644 if (ins->opcode == VSIR_OP_DCL_TEMPS) { -@@ -8915,18 +9556,17 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, +@@ -8915,18 +10027,17 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, continue; } @@ -9870,7 +14709,7 @@ index 23e059a3490..453b79c75d2 100644 ins->declaration.count = temp_count; temp_count = 0; continue; -@@ -8945,15 +9585,15 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, +@@ -8945,15 +10056,15 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, } } @@ -9891,7 +14730,7 @@ index 23e059a3490..453b79c75d2 100644 ins->declaration.count = temp_count; } -@@ -8965,7 +9605,7 @@ struct validation_context +@@ -8965,7 +10076,7 @@ struct validation_context struct vkd3d_shader_message_context *message_context; const struct vsir_program *program; size_t instruction_idx; @@ -9900,7 +14739,7 @@ index 23e059a3490..453b79c75d2 100644 bool invalid_instruction_idx; enum vkd3d_result status; bool dcl_temps_found; -@@ -9024,13 +9664,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c +@@ -9024,13 +10135,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c if (ctx->invalid_instruction_idx) { @@ -9916,7 +14755,7 @@ index 23e059a3490..453b79c75d2 100644 "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); WARN("VSIR validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer); } -@@ -9359,6 +9998,37 @@ static void vsir_validate_io_register(struct validation_context *ctx, const stru +@@ -9359,6 +10469,37 @@ static void vsir_validate_io_register(struct validation_context *ctx, const stru reg->idx[control_point_index].offset, control_point_count, reg->type); } @@ -9954,7 +14793,7 @@ index 23e059a3490..453b79c75d2 100644 static void vsir_validate_temp_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg) { -@@ -9459,7 +10129,8 @@ static void vsir_validate_label_register(struct validation_context *ctx, +@@ -9459,7 +10600,8 @@ static void vsir_validate_label_register(struct validation_context *ctx, if (reg->data_type != VSIR_DATA_UNUSED) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -9964,7 +14803,7 @@ index 23e059a3490..453b79c75d2 100644 if (reg->dimension != VSIR_DIMENSION_NONE) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, -@@ -9538,7 +10209,8 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, +@@ -9538,7 +10680,8 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, if (reg->data_type != VSIR_DATA_UNUSED) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -9974,7 +14813,7 @@ index 23e059a3490..453b79c75d2 100644 /* VEC4 is allowed in gather operations. */ if (reg->dimension == VSIR_DIMENSION_SCALAR) -@@ -9564,7 +10236,8 @@ static void vsir_validate_resource_register(struct validation_context *ctx, +@@ -9564,7 +10707,8 @@ static void vsir_validate_resource_register(struct validation_context *ctx, if (reg->data_type != VSIR_DATA_UNUSED) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -9984,7 +14823,7 @@ index 23e059a3490..453b79c75d2 100644 if (reg->dimension != VSIR_DIMENSION_VEC4) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, -@@ -9590,8 +10263,8 @@ static void vsir_validate_uav_register(struct validation_context *ctx, +@@ -9590,8 +10734,8 @@ static void vsir_validate_uav_register(struct validation_context *ctx, if (reg->data_type != VSIR_DATA_UNUSED) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -9995,7 +14834,7 @@ index 23e059a3490..453b79c75d2 100644 /* NONE is allowed in counter operations. */ if (reg->dimension == VSIR_DIMENSION_SCALAR) -@@ -9663,9 +10336,10 @@ static void vsir_validate_ssa_register(struct validation_context *ctx, +@@ -9663,9 +10807,10 @@ static void vsir_validate_ssa_register(struct validation_context *ctx, if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -10009,7 +14848,7 @@ index 23e059a3490..453b79c75d2 100644 } } -@@ -9824,6 +10498,10 @@ static void vsir_validate_register(struct validation_context *ctx, +@@ -9824,6 +10969,10 @@ static void vsir_validate_register(struct validation_context *ctx, vsir_validate_register_without_indices(ctx, reg); break; @@ -10020,7 +14859,40 @@ index 23e059a3490..453b79c75d2 100644 case VKD3DSPR_SSA: vsir_validate_ssa_register(ctx, reg); break; -@@ -9872,6 +10550,8 @@ static void vsir_validate_io_dst_param(struct validation_context *ctx, +@@ -9863,15 +11012,41 @@ static void vsir_validate_io_dst_param(struct validation_context *ctx, + const struct vkd3d_shader_dst_param *dst) + { + struct vsir_io_register_data io_reg_data; ++ const struct signature_element *e; ++ unsigned int idx; + + if (!vsir_get_io_register_data(ctx, dst->reg.type, &io_reg_data) || !(io_reg_data.flags & OUTPUT_BIT)) ++ { + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, + "Invalid register type %#x used as destination parameter.", dst->reg.type); ++ return; ++ } ++ ++ if (ctx->program->normalisation_level >= VSIR_NORMALISED_SM6) ++ { ++ if (!dst->reg.idx_count) ++ { ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, ++ "Invalid index count %u for a register of type %#x.", ++ dst->reg.idx_count, dst->reg.type); ++ return; ++ } ++ ++ idx = dst->reg.idx[dst->reg.idx_count - 1].offset; ++ e = &io_reg_data.signature->elements[idx]; ++ ++ if (dst->write_mask & ~e->mask) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, ++ "Invalid destination write mask %#x for signature element with mask %#x.", ++ dst->write_mask, e->mask); ++ } + } + static void vsir_validate_dst_param(struct validation_context *ctx, const struct vkd3d_shader_dst_param *dst) { @@ -10029,7 +14901,16 @@ index 23e059a3490..453b79c75d2 100644 vsir_validate_register(ctx, &dst->reg); if (dst->write_mask & ~VKD3DSP_WRITEMASK_ALL) -@@ -9913,7 +10593,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, +@@ -9898,7 +11073,7 @@ static void vsir_validate_dst_param(struct validation_context *ctx, + break; + } + +- if (dst->modifiers & ~VKD3DSPDM_MASK) ++ if (dst->modifiers & ~VKD3DSPDM_MASK || (ctx->program->has_no_modifiers && dst->modifiers)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.", + dst->modifiers); + +@@ -9913,7 +11088,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, default: validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -10039,7 +14920,7 @@ index 23e059a3490..453b79c75d2 100644 break; } -@@ -9932,7 +10613,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, +@@ -9932,7 +11108,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, case 15: if (dst->reg.data_type != VSIR_DATA_F32) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -10049,22 +14930,27 @@ index 23e059a3490..453b79c75d2 100644 break; default: -@@ -9999,6 +10681,11 @@ static void vsir_validate_dst_param(struct validation_context *ctx, +@@ -9999,8 +11176,13 @@ static void vsir_validate_dst_param(struct validation_context *ctx, vsir_validate_io_dst_param(ctx, dst); break; +- default: +- break; + case VKD3DSPR_TEXTURE: + if (vkd3d_shader_ver_ge(version, 1, 4)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, + "Texture registers cannot be written in version %u.%u.", version->major, version->minor); + - default: - break; ++ default: ++ break; } -@@ -10062,6 +10749,16 @@ static void vsir_validate_src_param(struct validation_context *ctx, + } + +@@ -10062,7 +11244,17 @@ static void vsir_validate_src_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source of dimension %u has invalid swizzle %#x.", src->reg.dimension, src->swizzle); +- if (src->modifiers >= VKD3DSPSM_COUNT) + if (src->reg.dimension == VSIR_DIMENSION_VEC4 && src->reg.type == VKD3DSPR_IMMCONST + && src->swizzle != VKD3D_SHADER_NO_SWIZZLE) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, @@ -10075,10 +14961,11 @@ index 23e059a3490..453b79c75d2 100644 + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, + "Immediate constant source has invalid swizzle %#x.", src->swizzle); + - if (src->modifiers >= VKD3DSPSM_COUNT) ++ if (src->modifiers >= VKD3DSPSM_COUNT || (ctx->program->has_no_modifiers && src->modifiers)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.", src->modifiers); -@@ -10070,7 +10767,8 @@ static void vsir_validate_src_param(struct validation_context *ctx, + +@@ -10070,7 +11262,8 @@ static void vsir_validate_src_param(struct validation_context *ctx, { if (!(src_modifier_data[src->modifiers].data_type_mask & (1u << src->reg.data_type))) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, @@ -10088,7 +14975,7 @@ index 23e059a3490..453b79c75d2 100644 } switch (src->reg.type) -@@ -10722,7 +11420,7 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, +@@ -10722,7 +11915,7 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, static void vsir_validate_elementwise_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) { @@ -10097,7 +14984,7 @@ index 23e059a3490..453b79c75d2 100644 unsigned int i; if (instruction->dst_count < 1) -@@ -10735,16 +11433,18 @@ static void vsir_validate_elementwise_operation(struct validation_context *ctx, +@@ -10735,16 +11928,18 @@ static void vsir_validate_elementwise_operation(struct validation_context *ctx, if (!types[dst_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -10121,7 +15008,25 @@ index 23e059a3490..453b79c75d2 100644 vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } } -@@ -10777,6 +11477,7 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex +@@ -10771,12 +11966,25 @@ static void vsir_validate_float_elementwise_operation(struct validation_context + vsir_validate_elementwise_operation(ctx, instruction, types); + } + ++static void vsir_validate_float_or_double_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_DATA_F64] = 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, @@ -10129,7 +15034,7 @@ index 23e059a3490..453b79c75d2 100644 [VSIR_DATA_U32] = true, [VSIR_DATA_U64] = true, }; -@@ -10784,6 +11485,18 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex +@@ -10784,6 +11992,18 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex vsir_validate_elementwise_operation(ctx, instruction, types); } @@ -10148,7 +15053,7 @@ index 23e059a3490..453b79c75d2 100644 static void vsir_validate_logic_elementwise_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { -@@ -10801,7 +11514,7 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context +@@ -10801,7 +12021,7 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context static void vsir_validate_comparison_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) { @@ -10157,7 +15062,7 @@ index 23e059a3490..453b79c75d2 100644 unsigned int i; if (instruction->dst_count < 1) -@@ -10811,8 +11524,9 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, +@@ -10811,8 +12031,9 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VSIR_DATA_BOOL) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -10169,7 +15074,7 @@ index 23e059a3490..453b79c75d2 100644 if (instruction->src_count == 0) return; -@@ -10824,16 +11538,18 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, +@@ -10824,16 +12045,18 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, if (!types[src_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -10194,7 +15099,7 @@ index 23e059a3490..453b79c75d2 100644 vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } } -@@ -10874,6 +11590,18 @@ static void vsir_validate_integer_comparison_operation(struct validation_context +@@ -10874,6 +12097,18 @@ static void vsir_validate_integer_comparison_operation(struct validation_context vsir_validate_comparison_operation(ctx, instruction, types); } @@ -10213,7 +15118,7 @@ index 23e059a3490..453b79c75d2 100644 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]) -@@ -10891,45 +11619,72 @@ static void vsir_validate_cast_operation(struct validation_context *ctx, +@@ -10891,45 +12126,72 @@ static void vsir_validate_cast_operation(struct validation_context *ctx, if (!src_types[src_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -10304,7 +15209,7 @@ index 23e059a3490..453b79c75d2 100644 } static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -@@ -11490,14 +12245,39 @@ static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d +@@ -11490,14 +12752,39 @@ static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d vsir_validator_push_block(ctx, VSIR_OP_IF); } @@ -10346,7 +15251,7 @@ index 23e059a3490..453b79c75d2 100644 }; static const bool dst_types[VSIR_DATA_TYPE_COUNT] = { -@@ -11624,7 +12404,8 @@ static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validat +@@ -11624,7 +12911,8 @@ static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validat enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, @@ -10356,7 +15261,7 @@ index 23e059a3490..453b79c75d2 100644 vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode, instruction->flags); } -@@ -11721,6 +12502,18 @@ static void vsir_validate_switch_monolithic(struct validation_context *ctx, +@@ -11721,6 +13009,18 @@ static void vsir_validate_switch_monolithic(struct validation_context *ctx, ctx->inside_block = false; } @@ -10375,7 +15280,14 @@ index 23e059a3490..453b79c75d2 100644 struct vsir_validator_instruction_desc { unsigned int dst_param_count; -@@ -11736,6 +12529,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ +@@ -11730,12 +13030,13 @@ struct vsir_validator_instruction_desc + + static const struct vsir_validator_instruction_desc vsir_validator_instructions[] = + { +- [VSIR_OP_ABS] = {1, 1, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_ABS] = {1, 1, vsir_validate_float_or_double_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}, @@ -10383,7 +15295,11 @@ index 23e059a3490..453b79c75d2 100644 [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}, -@@ -11800,17 +12594,17 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ +@@ -11797,20 +13098,21 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ + [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_IDIV] = {1, 2, vsir_validate_signed_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}, @@ -10398,7 +15314,8 @@ index 23e059a3490..453b79c75d2 100644 + [VSIR_OP_IMIN] = {1, 2, vsir_validate_signed_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_IREM] = {1, 2, vsir_validate_integer_elementwise_operation}, ++ [VSIR_OP_IREM] = {1, 2, vsir_validate_signed_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}, @@ -10407,8 +15324,19 @@ index 23e059a3490..453b79c75d2 100644 [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}, -@@ -11840,16 +12634,15 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ +@@ -11824,6 +13126,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ + [VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation}, ++ [VSIR_OP_NEG] = {1, 1, vsir_validate_float_or_double_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}, +@@ -11838,18 +13141,18 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ + [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_SATURATE] = {1, 1, vsir_validate_float_or_double_elementwise_operation}, [VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch}, [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, + [VSIR_OP_USHR] = {1, 2, vsir_validate_ushr}, @@ -10427,7 +15355,7 @@ index 23e059a3490..453b79c75d2 100644 for (i = 0; i < instruction->dst_count; ++i) vsir_validate_dst_param(ctx, &instruction->dst[i]); -@@ -11927,7 +12720,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c +@@ -11927,7 +13230,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c { .message_context = message_context, .program = program, @@ -10436,7 +15364,7 @@ index 23e059a3490..453b79c75d2 100644 .status = VKD3D_OK, .phase = VSIR_OP_INVALID, .invalid_instruction_idx = true, -@@ -11938,6 +12731,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c +@@ -11938,6 +13241,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c .inner_tess_idxs[0] = ~0u, .inner_tess_idxs[1] = ~0u, }; @@ -10445,7 +15373,7 @@ index 23e059a3490..453b79c75d2 100644 unsigned int i; if (!(config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) -@@ -12046,11 +12841,17 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c +@@ -12046,11 +13351,17 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c ctx.invalid_instruction_idx = false; @@ -10466,10 +15394,19 @@ index 23e059a3490..453b79c75d2 100644 if (ctx.depth != 0) validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "%zu nested blocks were not closed.", ctx.depth); -@@ -12113,14 +12914,9 @@ static void vsir_transform_( - enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) - { +@@ -12104,71 +13415,706 @@ static void vsir_transform_( + } + } + +-/* Transformations which should happen at parse time, i.e. before scan +- * information is returned to the user. +- * +- * In particular, some passes need to modify the signature, and +- * vkd3d_shader_scan() should report the modified signature for the given +- * target. */ +-enum vkd3d_result vsir_program_transform_early(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, @@ -10478,16 +15415,23 @@ index 23e059a3490..453b79c75d2 100644 - .compile_info = compile_info, - .message_context = message_context, - }; -+ struct vsir_transformation_context ctx; -+ -+ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); - - /* For vsir_program_ensure_diffuse(). */ - if (program->shader_version.major <= 2) -@@ -12138,18 +12934,18 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin - 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) - { +- +- /* For vsir_program_ensure_diffuse(). */ +- if (program->shader_version.major <= 2) +- vsir_transform(&ctx, vsir_program_add_diffuse_output); +- +- /* For vsir_program_insert_fragment_fog(). */ +- vsir_transform(&ctx, vsir_program_add_fog_input); +- +- /* For vsir_program_insert_vertex_fog(). */ +- vsir_transform(&ctx, vsir_program_add_fog_output); +- +- 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, @@ -10496,41 +15440,731 @@ index 23e059a3490..453b79c75d2 100644 - .compile_info = compile_info, - .message_context = message_context, - }; -+ struct vsir_transformation_context ctx; - -+ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); - vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); +- +- 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) ++static bool vsir_instruction_has_side_effects(const struct vkd3d_shader_instruction *ins) + { +- struct vsir_transformation_context ctx = ++ switch (ins->opcode) + { +- .result = VKD3D_OK, +- .program = program, +- .config_flags = config_flags, +- .compile_info = compile_info, +- .message_context = message_context, +- }; ++ 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_BEM: ++ case VSIR_OP_BFI: ++ case VSIR_OP_BFREV: ++ case VSIR_OP_BUFINFO: ++ case VSIR_OP_CHECK_ACCESS_FULLY_MAPPED: ++ case VSIR_OP_CMP: ++ case VSIR_OP_CND: ++ case VSIR_OP_COS: ++ case VSIR_OP_COUNTBITS: ++ case VSIR_OP_CRS: ++ case VSIR_OP_DADD: ++ case VSIR_OP_DDIV: ++ case VSIR_OP_DEF: ++ case VSIR_OP_DEFB: ++ case VSIR_OP_DEFI: ++ case VSIR_OP_DEQO: ++ case VSIR_OP_DFMA: ++ case VSIR_OP_DGEO: ++ case VSIR_OP_DIV: ++ case VSIR_OP_DLT: ++ case VSIR_OP_DMAX: ++ case VSIR_OP_DMIN: ++ case VSIR_OP_DMOV: ++ case VSIR_OP_DMOVC: ++ case VSIR_OP_DMUL: ++ case VSIR_OP_DNE: ++ case VSIR_OP_DP2: ++ case VSIR_OP_DP2ADD: ++ case VSIR_OP_DP3: ++ case VSIR_OP_DP4: ++ case VSIR_OP_DRCP: ++ case VSIR_OP_DST: ++ 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_DTOF: ++ case VSIR_OP_DTOI: ++ case VSIR_OP_DTOU: ++ case VSIR_OP_EQO: ++ case VSIR_OP_EQU: ++ case VSIR_OP_EVAL_CENTROID: ++ case VSIR_OP_EVAL_SAMPLE_INDEX: ++ 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_GATHER4: ++ case VSIR_OP_GATHER4_C: ++ case VSIR_OP_GATHER4_C_S: ++ 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_GATHER4_S: ++ 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_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_STRUCTURED: ++ case VSIR_OP_LD_STRUCTURED_S: ++ case VSIR_OP_LD_UAV_TYPED: ++ case VSIR_OP_LD_UAV_TYPED_S: ++ case VSIR_OP_LIT: ++ case VSIR_OP_LOD: ++ case VSIR_OP_LOG: ++ case VSIR_OP_LOGP: ++ case VSIR_OP_LRP: ++ case VSIR_OP_LTO: ++ case VSIR_OP_LTU: ++ case VSIR_OP_M3x2: ++ case VSIR_OP_M3x3: ++ case VSIR_OP_M3x4: ++ case VSIR_OP_M4x3: ++ case VSIR_OP_M4x4: ++ 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: ++ case VSIR_OP_MUL: ++ case VSIR_OP_NEG: ++ case VSIR_OP_NEO: ++ case VSIR_OP_NEU: ++ case VSIR_OP_NOP: ++ case VSIR_OP_NOT: ++ case VSIR_OP_NRM: ++ 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_QUAD_READ_LANE_AT: ++ case VSIR_OP_RCP: ++ case VSIR_OP_RESINFO: ++ 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_B_CL_S: ++ case VSIR_OP_SAMPLE_C: ++ case VSIR_OP_SAMPLE_C_CL_S: ++ case VSIR_OP_SAMPLE_C_LZ: ++ case VSIR_OP_SAMPLE_C_LZ_S: ++ case VSIR_OP_SAMPLE_CL_S: ++ case VSIR_OP_SAMPLE_GRAD: ++ case VSIR_OP_SAMPLE_GRAD_CL_S: ++ case VSIR_OP_SAMPLE_INFO: ++ case VSIR_OP_SAMPLE_LOD: ++ case VSIR_OP_SAMPLE_LOD_S: ++ case VSIR_OP_SAMPLE_POS: ++ case VSIR_OP_SATURATE: ++ case VSIR_OP_SETP: ++ case VSIR_OP_SGE: ++ case VSIR_OP_SGN: ++ case VSIR_OP_SIN: ++ case VSIR_OP_SINCOS: ++ case VSIR_OP_SLT: ++ case VSIR_OP_SQRT: ++ case VSIR_OP_SUB: ++ case VSIR_OP_SWAPC: ++ case VSIR_OP_TAN: ++ 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: ++ 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_BALLOT: ++ 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_BIT_COUNT: ++ case VSIR_OP_WAVE_ALL_TRUE: ++ case VSIR_OP_WAVE_ANY_TRUE: ++ case VSIR_OP_WAVE_IS_FIRST_LANE: ++ 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_PREFIX_BIT_COUNT: ++ case VSIR_OP_WAVE_READ_LANE_AT: ++ case VSIR_OP_WAVE_READ_LANE_FIRST: ++ case VSIR_OP_XOR: ++ return false; + - if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ++ 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_BRANCH: ++ case VSIR_OP_BREAK: ++ case VSIR_OP_BREAKC: ++ case VSIR_OP_BREAKP: ++ case VSIR_OP_CALL: ++ case VSIR_OP_CALLNZ: ++ case VSIR_OP_CASE: ++ case VSIR_OP_CONTINUE: ++ case VSIR_OP_CONTINUEP: ++ 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_INDEX_RANGE: ++ case VSIR_OP_DCL_INDEXABLE_TEMP: ++ 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_DEFAULT: ++ case VSIR_OP_DISCARD: ++ 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: ++ 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_PHASE: ++ case VSIR_OP_REP: ++ case VSIR_OP_RET: ++ case VSIR_OP_RETP: ++ 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_TEXKILL: ++ return true; ++ ++ case VSIR_OP_INVALID: ++ case VSIR_OP_COUNT: ++ break; ++ } ++ ++ vkd3d_unreachable(); ++} ++ ++static enum vkd3d_result vsir_program_dce(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; ++ struct liveness_tracker tracker; ++ enum vkd3d_result ret; ++ unsigned int i; ++ ++ if ((ret = track_liveness(program, &tracker))) ++ return ret; ++ ++ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) ++ { ++ unsigned int used_dst_count = 0; ++ ++ /* FIXME: IMM_ATOMIC_* can still be effectively DCE'd by turning them ++ * into non-immediate ATOMIC_* instructions. */ ++ if (vsir_instruction_has_side_effects(ins)) ++ continue; ++ ++ for (unsigned int j = 0; j < ins->dst_count; ++j) ++ { ++ struct vkd3d_shader_dst_param *dst = &ins->dst[j]; ++ ++ if (dst->reg.type == VKD3DSPR_SSA && !tracker.ssa_regs[dst->reg.idx[0].offset].last_read) ++ { ++ vsir_dst_param_init_null(dst); ++ ctx->progress = true; ++ } ++ else if (dst->reg.type == VKD3DSPR_TEMP ++ && tracker.temp_regs[dst->reg.idx[0].offset].last_read <= i ++ && !(program->shader_version.major == 1 && dst->reg.idx[0].offset == 0)) ++ { ++ vsir_dst_param_init_null(dst); ++ ctx->progress = true; ++ } ++ else if (dst->reg.type != VKD3DSPR_NULL) ++ { ++ ++used_dst_count; ++ } ++ } ++ ++ if (!used_dst_count) ++ vkd3d_shader_instruction_make_nop(ins); ++ } ++ ++ liveness_tracker_cleanup(&tracker); ++ return VKD3D_OK; ++} ++ ++/* ++ * This pass attempts to reduce redundant MOVs (copies) by combining them with ++ * adjacent instructions. The resulting MOVs will subsequently be removed by ++ * DCE if no longer used. ++ * ++ * We attempt to combine two instructions, not necessarily consecutive, ++ * of the form ++ * ++ * mov aaa.bbb, ccc ++ * XXX ..., aaa.ddd ++ * ++ * into ++ * ++ * XXX ..., ccc ++ * ++ * There are many constraints, including: ++ * ++ * - The ddd components of aaa must not have been modified between the ++ * two instructions. ++ * Currently, only SSA is supported, so this is trivial. ++ * ++ * - The relevant components of ccc must not have been modified between the ++ * two instructions. ++ * Currently, we require ccc to be a read-only register, so this is trivial. ++ * ++ * - ddd must be a subset of bbb. This is again trivial for SSA. ++ */ ++ ++struct vsir_copy_propagation_state ++{ ++ /* The sources for each SSA register, if it was written by a ++ * MOV instruction, or NULL if not. ++ * ++ * We do not add or remove instructions in this pass, only modifying their ++ * content, so these pointers are safe to store. ++ */ ++ const struct vkd3d_shader_instruction **ssa_sources; ++}; ++ ++static bool is_read_only(const struct vsir_program *program, enum vkd3d_shader_register_type type) ++{ ++ switch (type) ++ { ++ case VKD3DSPR_ADDR: ++ case VKD3DSPR_IDXTEMP: ++ case VKD3DSPR_LOOP: ++ case VKD3DSPR_TEMP: ++ case VKD3DSPR_TEMPFLOAT16: ++ return false; ++ ++ case VKD3DSPR_TEXTURE: ++ return vkd3d_shader_ver_ge(&program->shader_version, 1, 4); ++ ++ /* Not applicable since they're not numeric or can't be sources. */ ++ case VKD3DSPR_ATTROUT: ++ case VKD3DSPR_COLOROUT: ++ case VKD3DSPR_COMBINED_SAMPLER: ++ case VKD3DSPR_COUNT: ++ case VKD3DSPR_DEPTHOUT: ++ case VKD3DSPR_DEPTHOUTGE: ++ case VKD3DSPR_DEPTHOUTLE: ++ case VKD3DSPR_FUNCTIONBODY: ++ case VKD3DSPR_FUNCTIONPOINTER: ++ case VKD3DSPR_GROUPSHAREDMEM: ++ case VKD3DSPR_INVALID: ++ case VKD3DSPR_LABEL: ++ case VKD3DSPR_NULL: ++ case VKD3DSPR_OUTPUT: ++ case VKD3DSPR_OUTSTENCILREF: ++ case VKD3DSPR_PREDICATE: ++ case VKD3DSPR_RASTERIZER: ++ case VKD3DSPR_RASTOUT: ++ case VKD3DSPR_RESOURCE: ++ case VKD3DSPR_SAMPLER: ++ case VKD3DSPR_STREAM: ++ case VKD3DSPR_TEXCRDOUT: ++ case VKD3DSPR_UAV: ++ return false; ++ ++ case VKD3DSPR_CONST: ++ case VKD3DSPR_CONSTBOOL: ++ case VKD3DSPR_CONSTBUFFER: ++ case VKD3DSPR_CONSTINT: ++ case VKD3DSPR_COVERAGE: ++ case VKD3DSPR_FORKINSTID: ++ case VKD3DSPR_GSINSTID: ++ case VKD3DSPR_IMMCONST: ++ case VKD3DSPR_IMMCONST64: ++ case VKD3DSPR_IMMCONSTBUFFER: ++ case VKD3DSPR_INCONTROLPOINT: ++ case VKD3DSPR_INPUT: ++ case VKD3DSPR_JOININSTID: ++ case VKD3DSPR_LOCALTHREADID: ++ case VKD3DSPR_LOCALTHREADINDEX: ++ case VKD3DSPR_MISCTYPE: ++ case VKD3DSPR_OUTCONTROLPOINT: ++ case VKD3DSPR_OUTPOINTID: ++ case VKD3DSPR_PARAMETER: ++ case VKD3DSPR_PATCHCONST: ++ case VKD3DSPR_POINT_COORD: ++ case VKD3DSPR_PRIMID: ++ case VKD3DSPR_SAMPLEMASK: ++ case VKD3DSPR_SSA: ++ case VKD3DSPR_TESSCOORD: ++ case VKD3DSPR_THREADGROUPID: ++ case VKD3DSPR_THREADID: ++ case VKD3DSPR_UNDEF: ++ case VKD3DSPR_WAVELANECOUNT: ++ case VKD3DSPR_WAVELANEINDEX: ++ return true; ++ } ++ ++ vkd3d_unreachable(); ++} ++ ++static bool can_propagate_ssa_source(const struct vsir_program *program, const struct vkd3d_shader_instruction *ins) ++{ ++ if (ins->opcode != VSIR_OP_MOV) ++ return false; ++ /* TODO: Propagate copies for other register types. */ ++ if (ins->dst[0].reg.type != VKD3DSPR_SSA) ++ return false; ++ if (ins->dst[0].modifiers || ins->dst[0].shift) ++ return false; ++ ++ /* TODO: We can perform copy-prop for read-write register types, but we ++ * have to be sure that the register wasn't modified between the two ++ * instructions. */ ++ if (!is_read_only(program, ins->src[0].reg.type)) ++ return false; ++ for (unsigned int k = 0; k < ins->src[0].reg.idx_count; ++k) ++ { ++ if (ins->src[0].reg.idx[k].rel_addr && !is_read_only(program, ins->src[0].reg.idx[k].rel_addr->reg.type)) ++ return false; ++ } ++ ++ /* Don't bother with other source modifiers for now; the HLSL compiler ++ * doesn't emit them. */ ++ switch (ins->src[0].modifiers) ++ { ++ case VKD3DSPSM_ABS: ++ case VKD3DSPSM_ABSNEG: ++ case VKD3DSPSM_NEG: ++ case VKD3DSPSM_NONE: ++ break; ++ ++ default: ++ return false; ++ } ++ return true; ++} ++ ++static enum vkd3d_result vsir_program_copy_propagation(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vsir_copy_propagation_state state = {0}; ++ struct vkd3d_shader_instruction *ins; ++ ++ if (!(state.ssa_sources = vkd3d_calloc(program->ssa_count, sizeof(*state.ssa_sources)))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ for (unsigned int j = 0; j < ins->src_count; ++j) ++ { ++ struct vkd3d_shader_src_param *src = &ins->src[j]; ++ const struct vkd3d_shader_src_param *mov_src; ++ const struct vkd3d_shader_instruction *mov; ++ enum vsir_data_type data_type; ++ uint32_t new_swizzle = 0; ++ ++ if (src->reg.type != VKD3DSPR_SSA) ++ continue; ++ if (data_type_is_64_bit(src->reg.data_type)) ++ continue; ++ if (!(mov = state.ssa_sources[src->reg.idx[0].offset])) ++ continue; ++ mov_src = &mov->src[0]; ++ data_type = src->reg.data_type; ++ ++ src->reg = mov_src->reg; ++ src->reg.data_type = data_type; ++ ++ if (!shader_register_clone_relative_addresses(&src->reg, program)) ++ { ++ vkd3d_free(state.ssa_sources); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ ++ for (unsigned int k = 0; k < 4; ++k) ++ { ++ unsigned int s = vsir_swizzle_get_component(src->swizzle, k); ++ ++ if (mov_src->reg.type == VKD3DSPR_IMMCONST) ++ src->reg.u.immconst_u32[k] = mov_src->reg.u.immconst_u32[s]; ++ else ++ vsir_swizzle_set_component(&new_swizzle, k, vsir_swizzle_get_component(mov_src->swizzle, s)); ++ } ++ if (mov_src->reg.type != VKD3DSPR_IMMCONST) ++ src->swizzle = new_swizzle; ++ ++ if (src->modifiers == VKD3DSPSM_NONE) ++ src->modifiers = mov_src->modifiers; ++ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_ABS) ++ src->modifiers = VKD3DSPSM_ABSNEG; ++ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_ABSNEG) ++ src->modifiers = VKD3DSPSM_ABS; ++ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_NEG) ++ src->modifiers = VKD3DSPSM_NONE; ++ /* Otherwise no change is necessary. */ ++ ++ ctx->progress = true; ++ } ++ ++ if (can_propagate_ssa_source(program, ins)) ++ state.ssa_sources[ins->dst[0].reg.idx[0].offset] = ins; ++ } ++ ++ vkd3d_free(state.ssa_sources); ++ return VKD3D_OK; ++} ++ ++enum vkd3d_result vsir_program_optimize(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; ++ ++ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); ++ ++ do ++ { ++ ctx.progress = false; ++ vsir_transform(&ctx, vsir_program_copy_propagation); ++ vsir_transform(&ctx, vsir_program_dce); ++ } ++ while (ctx.progress); ++ ++ if (TRACE_ON()) ++ vsir_program_trace(program); ++ ++ return ctx.result; ++} ++ ++/* Transformations which should happen at parse time, i.e. before scan ++ * information is returned to the user. ++ * ++ * In particular, some passes need to modify the signature, and ++ * vkd3d_shader_scan() should report the modified signature for the given ++ * target. */ ++enum vkd3d_result vsir_program_transform_early(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; ++ ++ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); ++ ++ /* For vsir_program_ensure_diffuse(). */ ++ if (program->shader_version.major <= 2) ++ vsir_transform(&ctx, vsir_program_add_diffuse_output); ++ ++ /* For vsir_program_insert_fragment_fog(). */ ++ vsir_transform(&ctx, vsir_program_add_fog_input); ++ ++ /* For vsir_program_insert_vertex_fog(). */ ++ vsir_transform(&ctx, vsir_program_add_fog_output); ++ ++ 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; ++ ++ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); ++ vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); ++ ++ if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) + { + if (program->shader_version.minor < 4) + vsir_transform(&ctx, vsir_program_lower_texture_writes); + - vsir_transform(&ctx, vsir_program_normalise_ps1_output); ++ vsir_transform(&ctx, vsir_program_normalise_ps1_output); + } - - if (TRACE_ON()) - vsir_program_trace(program); -@@ -12160,15 +12956,9 @@ enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_ - 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) - { -- struct vsir_transformation_context ctx = -- { -- .result = VKD3D_OK, -- .program = program, -- .config_flags = config_flags, -- .compile_info = compile_info, -- .message_context = message_context, -- }; ++ ++ 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) ++{ + struct vsir_transformation_context ctx; + vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); ++ vsir_transform(&ctx, vsir_program_lower_modifiers); vsir_transform(&ctx, vsir_program_lower_instructions); if (program->shader_version.major >= 6) diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index c6e048adb20..8a89dcabd5e 100644 +index c6e048adb20..c974c9e532b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -167,6 +167,7 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, @@ -10541,7 +16175,252 @@ index c6e048adb20..8a89dcabd5e 100644 case VSIR_DATA_I32: vkd3d_string_buffer_printf(buffer, "i"); break; -@@ -485,6 +486,22 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu +@@ -208,132 +209,63 @@ static bool msl_check_shader_visibility(const struct msl_generator *gen, + } + } + +-static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const struct msl_generator *gen, +- unsigned int register_space, unsigned int register_idx) ++static bool msl_get_binding(const struct msl_generator *gen, const struct vkd3d_shader_descriptor_info1 *descriptor, ++ unsigned int register_idx, enum vkd3d_shader_binding_flag flags, unsigned int *idx) + { + const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; + unsigned int i; + + if (!interface_info) +- return NULL; ++ return false; + + for (i = 0; i < interface_info->binding_count; ++i) + { + const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; + +- if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) ++ if (binding->type != descriptor->type) + continue; +- if (binding->register_space != register_space) ++ if (binding->register_space != descriptor->register_space) + continue; + if (binding->register_index != register_idx) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; +- if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) ++ if ((binding->flags & flags) != flags) + continue; + +- return &binding->binding; ++ *idx = binding->binding.binding; ++ return true; + } + +- return NULL; ++ return false; + } + +-static const struct vkd3d_shader_descriptor_binding *msl_get_sampler_binding(const struct msl_generator *gen, +- unsigned int register_space, unsigned int register_idx) ++static bool msl_get_cbv_binding(const struct msl_generator *gen, ++ const struct vkd3d_shader_descriptor_info1 *descriptor, unsigned int register_idx, unsigned int *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; ++ return msl_get_binding(gen, descriptor, register_idx, VKD3D_SHADER_BINDING_FLAG_BUFFER, idx); + } + +-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) ++static bool msl_get_sampler_binding(const struct msl_generator *gen, ++ const struct vkd3d_shader_descriptor_info1 *descriptor, unsigned int register_idx, unsigned int *idx) + { +- const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; +- 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) +- { +- const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; +- +- if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV) +- 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; ++ return msl_get_binding(gen, descriptor, register_idx, 0, idx); + } + +-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) ++static bool msl_get_srv_binding(const struct msl_generator *gen, ++ const struct vkd3d_shader_descriptor_info1 *descriptor, unsigned int register_idx, unsigned int *idx) + { +- 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 msl_get_binding(gen, descriptor, register_idx, ++ descriptor->resource_type == VKD3D_SHADER_RESOURCE_BUFFER ++ ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE, idx); ++} + +- return NULL; ++static bool msl_get_uav_binding(const struct msl_generator *gen, ++ const struct vkd3d_shader_descriptor_info1 *descriptor, unsigned int register_idx, unsigned int *idx) ++{ ++ return msl_get_binding(gen, descriptor, register_idx, ++ descriptor->resource_type == VKD3D_SHADER_RESOURCE_BUFFER ++ ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE, idx); + } + + static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding) +@@ -369,6 +301,9 @@ static void msl_print_uav_name(struct vkd3d_string_buffer *buffer, struct msl_ge + static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer, + struct msl_generator *gen, const struct vkd3d_shader_register *reg) + { ++ const struct vkd3d_shader_descriptor_info1 *descriptor; ++ unsigned int binding, cbv_id, cbv_idx; ++ + switch (reg->type) + { + case VKD3DSPR_TEMP: +@@ -440,38 +375,47 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu + } + + case VKD3DSPR_CONSTBUFFER: ++ if (reg->idx_count != 3) + { +- const struct vkd3d_shader_descriptor_binding *binding; ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled constant buffer register index count %u.", ++ reg->idx_count); ++ vkd3d_string_buffer_printf(buffer, "", reg->type); ++ return MSL_DATA_UNION; ++ } + +- if (reg->idx_count != 3) +- { +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled constant buffer register index count %u.", +- reg->idx_count); +- vkd3d_string_buffer_printf(buffer, "", reg->type); +- return MSL_DATA_UNION; +- } +- 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, +- "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); +- msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); ++ 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; ++ } ++ ++ cbv_id = reg->idx[0].offset; ++ cbv_idx = reg->idx[1].offset; ++ ++ if (!(descriptor = vkd3d_shader_find_descriptor(&gen->program->descriptors, ++ VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cbv_id))) ++ { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Undeclared CBV descriptor %u.", cbv_id); ++ vkd3d_string_buffer_printf(buffer, "", reg->type); + return MSL_DATA_UNION; + } + ++ if (!msl_get_cbv_binding(gen, descriptor, cbv_idx, &binding)) ++ { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, ++ "No descriptor binding specified for CBV %u.", cbv_id); ++ vkd3d_string_buffer_printf(buffer, "", reg->type); ++ return MSL_DATA_UNION; ++ } ++ ++ msl_print_cbv_name(buffer, binding); ++ 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); +@@ -485,6 +429,22 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu vkd3d_string_buffer_printf(buffer, "o_mask"); return MSL_DATA_UNION; @@ -10564,7 +16443,91 @@ index c6e048adb20..8a89dcabd5e 100644 default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled register type %#x.", reg->type); -@@ -799,6 +816,7 @@ static void msl_relop(struct msl_generator *gen, const struct vkd3d_shader_instr +@@ -566,7 +526,7 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m + 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; ++ struct vkd3d_string_buffer *register_name; + enum msl_data_type src_data_type; + + register_name = vkd3d_string_buffer_get(&gen->string_buffers); +@@ -575,39 +535,10 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled 'non-uniform' modifier."); + +- if (!vsir_src->modifiers) +- str = buffer; +- else +- str = vkd3d_string_buffer_get(&gen->string_buffers); +- + src_data_type = msl_print_register_name(register_name, gen, reg); +- msl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, reg->dimension); ++ msl_print_bitcast(buffer, gen, register_name->buffer, data_type, src_data_type, reg->dimension); + if (reg->dimension == VSIR_DIMENSION_VEC4) +- msl_print_swizzle(str, vsir_src->swizzle, mask); +- +- switch (vsir_src->modifiers) +- { +- case VKD3DSPSM_NONE: +- break; +- case VKD3DSPSM_NEG: +- vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); +- break; +- 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); +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); +- break; +- } +- +- if (str != buffer) +- vkd3d_string_buffer_release(&gen->string_buffers, str); ++ msl_print_swizzle(buffer, vsir_src->swizzle, mask); + } + + static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, +@@ -671,32 +602,19 @@ static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_g + 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); +- if (modifiers & ~VKD3DSPDM_SATURATE) +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled destination modifier(s) %#x.", modifiers); + + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer); + +- if (modifiers & VKD3DSPDM_SATURATE) +- vkd3d_string_buffer_printf(gen->buffer, "saturate("); +- + va_start(args, format); + vkd3d_string_buffer_vprintf(gen->buffer, format, args); + va_end(args); + +- if (modifiers & VKD3DSPDM_SATURATE) +- vkd3d_string_buffer_printf(gen->buffer, ")"); +- + vkd3d_string_buffer_printf(gen->buffer, ";\n"); + } + +@@ -799,6 +717,7 @@ static void msl_relop(struct msl_generator *gen, const struct vkd3d_shader_instr static void msl_cast(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *constructor) { unsigned int component_count; @@ -10572,7 +16535,7 @@ index c6e048adb20..8a89dcabd5e 100644 struct msl_src src; struct msl_dst dst; uint32_t mask; -@@ -806,10 +824,11 @@ static void msl_cast(struct msl_generator *gen, const struct vkd3d_shader_instru +@@ -806,10 +725,11 @@ static void msl_cast(struct msl_generator *gen, const struct vkd3d_shader_instru mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); msl_src_init(&src, gen, &ins->src[0], mask); @@ -10586,7 +16549,7 @@ index c6e048adb20..8a89dcabd5e 100644 msl_src_cleanup(&src, &gen->string_buffers); msl_dst_cleanup(&dst, &gen->string_buffers); -@@ -943,8 +962,8 @@ static void msl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct ms +@@ -943,15 +863,14 @@ static void msl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct ms static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { @@ -10594,9 +16557,17 @@ index c6e048adb20..8a89dcabd5e 100644 const struct msl_resource_type_info *resource_type_info; - unsigned int resource_id, resource_idx, resource_space; const struct vkd3d_shader_descriptor_info1 *descriptor; - const struct vkd3d_shader_descriptor_binding *binding; +- const struct vkd3d_shader_descriptor_binding *binding; enum vkd3d_shader_resource_type resource_type; -@@ -969,6 +988,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + uint32_t coord_mask, write_mask_size; + struct vkd3d_string_buffer *read; + enum vsir_data_type data_type; +- unsigned int srv_binding; ++ unsigned int srv_binding = 0; + struct msl_dst dst; + + if (vkd3d_shader_instruction_has_texel_offset(ins)) +@@ -969,6 +888,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct { resource_type = descriptor->resource_type; resource_space = descriptor->register_space; @@ -10604,7 +16575,7 @@ index c6e048adb20..8a89dcabd5e 100644 data_type = descriptor->resource_data_type; } else -@@ -977,6 +997,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct +@@ -977,6 +897,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct "Internal compiler error: Undeclared resource descriptor %u.", resource_id); resource_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; @@ -10612,7 +16583,7 @@ index c6e048adb20..8a89dcabd5e 100644 data_type = VSIR_DATA_F32; } -@@ -988,6 +1009,16 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct +@@ -988,6 +909,16 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, "Texel fetches from resource type %#x are not supported.", resource_type); @@ -10629,7 +16600,26 @@ index c6e048adb20..8a89dcabd5e 100644 if (!(resource_type_info = msl_get_resource_type_info(resource_type))) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -1030,6 +1061,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct +@@ -996,17 +927,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + } + 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 +- { ++ if (descriptor && !msl_get_srv_binding(gen, descriptor, resource_idx, &srv_binding)) + 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; +- } + + msl_dst_init(&dst, gen, ins, &ins->dst[0]); + read = vkd3d_string_buffer_get(&gen->string_buffers); +@@ -1030,6 +954,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct vkd3d_string_buffer_printf(read, ", "); if (ins->opcode != VSIR_OP_LD2DMS) msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VSIR_DATA_U32); @@ -10640,7 +16630,73 @@ index c6e048adb20..8a89dcabd5e 100644 else msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32); } -@@ -1294,6 +1329,11 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh +@@ -1049,11 +977,10 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst + 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; ++ unsigned int srv_binding = 0, sampler_binding = 0; + 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; +@@ -1121,17 +1048,10 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst + } + 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 +- { ++ if (d && !msl_get_srv_binding(gen, d, resource_idx, &srv_binding)) + 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; +@@ -1161,17 +1081,10 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst + sampler_space = 0; + } + +- if ((binding = msl_get_sampler_binding(gen, sampler_space, sampler_idx))) +- { +- sampler_binding = binding->binding; +- } +- else +- { ++ if (d && !msl_get_sampler_binding(gen, d, sampler_idx, &sampler_binding)) + 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); +@@ -1263,13 +1176,12 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst + 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; ++ unsigned int uav_binding = 0; + uint32_t coord_mask; + + if (ins->dst[0].reg.idx[0].rel_addr || ins->dst[0].reg.idx[1].rel_addr) +@@ -1294,6 +1206,11 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh data_type = VSIR_DATA_F32; } @@ -10652,7 +16708,26 @@ index c6e048adb20..8a89dcabd5e 100644 if (!(resource_type_info = msl_get_resource_type_info(resource_type))) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -1414,6 +1454,12 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc +@@ -1302,17 +1219,10 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh + } + 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 +- { ++ if (d && !msl_get_uav_binding(gen, d, uav_idx, &uav_binding)) + 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); + +@@ -1414,6 +1324,12 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc static void msl_dcl_indexable_temp(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { const char *type = ins->declaration.indexable_temp.component_count == 4 ? "vkd3d_vec4" : "vkd3d_scalar"; @@ -10665,17 +16740,20 @@ index c6e048adb20..8a89dcabd5e 100644 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, -@@ -1426,6 +1472,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d +@@ -1426,6 +1342,12 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d switch (ins->opcode) { ++ case VSIR_OP_ABS: ++ msl_intrinsic(gen, ins, "abs"); ++ break; + case VSIR_OP_ACOS: + msl_intrinsic(gen, ins, "acos"); + break; case VSIR_OP_ADD: case VSIR_OP_IADD: msl_binop(gen, ins, "+"); -@@ -1433,6 +1482,12 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d +@@ -1433,6 +1355,12 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VSIR_OP_AND: msl_binop(gen, ins, "&"); break; @@ -10688,7 +16766,7 @@ index c6e048adb20..8a89dcabd5e 100644 case VSIR_OP_BREAK: msl_break(gen); break; -@@ -1442,6 +1497,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d +@@ -1442,6 +1370,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VSIR_OP_CONTINUE: msl_continue(gen); break; @@ -10698,7 +16776,7 @@ index c6e048adb20..8a89dcabd5e 100644 case VSIR_OP_DCL_INDEXABLE_TEMP: msl_dcl_indexable_temp(gen, ins); break; -@@ -1497,6 +1555,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d +@@ -1497,6 +1428,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VSIR_OP_FRC: msl_intrinsic(gen, ins, "fract"); break; @@ -10708,7 +16786,7 @@ index c6e048adb20..8a89dcabd5e 100644 case VSIR_OP_FTOI: msl_cast(gen, ins, "int"); break; -@@ -1516,8 +1577,18 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d +@@ -1516,11 +1450,29 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d break; case VSIR_OP_GEO: case VSIR_OP_IGE: @@ -10723,21 +16801,43 @@ index c6e048adb20..8a89dcabd5e 100644 + break; + case VSIR_OP_HTAN: + msl_intrinsic(gen, ins, "tanh"); ++ break; ++ case VSIR_OP_IDIV: ++ case VSIR_OP_UDIV_SIMPLE: ++ msl_binop(gen, ins, "/"); + break; case VSIR_OP_IF: msl_if(gen, ins); break; -@@ -1602,6 +1673,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d ++ case VSIR_OP_IREM: ++ case VSIR_OP_UREM: ++ msl_binop(gen, ins, "%"); ++ break; + case VSIR_OP_ISHL: + msl_binop(gen, ins, "<<"); + break; +@@ -1553,6 +1505,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + msl_relop(gen, ins, "!="); + break; + case VSIR_OP_INEG: ++ case VSIR_OP_NEG: + msl_unary_op(gen, ins, "-"); + break; + case VSIR_OP_ITOF: +@@ -1602,6 +1555,12 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VSIR_OP_RSQ: msl_intrinsic(gen, ins, "rsqrt"); break; ++ case VSIR_OP_SATURATE: ++ msl_intrinsic(gen, ins, "saturate"); ++ break; + case VSIR_OP_SIN: + msl_intrinsic(gen, ins, "sin"); + break; case VSIR_OP_SQRT: msl_intrinsic(gen, ins, "sqrt"); break; -@@ -1611,6 +1685,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d +@@ -1611,6 +1570,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VSIR_OP_SWITCH: msl_switch(gen, ins); break; @@ -10747,7 +16847,7 @@ index c6e048adb20..8a89dcabd5e 100644 case VSIR_OP_XOR: msl_binop(gen, ins, "^"); break; -@@ -1951,6 +2028,30 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) +@@ -1951,6 +1913,30 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) msl_print_write_mask(buffer, e->mask); vkd3d_string_buffer_printf(buffer, ";\n"); } @@ -10778,7 +16878,7 @@ index c6e048adb20..8a89dcabd5e 100644 } static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) -@@ -1995,6 +2096,7 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) +@@ -1995,6 +1981,7 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) static void msl_generate_entrypoint(struct msl_generator *gen) { enum vkd3d_shader_type type = gen->program->shader_version.type; @@ -10786,7 +16886,7 @@ index c6e048adb20..8a89dcabd5e 100644 switch (type) { -@@ -2006,13 +2108,21 @@ static void msl_generate_entrypoint(struct msl_generator *gen) +@@ -2006,13 +1993,21 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, "[[early_fragment_tests]]\n"); vkd3d_string_buffer_printf(gen->buffer, "fragment "); break; @@ -10809,7 +16909,7 @@ index c6e048adb20..8a89dcabd5e 100644 if (gen->program->descriptors.descriptor_count) { -@@ -2028,6 +2138,30 @@ static void msl_generate_entrypoint(struct msl_generator *gen) +@@ -2028,6 +2023,30 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, "uint vertex_id [[vertex_id]],\n"); } @@ -10840,7 +16940,7 @@ index c6e048adb20..8a89dcabd5e 100644 msl_print_indent(gen->buffer, 2); vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix); -@@ -2037,6 +2171,14 @@ static void msl_generate_entrypoint(struct msl_generator *gen) +@@ -2037,6 +2056,14 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix); if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) vkd3d_string_buffer_printf(gen->buffer, " vkd3d_scalar o_mask;\n"); @@ -10855,7 +16955,7 @@ index c6e048adb20..8a89dcabd5e 100644 vkd3d_string_buffer_printf(gen->buffer, "\n"); msl_generate_entrypoint_prologue(gen); -@@ -2048,13 +2190,23 @@ static void msl_generate_entrypoint(struct msl_generator *gen) +@@ -2048,13 +2075,23 @@ static void msl_generate_entrypoint(struct msl_generator *gen) 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"); @@ -10880,7 +16980,7 @@ index c6e048adb20..8a89dcabd5e 100644 } static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out) -@@ -2119,6 +2271,14 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader +@@ -2119,6 +2156,14 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader 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"); @@ -10895,6 +16995,14 @@ index c6e048adb20..8a89dcabd5e 100644 if (gen->program->descriptors.descriptor_count) vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors"); vkd3d_string_buffer_printf(gen->buffer, ")\n{\n"); +@@ -2201,6 +2246,7 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, + + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); ++ VKD3D_ASSERT(program->has_no_modifiers); + + if ((ret = msl_generator_init(&generator, program, compile_info, message_context)) < 0) + return ret; diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l index a8c0db358bc..f9b1d67ac36 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.l @@ -10935,55 +17043,131 @@ index a8c0db358bc..f9b1d67ac36 100644 fail: diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 97c0d0e73a8..9c5f71ee11f 100644 +index 97c0d0e73a8..3950021a2ef 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -2518,7 +2518,7 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build +@@ -989,7 +989,7 @@ struct vkd3d_spirv_builder + uint32_t type_bool_id; + uint32_t type_void_id; + uint32_t scope_subgroup_id; +- uint32_t numeric_type_ids[VKD3D_SHADER_COMPONENT_TYPE_COUNT][VKD3D_VEC4_SIZE]; ++ uint32_t numeric_type_ids[VSIR_DATA_TYPE_COUNT][VKD3D_VEC4_SIZE]; + + struct vkd3d_spirv_stream debug_stream; /* debug instructions */ + struct vkd3d_spirv_stream annotation_stream; /* decoration instructions */ +@@ -2116,20 +2116,6 @@ static uint32_t vkd3d_spirv_build_op_fdiv(struct vkd3d_spirv_builder *builder, + SpvOpFDiv, result_type, operand0, operand1); + } + +-static uint32_t vkd3d_spirv_build_op_fnegate(struct vkd3d_spirv_builder *builder, +- uint32_t result_type, uint32_t operand) +-{ +- return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, +- SpvOpFNegate, result_type, operand); +-} +- +-static uint32_t vkd3d_spirv_build_op_snegate(struct vkd3d_spirv_builder *builder, +- uint32_t result_type, uint32_t operand) +-{ +- return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, +- SpvOpSNegate, result_type, operand); +-} +- + static uint32_t vkd3d_spirv_build_op_and(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t operand0, uint32_t operand1) + { +@@ -2478,19 +2464,6 @@ static uint32_t vkd3d_spirv_build_op_group_nonuniform_broadcast_first(struct vkd + result_type, vkd3d_spirv_get_op_scope_subgroup(builder), val_id); + } + +-static uint32_t vkd3d_spirv_build_op_glsl_std450_tr1(struct vkd3d_spirv_builder *builder, +- enum GLSLstd450 op, uint32_t result_type, uint32_t operand) +-{ +- uint32_t id = vkd3d_spirv_get_glsl_std450_instr_set(builder); +- return vkd3d_spirv_build_op_ext_inst(builder, result_type, id, op, &operand, 1); +-} +- +-static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder *builder, +- uint32_t result_type, uint32_t operand) +-{ +- return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450FAbs, 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) + { +@@ -2518,70 +2491,6 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build GLSLstd450NClamp, operands, ARRAY_SIZE(operands)); } -static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, -+static uint32_t spirv_get_type_id_for_component_type(struct vkd3d_spirv_builder *builder, - enum vkd3d_shader_component_type component_type, unsigned int component_count) - { - uint32_t scalar_id, type_id; -@@ -2553,8 +2553,9 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, - case VKD3D_SHADER_COMPONENT_DOUBLE: - type_id = vkd3d_spirv_get_op_type_float(builder, 64); - break; -+ case VKD3D_SHADER_COMPONENT_INT64: - case VKD3D_SHADER_COMPONENT_UINT64: +- enum vkd3d_shader_component_type component_type, unsigned int component_count) +-{ +- uint32_t scalar_id, type_id; +- +- VKD3D_ASSERT(component_type < VKD3D_SHADER_COMPONENT_TYPE_COUNT); +- if (!component_count || component_count > VKD3D_VEC4_SIZE) +- { +- ERR("Invalid component count %u.\n", component_count); +- return 0; +- } +- +- if ((type_id = builder->numeric_type_ids[component_type][component_count - 1])) +- return type_id; +- +- if (component_count == 1) +- { +- switch (component_type) +- { +- case VKD3D_SHADER_COMPONENT_VOID: +- type_id = vkd3d_spirv_get_op_type_void(builder); +- break; +- case VKD3D_SHADER_COMPONENT_FLOAT: +- type_id = vkd3d_spirv_get_op_type_float(builder, 32); +- break; +- case VKD3D_SHADER_COMPONENT_INT: +- case VKD3D_SHADER_COMPONENT_UINT: +- type_id = vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT); +- break; +- case VKD3D_SHADER_COMPONENT_BOOL: +- type_id = vkd3d_spirv_get_op_type_bool(builder); +- break; +- case VKD3D_SHADER_COMPONENT_DOUBLE: +- type_id = vkd3d_spirv_get_op_type_float(builder, 64); +- break; +- case VKD3D_SHADER_COMPONENT_UINT64: - type_id = vkd3d_spirv_get_op_type_int(builder, 64, 0); -+ type_id = vkd3d_spirv_get_op_type_int(builder, 64, component_type == VKD3D_SHADER_COMPONENT_INT64); - break; - default: - FIXME("Unhandled component type %#x.\n", component_type); -@@ -2564,7 +2565,7 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, - else - { - VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID); +- break; +- default: +- FIXME("Unhandled component type %#x.\n", component_type); +- return 0; +- } +- } +- else +- { +- VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID); - scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ scalar_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); - } - -@@ -2573,13 +2574,13 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, - return type_id; - } - +- type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); +- } +- +- builder->numeric_type_ids[component_type][component_count - 1] = type_id; +- +- return type_id; +-} +- -static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, -+static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, - enum vsir_data_type data_type, unsigned int component_count) - { - enum vkd3d_shader_component_type component_type; - - component_type = vkd3d_component_type_from_data_type(data_type); +- enum vsir_data_type data_type, unsigned int component_count) +-{ +- enum vkd3d_shader_component_type component_type; +- +- component_type = vkd3d_component_type_from_data_type(data_type); - return vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ return spirv_get_type_id_for_component_type(builder, component_type, component_count); - } - +-} +- static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, -@@ -2794,7 +2795,7 @@ struct vkd3d_symbol_register_data + const char *entry_point, const char *source_name) + { +@@ -2794,7 +2703,7 @@ struct vkd3d_symbol_register_data { SpvStorageClass storage_class; uint32_t member_idx; @@ -10992,7 +17176,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 unsigned int write_mask; unsigned int structure_stride; unsigned int binding_base_idx; -@@ -2804,7 +2805,7 @@ struct vkd3d_symbol_register_data +@@ -2804,7 +2713,7 @@ struct vkd3d_symbol_register_data struct vkd3d_symbol_resource_data { struct vkd3d_shader_register_range range; @@ -11001,7 +17185,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 uint32_t type_id; const struct vkd3d_spirv_resource_type *resource_type_info; unsigned int structure_stride; -@@ -2919,15 +2920,14 @@ static void vkd3d_symbol_make_io(struct vkd3d_symbol *symbol, +@@ -2919,15 +2828,14 @@ static void vkd3d_symbol_make_io(struct vkd3d_symbol *symbol, symbol->key.reg.idx = index; } @@ -11020,7 +17204,16 @@ index 97c0d0e73a8..9c5f71ee11f 100644 symbol->info.reg.write_mask = write_mask; symbol->info.reg.structure_stride = 0; symbol->info.reg.binding_base_idx = 0; -@@ -3253,6 +3253,14 @@ static struct spirv_compiler *spirv_compiler_create(struct vsir_program *program +@@ -3063,7 +2971,7 @@ struct spirv_compiler + struct vkd3d_shader_output_info + { + uint32_t id; +- enum vkd3d_shader_component_type component_type; ++ enum vsir_data_type data_type; + uint32_t array_element_mask; + } *output_info; + uint32_t private_output_variable[MAX_REG_OUTPUT + 1]; /* 1 entry for oDepth */ +@@ -3253,6 +3161,14 @@ static struct spirv_compiler *spirv_compiler_create(struct vsir_program *program compiler->features = option->value; break; @@ -11035,7 +17228,82 @@ index 97c0d0e73a8..9c5f71ee11f 100644 default: WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value); break; -@@ -3649,122 +3657,128 @@ static const struct vkd3d_symbol *spirv_compiler_put_symbol(struct spirv_compile +@@ -3491,6 +3407,74 @@ static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spi + return buffer; + } + ++static uint32_t spirv_get_type_id(struct spirv_compiler *compiler, ++ enum vsir_data_type data_type, unsigned int component_count) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t scalar_id, type_id; ++ ++ VKD3D_ASSERT(data_type < VSIR_DATA_TYPE_COUNT); ++ if (!component_count || component_count > VKD3D_VEC4_SIZE) ++ { ++ ERR("Invalid component count %u.\n", component_count); ++ return 0; ++ } ++ ++ if ((type_id = builder->numeric_type_ids[data_type][component_count - 1])) ++ return type_id; ++ ++ if (component_count == 1) ++ { ++ switch (data_type) ++ { ++ case VSIR_DATA_BOOL: ++ type_id = vkd3d_spirv_get_op_type_bool(builder); ++ break; ++ ++ case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: ++ type_id = vkd3d_spirv_get_op_type_float(builder, 32); ++ break; ++ ++ case VSIR_DATA_F64: ++ type_id = vkd3d_spirv_get_op_type_float(builder, 64); ++ break; ++ ++ case VSIR_DATA_I32: ++ case VSIR_DATA_U32: ++ case VSIR_DATA_MIXED: ++ type_id = vkd3d_spirv_get_op_type_int(builder, 32, data_type == VSIR_DATA_I32); ++ break; ++ ++ case VSIR_DATA_I64: ++ case VSIR_DATA_U64: ++ type_id = vkd3d_spirv_get_op_type_int(builder, 64, data_type == VSIR_DATA_I64); ++ break; ++ ++ case VSIR_DATA_UNUSED: ++ type_id = vkd3d_spirv_get_op_type_void(builder); ++ break; ++ ++ default: ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, ++ "Unhandled data type \"%s\" (%#x).", ++ vsir_data_type_get_name(data_type, ""), data_type); ++ return 0; ++ } ++ } ++ else ++ { ++ VKD3D_ASSERT(data_type != VSIR_DATA_UNUSED); ++ scalar_id = spirv_get_type_id(compiler, data_type, 1); ++ type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); ++ } ++ ++ builder->numeric_type_ids[data_type][component_count - 1] = type_id; ++ ++ return type_id; ++} ++ + static uint32_t spirv_compiler_get_label_id(struct spirv_compiler *compiler, unsigned int block_id) + { + --block_id; +@@ -3649,132 +3633,134 @@ static const struct vkd3d_symbol *spirv_compiler_put_symbol(struct spirv_compile } static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, @@ -11048,7 +17316,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_VEC4_SIZE); - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id(builder, data_type, component_count); ++ type_id = spirv_get_type_id(compiler, data_type, component_count); - switch (component_type) + switch (data_type) @@ -11089,7 +17357,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - } - else + -+ scalar_type_id = spirv_get_type_id(builder, data_type, 1); ++ scalar_type_id = spirv_get_type_id(compiler, data_type, 1); + for (i = 0; i < component_count; ++i) { - scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); @@ -11112,7 +17380,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_DVEC2_SIZE); - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id(builder, data_type, component_count); ++ type_id = spirv_get_type_id(compiler, data_type, component_count); - if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_UINT64) + if (data_type != VSIR_DATA_F64 && data_type != VSIR_DATA_I64 && data_type != VSIR_DATA_U64) @@ -11130,7 +17398,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - } - else + -+ scalar_type_id = spirv_get_type_id(builder, data_type, 1); ++ scalar_type_id = spirv_get_type_id(compiler, data_type, 1); + for (i = 0; i < component_count; ++i) { - scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); @@ -11206,47 +17474,80 @@ index 97c0d0e73a8..9c5f71ee11f 100644 } static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compiler, -@@ -3772,9 +3786,7 @@ static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compil + const struct vkd3d_shader_register *reg, uint32_t write_mask) { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- - return vkd3d_spirv_get_type_id(builder, - vkd3d_component_type_from_data_type(reg->data_type), - vsir_write_mask_component_count(write_mask)); -+ return spirv_get_type_id(builder, reg->data_type, vsir_write_mask_component_count(write_mask)); ++ return spirv_get_type_id(compiler, reg->data_type, vsir_write_mask_component_count(write_mask)); } static uint32_t spirv_compiler_get_type_id_for_dst(struct spirv_compiler *compiler, -@@ -3901,7 +3913,7 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil +@@ -3893,15 +3879,14 @@ static void spirv_compiler_emit_register_debug_name(struct vkd3d_spirv_builder * + } + + static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compiler, +- struct vkd3d_spirv_stream *stream, SpvStorageClass storage_class, +- enum vkd3d_shader_component_type component_type, unsigned int component_count, +- const unsigned int *array_lengths, unsigned int length_count) ++ struct vkd3d_spirv_stream *stream, SpvStorageClass storage_class, enum vsir_data_type data_type, ++ unsigned int component_count, const unsigned int *array_lengths, unsigned int length_count) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, length_id, ptr_type_id; unsigned int i; - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); ++ type_id = spirv_get_type_id(compiler, data_type, component_count); for (i = 0; i < length_count; ++i) { if (!array_lengths[i]) -@@ -4000,8 +4012,8 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile +@@ -3909,17 +3894,16 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil + length_id = spirv_compiler_get_constant_uint(compiler, array_lengths[i]); + type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); + } +- + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); ++ + return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0); + } + +-static uint32_t spirv_compiler_emit_variable(struct spirv_compiler *compiler, +- struct vkd3d_spirv_stream *stream, SpvStorageClass storage_class, +- enum vkd3d_shader_component_type component_type, unsigned int component_count) ++static uint32_t spirv_compiler_emit_variable(struct spirv_compiler *compiler, struct vkd3d_spirv_stream *stream, ++ SpvStorageClass storage_class, enum vsir_data_type data_type, unsigned int component_count) + { +- return spirv_compiler_emit_array_variable(compiler, stream, storage_class, +- component_type, component_count, NULL, 0); ++ return spirv_compiler_emit_array_variable(compiler, stream, ++ storage_class, data_type, component_count, NULL, 0); + } + + static const struct vkd3d_spec_constant_info +@@ -4000,8 +3984,8 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile info = get_spec_constant_info(name); default_value = info ? info->default_value.u : 0; - scalar_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1); - vector_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count); -+ scalar_type_id = spirv_get_type_id(builder, type, 1); -+ vector_type_id = spirv_get_type_id(builder, type, component_count); ++ scalar_type_id = spirv_get_type_id(compiler, type, 1); ++ vector_type_id = spirv_get_type_id(compiler, type, component_count); for (unsigned int i = 0; i < component_count; ++i) { -@@ -4050,7 +4062,7 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi +@@ -4050,7 +4034,7 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi unsigned int index = parameter - compiler->program->parameters; uint32_t type_id, ptr_id, ptr_type_id; - type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count); -+ type_id = spirv_get_type_id(builder, type, component_count); ++ type_id = spirv_get_type_id(compiler, type, component_count); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, compiler->spirv_parameter_info[index].buffer_id, -@@ -4087,8 +4099,8 @@ static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *comp +@@ -4087,8 +4071,8 @@ static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *comp type, component_count, name, parameter->data_type); if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) @@ -11257,7 +17558,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT) return spirv_compiler_get_spec_constant(compiler, name, -@@ -4104,32 +4116,32 @@ default_parameter: +@@ -4104,32 +4088,32 @@ default_parameter: } static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *compiler, @@ -11275,7 +17576,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 VKD3D_ASSERT(val_component_idx < val_component_count); - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id(builder, data_type, component_count); ++ type_id = spirv_get_type_id(compiler, data_type, component_count); if (val_component_count == 1) { for (i = 0; i < component_count; ++i) @@ -11302,14 +17603,14 @@ index 97c0d0e73a8..9c5f71ee11f 100644 } static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, -@@ -4147,10 +4159,11 @@ static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *c +@@ -4147,10 +4131,11 @@ static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *c addr_id = spirv_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); if (reg_index->offset) { - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, - addr_id, spirv_compiler_get_constant_uint(compiler, reg_index->offset)); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); + addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, addr_id, + spirv_compiler_get_constant_uint(compiler, reg_index->offset)); } @@ -11317,7 +17618,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 return addr_id; } -@@ -4159,7 +4172,7 @@ struct vkd3d_shader_register_info +@@ -4159,7 +4144,7 @@ struct vkd3d_shader_register_info uint32_t id; const struct vkd3d_symbol *descriptor_array; SpvStorageClass storage_class; @@ -11326,7 +17627,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 unsigned int write_mask; uint32_t member_idx; unsigned int structure_stride; -@@ -4182,7 +4195,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, +@@ -4182,7 +4167,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, register_info->storage_class = SpvStorageClassPrivate; register_info->descriptor_array = NULL; register_info->member_idx = 0; @@ -11335,7 +17636,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 register_info->write_mask = VKD3DSP_WRITEMASK_ALL; register_info->structure_stride = 0; register_info->binding_base_idx = 0; -@@ -4203,7 +4216,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, +@@ -4203,7 +4188,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, memset(register_info, 0, sizeof(*register_info)); register_info->id = ssa->id; register_info->storage_class = SpvStorageClassMax; @@ -11344,7 +17645,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 register_info->write_mask = ssa->write_mask; return true; } -@@ -4222,7 +4235,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, +@@ -4222,7 +4207,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, register_info->descriptor_array = symbol->descriptor_array; register_info->storage_class = symbol->info.reg.storage_class; register_info->member_idx = symbol->info.reg.member_idx; @@ -11353,48 +17654,92 @@ index 97c0d0e73a8..9c5f71ee11f 100644 register_info->write_mask = symbol->info.reg.write_mask; register_info->structure_stride = symbol->info.reg.structure_stride; register_info->binding_base_idx = symbol->info.reg.binding_base_idx; -@@ -4296,7 +4309,7 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi +@@ -4296,7 +4281,7 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, ptr_type_id, ptr_id, offset_id, index_ids[2]; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); if (!(offset_id = compiler->descriptor_offset_ids[push_constant_index])) { index_ids[0] = compiler->descriptor_offsets_member_id; -@@ -4369,7 +4382,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp +@@ -4369,7 +4354,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp if (index_count) { component_count = vsir_write_mask_component_count(register_info->write_mask); - type_id = vkd3d_spirv_get_type_id(builder, register_info->component_type, component_count); -+ type_id = spirv_get_type_id(builder, register_info->data_type, component_count); ++ type_id = spirv_get_type_id(compiler, register_info->data_type, component_count); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id); register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, register_info->id, indexes, index_count); -@@ -4428,7 +4441,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, +@@ -4391,7 +4376,7 @@ static uint32_t spirv_compiler_get_register_id(struct spirv_compiler *compiler, + } + + return spirv_compiler_emit_variable(compiler, &builder->global_stream, +- SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); ++ SpvStorageClassPrivate, VSIR_DATA_F32, VKD3D_VEC4_SIZE); + } + + static bool vkd3d_swizzle_is_equal(uint32_t dst_write_mask, uint32_t swizzle, uint32_t write_mask) +@@ -4413,9 +4398,8 @@ static bool vkd3d_swizzle_is_scalar(uint32_t swizzle, const struct vkd3d_shader_ + && vsir_swizzle_get_component(swizzle, 3) == component_idx; + } + +-static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, +- uint32_t val_id, uint32_t val_write_mask, enum vkd3d_shader_component_type component_type, +- uint32_t swizzle, uint32_t write_mask) ++static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, uint32_t val_id, ++ uint32_t val_write_mask, enum vsir_data_type data_type, uint32_t swizzle, uint32_t write_mask) + { + unsigned int i, component_idx, component_count, val_component_count; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +@@ -4428,7 +4412,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, && (component_count == 1 || vkd3d_swizzle_is_equal(val_write_mask, swizzle, write_mask))) return val_id; - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); ++ type_id = spirv_get_type_id(compiler, data_type, component_count); if (component_count == 1) { -@@ -4479,7 +4492,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil +@@ -4456,13 +4440,14 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, + if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) + components[component_idx++] = vsir_swizzle_get_component(swizzle, i); + } +- return vkd3d_spirv_build_op_vector_shuffle(builder, +- type_id, val_id, val_id, components, component_count); ++ ++ return vkd3d_spirv_build_op_vector_shuffle(builder, type_id, ++ val_id, val_id, components, component_count); + } + + static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compiler, + uint32_t vector1_id, uint32_t vector2_id, uint32_t swizzle, uint32_t write_mask, +- enum vkd3d_shader_component_type component_type, unsigned int component_count) ++ enum vsir_data_type data_type, unsigned int component_count) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t components[VKD3D_VEC4_SIZE]; +@@ -4478,10 +4463,10 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil + else components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle, i); } ++ type_id = spirv_get_type_id(compiler, data_type, component_count); - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - return vkd3d_spirv_build_op_vector_shuffle(builder, - type_id, vector1_id, vector2_id, components, component_count); +- return vkd3d_spirv_build_op_vector_shuffle(builder, +- type_id, vector1_id, vector2_id, components, component_count); ++ return vkd3d_spirv_build_op_vector_shuffle(builder, type_id, ++ vector1_id, vector2_id, components, component_count); } -@@ -4494,10 +4507,11 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, + + static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, +@@ -4494,10 +4479,11 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, VKD3D_ASSERT(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_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, @@ -11403,47 +17748,47 @@ index 97c0d0e73a8..9c5f71ee11f 100644 ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); } -@@ -4510,7 +4524,8 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, +@@ -4510,7 +4496,8 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } -@@ -4523,7 +4538,8 @@ static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compile +@@ -4523,7 +4510,8 @@ static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compile true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, component_count); false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U64, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U64, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } -@@ -4535,7 +4551,8 @@ static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compile +@@ -4535,7 +4523,8 @@ static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compile true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } -@@ -4547,7 +4564,8 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil +@@ -4547,7 +4536,8 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F64, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F64, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } -@@ -4574,8 +4592,7 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile +@@ -4574,8 +4564,7 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile } } @@ -11453,7 +17798,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 } static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compiler, -@@ -4601,8 +4618,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi +@@ -4601,8 +4590,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi } } @@ -11463,12 +17808,12 @@ index 97c0d0e73a8..9c5f71ee11f 100644 } static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, -@@ -4614,18 +4630,18 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, +@@ -4614,18 +4602,18 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, VKD3D_ASSERT(reg->type == VKD3DSPR_UNDEF); - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, reg->data_type, component_count); -+ type_id = spirv_get_type_id(builder, reg->data_type, component_count); ++ type_id = spirv_get_type_id(compiler, reg->data_type, component_count); + return vkd3d_spirv_get_op_undef(builder, type_id); } @@ -11486,7 +17831,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 uint32_t skipped_component_mask; VKD3D_ASSERT(!register_is_constant_or_undef(reg)); -@@ -4636,7 +4652,6 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, +@@ -4636,7 +4624,6 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, skipped_component_mask = ~reg_info->write_mask & ((VKD3DSP_WRITEMASK_0 << component_idx) - 1); if (skipped_component_mask) component_idx -= vsir_write_mask_component_count(skipped_component_mask); @@ -11494,16 +17839,16 @@ index 97c0d0e73a8..9c5f71ee11f 100644 reg_component_count = vsir_write_mask_component_count(reg_info->write_mask); -@@ -4646,7 +4661,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, +@@ -4646,7 +4633,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, component_idx, reg->type, reg->idx[0].offset, reg_info->write_mask); } - type_id = vkd3d_spirv_get_type_id(builder, reg_info->component_type, 1); -+ type_id = spirv_get_type_id(builder, reg_info->data_type, 1); ++ type_id = spirv_get_type_id(compiler, reg_info->data_type, 1); reg_id = reg_info->id; if (reg_component_count != 1) { -@@ -4656,27 +4671,22 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, +@@ -4656,27 +4643,22 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, } val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_id, SpvMemoryAccessMaskNone); @@ -11528,14 +17873,14 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } -+ type_id = spirv_get_type_id(builder, reg->data_type, 1); ++ type_id = spirv_get_type_id(compiler, reg->data_type, 1); + return vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); } - return val_id; + if (reg_info->data_type != VSIR_DATA_U32) + { -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } + @@ -11543,7 +17888,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 } static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compiler, -@@ -4684,14 +4694,12 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil +@@ -4684,14 +4666,12 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil { uint32_t *elements, elem_type_id, length_id, type_id, const_id; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -11555,11 +17900,11 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - component_type = vkd3d_component_type_from_data_type(icb->data_type); component_count = icb->component_count; - elem_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, icb->data_type, component_count); -+ elem_type_id = spirv_get_type_id(builder, icb->data_type, component_count); ++ elem_type_id = spirv_get_type_id(compiler, icb->data_type, component_count); length_id = spirv_compiler_get_constant_uint(compiler, element_count); type_id = vkd3d_spirv_get_op_type_array(builder, elem_type_id, length_id); -@@ -4706,7 +4714,6 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil +@@ -4706,7 +4686,6 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil if (!(elements = vkd3d_calloc(element_count, sizeof(*elements)))) { @@ -11567,7 +17912,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY, "Failed to allocate %u constant array elements.", element_count); return 0; -@@ -4718,22 +4725,27 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil +@@ -4718,22 +4697,27 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil case VSIR_DATA_I32: case VSIR_DATA_U32: for (i = 0; i < element_count; ++i) @@ -11601,7 +17946,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 break; } -@@ -4756,7 +4768,6 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, +@@ -4756,7 +4740,6 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -11609,8 +17954,19 @@ index 97c0d0e73a8..9c5f71ee11f 100644 struct vkd3d_shader_register_info reg_info; unsigned int component_count; uint32_t type_id, val_id; -@@ -4773,16 +4784,15 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, +@@ -4769,20 +4752,25 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, + else if (reg->type == VKD3DSPR_UNDEF) + return spirv_compiler_emit_load_undef(compiler, reg, write_mask); + else if (reg->type == VKD3DSPR_PARAMETER) +- return spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset, ++ { ++ val_id = spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset, reg->data_type, reg->dimension == VSIR_DIMENSION_VEC4 ? 4 : 1); ++ if (reg->dimension != VSIR_DIMENSION_VEC4) ++ return val_id; ++ return spirv_compiler_emit_swizzle(compiler, val_id, ++ VKD3DSP_WRITEMASK_ALL, reg->data_type, swizzle, write_mask); ++ } component_count = vsir_write_mask_component_count(write_mask); - component_type = vkd3d_component_type_from_data_type(reg->data_type); @@ -11618,7 +17974,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id(builder, reg->data_type, component_count); ++ type_id = spirv_get_type_id(compiler, reg->data_type, component_count); return vkd3d_spirv_get_op_undef(builder, type_id); } spirv_compiler_emit_dereference_register(compiler, reg, ®_info); @@ -11628,13 +17984,13 @@ index 97c0d0e73a8..9c5f71ee11f 100644 ? vsir_write_mask_32_from_64(write_mask) : write_mask; /* Intermediate value (no storage class). */ -@@ -4796,35 +4806,31 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, +@@ -4796,35 +4784,31 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, } else { - type_id = vkd3d_spirv_get_type_id(builder, - reg_info.component_type, vsir_write_mask_component_count(reg_info.write_mask)); -+ type_id = spirv_get_type_id(builder, reg_info.data_type, ++ type_id = spirv_get_type_id(compiler, reg_info.data_type, + vsir_write_mask_component_count(reg_info.write_mask)); val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone); swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle; @@ -11642,8 +17998,8 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - val_id = spirv_compiler_emit_swizzle(compiler, - val_id, reg_info.write_mask, reg_info.component_type, swizzle, val_write_mask); -+ val_id = spirv_compiler_emit_swizzle(compiler, val_id, reg_info.write_mask, -+ vkd3d_component_type_from_data_type(reg_info.data_type), swizzle, val_write_mask); ++ val_id = spirv_compiler_emit_swizzle(compiler, val_id, ++ reg_info.write_mask, reg_info.data_type, swizzle, val_write_mask); + if (reg->data_type == reg_info.data_type) + return val_id; @@ -11665,14 +18021,14 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } -+ type_id = spirv_get_type_id(builder, reg->data_type, component_count); ++ type_id = spirv_get_type_id(compiler, reg->data_type, component_count); + return vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); } - return val_id; + if (reg_info.data_type != VSIR_DATA_U32) + { -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, component_count); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } + @@ -11681,34 +18037,140 @@ index 97c0d0e73a8..9c5f71ee11f 100644 } static void spirv_compiler_emit_execution_mode(struct spirv_compiler *compiler, -@@ -4923,7 +4929,7 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, +@@ -4842,79 +4826,24 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler, + spirv_compiler_emit_execution_mode(compiler, mode, &literal, 1); + } + +-static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler, +- const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id; +- +- type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); +- if (data_type_is_floating_point(reg->data_type)) +- return vkd3d_spirv_build_op_glsl_std450_fabs(builder, type_id, val_id); +- +- FIXME("Unhandled data type %#x.\n", reg->data_type); +- return val_id; +-} +- +-static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, +- const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id; +- +- type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); +- if (data_type_is_floating_point(reg->data_type)) +- return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id); +- else if (data_type_is_integer(reg->data_type)) +- return vkd3d_spirv_build_op_snegate(builder, type_id, val_id); +- +- FIXME("Unhandled data type %#x.\n", reg->data_type); +- return val_id; +-} +- +-static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler, +- const struct vkd3d_shader_register *reg, uint32_t write_mask, +- enum vkd3d_shader_src_modifier modifier, uint32_t val_id) +-{ +- switch (modifier) +- { +- case VKD3DSPSM_NONE: +- break; +- case VKD3DSPSM_NEG: +- return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); +- case VKD3DSPSM_ABS: +- return spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); +- case VKD3DSPSM_ABSNEG: +- val_id = spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); +- return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); +- default: +- FIXME("Unhandled src modifier %#x.\n", modifier); +- break; +- } +- +- return val_id; +-} +- + static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, + const struct vkd3d_shader_src_param *src, uint32_t write_mask) + { +- uint32_t val_id; +- +- val_id = spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); +- return spirv_compiler_emit_src_modifier(compiler, &src->reg, write_mask, src->modifiers, val_id); ++ return spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); + } + + static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *compiler, +- const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vkd3d_shader_component_type component_type) ++ const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vsir_data_type data_type) + { + struct vkd3d_shader_src_param src_param = *src; + +- src_param.reg.data_type = vsir_data_type_from_component_type(component_type); ++ src_param.reg.data_type = data_type; ++ + return spirv_compiler_emit_load_src(compiler, &src_param, write_mask); + } + + static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, +- uint32_t dst_id, uint32_t dst_write_mask, enum vkd3d_shader_component_type component_type, ++ uint32_t dst_id, uint32_t dst_write_mask, enum vsir_data_type data_type, + SpvStorageClass storage_class, uint32_t write_mask, uint32_t val_id) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +@@ -4923,7 +4852,7 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, if (vsir_write_mask_component_count(dst_write_mask) > 1) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); ++ type_id = spirv_get_type_id(compiler, data_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); component_idx = vsir_write_mask_get_component_idx(write_mask); component_idx -= vsir_write_mask_get_component_idx(dst_write_mask); -@@ -4951,7 +4957,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, +@@ -4934,9 +4863,8 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, + vkd3d_spirv_build_op_store(builder, dst_id, val_id, SpvMemoryAccessMaskNone); + } + +-static void spirv_compiler_emit_store(struct spirv_compiler *compiler, +- uint32_t dst_id, uint32_t dst_write_mask, enum vkd3d_shader_component_type component_type, +- SpvStorageClass storage_class, uint32_t write_mask, uint32_t val_id) ++static void spirv_compiler_emit_store(struct spirv_compiler *compiler, uint32_t dst_id, uint32_t dst_write_mask, ++ enum vsir_data_type data_type, SpvStorageClass storage_class, uint32_t write_mask, uint32_t val_id) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + unsigned int component_count, dst_component_count; +@@ -4951,7 +4879,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, if (dst_component_count == 1 && component_count != 1) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); ++ type_id = spirv_get_type_id(compiler, data_type, 1); val_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, vsir_write_mask_get_component_idx(dst_write_mask)); write_mask &= dst_write_mask; -@@ -4966,7 +4972,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, +@@ -4959,14 +4887,12 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, + } + + if (component_count == 1) +- { +- return spirv_compiler_emit_store_scalar(compiler, +- dst_id, dst_write_mask, component_type, storage_class, write_mask, val_id); +- } ++ return spirv_compiler_emit_store_scalar(compiler, dst_id, ++ dst_write_mask, data_type, storage_class, write_mask, val_id); if (dst_component_count != component_count) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, dst_component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, dst_component_count); ++ type_id = spirv_get_type_id(compiler, data_type, dst_component_count); dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); VKD3D_ASSERT(component_count <= ARRAY_SIZE(components)); -@@ -4993,9 +4999,9 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, +@@ -4993,9 +4919,9 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -11719,7 +18181,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 uint32_t type_id; VKD3D_ASSERT(!register_is_constant_or_undef(reg)); -@@ -5010,22 +5016,22 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, +@@ -5010,22 +4936,22 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, return; spirv_compiler_emit_dereference_register(compiler, reg, ®_info); @@ -11736,7 +18198,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 val_id = spirv_compiler_emit_bool_to_int(compiler, vsir_write_mask_component_count(src_write_mask), val_id, false); - type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, -+ type_id = spirv_get_type_id(builder, reg_info.data_type, ++ type_id = spirv_get_type_id(compiler, reg_info.data_type, vsir_write_mask_component_count(src_write_mask)); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - component_type = reg_info.component_type; @@ -11746,41 +18208,140 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - spirv_compiler_emit_store(compiler, - reg_info.id, reg_info.write_mask, component_type, reg_info.storage_class, src_write_mask, val_id); + spirv_compiler_emit_store(compiler, reg_info.id, reg_info.write_mask, -+ vkd3d_component_type_from_data_type(data_type), reg_info.storage_class, src_write_mask, val_id); ++ data_type, reg_info.storage_class, src_write_mask, val_id); } static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, -@@ -5101,7 +5107,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp +@@ -5057,62 +4983,36 @@ static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, + static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler, + const struct vkd3d_shader_dst_param *dst, uint32_t val_id) + { +- uint32_t modifiers = dst->modifiers; +- +- /* It is always legitimate to ignore _pp. */ +- modifiers &= ~VKD3DSPDM_PARTIALPRECISION; +- +- if (modifiers & VKD3DSPDM_SATURATE) +- { +- val_id = spirv_compiler_emit_sat(compiler, &dst->reg, dst->write_mask, val_id); +- modifiers &= ~VKD3DSPDM_SATURATE; +- } +- +- if (dst->modifiers & VKD3DSPDM_MSAMPCENTROID) +- { +- FIXME("Ignoring _centroid modifier.\n"); +- modifiers &= ~VKD3DSPDM_MSAMPCENTROID; +- } +- +- VKD3D_ASSERT(!modifiers); +- + spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, val_id); + } + + static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compiler, +- const struct vkd3d_shader_dst_param *dst, uint32_t val_id, +- enum vkd3d_shader_component_type component_type, uint32_t swizzle) ++ const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vsir_data_type data_type, uint32_t swizzle) + { + struct vkd3d_shader_dst_param typed_dst = *dst; +- val_id = spirv_compiler_emit_swizzle(compiler, +- val_id, VKD3DSP_WRITEMASK_ALL, component_type, swizzle, dst->write_mask); ++ ++ val_id = spirv_compiler_emit_swizzle(compiler, val_id, ++ VKD3DSP_WRITEMASK_ALL, data_type, swizzle, dst->write_mask); + /* 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 = vsir_data_type_from_component_type(component_type); ++ * shaders the data types are stored in instructions modifiers. */ ++ typed_dst.reg.data_type = data_type; + spirv_compiler_emit_store_dst(compiler, &typed_dst, val_id); + } + + static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *compiler, +- const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_component_type component_type, +- uint32_t *component_ids) ++ const struct vkd3d_shader_dst_param *dst, enum vsir_data_type data_type, uint32_t *component_ids) + { + unsigned int component_count = vsir_write_mask_component_count(dst->write_mask); struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, dst_type_id, val_id; - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); ++ type_id = spirv_get_type_id(compiler, data_type, component_count); if (component_count > 1) - { - val_id = vkd3d_spirv_build_op_composite_construct(builder, -@@ -5112,7 +5118,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp +- { +- val_id = vkd3d_spirv_build_op_composite_construct(builder, +- type_id, component_ids, component_count); +- } ++ val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, component_ids, component_count); + else +- { val_id = *component_ids; - } +- } - dst_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count); -+ dst_type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); ++ dst_type_id = spirv_get_type_id(compiler, dst->reg.data_type, component_count); if (dst_type_id != type_id) val_id = vkd3d_spirv_build_op_bitcast(builder, dst_type_id, val_id); -@@ -5281,9 +5287,8 @@ static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler * +@@ -5120,8 +5020,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp + } + + static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler, +- const struct vkd3d_shader_dst_param *dst, uint32_t val_id, +- enum vkd3d_shader_component_type component_type, uint32_t swizzle) ++ const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vsir_data_type data_type, uint32_t swizzle) + { + unsigned int component_count = vsir_write_mask_component_count(dst->write_mask); + uint32_t component_ids[VKD3D_VEC4_SIZE]; +@@ -5135,7 +5034,7 @@ static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler + + component_ids[i] = val_id; + } +- spirv_compiler_emit_store_dst_components(compiler, dst, component_type, component_ids); ++ spirv_compiler_emit_store_dst_components(compiler, dst, data_type, component_ids); + } + + static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, +@@ -5227,7 +5126,7 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, + } + + static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler *compiler, +- enum vkd3d_shader_component_type component_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode) ++ enum vsir_data_type data_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + +@@ -5236,7 +5135,7 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler + case VKD3DSIM_NONE: + /* VUID-StandaloneSpirv-Flat-04744: integer or double types must be + * decorated 'Flat' for fragment shaders. */ +- if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || component_type == VKD3D_SHADER_COMPONENT_FLOAT) ++ if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || data_type == VSIR_DATA_F32) + break; + /* fall through */ + case VKD3DSIM_CONSTANT: +@@ -5276,14 +5175,13 @@ static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler * + + vkd3d_spirv_enable_capability(builder, SpvCapabilityDrawParameters); + +- base_var_id = spirv_compiler_emit_variable(compiler, &builder->global_stream, +- SpvStorageClassInput, VKD3D_SHADER_COMPONENT_INT, 1); ++ base_var_id = spirv_compiler_emit_variable(compiler, ++ &builder->global_stream, SpvStorageClassInput, VSIR_DATA_I32, 1); vkd3d_spirv_add_iface_variable(builder, base_var_id); spirv_compiler_decorate_builtin(compiler, base_var_id, base); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); - base_id = vkd3d_spirv_build_op_load(builder, - type_id, base_var_id, SpvMemoryAccessMaskNone); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_I32, 1); + base_id = vkd3d_spirv_build_op_load(builder, type_id, base_var_id, SpvMemoryAccessMaskNone); return vkd3d_spirv_build_op_isub(builder, type_id, index_id, base_id); } -@@ -5311,23 +5316,22 @@ static uint32_t sv_front_face_fixup(struct spirv_compiler *compiler, +@@ -5311,23 +5209,22 @@ static uint32_t sv_front_face_fixup(struct spirv_compiler *compiler, } /* frag_coord.w = 1.0f / frag_coord.w */ @@ -11792,13 +18353,13 @@ index 97c0d0e73a8..9c5f71ee11f 100644 uint32_t type_id, w_id; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 1); w_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, frag_coord_id, 3); - w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, - spirv_compiler_get_constant_float(compiler, 1.0f), w_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); + w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, spirv_compiler_get_constant_float(compiler, 1.0f), w_id); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, VKD3D_VEC4_SIZE); + return vkd3d_spirv_build_op_composite_insert1(builder, type_id, w_id, frag_coord_id, 3); } @@ -11810,7 +18371,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 unsigned int component_count; SpvBuiltIn spirv_builtin; vkd3d_spirv_builtin_fixup_pfn fixup_pfn; -@@ -5347,43 +5351,43 @@ static const struct +@@ -5347,43 +5244,43 @@ static const struct } vkd3d_system_value_builtins[] = { @@ -11874,7 +18435,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 }; static const struct { -@@ -5393,31 +5397,31 @@ static const struct +@@ -5393,31 +5290,31 @@ static const struct } vkd3d_register_builtins[] = { @@ -11923,22 +18484,22 @@ index 97c0d0e73a8..9c5f71ee11f 100644 }; static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *compiler, -@@ -5527,7 +5531,8 @@ static uint32_t spirv_compiler_emit_load_invocation_id(struct spirv_compiler *co +@@ -5527,7 +5424,8 @@ static uint32_t spirv_compiler_emit_load_invocation_id(struct spirv_compiler *co uint32_t type_id, id; id = spirv_compiler_get_invocation_id(compiler); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_I32, 1); + return vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); } -@@ -5641,13 +5646,12 @@ static uint32_t spirv_compiler_emit_builtin_variable_v(struct spirv_compiler *co +@@ -5641,13 +5539,12 @@ static uint32_t spirv_compiler_emit_builtin_variable_v(struct spirv_compiler *co sizes[0] = max(sizes[0], builtin->spirv_array_size); id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, - builtin->component_type, builtin->component_count, array_sizes, size_count); -+ vkd3d_component_type_from_data_type(builtin->data_type), builtin->component_count, array_sizes, size_count); ++ builtin->data_type, builtin->component_count, array_sizes, size_count); vkd3d_spirv_add_iface_variable(builder, id); spirv_compiler_decorate_builtin(compiler, id, builtin->spirv_builtin); @@ -11949,7 +18510,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationFlat, NULL, 0); return id; -@@ -5711,8 +5715,7 @@ static const struct vkd3d_symbol *spirv_compiler_emit_io_register(struct spirv_c +@@ -5711,8 +5608,7 @@ static const struct vkd3d_symbol *spirv_compiler_emit_io_register(struct spirv_c spirv_compiler_emit_register_debug_name(builder, id, reg); write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); @@ -11959,7 +18520,15 @@ index 97c0d0e73a8..9c5f71ee11f 100644 reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; return spirv_compiler_put_symbol(compiler, ®_symbol); -@@ -5733,6 +5736,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -5725,7 +5621,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + unsigned int component_idx, input_component_count; + 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; +@@ -5733,6 +5628,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, uint32_t val_id, input_id, var_id; uint32_t type_id, float_type_id; struct vkd3d_symbol reg_symbol; @@ -11967,23 +18536,47 @@ index 97c0d0e73a8..9c5f71ee11f 100644 SpvStorageClass storage_class; bool use_private_var = false; unsigned int array_sizes[2]; -@@ -5781,12 +5785,14 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -5781,12 +5677,12 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, if (builtin) { - component_type = builtin->component_type; + data_type = builtin->data_type; -+ component_type = vkd3d_component_type_from_data_type(data_type); input_component_count = builtin->component_count; } else { - component_type = signature_element->component_type; -+ data_type = vsir_data_type_from_component_type(component_type); +- component_type = signature_element->component_type; ++ data_type = vsir_data_type_from_component_type(signature_element->component_type); input_component_count = vsir_write_mask_component_count(signature_element->mask); } -@@ -5852,7 +5858,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -5828,7 +5724,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + unsigned int location = signature_element->target_location; + + input_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, +- storage_class, component_type, input_component_count, array_sizes, 2); ++ storage_class, data_type, input_component_count, array_sizes, 2); + vkd3d_spirv_add_iface_variable(builder, input_id); + if (reg_type == VKD3DSPR_PATCHCONST) + { +@@ -5839,8 +5735,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + if (component_idx) + vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); + +- spirv_compiler_emit_interpolation_decorations(compiler, component_type, input_id, +- signature_element->interpolation_mode); ++ spirv_compiler_emit_interpolation_decorations(compiler, data_type, ++ input_id, signature_element->interpolation_mode); + } + + var_id = input_id; +@@ -5848,11 +5744,11 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + { + storage_class = SpvStorageClassPrivate; + var_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, +- storage_class, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, array_sizes, 2); ++ storage_class, VSIR_DATA_F32, VKD3D_VEC4_SIZE, array_sizes, 2); } vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, @@ -11992,12 +18585,12 @@ index 97c0d0e73a8..9c5f71ee11f 100644 use_private_var ? VKD3DSP_WRITEMASK_ALL : reg_write_mask); reg_symbol.info.reg.is_aggregate = array_sizes[0] || array_sizes[1]; VKD3D_ASSERT(!builtin || !builtin->spirv_array_size || use_private_var || array_sizes[0] || array_sizes[1]); -@@ -5867,16 +5873,16 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -5867,22 +5763,22 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, 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); -+ type_id = spirv_get_type_id(builder, data_type, input_component_count); ++ type_id = spirv_get_type_id(compiler, data_type, input_component_count); val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone); @@ -12008,11 +18601,48 @@ index 97c0d0e73a8..9c5f71ee11f 100644 + if (data_type != VSIR_DATA_F32) { - float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, input_component_count); -+ float_type_id = spirv_get_type_id(builder, VSIR_DATA_F32, input_component_count); ++ float_type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, input_component_count); val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id); } -@@ -6024,13 +6030,14 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, +- vkd3d_write_mask_from_component_count(input_component_count), +- VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx); ++ vkd3d_write_mask_from_component_count(input_component_count), VSIR_DATA_F32, ++ VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx); + + spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask >> component_idx, val_id); + } +@@ -5917,7 +5813,7 @@ static void calculate_clip_or_cull_distance_mask(const struct signature_element + return; + } + +- write_mask = e->mask >> vsir_write_mask_get_component_idx(e->mask); ++ write_mask = e->mask; + *mask |= (write_mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); + } + +@@ -5973,13 +5869,13 @@ static void spirv_compiler_emit_shader_signature_outputs(struct spirv_compiler * + { + case VKD3D_SHADER_SV_CLIP_DISTANCE: + compiler->output_info[i].id = clip_distance_id; +- compiler->output_info[i].component_type = VKD3D_SHADER_COMPONENT_FLOAT; ++ compiler->output_info[i].data_type = VSIR_DATA_F32; + compiler->output_info[i].array_element_mask = clip_distance_mask; + break; + + case VKD3D_SHADER_SV_CULL_DISTANCE: + compiler->output_info[i].id = cull_distance_id; +- compiler->output_info[i].component_type = VKD3D_SHADER_COMPONENT_FLOAT; ++ compiler->output_info[i].data_type = VSIR_DATA_F32; + compiler->output_info[i].array_element_mask = cull_distance_mask; + break; + +@@ -6020,17 +5916,17 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + unsigned int component_idx, output_component_count; + const struct signature_element *signature_element; +- enum vkd3d_shader_component_type component_type; const struct shader_signature *shader_signature; const struct vkd3d_spirv_builtin *builtin; enum vkd3d_shader_sysval_semantic sysval; @@ -12028,24 +18658,55 @@ index 97c0d0e73a8..9c5f71ee11f 100644 is_patch_constant = (reg_type == VKD3DSPR_PATCHCONST); -@@ -6055,13 +6062,15 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, +@@ -6055,13 +5951,13 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, output_component_count = vsir_write_mask_component_count(write_mask); if (builtin) { - component_type = builtin->component_type; + data_type = builtin->data_type; -+ component_type = vkd3d_component_type_from_data_type(data_type); if (!builtin->spirv_array_size) output_component_count = builtin->component_count; } else { - component_type = signature_element->component_type; -+ data_type = vsir_data_type_from_component_type(component_type); +- component_type = signature_element->component_type; ++ data_type = vsir_data_type_from_component_type(signature_element->component_type); } storage_class = SpvStorageClassOutput; -@@ -6152,7 +6161,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, +@@ -6102,7 +5998,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + { + storage_class = SpvStorageClassPrivate; + id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, +- storage_class, component_type, output_component_count, array_sizes, 2); ++ storage_class, data_type, output_component_count, array_sizes, 2); + } + else + { +@@ -6115,7 +6011,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + location = signature_element->semantic_index; + + id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, +- storage_class, component_type, output_component_count, array_sizes, 2); ++ storage_class, data_type, output_component_count, array_sizes, 2); + vkd3d_spirv_add_iface_variable(builder, id); + + if (is_dual_source_blending(compiler) && location < 2) +@@ -6140,7 +6036,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + if (!is_patch_constant) + { + compiler->output_info[element_idx].id = id; +- compiler->output_info[element_idx].component_type = component_type; ++ compiler->output_info[element_idx].data_type = data_type; + } + + var_id = id; +@@ -6148,11 +6044,11 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + { + storage_class = SpvStorageClassPrivate; + var_id = spirv_compiler_emit_variable(compiler, &builder->global_stream, +- storage_class, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); ++ storage_class, VSIR_DATA_F32, VKD3D_VEC4_SIZE); } vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, @@ -12054,52 +18715,122 @@ index 97c0d0e73a8..9c5f71ee11f 100644 use_private_variable ? VKD3DSP_WRITEMASK_ALL : write_mask); reg_symbol.info.reg.is_aggregate = array_sizes[0] || array_sizes[1]; VKD3D_ASSERT(!builtin || !builtin->spirv_array_size || use_private_variable || array_sizes[0] || array_sizes[1]); -@@ -6225,7 +6234,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi +@@ -6164,7 +6060,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + if (use_private_variable) + { + compiler->private_output_variable[element_idx] = var_id; +- compiler->private_output_variable_write_mask[element_idx] |= write_mask >> component_idx; ++ compiler->private_output_variable_write_mask[element_idx] |= write_mask; + if (!compiler->epilogue_function_id) + compiler->epilogue_function_id = vkd3d_spirv_alloc_id(builder); + } +@@ -6198,6 +6094,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi + uint32_t type_id, zero_id, ptr_type_id, chain_id, object_id; + const struct signature_element *element; + unsigned int i, index, array_idx; ++ enum vsir_data_type data_type; + uint32_t output_id; - if (output_info->component_type != VKD3D_SHADER_COMPONENT_FLOAT) + dst_write_mask = output->mask; +@@ -6215,17 +6112,16 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi + use_mask |= element->used_mask; + } + } +- index = vsir_write_mask_get_component_idx(output->mask); +- dst_write_mask >>= index; +- use_mask >>= index; + write_mask &= dst_write_mask; + + if (!write_mask) + return; + +- if (output_info->component_type != VKD3D_SHADER_COMPONENT_FLOAT) ++ data_type = output_info->data_type; ++ ++ if (data_type != VSIR_DATA_F32) { - type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id(compiler, data_type, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); } -@@ -6236,7 +6245,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi +@@ -6235,35 +6131,32 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi + { /* Set values to 0 for not initialized shader output components. */ write_mask |= uninit_mask; - zero_id = spirv_compiler_get_constant_vector(compiler, +- zero_id = spirv_compiler_get_constant_vector(compiler, - output_info->component_type, VKD3D_VEC4_SIZE, 0); -+ vsir_data_type_from_component_type(output_info->component_type), VKD3D_VEC4_SIZE, 0); - val_id = spirv_compiler_emit_vector_shuffle(compiler, - zero_id, val_id, swizzle, uninit_mask, output_info->component_type, - vsir_write_mask_component_count(write_mask)); -@@ -6250,7 +6259,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi +- val_id = spirv_compiler_emit_vector_shuffle(compiler, +- zero_id, val_id, swizzle, uninit_mask, output_info->component_type, +- vsir_write_mask_component_count(write_mask)); ++ zero_id = spirv_compiler_get_constant_vector(compiler, data_type, VKD3D_VEC4_SIZE, 0); ++ val_id = spirv_compiler_emit_vector_shuffle(compiler, zero_id, val_id, swizzle, ++ uninit_mask, data_type, vsir_write_mask_component_count(write_mask)); + } + else + { +- val_id = spirv_compiler_emit_swizzle(compiler, +- val_id, VKD3DSP_WRITEMASK_ALL, output_info->component_type, swizzle, write_mask); ++ val_id = spirv_compiler_emit_swizzle(compiler, val_id, ++ VKD3DSP_WRITEMASK_ALL, data_type, swizzle, write_mask); + } + output_id = output_info->id; if (output_index_id) { - type_id = vkd3d_spirv_get_type_id(builder, -+ type_id = spirv_get_type_id_for_component_type(builder, - output_info->component_type, vsir_write_mask_component_count(dst_write_mask)); +- output_info->component_type, vsir_write_mask_component_count(dst_write_mask)); ++ type_id = spirv_get_type_id(compiler, data_type, vsir_write_mask_component_count(dst_write_mask)); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); output_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, output_id, output_index_id); -@@ -6263,7 +6272,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi + } + + if (!output_info->array_element_mask) + { +- spirv_compiler_emit_store(compiler, +- output_id, dst_write_mask, output_info->component_type, SpvStorageClassOutput, write_mask, val_id); ++ spirv_compiler_emit_store(compiler, output_id, dst_write_mask, ++ data_type, SpvStorageClassOutput, write_mask, val_id); return; } - type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, 1); ++ type_id = spirv_get_type_id(compiler, data_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); mask = output_info->array_element_mask; array_idx = spirv_compiler_get_output_array_index(compiler, output); -@@ -6305,7 +6314,7 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler * +@@ -6276,9 +6169,9 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi + chain_id = vkd3d_spirv_build_op_access_chain1(builder, + ptr_type_id, output_id, spirv_compiler_get_constant_uint(compiler, index)); + object_id = spirv_compiler_emit_swizzle(compiler, val_id, write_mask, +- output_info->component_type, VKD3D_SHADER_NO_SWIZZLE, VKD3DSP_WRITEMASK_0 << i); +- spirv_compiler_emit_store(compiler, chain_id, VKD3DSP_WRITEMASK_0, +- output_info->component_type, SpvStorageClassOutput, VKD3DSP_WRITEMASK_0 << i, object_id); ++ data_type, VKD3D_SHADER_NO_SWIZZLE, VKD3DSP_WRITEMASK_0 << i); ++ spirv_compiler_emit_store(compiler, chain_id, VKD3DSP_WRITEMASK_0, data_type, ++ SpvStorageClassOutput, VKD3DSP_WRITEMASK_0 << i, object_id); + ++index; + } + } +@@ -6305,7 +6198,7 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler * function_id = compiler->epilogue_function_id; void_id = vkd3d_spirv_get_op_type_void(builder); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 4); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 4); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); for (i = 0, count = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i) { -@@ -6514,7 +6523,6 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil +@@ -6485,7 +6378,7 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t + for (i = 0; i < compiler->temp_count; ++i) + { + id = spirv_compiler_emit_variable(compiler, &builder->global_stream, +- SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); ++ SpvStorageClassPrivate, VSIR_DATA_F32, VKD3D_VEC4_SIZE); + if (!i) + compiler->temp_id = id; + VKD3D_ASSERT(id == compiler->temp_id + i); +@@ -6514,7 +6407,6 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil const struct vkd3d_shader_indexable_temp *temp = &instruction->declaration.indexable_temp; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t id, type_id, length_id, ptr_type_id, init_id = 0; @@ -12107,17 +18838,17 @@ index 97c0d0e73a8..9c5f71ee11f 100644 struct vkd3d_shader_register reg; struct vkd3d_symbol reg_symbol; SpvStorageClass storage_class; -@@ -6535,8 +6543,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil +@@ -6535,8 +6427,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil function_location = spirv_compiler_get_current_function_location(compiler); vkd3d_spirv_begin_function_stream_insertion(builder, function_location); - component_type = vkd3d_component_type_from_data_type(temp->data_type); - type_id = vkd3d_spirv_get_type_id(builder, component_type, temp->component_count); -+ type_id = spirv_get_type_id(builder, temp->data_type, temp->component_count); ++ type_id = spirv_get_type_id(compiler, temp->data_type, temp->component_count); length_id = spirv_compiler_get_constant_uint(compiler, temp->register_size); type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); -@@ -6549,8 +6556,8 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil +@@ -6549,8 +6440,8 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil vkd3d_spirv_end_function_stream_insertion(builder); vkd3d_symbol_make_register(®_symbol, ®); @@ -12128,25 +18859,25 @@ index 97c0d0e73a8..9c5f71ee11f 100644 spirv_compiler_put_symbol(compiler, ®_symbol); } -@@ -6577,7 +6584,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com +@@ -6577,7 +6468,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com if (!(member_ids = vkd3d_calloc(count, sizeof(*member_ids)))) return; - vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ vec4_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); ++ vec4_id = spirv_get_type_id(compiler, VSIR_DATA_F32, VKD3D_VEC4_SIZE); for (i = 0, j = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) { -@@ -6594,7 +6601,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com +@@ -6594,7 +6485,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com if (compiler->offset_info.descriptor_table_count) { - uint32_t type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ uint32_t type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ uint32_t type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); length_id = spirv_compiler_get_constant_uint(compiler, compiler->offset_info.descriptor_table_count); member_ids[j] = vkd3d_spirv_build_op_type_array(builder, type_id, length_id); vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 4); -@@ -6626,8 +6633,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com +@@ -6626,8 +6517,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com vkd3d_spirv_build_op_member_name(builder, struct_id, j, "cb%u", reg_idx); vkd3d_symbol_make_register(®_symbol, &cb->reg); @@ -12156,16 +18887,16 @@ index 97c0d0e73a8..9c5f71ee11f 100644 reg_symbol.info.reg.member_idx = j; spirv_compiler_put_symbol(compiler, ®_symbol); -@@ -6788,7 +6794,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, +@@ -6788,7 +6678,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, return; } - vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ vec4_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); ++ vec4_id = spirv_get_type_id(compiler, VSIR_DATA_F32, VKD3D_VEC4_SIZE); length_id = spirv_compiler_get_constant_uint(compiler, size); array_type_id = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 16); -@@ -6802,8 +6808,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, +@@ -6802,38 +6692,12 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, ®, range, VKD3D_SHADER_RESOURCE_BUFFER, descriptor, false, &var_info); vkd3d_symbol_make_register(®_symbol, ®); @@ -12175,17 +18906,37 @@ index 97c0d0e73a8..9c5f71ee11f 100644 reg_symbol.descriptor_array = var_info.array_symbol; reg_symbol.info.reg.binding_base_idx = var_info.binding_base_idx; spirv_compiler_put_symbol(compiler, ®_symbol); -@@ -6829,8 +6834,7 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi - reg.idx[0].offset = icb->register_idx; - vkd3d_symbol_make_register(®_symbol, ®); - vkd3d_symbol_set_register_info(®_symbol, icb_id, SpvStorageClassPrivate, -- vkd3d_component_type_from_data_type(icb->data_type), -- vkd3d_write_mask_from_component_count(icb->component_count)); -+ icb->data_type, vkd3d_write_mask_from_component_count(icb->component_count)); - spirv_compiler_put_symbol(compiler, ®_symbol); } -@@ -6859,8 +6863,7 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi +-static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) +-{ +- const struct vkd3d_shader_immediate_constant_buffer *icb = instruction->declaration.icb; +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id, const_id, ptr_type_id, icb_id; +- struct vkd3d_shader_register reg; +- struct vkd3d_symbol reg_symbol; +- +- const_id = spirv_compiler_emit_constant_array(compiler, icb, &type_id); +- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); +- icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, +- ptr_type_id, SpvStorageClassPrivate, const_id); +- 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, 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, +- vkd3d_component_type_from_data_type(icb->data_type), +- vkd3d_write_mask_from_component_count(icb->component_count)); +- spirv_compiler_put_symbol(compiler, ®_symbol); +-} +- + static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compiler, + const struct vkd3d_shader_register_range *range, const struct vkd3d_shader_descriptor_info1 *descriptor) + { +@@ -6859,8 +6723,7 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi ®, range, VKD3D_SHADER_RESOURCE_NONE, descriptor, false, &var_info); vkd3d_symbol_make_register(®_symbol, ®); @@ -12195,61 +18946,111 @@ index 97c0d0e73a8..9c5f71ee11f 100644 reg_symbol.descriptor_array = var_info.array_symbol; reg_symbol.info.reg.binding_base_idx = var_info.binding_base_idx; spirv_compiler_put_symbol(compiler, ®_symbol); -@@ -6927,7 +6930,7 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler +@@ -6883,7 +6746,7 @@ static const struct vkd3d_spirv_resource_type *spirv_compiler_enable_resource_ty + return resource_type_info; + } + +-static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_type data_type) ++static SpvImageFormat image_format_for_image_read(enum vsir_data_type data_type) + { + /* The following formats are supported by Direct3D 11 hardware for UAV + * typed loads. A newer hardware may support more formats for UAV typed +@@ -6891,11 +6754,13 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty + */ + switch (data_type) + { +- case VKD3D_SHADER_COMPONENT_FLOAT: ++ case VSIR_DATA_F32: ++ case VSIR_DATA_SNORM: ++ case VSIR_DATA_UNORM: + return SpvImageFormatR32f; +- case VKD3D_SHADER_COMPONENT_INT: ++ case VSIR_DATA_I32: + return SpvImageFormatR32i; +- case VKD3D_SHADER_COMPONENT_UINT: ++ case VSIR_DATA_U32: + return SpvImageFormatR32ui; + default: + FIXME("Unhandled type %#x.\n", data_type); +@@ -6905,8 +6770,7 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty + + static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler, + const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, +- const struct vkd3d_spirv_resource_type *resource_type_info, enum vkd3d_shader_component_type data_type, +- bool raw_structured) ++ const struct vkd3d_spirv_resource_type *resource_type_info, enum vsir_data_type data_type, bool raw_structured) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_descriptor_info1 *d; +@@ -6927,15 +6791,15 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat); } - sampled_type_id = vkd3d_spirv_get_type_id(builder, data_type, 1); -+ sampled_type_id = spirv_get_type_id_for_component_type(builder, data_type, 1); - return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, - 2, resource_type_info->arrayed, resource_type_info->ms, - reg->type == VKD3DSPR_UAV ? 2 : 1, format); -@@ -6996,7 +6999,7 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi - symbol.id = var_id; - symbol.descriptor_array = NULL; - symbol.info.resource.range = *resource_range; -- symbol.info.resource.sampled_type = sampled_type; -+ symbol.info.resource.sampled_type = vsir_data_type_from_component_type(sampled_type); - symbol.info.resource.type_id = image_type_id; - symbol.info.resource.resource_type_info = resource_type_info; - symbol.info.resource.structure_stride = structure_stride; -@@ -7053,7 +7056,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp +- return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, +- 2, resource_type_info->arrayed, resource_type_info->ms, +- reg->type == VKD3DSPR_UAV ? 2 : 1, format); ++ sampled_type_id = spirv_get_type_id(compiler, data_type, 1); ++ ++ return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, 2, ++ resource_type_info->arrayed, resource_type_info->ms, reg->type == VKD3DSPR_UAV ? 2 : 1, format); + } + + static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compiler *compiler, + const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register_range *resource_range, +- enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_component_type sampled_type, ++ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type sampled_type, + unsigned int structure_stride, bool raw, const struct vkd3d_spirv_resource_type *resource_type_info) + { + const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; +@@ -7021,9 +6885,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + uint32_t counter_type_id, type_id, var_id, counter_var_id = 0; + const struct vkd3d_spirv_resource_type *resource_type_info; + unsigned int sample_count = descriptor->sample_count; +- enum vkd3d_shader_component_type sampled_type; + struct vkd3d_symbol resource_symbol; + struct vkd3d_shader_register reg; ++ enum vsir_data_type sampled_type; + + vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_F32, 1); + reg.idx[0].offset = descriptor->register_id; +@@ -7040,7 +6904,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + return; + } + +- sampled_type = vkd3d_component_type_from_data_type(descriptor->resource_data_type); ++ sampled_type = descriptor->resource_data_type; + + if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range)) + { +@@ -7053,7 +6917,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp { uint32_t array_type_id, struct_id; - type_id = vkd3d_spirv_get_type_id(builder, sampled_type, 1); -+ type_id = spirv_get_type_id(builder, descriptor->resource_data_type, 1); ++ type_id = spirv_get_type_id(compiler, sampled_type, 1); array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id); vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4); -@@ -7094,7 +7097,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp +@@ -7094,7 +6958,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp { VKD3D_ASSERT(structure_stride); /* counters are valid only for structured buffers */ - counter_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ counter_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ counter_type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); if (spirv_compiler_is_opengl_target(compiler)) { vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage); -@@ -7126,7 +7129,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - resource_symbol.id = var_id; - resource_symbol.descriptor_array = var_info.array_symbol; - resource_symbol.info.resource.range = *range; -- resource_symbol.info.resource.sampled_type = sampled_type; -+ resource_symbol.info.resource.sampled_type = descriptor->resource_data_type; - resource_symbol.info.resource.type_id = type_id; - resource_symbol.info.resource.resource_type_info = resource_type_info; - resource_symbol.info.resource.structure_stride = structure_stride; -@@ -7158,7 +7161,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler +@@ -7158,7 +7022,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler if (alignment) TRACE("Ignoring alignment %u.\n", alignment); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); length_id = spirv_compiler_get_constant_uint(compiler, size); array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); -@@ -7170,8 +7173,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler +@@ -7170,8 +7034,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler spirv_compiler_emit_register_debug_name(builder, var_id, reg); vkd3d_symbol_make_register(®_symbol, reg); @@ -12259,7 +19060,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 reg_symbol.info.reg.structure_stride = structure_stride; spirv_compiler_put_symbol(compiler, ®_symbol); } -@@ -7209,10 +7211,9 @@ static void spirv_compiler_emit_output_vertex_count(struct spirv_compiler *compi +@@ -7209,10 +7072,9 @@ static void spirv_compiler_emit_output_vertex_count(struct spirv_compiler *compi SpvExecutionModeOutputVertices, instruction->declaration.count); } @@ -12272,7 +19073,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 SpvExecutionMode mode; switch (primitive_type) -@@ -7233,7 +7234,8 @@ static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compi +@@ -7233,7 +7095,8 @@ static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compi mode = SpvExecutionModeInputTrianglesAdjacency; break; default: @@ -12282,7 +19083,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 return; } -@@ -7263,10 +7265,9 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) +@@ -7263,10 +7126,9 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) } } @@ -12295,7 +19096,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 SpvExecutionMode mode; switch (primitive_type) -@@ -7282,7 +7283,8 @@ static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compi +@@ -7282,7 +7144,8 @@ static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compi mode = SpvExecutionModeOutputTriangleStrip; break; default: @@ -12305,7 +19106,15 @@ index 97c0d0e73a8..9c5f71ee11f 100644 return; } -@@ -7624,11 +7626,12 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, +@@ -7569,6 +7432,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru + {VSIR_OP_ITOF, SpvOpConvertSToF}, + {VSIR_OP_ITOI, SpvOpSConvert}, + {VSIR_OP_MUL, SpvOpFMul}, ++ {VSIR_OP_NEG, SpvOpFNegate}, + {VSIR_OP_NOT, SpvOpNot}, + {VSIR_OP_OR, SpvOpBitwiseOr}, + {VSIR_OP_UDIV_SIMPLE, SpvOpUDiv}, +@@ -7624,11 +7488,12 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, /* ITOD is not supported. Frontends which emit bool casts must use ITOF for double. */ val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); } @@ -12320,16 +19129,69 @@ index 97c0d0e73a8..9c5f71ee11f 100644 { val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); } -@@ -7724,7 +7727,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]); +@@ -7645,14 +7510,13 @@ 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; +- unsigned int i, component_count; ++ uint32_t src_ids[SPIRV_MAX_SRC_COUNT]; + uint32_t type_id, val_id; + SpvOp op = SpvOpMax; +- bool check_zero; ++ unsigned int i; + if (src->reg.data_type == VSIR_DATA_U64 && instruction->opcode == VSIR_OP_COUNTBITS) + { +@@ -7692,44 +7556,14 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil + 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) -+ if (data_type_is_64_bit(dst[0].reg.data_type)) - 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); -@@ -7741,7 +7744,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +- 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. +@@ -7741,7 +7575,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil || instruction->opcode == VSIR_OP_ISHR || instruction->opcode == VSIR_OP_USHR)) { uint32_t mask_id = spirv_compiler_get_constant_vector(compiler, @@ -12338,7 +19200,33 @@ index 97c0d0e73a8..9c5f71ee11f 100644 src_ids[1] = vkd3d_spirv_build_op_and(builder, type_id, src_ids[1], mask_id); } -@@ -7839,7 +7842,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp +@@ -7750,13 +7584,22 @@ 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; + } + ++static void spirv_compiler_emit_saturate(struct spirv_compiler *compiler, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ const struct vkd3d_shader_dst_param *dst = instruction->dst; ++ const struct vkd3d_shader_src_param *src = instruction->src; ++ uint32_t val_id; ++ ++ val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); ++ val_id = spirv_compiler_emit_sat(compiler, &dst->reg, dst->write_mask, val_id); ++ spirv_compiler_emit_store_dst(compiler, dst, val_id); ++} ++ + static void spirv_compiler_emit_isfinite(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) + { +@@ -7839,7 +7682,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp unsigned int i, component_count; enum GLSLstd450 glsl_inst; @@ -12347,16 +19235,16 @@ index 97c0d0e73a8..9c5f71ee11f 100644 || 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. */ -@@ -7878,7 +7881,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp +@@ -7878,7 +7721,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp component_count = vsir_write_mask_component_count(dst->write_mask); uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT32_MAX, component_count); condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpIEqual, - vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), val_id, uint_max_id); -+ spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count), val_id, uint_max_id); ++ spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count), val_id, uint_max_id); rev_val_id = vkd3d_spirv_build_op_isub(builder, type_id, spirv_compiler_get_constant_uint_vector(compiler, 31, component_count), val_id); val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, rev_val_id); -@@ -7905,7 +7908,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, +@@ -7905,7 +7748,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, spirv_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info); spirv_compiler_get_register_info(compiler, &src->reg, &src_reg_info); @@ -12365,43 +19253,43 @@ index 97c0d0e73a8..9c5f71ee11f 100644 || dst_reg_info.write_mask != src_reg_info.write_mask) goto general_implementation; -@@ -7928,7 +7931,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, +@@ -7928,7 +7771,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); src_id = spirv_compiler_get_register_id(compiler, &src->reg); - type_id = vkd3d_spirv_get_type_id(builder, dst_reg_info.component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(builder, dst_reg_info.data_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id(compiler, dst_reg_info.data_type, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone); dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); -@@ -7957,7 +7960,7 @@ general_implementation: +@@ -7957,7 +7800,7 @@ general_implementation: val_id = spirv_compiler_emit_load_src(compiler, src, write_mask); if (dst->reg.data_type != src->reg.data_type) { - val_id = vkd3d_spirv_build_op_bitcast(builder, vkd3d_spirv_get_type_id_for_data_type(builder, -+ val_id = vkd3d_spirv_build_op_bitcast(builder, spirv_get_type_id(builder, ++ val_id = vkd3d_spirv_build_op_bitcast(builder, spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)), val_id); } spirv_compiler_emit_store_dst(compiler, dst, val_id); -@@ -7983,7 +7986,7 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, +@@ -7983,7 +7826,7 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, { 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_get_type_id(builder, VSIR_DATA_BOOL, component_count), condition_id, ++ spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count), condition_id, spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); else condition_id = spirv_compiler_emit_int_to_bool(compiler, -@@ -8010,7 +8013,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, +@@ -8010,7 +7853,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); component_count = vsir_write_mask_component_count(dst->write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, component_count); condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); -@@ -8027,13 +8030,13 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, +@@ -8027,13 +7870,13 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, 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; @@ -12417,12 +19305,12 @@ index 97c0d0e73a8..9c5f71ee11f 100644 if (instruction->opcode == VSIR_OP_DP4) write_mask = VKD3DSP_WRITEMASK_ALL; -@@ -8046,15 +8049,12 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, +@@ -8046,15 +7889,12 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, for (i = 0; i < ARRAY_SIZE(src_ids); ++i) src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], write_mask); - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id(builder, data_type, 1); ++ type_id = spirv_get_type_id(compiler, data_type, 1); val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpDot, type_id, src_ids[0], src_ids[1]); @@ -12435,16 +19323,16 @@ index 97c0d0e73a8..9c5f71ee11f 100644 if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); -@@ -8092,7 +8092,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, +@@ -8092,7 +7932,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, unsigned int i, component_count; component_count = vsir_write_mask_component_count(dst->write_mask); - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); ++ type_id = spirv_get_type_id(compiler, dst->reg.data_type, component_count); for (i = 0; i < ARRAY_SIZE(src_ids); ++i) src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); -@@ -8111,7 +8111,6 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, +@@ -8111,7 +7951,6 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; uint32_t src_type_id, dst_type_id, condition_type_id; @@ -12452,7 +19340,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 unsigned int component_count; uint32_t write_mask; -@@ -8143,17 +8142,16 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, +@@ -8143,17 +7982,16 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, int_min_id); /* VSIR allows the destination of a signed conversion to be unsigned. */ @@ -12461,7 +19349,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - int_max_id = spirv_compiler_get_constant_vector(compiler, component_type, component_count, INT_MAX); - condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + int_max_id = spirv_compiler_get_constant_vector(compiler, dst->reg.data_type, component_count, INT_MAX); -+ condition_type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); ++ condition_type_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count); condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); @@ -12473,76 +19361,125 @@ index 97c0d0e73a8..9c5f71ee11f 100644 condition_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsNan, condition_type_id, src_id); val_id = vkd3d_spirv_build_op_select(builder, dst_type_id, condition_id, zero_id, val_id); -@@ -8199,7 +8197,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, +@@ -8199,7 +8037,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id); uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); - condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ condition_type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); ++ condition_type_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count); condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); -@@ -8224,7 +8222,7 @@ static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler, +@@ -8224,7 +8062,7 @@ static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler, src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, component_count); val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id); if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); -@@ -8248,8 +8246,8 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp +@@ -8239,17 +8077,17 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp + 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; +- enum vkd3d_shader_component_type component_type; + unsigned int i, j, k, src_count, size; ++ enum vsir_data_type data_type; + uint32_t write_mask; + SpvOp op; + + src_count = instruction->src_count; VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids)); - component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); +- 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 == VSIR_DATA_U64) ? 0x40 : 0x20; -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, 1); ++ data_type = dst->reg.data_type; ++ type_id = spirv_get_type_id(compiler, data_type, 1); + size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20; mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); size_id = spirv_compiler_get_constant_uint(compiler, size); -@@ -8305,8 +8303,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, +@@ -8274,7 +8112,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp + for (j = 0; j < src_count; ++j) + { + src_ids[src_count - j - 1] = spirv_compiler_emit_load_src_with_type(compiler, +- &src[j], write_mask, component_type); ++ &src[j], write_mask, data_type); + } + + /* In SPIR-V, the last two operands are Offset and Count. */ +@@ -8290,7 +8128,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp + op, type_id, src_ids, src_count); + } + +- spirv_compiler_emit_store_dst_components(compiler, dst, component_type, constituents); ++ spirv_compiler_emit_store_dst_components(compiler, dst, data_type, constituents); + } + + static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, +@@ -8305,8 +8143,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, unsigned int i, j; instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); - scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); -+ scalar_type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 2); ++ scalar_type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 1); /* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */ VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); -@@ -8338,8 +8336,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, +@@ -8322,8 +8160,7 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, + scalar_type_id, result_id, 0); + } + +- spirv_compiler_emit_store_dst_components(compiler, +- dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); ++ spirv_compiler_emit_store_dst_components(compiler, dst, dst->reg.data_type, components); + } + + static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, +@@ -8338,8 +8175,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, unsigned int i, j; instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); - scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); -+ scalar_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 2); ++ scalar_type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); zero_id = spirv_compiler_get_constant_float(compiler, 0.0f); /* FIXME: Consider a single PackHalf2x16 instruction per 2 components. */ -@@ -8418,7 +8416,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co +@@ -8358,8 +8195,7 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, + instr_set_id, GLSLstd450PackHalf2x16, &src_id, 1); + } + +- spirv_compiler_emit_store_dst_components(compiler, +- dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); ++ spirv_compiler_emit_store_dst_components(compiler, dst, dst->reg.data_type, components); + } + + static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *compiler, +@@ -8418,7 +8254,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co src0_id = spirv_compiler_emit_load_src(compiler, &src[0], write_mask); src1_id = spirv_compiler_emit_load_src(compiler, &src[1], write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count); result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id); -@@ -8470,7 +8468,7 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil +@@ -8470,7 +8306,7 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count); result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id); result_id = spirv_compiler_emit_bool_to_float(compiler, component_count, result_id, false); -@@ -8806,7 +8804,7 @@ struct vkd3d_shader_image +@@ -8806,7 +8642,7 @@ struct vkd3d_shader_image uint32_t image_id; uint32_t sampled_image_id; @@ -12551,7 +19488,7 @@ index 97c0d0e73a8..9c5f71ee11f 100644 uint32_t image_type_id; const struct vkd3d_spirv_resource_type *resource_type_info; unsigned int structure_stride; -@@ -8926,9 +8924,9 @@ static void spirv_compiler_prepare_image(struct spirv_compiler *compiler, +@@ -8926,9 +8762,8 @@ static void spirv_compiler_prepare_image(struct spirv_compiler *compiler, image->image_id = 0; } @@ -12559,12 +19496,11 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - &symbol->info.resource.range, image->resource_type_info, - image->sampled_type, image->structure_stride || image->raw); + image->image_type_id = spirv_compiler_get_image_type_id(compiler, resource_reg, &symbol->info.resource.range, -+ image->resource_type_info, vkd3d_component_type_from_data_type(image->sampled_type), -+ image->structure_stride || image->raw); ++ image->resource_type_info, image->sampled_type, image->structure_stride || image->raw); if (sampled) { -@@ -8977,8 +8975,7 @@ static uint32_t spirv_compiler_emit_texel_offset(struct spirv_compiler *compiler +@@ -8977,8 +8812,7 @@ static uint32_t spirv_compiler_emit_texel_offset(struct spirv_compiler *compiler int32_t data[4] = {offset->u, offset->v, offset->w, 0}; VKD3D_ASSERT(resource_type_info->dim != SpvDimCube); @@ -12574,49 +19510,47 @@ index 97c0d0e73a8..9c5f71ee11f 100644 } static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, -@@ -8999,7 +8996,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, +@@ -8999,7 +8833,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); if (image.resource_type_info->resource_type != VKD3D_SHADER_RESOURCE_BUFFER && !multisample) -@@ -9024,8 +9021,8 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, +@@ -9024,8 +8858,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_image_fetch(builder, type_id, image.image_id, coordinate_id, operands_mask, image_operands, image_operand_count); - spirv_compiler_emit_store_dst_swizzled(compiler, - dst, val_id, image.sampled_type, src[1].swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -+ vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); ++ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, -@@ -9045,13 +9042,13 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, +@@ -9045,13 +8878,12 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, spirv_compiler_prepare_image(compiler, &image, &resource->reg, &sampler->reg, VKD3D_IMAGE_FLAG_SAMPLED); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 2); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); val_id = vkd3d_spirv_build_op_image_query_lod(builder, type_id, image.sampled_image_id, coordinate_id); - spirv_compiler_emit_store_dst_swizzled(compiler, - dst, val_id, image.sampled_type, resource->swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -+ vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); ++ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, -@@ -9115,14 +9112,14 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, +@@ -9115,14 +8947,13 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, instruction, image.resource_type_info); } - sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ sampled_type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ sampled_type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); VKD3D_ASSERT(image_operand_count <= ARRAY_SIZE(image_operands)); val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, @@ -12624,17 +19558,16 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - spirv_compiler_emit_store_dst_swizzled(compiler, - dst, val_id, image.sampled_type, resource->swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -+ vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); ++ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, -@@ -9160,15 +9157,15 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, +@@ -9160,15 +8991,14 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, instruction, image.resource_type_info); } - sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); -+ sampled_type_id = spirv_get_type_id(builder, image.sampled_type, 1); ++ sampled_type_id = spirv_get_type_id(compiler, image.sampled_type, 1); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); dref_id = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_image_sample_dref(builder, op, sampled_type_id, @@ -12643,21 +19576,20 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - spirv_compiler_emit_store_dst_scalar(compiler, - dst, val_id, image.sampled_type, src[1].swizzle); -+ spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id, -+ vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); ++ spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, -@@ -9219,7 +9216,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, +@@ -9219,7 +9049,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, instruction, image.resource_type_info); } - sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ sampled_type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ sampled_type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; coordinate_id = spirv_compiler_emit_load_src(compiler, addr, coordinate_mask); if (image_flags & VKD3D_IMAGE_FLAG_DEPTH) -@@ -9234,15 +9231,14 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, +@@ -9234,15 +9064,13 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, { component_idx = vsir_swizzle_get_component(sampler->swizzle, 0); /* Nvidia driver requires signed integer type. */ @@ -12671,70 +19603,87 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - spirv_compiler_emit_store_dst_swizzled(compiler, - dst, val_id, image.sampled_type, resource->swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -+ vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); ++ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } static uint32_t spirv_compiler_emit_raw_structured_addressing( -@@ -9301,10 +9297,10 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler +@@ -9301,10 +9129,10 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler if (storage_buffer_uav) { - texel_type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ texel_type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ++ texel_type_id = spirv_get_type_id(compiler, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9336,11 +9332,11 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler +@@ -9336,11 +9164,11 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); - texel_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ texel_type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ texel_type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { -@@ -9379,7 +9375,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, +@@ -9359,7 +9187,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler + type_id, val_id, 0); + } + } +- spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); ++ spirv_compiler_emit_store_dst_components(compiler, dst, VSIR_DATA_U32, constituents); + } + + static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, +@@ -9379,7 +9207,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, if (!spirv_compiler_get_register_info(compiler, &resource->reg, ®_info)) return; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9438,10 +9434,10 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * +@@ -9399,7 +9227,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, + ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id); + constituents[j++] = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); + } +- spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); ++ spirv_compiler_emit_store_dst_components(compiler, dst, VSIR_DATA_U32, constituents); + } + + static void spirv_compiler_emit_ld_raw_structured(struct spirv_compiler *compiler, +@@ -9438,10 +9266,10 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { - type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ++ type_id = spirv_get_type_id(compiler, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9469,7 +9465,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * +@@ -9469,7 +9297,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * } else { - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9482,7 +9478,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * +@@ -9482,7 +9310,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * for (component_idx = 0; component_idx < component_count; ++component_idx) { /* Mesa Vulkan drivers require the texel parameter to be a vector. */ @@ -12743,36 +19692,30 @@ index 97c0d0e73a8..9c5f71ee11f 100644 VKD3D_VEC4_SIZE, val_id, component_idx, component_count); coordinate_id = base_coordinate_id; -@@ -9512,7 +9508,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, +@@ -9512,7 +9340,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, if (!spirv_compiler_get_register_info(compiler, &dst->reg, ®_info)) return; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9570,7 +9566,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, +@@ -9570,7 +9398,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { - type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ++ type_id = spirv_get_type_id(compiler, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); indices[0] = spirv_compiler_get_constant_uint(compiler, 0); -@@ -9580,20 +9576,20 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); - - spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -- resource_symbol->info.resource.sampled_type, src[1].swizzle); -+ vkd3d_component_type_from_data_type(resource_symbol->info.resource.sampled_type), src[1].swizzle); - } +@@ -9585,15 +9413,14 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, else { spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); @@ -12781,66 +19724,52 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - spirv_compiler_emit_store_dst_swizzled(compiler, - dst, val_id, image.sampled_type, src[1].swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -+ vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); ++ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } } -@@ -9613,14 +9609,14 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, +@@ -9613,7 +9440,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { - type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ++ type_id = spirv_get_type_id(compiler, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); indices[0] = spirv_compiler_get_constant_uint(compiler, 0); - indices[1] = coordinate_id; - -- val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], -- VKD3DSP_WRITEMASK_0, resource_symbol->info.resource.sampled_type); -+ val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, -+ vkd3d_component_type_from_data_type(resource_symbol->info.resource.sampled_type)); - ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); - vkd3d_spirv_build_op_store(builder, ptr_id, val_id, SpvMemoryAccessMaskNone); - } -@@ -9631,7 +9627,8 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, - spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); -- texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], dst->write_mask, image.sampled_type); -+ texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], -+ dst->write_mask, vkd3d_component_type_from_data_type(image.sampled_type)); - - vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, texel_id, - SpvImageOperandsMaskNone, NULL, 0); -@@ -9658,7 +9655,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c +@@ -9658,7 +9485,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c counter_id = resource_symbol->info.resource.uav_counter_id; VKD3D_ASSERT(counter_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); if (resource_symbol->info.resource.uav_counter_array) { -@@ -9772,6 +9769,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9766,12 +9593,11 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil + const struct vkd3d_shader_src_param *src = instruction->src; + const struct vkd3d_symbol *resource_symbol = NULL; + uint32_t ptr_type_id, type_id, val_id, result_id; +- enum vkd3d_shader_component_type component_type; + const struct vkd3d_shader_dst_param *resource; + uint32_t coordinate_id, sample_id, pointer_id; struct vkd3d_shader_register_info reg_info; - SpvMemorySemanticsMask memory_semantic; +- SpvMemorySemanticsMask memory_semantic; struct vkd3d_shader_image image; + enum vsir_data_type data_type; unsigned int structure_stride; uint32_t coordinate_mask; uint32_t operands[6]; -@@ -9820,7 +9818,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9820,7 +9646,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil } } - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); if (structure_stride || raw) { VKD3D_ASSERT(!raw != !structure_stride); -@@ -9836,7 +9834,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9836,7 +9662,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil if (resource->reg.type == VKD3DSPR_GROUPSHAREDMEM) { @@ -12849,69 +19778,112 @@ index 97c0d0e73a8..9c5f71ee11f 100644 ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); pointer_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id); } -@@ -9844,8 +9842,8 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9844,8 +9670,8 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil { if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { - component_type = resource_symbol->info.resource.sampled_type; - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + data_type = resource_symbol->info.resource.sampled_type; -+ type_id = spirv_get_type_id(builder, data_type, 1); ++ type_id = spirv_get_type_id(compiler, data_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); operands[0] = spirv_compiler_get_constant_uint(compiler, 0); operands[1] = coordinate_id; -@@ -9853,8 +9851,8 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9853,8 +9679,8 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil } else { - component_type = image.sampled_type; - type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); + data_type = image.sampled_type; -+ type_id = spirv_get_type_id(builder, data_type, 1); ++ type_id = spirv_get_type_id(compiler, data_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id); sample_id = spirv_compiler_get_constant_uint(compiler, 0); pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, -@@ -9862,6 +9860,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9862,7 +9688,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil } } -+ component_type = vkd3d_component_type_from_data_type(data_type); - val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type); +- val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type); ++ val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, data_type); if (instruction->flags & VKD3DARF_VOLATILE) -@@ -9907,7 +9906,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, + { +@@ -9871,17 +9697,13 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + } + +- memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) +- ? SpvMemorySemanticsSequentiallyConsistentMask +- : SpvMemorySemanticsMaskNone; +- + operands[i++] = pointer_id; + operands[i++] = spirv_compiler_get_constant_uint(compiler, scope); +- operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic); ++ operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); + if (instruction->src_count >= 3) + { +- operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic); +- operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, component_type); ++ operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); ++ operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, data_type); + } + operands[i++] = val_id; + result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, +@@ -9907,7 +9729,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, { resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); val_id = vkd3d_spirv_build_op_array_length(builder, type_id, resource_symbol->id, 0); write_mask = VKD3DSP_WRITEMASK_0; } -@@ -9917,7 +9916,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, +@@ -9917,7 +9739,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id); write_mask = VKD3DSP_WRITEMASK_0; } -@@ -9927,7 +9926,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, +@@ -9927,7 +9749,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, stride_id = spirv_compiler_get_constant_uint(compiler, image.structure_stride); constituents[0] = vkd3d_spirv_build_op_udiv(builder, type_id, val_id, stride_id); constituents[1] = stride_id; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents)); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, ARRAY_SIZE(constituents)); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, ARRAY_SIZE(constituents)); val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, ARRAY_SIZE(constituents)); write_mask |= VKD3DSP_WRITEMASK_1; -@@ -9966,14 +9965,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, +@@ -9939,18 +9761,18 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, + } + + val_id = spirv_compiler_emit_swizzle(compiler, val_id, write_mask, +- VKD3D_SHADER_COMPONENT_UINT, src->swizzle, dst->write_mask); ++ VSIR_DATA_U32, src->swizzle, dst->write_mask); + spirv_compiler_emit_store_dst(compiler, dst, val_id); + } + + 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 vsir_data_type data_type = VSIR_DATA_U32; + uint32_t constituents[VKD3D_VEC4_SIZE]; + unsigned int i, size_component_count; + struct vkd3d_shader_image image; +@@ -9966,14 +9788,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, size_component_count = image.resource_type_info->coordinate_component_count; if (image.resource_type_info->dim == SpvDimCube) --size_component_count; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, size_component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, size_component_count); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, size_component_count); supports_mipmaps = src[1].reg.type != VKD3DSPR_UAV && !image.resource_type_info->ms; if (supports_mipmaps) @@ -12919,38 +19891,59 @@ index 97c0d0e73a8..9c5f71ee11f 100644 lod_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_image_query_size_lod(builder, type_id, image.image_id, lod_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); miplevel_count_id = vkd3d_spirv_build_op_image_query_levels(builder, type_id, image.image_id); } else -@@ -9987,14 +9986,13 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, +@@ -9987,20 +9809,19 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, for (i = 0; i < 3 - size_component_count; ++i) constituents[i + 1] = spirv_compiler_get_constant_uint(compiler, 0); constituents[i + 1] = miplevel_count_id; - 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, i + 2); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, i + 2); if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) { - component_type = VKD3D_SHADER_COMPONENT_FLOAT; +- component_type = VKD3D_SHADER_COMPONENT_FLOAT; - type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); ++ data_type = VSIR_DATA_F32; ++ type_id = spirv_get_type_id(compiler, data_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); -@@ -10022,7 +10020,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co + } +- val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, +- component_type, src[1].swizzle, dst->write_mask); ++ val_id = spirv_compiler_emit_swizzle(compiler, val_id, ++ VKD3DSP_WRITEMASK_ALL, data_type, src[1].swizzle, dst->write_mask); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); + } +@@ -10022,7 +9843,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); val_id = vkd3d_spirv_build_op_image_query_samples(builder, type_id, image.image_id); } -@@ -10048,14 +10046,16 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, +@@ -10032,10 +9853,10 @@ 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; ++ enum vsir_data_type data_type = VSIR_DATA_U32; + uint32_t constituents[VKD3D_VEC4_SIZE]; + uint32_t type_id, val_id; + unsigned int i; +@@ -10048,20 +9869,22 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, constituents[0] = val_id; for (i = 1; i < VKD3D_VEC4_SIZE; ++i) @@ -12958,23 +19951,32 @@ index 97c0d0e73a8..9c5f71ee11f 100644 constituents[i] = spirv_compiler_get_constant_uint(compiler, 0); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + } -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE); if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) { - component_type = VKD3D_SHADER_COMPONENT_FLOAT; +- component_type = VKD3D_SHADER_COMPONENT_FLOAT; - type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); ++ data_type = VSIR_DATA_F32; ++ type_id = spirv_get_type_id(compiler, data_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); -@@ -10121,13 +10121,12 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, + } +- val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, +- component_type, src->swizzle, dst->write_mask); ++ val_id = spirv_compiler_emit_swizzle(compiler, val_id, ++ VKD3DSP_WRITEMASK_ALL, data_type, src->swizzle, dst->write_mask); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); + } +@@ -10121,13 +9944,12 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, sample_count_id = spirv_compiler_emit_query_sample_count(compiler, &instruction->src[0]); sample_index_id = spirv_compiler_emit_load_src(compiler, &instruction->src[1], VKD3DSP_WRITEMASK_0); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); index_id = vkd3d_spirv_build_op_iadd(builder, type_id, sample_count_id, sample_index_id); - index_id = vkd3d_spirv_build_op_isub(builder, - type_id, index_id, spirv_compiler_get_constant_uint(compiler, 1)); @@ -12982,16 +19984,16 @@ index 97c0d0e73a8..9c5f71ee11f 100644 /* Validate sample index. */ - bool_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, 1); -+ bool_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, 1); ++ bool_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, 1); id = vkd3d_spirv_build_op_logical_and(builder, bool_id, vkd3d_spirv_build_op_uless_than(builder, bool_id, sample_index_id, sample_count_id), vkd3d_spirv_build_op_uless_than_equal(builder, -@@ -10135,16 +10134,16 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, +@@ -10135,16 +9957,16 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, index_id = vkd3d_spirv_build_op_select(builder, type_id, id, index_id, spirv_compiler_get_constant_uint(compiler, 0)); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 2); if (!(id = compiler->sample_positions_id)) { length_id = spirv_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions)); @@ -13007,28 +20009,45 @@ index 97c0d0e73a8..9c5f71ee11f 100644 } id = vkd3d_spirv_build_op_constant_composite(builder, array_type_id, constituents, ARRAY_SIZE(constituents)); -@@ -10199,7 +10198,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, +@@ -10159,7 +9981,7 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, + id = vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); + + id = spirv_compiler_emit_swizzle(compiler, id, VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1, +- VKD3D_SHADER_COMPONENT_FLOAT, instruction->src[0].swizzle, dst->write_mask); ++ VSIR_DATA_F32, instruction->src[0].swizzle, dst->write_mask); + spirv_compiler_emit_store_dst(compiler, dst, id); + } + +@@ -10199,14 +10021,14 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); } - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, vsir_write_mask_component_count(register_info.write_mask)); instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); -@@ -10334,9 +10333,8 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler + val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, op, src_ids, src_count); + + val_id = spirv_compiler_emit_swizzle(compiler, val_id, register_info.write_mask, +- VKD3D_SHADER_COMPONENT_FLOAT, src[0].swizzle, dst->write_mask); ++ VSIR_DATA_F32, src[0].swizzle, dst->write_mask); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); + } +@@ -10334,9 +10156,8 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler const struct vkd3d_shader_src_param *src = instruction->src; uint32_t type_id, direction_type_id, direction_id, val_id; - 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, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -+ direction_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); ++ direction_type_id = spirv_get_type_id(compiler, 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); -@@ -10355,14 +10353,12 @@ static void spirv_compiler_emit_quad_read_lane_at(struct spirv_compiler *compile +@@ -10355,14 +10176,12 @@ static void spirv_compiler_emit_quad_read_lane_at(struct spirv_compiler *compile if (!register_is_constant_or_undef(&src[1].reg)) { @@ -13040,59 +20059,69 @@ index 97c0d0e73a8..9c5f71ee11f 100644 - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); ++ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_group_nonuniform_quad_broadcast(builder, type_id, val_id, lane_id); -@@ -10411,7 +10407,7 @@ static uint32_t spirv_compiler_emit_group_nonuniform_ballot(struct spirv_compile +@@ -10411,7 +10230,7 @@ static uint32_t spirv_compiler_emit_group_nonuniform_ballot(struct spirv_compile struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, val_id; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, VKD3D_VEC4_SIZE); val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_group_nonuniform_ballot(builder, type_id, val_id); -@@ -10470,8 +10466,7 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, +@@ -10470,8 +10289,7 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, op = map_wave_alu_op(instruction->opcode, data_type_is_floating_point(src->reg.data_type)); - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); ++ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformArithmetic); -@@ -10495,7 +10490,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, +@@ -10495,7 +10313,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, : SpvGroupOperationReduce; val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); val_id = vkd3d_spirv_build_op_group_nonuniform_ballot_bit_count(builder, type_id, group_op, val_id); spirv_compiler_emit_store_dst(compiler, dst, val_id); -@@ -10520,8 +10515,7 @@ static void spirv_compiler_emit_wave_read_lane_at(struct spirv_compiler *compile +@@ -10520,8 +10338,7 @@ static void spirv_compiler_emit_wave_read_lane_at(struct spirv_compiler *compile const struct vkd3d_shader_src_param *src = instruction->src; uint32_t type_id, lane_id, val_id; - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); ++ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); -@@ -10548,8 +10542,7 @@ static void spirv_compiler_emit_wave_read_lane_first(struct spirv_compiler *comp +@@ -10548,8 +10365,7 @@ static void spirv_compiler_emit_wave_read_lane_first(struct spirv_compiler *comp const struct vkd3d_shader_src_param *src = instruction->src; uint32_t type_id, val_id; - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); ++ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); val_id = vkd3d_spirv_build_op_group_nonuniform_broadcast_first(builder, type_id, val_id); -@@ -10608,12 +10601,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -10593,9 +10409,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VSIR_OP_DCL_INDEXABLE_TEMP: + spirv_compiler_emit_dcl_indexable_temp(compiler, instruction); + break; +- case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: +- spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction); +- break; + case VSIR_OP_DCL_TGSM_RAW: + spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction); + break; +@@ -10608,12 +10421,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VSIR_OP_DCL_VERTICES_OUT: spirv_compiler_emit_output_vertex_count(compiler, instruction); break; @@ -13105,7 +20134,62 @@ index 97c0d0e73a8..9c5f71ee11f 100644 case VSIR_OP_DCL_GS_INSTANCES: spirv_compiler_emit_dcl_gs_instances(compiler, instruction); break; -@@ -11066,7 +11053,14 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, +@@ -10668,6 +10475,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VSIR_OP_ITOF: + case VSIR_OP_ITOI: + case VSIR_OP_MUL: ++ case VSIR_OP_NEG: + case VSIR_OP_NOT: + case VSIR_OP_OR: + case VSIR_OP_UDIV_SIMPLE: +@@ -10682,6 +10490,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VSIR_OP_ISFINITE: + spirv_compiler_emit_isfinite(compiler, instruction); + break; ++ case VSIR_OP_SATURATE: ++ spirv_compiler_emit_saturate(compiler, instruction); ++ break; + case VSIR_OP_ABS: + case VSIR_OP_ACOS: + case VSIR_OP_ASIN: +@@ -11044,6 +10855,36 @@ static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *c + } + } + ++static void spirv_compiler_emit_immediate_constant_buffers(struct spirv_compiler *compiler) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ const struct vkd3d_shader_immediate_constant_buffer *icb; ++ const struct vsir_program *program = compiler->program; ++ uint32_t type_id, const_id, ptr_type_id, icb_id; ++ struct vkd3d_shader_register reg; ++ struct vkd3d_symbol reg_symbol; ++ size_t i; ++ ++ for (i = 0; i < program->icb_count; ++i) ++ { ++ icb = program->icbs[i]; ++ ++ const_id = spirv_compiler_emit_constant_array(compiler, icb, &type_id); ++ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); ++ icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ++ ptr_type_id, SpvStorageClassPrivate, const_id); ++ vkd3d_spirv_build_op_name(builder, icb_id, "icb%zu", icb->register_idx); ++ ++ /* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */ ++ 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, ++ icb->data_type, vkd3d_write_mask_from_component_count(icb->component_count)); ++ spirv_compiler_put_symbol(compiler, ®_symbol); ++ } ++} ++ + static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv) + { +@@ -11066,10 +10907,18 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (program->ssa_count) spirv_compiler_allocate_ssa_register_ids(compiler, program->ssa_count); if (compiler->shader_type == VKD3D_SHADER_TYPE_COMPUTE) @@ -13120,18 +20204,42 @@ index 97c0d0e73a8..9c5f71ee11f 100644 spirv_compiler_emit_global_flags(compiler, program->global_flags); spirv_compiler_emit_descriptor_declarations(compiler); -@@ -11080,8 +11074,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, ++ spirv_compiler_emit_immediate_constant_buffers(compiler); + + compiler->spirv_parameter_info = vkd3d_calloc(program->parameter_count, sizeof(*compiler->spirv_parameter_info)); + for (i = 0; i < program->parameter_count; ++i) +@@ -11080,8 +10929,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, { uint32_t type_id, struct_id, ptr_type_id, var_id; - type_id = vkd3d_spirv_get_type_id(builder, - vkd3d_component_type_from_data_type(parameter_data_type_map[parameter->data_type].type), -+ type_id = spirv_get_type_id(builder, parameter_data_type_map[parameter->data_type].type, ++ type_id = spirv_get_type_id(compiler, parameter_data_type_map[parameter->data_type].type, parameter_data_type_map[parameter->data_type].component_count); struct_id = vkd3d_spirv_build_op_type_struct(builder, &type_id, 1); +@@ -11188,7 +11036,11 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + } + + if (compiler->failed) ++ { ++ vkd3d_shader_free_shader_code(spirv); ++ + return VKD3D_ERROR_INVALID_SHADER; ++ } + + if (compile_info->target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT) + { +@@ -11215,6 +11067,7 @@ int spirv_compile(struct vsir_program *program, uint64_t config_flags, + + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); ++ VKD3D_ASSERT(program->has_no_modifiers); + + if (!(spirv_compiler = spirv_compiler_create(program, compile_info, + message_context, config_flags))) diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index ea15c1a9ad5..c6d239847c8 100644 +index ea15c1a9ad5..4798a75ce90 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -665,6 +665,8 @@ struct vkd3d_shader_sm4_parser @@ -13344,7 +20452,38 @@ index ea15c1a9ad5..c6d239847c8 100644 struct sm4_instruction instr = { -@@ -4222,6 +4227,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ +@@ -3869,8 +3874,11 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s + + if (ins->opcode == VSIR_OP_DCL || ins->opcode == VSIR_OP_DCL_UAV_TYPED) + { ++ enum vkd3d_sm4_resource_type resource_type = sm4_resource_dimension(ins->declaration.semantic.resource_type); ++ + instr.idx[0] = pack_resource_data_type(ins->declaration.semantic.resource_data_type); + instr.idx_count = 1; ++ instr.extra_bits |= resource_type << VKD3D_SM4_RESOURCE_TYPE_SHIFT; + instr.extra_bits |= ins->declaration.semantic.sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; + resource = &ins->declaration.semantic.resource; + } +@@ -3905,8 +3913,6 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s + if (uav) + instr.extra_bits |= ins->flags << VKD3D_SM5_UAV_FLAGS_SHIFT; + +- instr.extra_bits |= (sm4_resource_dimension(ins->resource_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); +- + write_sm4_instruction(tpf, &instr); + } + +@@ -4164,6 +4170,9 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + { + switch (ins->opcode) + { ++ case VSIR_OP_NOP: ++ break; ++ + case VSIR_OP_DCL_CONSTANT_BUFFER: + tpf_dcl_constant_buffer(tpf, ins); + break; +@@ -4222,6 +4231,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VSIR_OP_DCL: case VSIR_OP_DCL_RESOURCE_RAW: @@ -13352,7 +20491,7 @@ index ea15c1a9ad5..c6d239847c8 100644 case VSIR_OP_DCL_UAV_RAW: case VSIR_OP_DCL_UAV_STRUCTURED: case VSIR_OP_DCL_UAV_TYPED: -@@ -4242,6 +4248,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ +@@ -4242,6 +4252,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VSIR_OP_BREAK: case VSIR_OP_CASE: case VSIR_OP_CONTINUE: @@ -13360,7 +20499,7 @@ index ea15c1a9ad5..c6d239847c8 100644 case VSIR_OP_CUT: case VSIR_OP_CUT_STREAM: case VSIR_OP_DCL_STREAM: -@@ -4267,6 +4274,9 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ +@@ -4267,6 +4278,9 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VSIR_OP_EXP: case VSIR_OP_F16TOF32: case VSIR_OP_F32TOF16: @@ -13370,7 +20509,7 @@ index ea15c1a9ad5..c6d239847c8 100644 case VSIR_OP_FRC: case VSIR_OP_FTOI: case VSIR_OP_FTOU: -@@ -4305,6 +4315,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ +@@ -4305,6 +4319,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VSIR_OP_LD: case VSIR_OP_LD2DMS: case VSIR_OP_LD_RAW: @@ -13378,8 +20517,28 @@ index ea15c1a9ad5..c6d239847c8 100644 case VSIR_OP_LD_UAV_TYPED: case VSIR_OP_LOG: case VSIR_OP_LOOP: +@@ -4508,7 +4523,8 @@ static void tpf_write_section(struct tpf_compiler *tpf, uint32_t tag, const stru + add_section(tpf, tag, &buffer); + } + +-int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_code *rdef, ++int tpf_compile(struct vsir_program *program, uint64_t config_flags, ++ const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_code *rdef, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) + { + enum vkd3d_shader_type shader_type = program->shader_version.type; +@@ -4517,6 +4533,9 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struc + size_t i; + int ret; + ++ if ((ret = vsir_program_optimize(program, config_flags, compile_info, message_context))) ++ return ret; ++ + if ((ret = vsir_allocate_temp_registers(program, message_context))) + return ret; + diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 5fcc836aae1..6087df80970 100644 +index 5fcc836aae1..c0faa30f14a 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 @@ @@ -13441,15 +20600,125 @@ index 5fcc836aae1..6087df80970 100644 } void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, -@@ -1523,7 +1549,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -924,6 +950,7 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig + struct vkd3d_shader_scan_context + { + const struct vkd3d_shader_version *version; ++ const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info; + + struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info; + size_t descriptors_size; +@@ -991,6 +1018,7 @@ static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *con + context->location.line = 2; /* Line 1 is the version token. */ + context->api_version = VKD3D_SHADER_API_VERSION_1_2; + context->combined_sampler_info = combined_sampler_info; ++ context->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO); + + for (i = 0; i < compile_info->option_count; ++i) + { +@@ -1192,15 +1220,6 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; + } + +-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, VSIR_DATA_UNUSED); +- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, +- &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32); +-} +- + const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( + const struct vkd3d_shader_scan_descriptor_info1 *info, + enum vkd3d_shader_descriptor_type type, unsigned int register_id) +@@ -1286,40 +1305,6 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co + s->sampler_index = sampler_idx; + } + +-static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context, +- const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler) +-{ +- unsigned int resource_idx = resource->idx[0].offset; +- unsigned int sampler_idx = sampler->idx[0].offset; +- +- vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler); +- +- if (!context->scan_descriptor_info) +- return; +- +- /* Sample instructions lowered from 1.x texture instructions have no +- * DCL, so we need to add the resource if it didn't already exist. +- * Such descriptors have a fixed count, type, etc. */ +- +- if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, +- VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx)) +- { +- struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx}; +- +- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource, +- &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32); +- } +- +- if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, +- VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx)) +- { +- struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; +- +- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource, +- &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); +- } +-} +- + static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, + enum vsir_data_type resource_data_type, unsigned int sample_count, +@@ -1377,14 +1362,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + vkd3d_shader_scan_sampler_declaration(context, instruction); + break; + case VSIR_OP_DCL: +- if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE) ++ if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE ++ || instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) + break; +- +- if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) +- { +- vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic); +- break; +- } + /* fall through */ + case VSIR_OP_DCL_UAV_TYPED: + vkd3d_shader_scan_typed_resource_declaration(context, instruction); +@@ -1523,9 +1503,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte if (context->cf_info_count) context->cf_info[context->cf_info_count - 1].inside_block = false; break; - case VSIR_OP_TEX: - case VSIR_OP_TEXBEM: - case VSIR_OP_TEXBEML: +- case VSIR_OP_TEXBEM: +- case VSIR_OP_TEXBEML: case VSIR_OP_TEXDP3TEX: -@@ -1683,6 +1708,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + case VSIR_OP_TEXM3x2TEX: + case VSIR_OP_TEXM3x3SPEC: +@@ -1539,6 +1516,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + break; + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_C: ++ case VSIR_OP_SAMPLE: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_C_LZ: +@@ -1546,9 +1524,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + case VSIR_OP_SAMPLE_LOD: + vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg); + break; +- case VSIR_OP_SAMPLE: +- vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg); +- break; + case VSIR_OP_GATHER4_PO: + case VSIR_OP_GATHER4_PO_C: + vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg); +@@ -1683,12 +1658,12 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; struct vkd3d_shader_scan_hull_shader_tessellation_info *tessellation_info; @@ -13457,15 +20726,47 @@ index 5fcc836aae1..6087df80970 100644 struct vkd3d_shader_scan_descriptor_info *descriptor_info; struct vkd3d_shader_scan_signature_info *signature_info; struct vkd3d_shader_scan_context context; -@@ -1704,6 +1730,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + struct vkd3d_shader_instruction *ins; + int ret = VKD3D_OK; +- unsigned int i; + + descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO); + if (descriptor_info) +@@ -1703,7 +1678,11 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + add_descriptor_info = true; } ++ if (program->has_descriptor_info) ++ add_descriptor_info = false; ++ tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO); + thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO); vkd3d_shader_scan_context_init(&context, &program->shader_version, compile_info, add_descriptor_info ? &program->descriptors : NULL, combined_sampler_info, message_context); -@@ -1756,6 +1783,13 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh +@@ -1720,21 +1699,6 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + break; + } + +- for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) +- { +- struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; +- struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1}; +- unsigned int size = program->flat_constant_count[i]; +- struct vkd3d_shader_descriptor_info1 *d; +- +- if (size) +- { +- 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; +- } +- } +- + if (!ret && signature_info) + { + if (!vkd3d_shader_signature_from_shader_signature(&signature_info->input, &program->input_signature) +@@ -1756,6 +1720,13 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh tessellation_info->partitioning = context.partitioning; } @@ -13479,7 +20780,16 @@ index 5fcc836aae1..6087df80970 100644 if (ret < 0) { if (combined_sampler_info) -@@ -2182,6 +2216,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( +@@ -1840,7 +1811,7 @@ static int vsir_program_compile(struct vsir_program *program, const struct vkd3d + 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); ++ ret = tpf_compile(program, config_flags, compile_info, reflection_data, out, message_context); + break; + + case VKD3D_SHADER_TARGET_GLSL: +@@ -2182,6 +2153,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_D3D_BYTECODE, VKD3D_SHADER_TARGET_DXBC_TPF, VKD3D_SHADER_TARGET_FX, @@ -13489,7 +20799,7 @@ index 5fcc836aae1..6087df80970 100644 }; static const enum vkd3d_shader_target_type d3dbc_types[] = -@@ -2253,6 +2290,7 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info +@@ -2253,6 +2227,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; @@ -13497,7 +20807,7 @@ index 5fcc836aae1..6087df80970 100644 int ret; TRACE("compile_info %p, out %p, messages %p.\n", compile_info, out, messages); -@@ -2265,7 +2303,11 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info +@@ -2265,7 +2240,11 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info vkd3d_shader_message_context_init(&message_context, compile_info->log_level); @@ -13510,7 +20820,7 @@ index 5fcc836aae1..6087df80970 100644 vkd3d_shader_message_context_trace_messages(&message_context); if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) -@@ -2279,204 +2321,6 @@ void vkd3d_shader_set_log_callback(PFN_vkd3d_log callback) +@@ -2279,204 +2258,6 @@ void vkd3d_shader_set_log_callback(PFN_vkd3d_log callback) vkd3d_dbg_set_log_callback(callback); } @@ -13716,7 +21026,7 @@ index 5fcc836aae1..6087df80970 100644 const struct vkd3d_shader_signature *input_signature, unsigned int *ret_count, struct vkd3d_shader_varying_map *varyings) diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index e758c16b3d4..3637aa4fdb9 100644 +index e758c16b3d4..404e7cec6ea 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -213,7 +213,7 @@ enum vkd3d_shader_error @@ -13736,7 +21046,23 @@ index e758c16b3d4..3637aa4fdb9 100644 VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, -@@ -716,7 +717,10 @@ enum vsir_data_type +@@ -502,6 +503,7 @@ enum vkd3d_shader_opcode + VSIR_OP_MOVC, + VSIR_OP_MSAD, + VSIR_OP_MUL, ++ VSIR_OP_NEG, + VSIR_OP_NEO, + VSIR_OP_NEU, + VSIR_OP_NOP, +@@ -540,6 +542,7 @@ enum vkd3d_shader_opcode + VSIR_OP_SAMPLE_LOD, + VSIR_OP_SAMPLE_LOD_S, + VSIR_OP_SAMPLE_POS, ++ VSIR_OP_SATURATE, + VSIR_OP_SETP, + VSIR_OP_SGE, + VSIR_OP_SGN, +@@ -716,7 +719,10 @@ enum vsir_data_type VSIR_DATA_F32, VSIR_DATA_F64, @@ -13747,7 +21073,7 @@ index e758c16b3d4..3637aa4fdb9 100644 VSIR_DATA_U8, VSIR_DATA_U16, -@@ -734,10 +738,18 @@ enum vsir_data_type +@@ -734,10 +740,18 @@ enum vsir_data_type VSIR_DATA_TYPE_COUNT, }; @@ -13768,7 +21094,7 @@ index e758c16b3d4..3637aa4fdb9 100644 } static inline bool data_type_is_bool(enum vsir_data_type data_type) -@@ -752,7 +764,7 @@ static inline bool data_type_is_floating_point(enum vsir_data_type data_type) +@@ -752,7 +766,7 @@ static inline bool data_type_is_floating_point(enum vsir_data_type data_type) static inline bool data_type_is_64_bit(enum vsir_data_type data_type) { @@ -13777,7 +21103,17 @@ index e758c16b3d4..3637aa4fdb9 100644 } enum vsir_dimension -@@ -1357,6 +1369,13 @@ static inline bool vkd3d_shader_ver_le(const struct vkd3d_shader_version *v, uns +@@ -866,8 +880,7 @@ enum vkd3d_shader_uav_flags + + enum vkd3d_shader_atomic_rmw_flags + { +- VKD3DARF_SEQ_CST = 0x1, +- VKD3DARF_VOLATILE = 0x2, ++ VKD3DARF_VOLATILE = 0x1, + }; + + enum vkd3d_tessellator_domain +@@ -1357,6 +1370,13 @@ static inline bool vkd3d_shader_ver_le(const struct vkd3d_shader_version *v, uns void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode); @@ -13791,7 +21127,7 @@ index e758c16b3d4..3637aa4fdb9 100644 static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins) { return ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w; -@@ -1410,44 +1429,15 @@ struct vkd3d_shader_param_allocator +@@ -1410,44 +1430,15 @@ struct vkd3d_shader_param_allocator void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count); @@ -13838,7 +21174,7 @@ index e758c16b3d4..3637aa4fdb9 100644 struct vsir_program_iterator { -@@ -1503,13 +1493,46 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev( +@@ -1503,13 +1494,46 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev( } /* When insertion takes place, argument `it' is updated to point to the same @@ -13853,9 +21189,9 @@ index e758c16b3d4..3637aa4fdb9 100644 } +/* When insertion takes place, argument `it' is updated to point to the same -+ * instruction as before the insertion, and the optional argument `ins_it' is -+ * initialized to point to the first inserted instruction. -+ * A pointer to the first inserted instruction is returned. */ ++ * instruction as before the insertion, and argument `ins_it' is initialized ++ * to point to the first inserted instruction. A pointer to the first inserted ++ * instruction is returned. */ +static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before( + struct vsir_program_iterator *it, struct vsir_program_iterator *ins_it, size_t count) +{ @@ -13887,16 +21223,33 @@ index e758c16b3d4..3637aa4fdb9 100644 enum vkd3d_shader_config_flags { VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, -@@ -1575,7 +1598,7 @@ struct vsir_program +@@ -1567,6 +1591,7 @@ struct vsir_program + + struct vkd3d_shader_scan_descriptor_info1 descriptors; + bool has_descriptor_info; ++ size_t descriptors_size; + + unsigned int parameter_count; + const struct vkd3d_shader_parameter1 *parameters; +@@ -1574,8 +1599,7 @@ struct vsir_program + unsigned int input_control_point_count, output_control_point_count; struct vsir_thread_group_size thread_group_size; - unsigned int flat_constant_count[3]; +- unsigned int flat_constant_count[3]; - unsigned int block_count; + unsigned int block_count; /* maximum block count in any function */ unsigned int temp_count; unsigned int ssa_count; enum vsir_global_flags global_flags; -@@ -1599,12 +1622,21 @@ struct vsir_program +@@ -1586,6 +1610,7 @@ struct vsir_program + uint8_t diffuse_written_mask; + enum vsir_control_flow_type cf_type; + enum vsir_normalisation_level normalisation_level; ++ bool has_no_modifiers; + enum vkd3d_tessellator_domain tess_domain; + enum vkd3d_shader_tessellator_partitioning tess_partitioning; + enum vkd3d_shader_tessellator_output_primitive tess_output_primitive; +@@ -1599,12 +1624,25 @@ struct vsir_program struct vkd3d_shader_source_list source_files; const char **block_names; size_t block_name_count; @@ -13914,11 +21267,24 @@ index e758c16b3d4..3637aa4fdb9 100644 enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, struct vkd3d_shader_message_context *message_context); + ++struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program, ++ enum vkd3d_shader_descriptor_type type, unsigned int register_id, ++ const struct vkd3d_shader_register_range *range, ++ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type); +bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb); 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); -@@ -1627,37 +1659,39 @@ bool vsir_instruction_init_with_params(struct vsir_program *program, +@@ -1613,6 +1651,8 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c + 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_optimize(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, +@@ -1627,37 +1667,39 @@ bool vsir_instruction_init_with_params(struct vsir_program *program, static inline struct vkd3d_shader_instruction *vsir_program_append(struct vsir_program *program) { @@ -13969,38 +21335,49 @@ index e758c16b3d4..3637aa4fdb9 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); -@@ -1852,20 +1886,28 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty - { - case VSIR_DATA_BOOL: - return VKD3D_SHADER_COMPONENT_BOOL; +@@ -1826,7 +1868,8 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, + struct vkd3d_shader_message_context *message_context); + +-int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_code *rdef, ++int tpf_compile(struct vsir_program *program, uint64_t config_flags, ++ const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_code *rdef, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); + + enum vkd3d_md5_variant +@@ -1846,55 +1889,39 @@ int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, + struct vsir_program *program, struct vkd3d_shader_code *reflection_data); + +-static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) +-{ +- switch (data_type) +- { +- case VSIR_DATA_BOOL: +- return VKD3D_SHADER_COMPONENT_BOOL; - case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */ -+ case VSIR_DATA_F16: -+ return VKD3D_SHADER_COMPONENT_FLOAT16; - case VSIR_DATA_F32: - case VSIR_DATA_SNORM: - case VSIR_DATA_UNORM: - return VKD3D_SHADER_COMPONENT_FLOAT; - case VSIR_DATA_F64: - return VKD3D_SHADER_COMPONENT_DOUBLE; -+ case VSIR_DATA_I16: -+ return VKD3D_SHADER_COMPONENT_INT16; - case VSIR_DATA_I32: - return VKD3D_SHADER_COMPONENT_INT; +- case VSIR_DATA_F32: +- case VSIR_DATA_SNORM: +- case VSIR_DATA_UNORM: +- return VKD3D_SHADER_COMPONENT_FLOAT; +- case VSIR_DATA_F64: +- return VKD3D_SHADER_COMPONENT_DOUBLE; +- case VSIR_DATA_I32: +- return VKD3D_SHADER_COMPONENT_INT; - case VSIR_DATA_U16: /* Minimum precision. TODO: native 16-bit */ -+ case VSIR_DATA_I64: -+ return VKD3D_SHADER_COMPONENT_INT64; -+ case VSIR_DATA_U16: -+ return VKD3D_SHADER_COMPONENT_UINT16; - case VSIR_DATA_U32: - return VKD3D_SHADER_COMPONENT_UINT; - case VSIR_DATA_U64: - return VKD3D_SHADER_COMPONENT_UINT64; -+ case VSIR_DATA_UNUSED: -+ return VKD3D_SHADER_COMPONENT_VOID; - default: - FIXME("Unhandled data type %#x.\n", data_type); - /* fall-through */ -@@ -1878,23 +1920,41 @@ static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_ +- case VSIR_DATA_U32: +- return VKD3D_SHADER_COMPONENT_UINT; +- case VSIR_DATA_U64: +- return VKD3D_SHADER_COMPONENT_UINT64; +- default: +- FIXME("Unhandled data type %#x.\n", data_type); +- /* fall-through */ +- case VSIR_DATA_MIXED: +- return VKD3D_SHADER_COMPONENT_UINT; +- } +-} +- + static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_shader_component_type component_type) { switch (component_type) { @@ -14034,19 +21411,16 @@ index e758c16b3d4..3637aa4fdb9 100644 + case VKD3D_SHADER_COMPONENT_TYPE_FORCE_32BIT: + break; } -+ +-} + +-static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) +-{ +- return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; + FIXME("Unhandled component type %#x.\n", component_type); + + return VSIR_DATA_UNUSED; } - static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) - { -- return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; -+ return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_INT64 -+ || component_type == VKD3D_SHADER_COMPONENT_UINT64; - } - static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c index f2967835b62..fea8c2440d1 100644 @@ -14312,9 +21686,18 @@ index 67f84aafa29..6af5e2a5c7d 100644 static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3D12Device9 *iface, diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 6bbd6533b74..b6055a50a99 100644 +index 6bbd6533b74..4bd97fd599f 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c +@@ -843,7 +843,7 @@ static struct vk_binding_array *d3d12_root_signature_vk_binding_array_for_type( + { + if (!context->static_samplers_descriptor_set) + { +- if (!context->push_descriptor && context->root_descriptor_set) ++ if (!root_signature->device->vk_info.KHR_push_descriptor && context->root_descriptor_set) + context->static_samplers_descriptor_set = context->root_descriptor_set; + else + /* The descriptor type is irrelevant here, it will never be used. */ @@ -2391,7 +2391,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device, const struct vkd3d_shader_compile_option options[] = diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-74ebd4621f3177f45ce22512019ee968ec4.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-74ebd4621f3177f45ce22512019ee968ec4.patch new file mode 100644 index 00000000..fa786b1f --- /dev/null +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-74ebd4621f3177f45ce22512019ee968ec4.patch @@ -0,0 +1,895 @@ +From 1d274d4a0da9ef10f377394b92fd871904d4319f Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Wed, 5 Nov 2025 10:32:36 +1100 +Subject: [PATCH] Updated vkd3d to 74ebd4621f3177f45ce22512019ee968ec400f4d. + +--- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 22 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 17 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 26 +- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 370 +++++++++++++++++- + libs/vkd3d/libs/vkd3d-shader/msl.c | 164 +++++++- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 1 + + 6 files changed, 573 insertions(+), 27 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index 1de17e2b551..dc9886b5384 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -1976,14 +1976,15 @@ static struct hlsl_ir_node *hlsl_new_error_expr(struct hlsl_ctx *ctx) + return hlsl_new_expr(ctx, HLSL_OP0_ERROR, operands, ctx->builtin_types.error, &loc); + } + +-struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, +- struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc) ++struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct hlsl_block *then_block, ++ struct hlsl_block *else_block, enum hlsl_if_flatten_type flatten_type, const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_if *iff; + + if (!(iff = hlsl_alloc(ctx, sizeof(*iff)))) + return NULL; + init_node(&iff->node, HLSL_IR_IF, NULL, loc); ++ iff->flatten_type = flatten_type; + hlsl_src_from_node(&iff->condition, condition); + hlsl_block_init(&iff->then_block); + hlsl_block_add_block(&iff->then_block, then_block); +@@ -1993,10 +1994,11 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond + return &iff->node; + } + +-void hlsl_block_add_if(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *condition, +- struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc) ++void hlsl_block_add_if(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ struct hlsl_ir_node *condition, struct hlsl_block *then_block, struct hlsl_block *else_block, ++ enum hlsl_if_flatten_type flatten_type, const struct vkd3d_shader_location *loc) + { +- struct hlsl_ir_node *instr = hlsl_new_if(ctx, condition, then_block, else_block, loc); ++ struct hlsl_ir_node *instr = hlsl_new_if(ctx, condition, then_block, else_block, flatten_type, loc); + + if (instr) + { +@@ -2674,7 +2676,8 @@ static struct hlsl_ir_node *clone_if(struct hlsl_ctx *ctx, struct clone_instr_ma + return NULL; + } + +- if (!(dst = hlsl_new_if(ctx, map_instr(map, src->condition.node), &then_block, &else_block, &src->node.loc))) ++ if (!(dst = hlsl_new_if(ctx, map_instr(map, src->condition.node), ++ &then_block, &else_block, src->flatten_type, &src->node.loc))) + { + hlsl_block_cleanup(&then_block); + hlsl_block_cleanup(&else_block); +@@ -3849,6 +3852,13 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i + vkd3d_string_buffer_printf(buffer, "unresolved_continue"); + break; + } ++ ++ if (jump->condition.node) ++ { ++ vkd3d_string_buffer_printf(buffer, " ("); ++ dump_src(buffer, &jump->condition); ++ vkd3d_string_buffer_printf(buffer, ")"); ++ } + } + + static void dump_ir_loop(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_loop *loop) +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index 75027f83e33..87cfaf83f76 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -661,12 +661,20 @@ struct hlsl_ir_call + struct hlsl_ir_function_decl *decl; + }; + ++enum hlsl_if_flatten_type ++{ ++ HLSL_IF_FLATTEN_DEFAULT, ++ HLSL_IF_FORCE_FLATTEN, ++ HLSL_IF_FORCE_BRANCH ++}; ++ + struct hlsl_ir_if + { + struct hlsl_ir_node node; + struct hlsl_src condition; + struct hlsl_block then_block; + struct hlsl_block else_block; ++ enum hlsl_if_flatten_type flatten_type; + }; + + enum hlsl_loop_unroll_type +@@ -1586,8 +1594,9 @@ struct hlsl_ir_node *hlsl_block_add_expr(struct hlsl_ctx *ctx, struct hlsl_block + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_float_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + float f, const struct vkd3d_shader_location *loc); +-void hlsl_block_add_if(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *condition, +- struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc); ++void hlsl_block_add_if(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ struct hlsl_ir_node *condition, struct hlsl_block *then_block, struct hlsl_block *else_block, ++ enum hlsl_if_flatten_type flatten_type, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_node *val, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_int_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -1704,8 +1713,8 @@ struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *no + 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); +-struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, +- struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc); ++struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct hlsl_block *then_block, ++ struct hlsl_block *else_block, enum hlsl_if_flatten_type flatten_type, const struct vkd3d_shader_location *loc); + struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, + enum hlsl_so_object_type so_type, struct hlsl_type *type); + struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 8ec963c8656..92bfd7040fc 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -471,7 +471,7 @@ static void append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co + + hlsl_block_init(&then_block); + hlsl_block_add_jump(ctx, &then_block, HLSL_IR_JUMP_BREAK, NULL, &condition->loc); +- hlsl_block_add_if(ctx, cond_block, not, &then_block, NULL, &condition->loc); ++ hlsl_block_add_if(ctx, cond_block, not, &then_block, NULL, HLSL_IF_FLATTEN_DEFAULT, &condition->loc); + } + + static void check_attribute_list_for_duplicates(struct hlsl_ctx *ctx, const struct parse_attribute_list *attrs) +@@ -9139,6 +9139,7 @@ selection_statement: + { + struct hlsl_ir_node *condition = node_from_block($4); + const struct parse_attribute_list *attributes = &$1; ++ enum hlsl_if_flatten_type flatten_type = HLSL_IF_FLATTEN_DEFAULT; + unsigned int i; + + check_attribute_list_for_duplicates(ctx, attributes); +@@ -9147,10 +9148,19 @@ selection_statement: + { + const struct hlsl_attribute *attr = attributes->attrs[i]; + +- if (!strcmp(attr->name, "branch") +- || !strcmp(attr->name, "flatten")) ++ if (!strcmp(attr->name, "branch")) + { +- hlsl_warning(ctx, &@1, VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE, "Unhandled attribute '%s'.", attr->name); ++ if (flatten_type == HLSL_IF_FORCE_FLATTEN) ++ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, ++ "The 'branch' and 'flatten' attributes are mutually exclusive."); ++ flatten_type = HLSL_IF_FORCE_BRANCH; ++ } ++ else if (!strcmp(attr->name, "flatten")) ++ { ++ if (flatten_type == HLSL_IF_FORCE_BRANCH) ++ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, ++ "The 'branch' and 'flatten' attributes are mutually exclusive."); ++ flatten_type = HLSL_IF_FORCE_FLATTEN; + } + else + { +@@ -9158,10 +9168,16 @@ selection_statement: + } + } + ++ if (flatten_type == HLSL_IF_FORCE_BRANCH && hlsl_version_lt(ctx, 2, 1)) ++ { ++ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, ++ "The 'branch' attribute requires shader model 2.1 or higher."); ++ } ++ + check_condition_type(ctx, condition); + + condition = add_cast(ctx, $4, condition, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &@4); +- hlsl_block_add_if(ctx, $4, condition, $6.then_block, $6.else_block, &@2); ++ hlsl_block_add_if(ctx, $4, condition, $6.then_block, $6.else_block, flatten_type, &@2); + + destroy_block($6.then_block); + destroy_block($6.else_block); +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 9048214923b..6fe29e5bfed 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -1060,7 +1060,7 @@ static void insert_early_return_break(struct hlsl_ctx *ctx, + + hlsl_block_add_jump(ctx, &then_block, HLSL_IR_JUMP_BREAK, NULL, &cf_instr->loc); + +- if (!(iff = hlsl_new_if(ctx, &load->node, &then_block, NULL, &cf_instr->loc))) ++ if (!(iff = hlsl_new_if(ctx, &load->node, &then_block, NULL, HLSL_IF_FLATTEN_DEFAULT, &cf_instr->loc))) + return; + list_add_after(&load->node.entry, &iff->entry); + } +@@ -1245,7 +1245,7 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun + + load = hlsl_block_add_simple_load(ctx, block, func->early_return_var, &cf_instr->loc); + not = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_LOGIC_NOT, load, &cf_instr->loc); +- hlsl_block_add_if(ctx, block, not, &then_block, NULL, &cf_instr->loc); ++ hlsl_block_add_if(ctx, block, not, &then_block, NULL, HLSL_IF_FLATTEN_DEFAULT, &cf_instr->loc); + } + + return has_early_return; +@@ -3916,6 +3916,320 @@ static bool remove_trivial_conditional_branches(struct hlsl_ctx *ctx, struct hls + return true; + } + ++static bool is_conditional_block_simple(const struct hlsl_block *cond_block) ++{ ++ static const unsigned int max_cost = 10; ++ struct hlsl_ir_node *instr; ++ unsigned int cost = 0; ++ ++ LIST_FOR_EACH_ENTRY(instr, &cond_block->instrs, struct hlsl_ir_node, entry) ++ { ++ switch (instr->type) ++ { ++ case HLSL_IR_CONSTANT: ++ case HLSL_IR_STRING_CONSTANT: ++ case HLSL_IR_SWIZZLE: ++ break; ++ ++ case HLSL_IR_EXPR: ++ ++cost; ++ break; ++ ++ case HLSL_IR_JUMP: ++ { ++ struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); ++ ++ if (jump->type != HLSL_IR_JUMP_DISCARD_NZ && jump->type != HLSL_IR_JUMP_DISCARD_NEG) ++ return false; ++ ++cost; ++ break; ++ } ++ ++ case HLSL_IR_STORE: ++ if (hlsl_ir_store(instr)->lhs.var->is_tgsm) ++ return false; ++ ++cost; ++ break; ++ ++ case HLSL_IR_LOAD: ++ if (hlsl_ir_load(instr)->src.var->is_tgsm) ++ return false; ++ break; ++ ++ default: ++ return false; ++ } ++ ++ if (cost > max_cost) ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool can_flatten_conditional_block(struct hlsl_ctx *ctx, const struct hlsl_block *cond_block) ++{ ++ struct hlsl_ir_node *instr; ++ ++ LIST_FOR_EACH_ENTRY(instr, &cond_block->instrs, struct hlsl_ir_node, entry) ++ { ++ switch (instr->type) ++ { ++ case HLSL_IR_CALL: ++ case HLSL_IR_RESOURCE_STORE: ++ case HLSL_IR_INTERLOCKED: ++ case HLSL_IR_SYNC: ++ goto fail; ++ ++ case HLSL_IR_JUMP: ++ { ++ struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); ++ ++ if (jump->type != HLSL_IR_JUMP_DISCARD_NZ && jump->type != HLSL_IR_JUMP_DISCARD_NEG) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Flattening conditional blocks with non-discard jump instructions."); ++ return false; ++ } ++ break; ++ } ++ ++ case HLSL_IR_STORE: ++ if (hlsl_ir_store(instr)->lhs.var->is_tgsm) ++ goto fail; ++ break; ++ ++ case HLSL_IR_IF: ++ { ++ struct hlsl_ir_if *iff = hlsl_ir_if(instr); ++ ++ if (!can_flatten_conditional_block(ctx, &iff->then_block) ++ || !can_flatten_conditional_block(ctx, &iff->else_block)) ++ return false; ++ break; ++ } ++ ++ case HLSL_IR_LOOP: ++ { ++ struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); ++ ++ if (!can_flatten_conditional_block(ctx, &loop->iter) ++ || !can_flatten_conditional_block(ctx, &loop->body)) ++ return false; ++ break; ++ } ++ ++ case HLSL_IR_SWITCH: ++ { ++ struct hlsl_ir_switch *s = hlsl_ir_switch(instr); ++ struct hlsl_ir_switch_case *c; ++ ++ LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) ++ { ++ if (!can_flatten_conditional_block(ctx, &c->body)) ++ return false; ++ } ++ break; ++ } ++ ++ case HLSL_IR_CONSTANT: ++ case HLSL_IR_EXPR: ++ case HLSL_IR_INDEX: ++ case HLSL_IR_LOAD: ++ case HLSL_IR_RESOURCE_LOAD: ++ case HLSL_IR_STRING_CONSTANT: ++ case HLSL_IR_SWIZZLE: ++ case HLSL_IR_COMPILE: ++ case HLSL_IR_SAMPLER_STATE: ++ case HLSL_IR_STATEBLOCK_CONSTANT: ++ break; ++ } ++ } ++ ++ return true; ++ ++fail: ++ hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_CANNOT_FLATTEN, ++ "Conditional branches with side effects cannot be flattened."); ++ return false; ++} ++ ++static bool lower_conditional_block_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, ++ struct hlsl_ir_node *cond, bool is_then) ++{ ++ struct hlsl_ir_node *load, *new_val; ++ struct hlsl_ir_store *store; ++ struct hlsl_type *rhs_type; ++ struct hlsl_block block; ++ ++ if (instr->type != HLSL_IR_STORE) ++ return false; ++ store = hlsl_ir_store(instr); ++ rhs_type = store->rhs.node->data_type; ++ ++ VKD3D_ASSERT(rhs_type->class <= HLSL_CLASS_VECTOR); ++ VKD3D_ASSERT(cond->data_type->e.numeric.dimx == 1); ++ ++ hlsl_block_init(&block); ++ ++ load = hlsl_block_add_load_index(ctx, &block, &store->lhs, NULL, &store->node.loc); ++ ++ if (store->writemask && !hlsl_types_are_equal(rhs_type, load->data_type)) ++ load = hlsl_block_add_swizzle(ctx, &block, hlsl_swizzle_from_writemask(store->writemask), ++ rhs_type->e.numeric.dimx, load, &store->node.loc); ++ ++ if (rhs_type->e.numeric.dimx != 1) ++ cond = hlsl_block_add_swizzle(ctx, &block, HLSL_SWIZZLE(X, X, X, X), ++ rhs_type->e.numeric.dimx, cond, &store->node.loc); ++ ++ if (is_then) ++ new_val = hlsl_add_conditional(ctx, &block, cond, store->rhs.node, load); ++ else ++ new_val = hlsl_add_conditional(ctx, &block, cond, load, store->rhs.node); ++ ++ list_move_before(&store->node.entry, &block.instrs); ++ hlsl_src_remove(&store->rhs); ++ hlsl_src_from_node(&store->rhs, new_val); ++ return true; ++} ++ ++static bool lower_conditional_block_discard_nz(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, ++ struct hlsl_ir_node *cond, bool is_then) ++{ ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; ++ struct hlsl_ir_node *discard_cond, *new_cond = NULL; ++ struct hlsl_ir_jump *jump; ++ struct hlsl_block block; ++ ++ if (instr->type != HLSL_IR_JUMP) ++ return false; ++ jump = hlsl_ir_jump(instr); ++ discard_cond = jump->condition.node; ++ ++ if (jump->type != HLSL_IR_JUMP_DISCARD_NZ) ++ return false; ++ ++ VKD3D_ASSERT(ctx->profile->major_version >= 4); ++ VKD3D_ASSERT(cond->data_type->e.numeric.type == HLSL_TYPE_BOOL && cond->data_type->e.numeric.dimx == 1); ++ VKD3D_ASSERT(discard_cond->data_type->e.numeric.dimx == 1); ++ ++ hlsl_block_init(&block); ++ ++ if (!is_then) ++ cond = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, cond, &instr->loc); ++ discard_cond = hlsl_block_add_cast(ctx, &block, discard_cond, cond->data_type, &instr->loc); ++ ++ operands[0] = cond; ++ operands[1] = discard_cond; ++ ++ /* discard_nz (cond && discard_cond) */ ++ new_cond = hlsl_block_add_expr(ctx, &block, HLSL_OP2_LOGIC_AND, operands, ++ hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &jump->node.loc); ++ ++ list_move_before(&jump->node.entry, &block.instrs); ++ hlsl_src_remove(&jump->condition); ++ hlsl_src_from_node(&jump->condition, new_cond); ++ return true; ++} ++ ++static bool lower_conditional_block_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, ++ struct hlsl_ir_node *cond, bool is_then) ++{ ++ struct hlsl_ir_node *discard_cond, *new_cond = NULL; ++ struct hlsl_constant_value zero_value = {0}; ++ struct hlsl_ir_node *zero; ++ struct hlsl_ir_jump *jump; ++ struct hlsl_block block; ++ ++ if (instr->type != HLSL_IR_JUMP) ++ return false; ++ jump = hlsl_ir_jump(instr); ++ discard_cond = jump->condition.node; ++ ++ if (jump->type != HLSL_IR_JUMP_DISCARD_NEG) ++ return false; ++ ++ VKD3D_ASSERT(ctx->profile->major_version < 4); ++ VKD3D_ASSERT(cond->data_type->e.numeric.type == HLSL_TYPE_BOOL && cond->data_type->e.numeric.dimx == 1); ++ ++ hlsl_block_init(&block); ++ ++ if (!(zero = hlsl_new_constant(ctx, discard_cond->data_type, &zero_value, &instr->loc))) ++ return false; ++ hlsl_block_add_instr(&block, zero); ++ ++ if (zero->data_type->e.numeric.dimx != 1) ++ cond = hlsl_block_add_swizzle(ctx, &block, HLSL_SWIZZLE(X, X, X, X), ++ zero->data_type->e.numeric.dimx, cond, &instr->loc); ++ ++ if (is_then) ++ new_cond = hlsl_add_conditional(ctx, &block, cond, discard_cond, zero); ++ else ++ new_cond = hlsl_add_conditional(ctx, &block, cond, zero, discard_cond); ++ ++ list_move_before(&jump->node.entry, &block.instrs); ++ hlsl_src_remove(&jump->condition); ++ hlsl_src_from_node(&jump->condition, new_cond); ++ return true; ++} ++ ++struct flatten_conditional_block_ctx ++{ ++ struct hlsl_ir_node *cond; ++ bool is_then; ++}; ++ ++static bool lower_conditional_block_instrs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct flatten_conditional_block_ctx *flatten_ctx = context; ++ ++ return lower_conditional_block_stores(ctx, instr, flatten_ctx->cond, flatten_ctx->is_then) ++ || lower_conditional_block_discard_nz(ctx, instr, flatten_ctx->cond, flatten_ctx->is_then) ++ || lower_conditional_block_discard_neg(ctx, instr, flatten_ctx->cond, flatten_ctx->is_then); ++} ++ ++static bool flatten_conditional_branches(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct flatten_conditional_block_ctx flatten_ctx; ++ struct hlsl_ir_if *iff; ++ bool force_flatten; ++ ++ if (instr->type != HLSL_IR_IF) ++ return false; ++ iff = hlsl_ir_if(instr); ++ ++ if (iff->flatten_type == HLSL_IF_FORCE_BRANCH) ++ return false; ++ ++ force_flatten = iff->flatten_type == HLSL_IF_FORCE_FLATTEN ++ || hlsl_version_lt(ctx, 2, 1); /* Always flatten branches for SM < 2.1. */ ++ ++ if (force_flatten) ++ { ++ if (!can_flatten_conditional_block(ctx, &iff->then_block) ++ || !can_flatten_conditional_block(ctx, &iff->else_block)) ++ return false; ++ } ++ else if (!is_conditional_block_simple(&iff->then_block) || !is_conditional_block_simple(&iff->else_block)) ++ { ++ /* Only flatten simple blocks by default. */ ++ return false; ++ } ++ ++ flatten_ctx.cond = iff->condition.node; ++ ++ flatten_ctx.is_then = true; ++ hlsl_transform_ir(ctx, lower_conditional_block_instrs, &iff->then_block, &flatten_ctx); ++ ++ flatten_ctx.is_then = false; ++ hlsl_transform_ir(ctx, lower_conditional_block_instrs, &iff->else_block, &flatten_ctx); ++ ++ list_move_before(&instr->entry, &iff->then_block.instrs); ++ list_move_before(&instr->entry, &iff->else_block.instrs); ++ list_remove(&instr->entry); ++ hlsl_free_instr(instr); ++ return true; ++} ++ + static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + struct hlsl_ir_switch_case *c, *def = NULL; +@@ -5462,6 +5776,35 @@ static bool lower_discard_nz(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v + return true; + } + ++static bool cast_discard_neg_conditions_to_vec4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *swizzle; ++ struct hlsl_ir_jump *jump; ++ struct hlsl_block block; ++ unsigned int dimx; ++ ++ if (instr->type != HLSL_IR_JUMP) ++ return false; ++ jump = hlsl_ir_jump(instr); ++ if (jump->type != HLSL_IR_JUMP_DISCARD_NEG) ++ return false; ++ ++ dimx = jump->condition.node->data_type->e.numeric.dimx; ++ if (dimx == 4) ++ return false; ++ ++ hlsl_block_init(&block); ++ ++ swizzle = hlsl_block_add_swizzle(ctx, &block, hlsl_swizzle_from_writemask((1 << dimx) - 1), 4, ++ jump->condition.node, &instr->loc); ++ ++ list_move_before(&instr->entry, &block.instrs); ++ hlsl_src_remove(&jump->condition); ++ hlsl_src_from_node(&jump->condition, swizzle); ++ ++ return true; ++} ++ + static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + switch (instr->type) +@@ -8465,6 +8808,7 @@ static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *bod + progress |= replace_ir(ctx, fold_swizzle_chains, body); + progress |= replace_ir(ctx, fold_trivial_swizzles, body); + progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); ++ progress |= hlsl_transform_ir(ctx, flatten_conditional_branches, body, NULL); + } while (progress); + replace_ir(ctx, fold_redundant_casts, body); + } +@@ -9996,6 +10340,8 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, + + if (jump->type == HLSL_IR_JUMP_DISCARD_NEG) + { ++ VKD3D_ASSERT(condition->data_type->e.numeric.dimx == 4); ++ + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_TEXKILL, 0, 1))) + return; + +@@ -10016,11 +10362,9 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program + struct hlsl_ir_node *instr = &iff->node; + struct vkd3d_shader_instruction *ins; + +- if (hlsl_version_lt(ctx, 2, 1)) +- { +- hlsl_fixme(ctx, &instr->loc, "Flatten \"if\" conditionals branches."); +- return; +- } ++ /* Conditional branches should have already been flattened for SM < 2.1. */ ++ VKD3D_ASSERT(hlsl_version_ge(ctx, 2, 1)); ++ + 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, VSIR_OP_IFC, 0, 2))) +@@ -13835,7 +14179,7 @@ static struct hlsl_ir_if *loop_unrolling_generate_var_check(struct hlsl_ctx *ctx + load = hlsl_block_add_simple_load(ctx, dst, var, loc); + cond = hlsl_block_add_unary_expr(ctx, dst, HLSL_OP1_LOGIC_NOT, load, loc); + +- if (!(iff = hlsl_new_if(ctx, cond, &then_block, NULL, loc))) ++ if (!(iff = hlsl_new_if(ctx, cond, &then_block, NULL, HLSL_IF_FLATTEN_DEFAULT, loc))) + return NULL; + hlsl_block_add_instr(dst, iff); + +@@ -14815,6 +15159,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v + { + while (replace_ir(ctx, lower_nonconstant_array_loads, body)); + ++ hlsl_transform_ir(ctx, cast_discard_neg_conditions_to_vec4, body, NULL); ++ + replace_ir(ctx, lower_ternary, body); + replace_ir(ctx, lower_int_modulus_sm1, body); + replace_ir(ctx, lower_division, body); +@@ -14847,6 +15193,14 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v + + hlsl_run_folding_passes(ctx, body); + ++ if (profile->major_version < 4) ++ { ++ /* Ternary operations can be potentially introduced by hlsl_run_folding_passes(). */ ++ replace_ir(ctx, lower_ternary, body); ++ if (ctx->profile->type != VKD3D_SHADER_TYPE_PIXEL) ++ replace_ir(ctx, lower_cmp, body); ++ } ++ + do + compute_liveness(ctx, body); + while (hlsl_transform_ir(ctx, dce, body, NULL)); +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index c974c9e532b..d34133d6d4c 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -226,14 +226,22 @@ static bool msl_get_binding(const struct msl_generator *gen, const struct vkd3d_ + continue; + if (binding->register_space != descriptor->register_space) + continue; +- if (binding->register_index != register_idx) ++ if (binding->register_index > descriptor->register_index) ++ continue; ++ if (descriptor->count != ~0u && binding->binding.count < descriptor->count) ++ continue; ++ if (descriptor->count != ~0u ++ && binding->binding.count - descriptor->count < descriptor->register_index - binding->register_index) ++ continue; ++ if (descriptor->count == ~0u ++ && binding->binding.count <= descriptor->register_index - binding->register_index) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; + if ((binding->flags & flags) != flags) + continue; + +- *idx = binding->binding.binding; ++ *idx = register_idx + binding->binding.binding - binding->register_index; + return true; + } + +@@ -416,6 +424,11 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu + msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); + return MSL_DATA_UNION; + ++ case VKD3DSPR_IMMCONSTBUFFER: ++ vkd3d_string_buffer_printf(buffer, "icb%u", reg->idx[0].offset); ++ msl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); ++ return MSL_DATA_UINT; ++ + 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); +@@ -445,6 +458,24 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu + vkd3d_string_buffer_printf(buffer, "v_local_thread_index"); + return MSL_DATA_UNION; + ++ case VKD3DSPR_UNDEF: ++ switch (reg->dimension) ++ { ++ case VSIR_DIMENSION_SCALAR: ++ vkd3d_string_buffer_printf(buffer, "0u"); ++ return MSL_DATA_UINT; ++ ++ case VSIR_DIMENSION_VEC4: ++ vkd3d_string_buffer_printf(buffer, "uint4(0u, 0u, 0u, 0u)"); ++ return MSL_DATA_UINT; ++ ++ default: ++ vkd3d_string_buffer_printf(buffer, "", reg->dimension); ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled dimension %#x.", reg->dimension); ++ return MSL_DATA_UINT; ++ } ++ + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled register type %#x.", reg->type); +@@ -667,6 +698,28 @@ static void msl_dot(struct msl_generator *gen, const struct vkd3d_shader_instruc + msl_dst_cleanup(&dst, &gen->string_buffers); + } + ++static void msl_firstbit(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ const char *op = ins->opcode == VSIR_OP_FIRSTBIT_LO ? "ctz" : "clz"; ++ unsigned int mask_size; ++ struct msl_src src; ++ struct msl_dst dst; ++ uint32_t mask; ++ ++ mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); ++ msl_src_init(&src, gen, &ins->src[0], mask); ++ ++ if ((mask_size = vsir_write_mask_component_count(mask)) > 1) ++ msl_print_assignment(gen, &dst, "select(uint%u(0xffffffffu), %s(%s), bool%u(%s))", ++ mask_size, op, src.str->buffer, mask_size, src.str->buffer); ++ else ++ msl_print_assignment(gen, &dst, "%s ? %s(%s) : 0xffffffffu", ++ src.str->buffer, op, src.str->buffer); ++ ++ msl_src_cleanup(&src, &gen->string_buffers); ++ msl_dst_cleanup(&dst, &gen->string_buffers); ++} ++ + static void msl_intrinsic(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) + { + struct vkd3d_string_buffer *args; +@@ -1336,6 +1389,46 @@ static void msl_dcl_indexable_temp(struct msl_generator *gen, const struct vkd3d + ins->declaration.indexable_temp.register_size); + } + ++static void msl_barrier(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ uint32_t flags = ins->flags; ++ ++ if (flags & (VKD3DSSF_GLOBAL_UAV | VKD3DSSF_THREAD_GROUP_UAV)) ++ { ++ const char *scope = flags & VKD3DSSF_GLOBAL_UAV ? "thread_scope_device" : "thread_scope_threadgroup"; ++ const char *mem_flags = "mem_flags::mem_device | mem_flags::mem_texture"; ++ ++ if (flags & VKD3DSSF_GROUP_SHARED_MEMORY) ++ { ++ mem_flags = "mem_flags::mem_device | mem_flags::mem_texture | mem_flags::mem_threadgroup"; ++ flags &= ~VKD3DSSF_GROUP_SHARED_MEMORY; ++ } ++ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, ++ "atomic_thread_fence(%s, memory_order_seq_cst, %s);\n", mem_flags, scope); ++ flags &= ~(VKD3DSSF_GLOBAL_UAV | VKD3DSSF_THREAD_GROUP_UAV); ++ } ++ else if (flags & VKD3DSSF_GROUP_SHARED_MEMORY) ++ { ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, ++ "atomic_thread_fence(mem_flags::mem_threadgroup, memory_order_seq_cst, thread_scope_threadgroup);\n"); ++ flags &= ~VKD3DSSF_GROUP_SHARED_MEMORY; ++ } ++ ++ if (flags & VKD3DSSF_THREAD_GROUP) ++ { ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "threadgroup_barrier(mem_flags::mem_none);\n"); ++ flags &= ~VKD3DSSF_THREAD_GROUP; ++ } ++ ++ if (flags) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled synchronisation flags %#x.", flags); ++} ++ + static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + gen->location = ins->location; +@@ -1373,6 +1466,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VSIR_OP_COS: + msl_intrinsic(gen, ins, "cos"); + break; ++ case VSIR_OP_COUNTBITS: ++ msl_intrinsic(gen, ins, "popcount"); ++ break; + case VSIR_OP_DCL_INDEXABLE_TEMP: + msl_dcl_indexable_temp(gen, ins); + break; +@@ -1425,6 +1521,10 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VSIR_OP_EXP: + msl_intrinsic(gen, ins, "exp2"); + break; ++ case VSIR_OP_FIRSTBIT_HI: ++ case VSIR_OP_FIRSTBIT_LO: ++ msl_firstbit(gen, ins); ++ break; + case VSIR_OP_FRC: + msl_intrinsic(gen, ins, "fract"); + break; +@@ -1570,6 +1670,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VSIR_OP_SWITCH: + msl_switch(gen, ins); + break; ++ case VSIR_OP_SYNC: ++ msl_barrier(gen, ins); ++ break; + case VSIR_OP_TAN: + msl_intrinsic(gen, ins, "tan"); + break; +@@ -1857,6 +1960,59 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) + vkd3d_string_buffer_printf(buffer, "};\n\n"); + } + ++static void msl_generate_immediate_constant_buffers(struct msl_generator *gen) ++{ ++ const struct vkd3d_shader_immediate_constant_buffer *icb; ++ size_t i, j; ++ ++ for (i = 0; i < gen->program->icb_count; ++i) ++ { ++ icb = gen->program->icbs[i]; ++ ++ if (data_type_is_64_bit(icb->data_type)) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Immediate constant buffer %zu has unhandled data type \"%s\" (%#x).", ++ i, vsir_data_type_get_name(icb->data_type, ""), icb->data_type); ++ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "constant %s icb%u[%u] =", ++ icb->component_count == 4 ? "uint4" : "uint", icb->register_idx, icb->element_count); ++ ++ if (icb->is_null || data_type_is_64_bit(icb->data_type)) ++ { ++ vkd3d_string_buffer_printf(gen->buffer, " {};\n\n"); ++ continue; ++ } ++ ++ vkd3d_string_buffer_printf(gen->buffer, "\n"); ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "{\n"); ++ ++ if (icb->component_count == 4) ++ { ++ for (j = 0; j < icb->element_count; ++j) ++ { ++ msl_print_indent(gen->buffer, gen->indent + 1); ++ vkd3d_string_buffer_printf(gen->buffer, "{0x%08x, 0x%08x, 0x%08x, 0x%08x},\n", ++ icb->data[4 * j + 0], icb->data[4 * j + 1], icb->data[4 * j + 2], icb->data[4 * j + 3]); ++ } ++ } ++ else ++ { ++ for (j = 0; j < icb->element_count; ++j) ++ { ++ if (!(j & 3)) ++ msl_print_indent(gen->buffer, gen->indent + 1); ++ vkd3d_string_buffer_printf(gen->buffer, "0x%08x,%s", icb->data[j], ++ j == icb->element_count - 1 || (j & 3) == 3 ? "\n" : " "); ++ } ++ } ++ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "};\n\n"); ++ } ++} ++ + static void msl_generate_entrypoint_prologue(struct msl_generator *gen) + { + const struct shader_signature *signature = &gen->program->input_signature; +@@ -2102,8 +2258,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); + + vkd3d_string_buffer_printf(gen->buffer, "/* Generated by %s. */\n\n", vkd3d_shader_get_version(NULL, NULL)); +- vkd3d_string_buffer_printf(gen->buffer, "#include \n"); +- vkd3d_string_buffer_printf(gen->buffer, "#include \n\n"); ++ vkd3d_string_buffer_printf(gen->buffer, "#include \n"); + vkd3d_string_buffer_printf(gen->buffer, "using namespace metal;\n\n"); + + if (gen->program->global_flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL)) +@@ -2144,6 +2299,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + + msl_generate_input_struct_declarations(gen); + msl_generate_output_struct_declarations(gen); ++ msl_generate_immediate_constant_buffers(gen); + + vkd3d_string_buffer_printf(gen->buffer, + "static void %s_main(thread vkd3d_vec4 *v, " +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 404e7cec6ea..763a4906919 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -175,6 +175,7 @@ enum vkd3d_shader_error + 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_ERROR_HLSL_CANNOT_FLATTEN = 5046, + + VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, + VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, +-- +2.51.0 + diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-cd64aa69c886c7dd7148072ee69b6e70bff.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-cd64aa69c886c7dd7148072ee69b6e70bff.patch deleted file mode 100644 index d933fe97..00000000 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-cd64aa69c886c7dd7148072ee69b6e70bff.patch +++ /dev/null @@ -1,1571 +0,0 @@ -From a42f0f57fe9b61c4591efe5fd148ee2e0e1752a4 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 7 Oct 2025 08:00:36 +1100 -Subject: [PATCH] Updated vkd3d to cd64aa69c886c7dd7148072ee69b6e70bff2f064. - ---- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 57 ++- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 1 + - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 28 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 51 ++- - libs/vkd3d/libs/vkd3d-shader/ir.c | 431 +++++++++++++++++- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 171 ++++--- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 14 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 2 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 5 +- - 9 files changed, 616 insertions(+), 144 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index fbf9de20278..2379efd3a02 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -659,7 +659,7 @@ static unsigned int make_mask_contiguous(unsigned int mask) - - static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool output, - const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval, -- unsigned int register_index, bool is_dcl, unsigned int mask) -+ unsigned int register_index, bool is_dcl, unsigned int mask, uint32_t dst_modifiers) - { - struct vsir_program *program = sm1->program; - struct shader_signature *signature; -@@ -695,7 +695,8 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp - element->mask = make_mask_contiguous(mask); - element->used_mask = is_dcl ? 0 : mask; - if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) -- element->interpolation_mode = VKD3DSIM_LINEAR; -+ element->interpolation_mode = (dst_modifiers & VKD3DSPDM_MSAMPCENTROID) -+ ? VKD3DSIM_LINEAR_CENTROID : VKD3DSIM_LINEAR; - - return true; - } -@@ -748,7 +749,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, - } - - static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1, -- const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) -+ const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask, uint32_t dst_modifiers) - { - const struct vkd3d_shader_version *version = &sm1->program->shader_version; - unsigned int register_index = reg->idx_count > 0 ? reg->idx[0].offset : 0; -@@ -757,7 +758,8 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * - { - case VKD3DSPR_TEMP: - if (version->type == VKD3D_SHADER_TYPE_PIXEL && version->major == 1 && !register_index) -- return add_signature_element(sm1, true, "COLOR", 0, VKD3D_SHADER_SV_TARGET, 0, is_dcl, mask); -+ return add_signature_element(sm1, true, "COLOR", 0, VKD3D_SHADER_SV_TARGET, -+ 0, is_dcl, mask, dst_modifiers); - return true; - - case VKD3DSPR_INPUT: -@@ -769,15 +771,15 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * - return true; - } - return add_signature_element(sm1, false, "COLOR", register_index, -- VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask); -+ VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask, dst_modifiers); - - case VKD3DSPR_TEXTURE: - return add_signature_element(sm1, false, "TEXCOORD", register_index, -- VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask); -+ VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask, dst_modifiers); - - case VKD3DSPR_TEXCRDOUT: - return add_signature_element(sm1, true, "TEXCOORD", register_index, -- VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask); -+ VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask, dst_modifiers); - - case VKD3DSPR_OUTPUT: - if (version->type == VKD3D_SHADER_TYPE_VERTEX) -@@ -789,30 +791,30 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * - - case VKD3DSPR_ATTROUT: - return add_signature_element(sm1, true, "COLOR", register_index, -- VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask); -+ VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask, dst_modifiers); - - case VKD3DSPR_COLOROUT: - return add_signature_element(sm1, true, "COLOR", register_index, -- VKD3D_SHADER_SV_TARGET, register_index, is_dcl, mask); -+ VKD3D_SHADER_SV_TARGET, register_index, is_dcl, mask, dst_modifiers); - - case VKD3DSPR_DEPTHOUT: - return add_signature_element(sm1, true, "DEPTH", 0, -- VKD3D_SHADER_SV_DEPTH, register_index, is_dcl, 0x1); -+ VKD3D_SHADER_SV_DEPTH, register_index, is_dcl, 0x1, dst_modifiers); - - case VKD3DSPR_RASTOUT: - switch (register_index) - { - case 0: -- return add_signature_element(sm1, true, "POSITION", 0, -- VKD3D_SHADER_SV_POSITION, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, mask); -+ return add_signature_element(sm1, true, "POSITION", 0, VKD3D_SHADER_SV_POSITION, -+ SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, mask, dst_modifiers); - - case 1: -- return add_signature_element(sm1, true, "FOG", 0, -- VKD3D_SHADER_SV_NONE, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1); -+ return add_signature_element(sm1, true, "FOG", 0, VKD3D_SHADER_SV_NONE, -+ SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1, dst_modifiers); - - case 2: -- return add_signature_element(sm1, true, "PSIZE", 0, -- VKD3D_SHADER_SV_NONE, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1); -+ return add_signature_element(sm1, true, "PSIZE", 0, VKD3D_SHADER_SV_NONE, -+ SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1, dst_modifiers); - - default: - vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX, -@@ -825,11 +827,11 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * - { - case 0: - return add_signature_element(sm1, false, "VPOS", 0, -- VKD3D_SHADER_SV_POSITION, register_index, is_dcl, mask); -+ VKD3D_SHADER_SV_POSITION, register_index, is_dcl, mask, dst_modifiers); - - case 1: - return add_signature_element(sm1, false, "VFACE", 0, -- VKD3D_SHADER_SV_IS_FRONT_FACE, register_index, is_dcl, 0x1); -+ VKD3D_SHADER_SV_IS_FRONT_FACE, register_index, is_dcl, 0x1, dst_modifiers); - - default: - vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX, -@@ -849,6 +851,7 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser * - const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg; - enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; - unsigned int mask = semantic->resource.reg.write_mask; -+ uint32_t modifiers = semantic->resource.reg.modifiers; - bool output; - - static const char sm1_semantic_names[][13] = -@@ -874,11 +877,11 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser * - else if (reg->type == VKD3DSPR_INPUT || reg->type == VKD3DSPR_TEXTURE) - output = false; - else /* vpos and vface don't have a semantic. */ -- return add_signature_element_from_register(sm1, reg, true, mask); -+ return add_signature_element_from_register(sm1, reg, true, mask, modifiers); - - /* sm2 pixel shaders use DCL but don't provide a semantic. */ - if (version->type == VKD3D_SHADER_TYPE_PIXEL && version->major == 2) -- return add_signature_element_from_register(sm1, reg, true, mask); -+ return add_signature_element_from_register(sm1, reg, true, mask, modifiers); - - /* With the exception of vertex POSITION output, none of these are system - * values. Pixel POSITION input is not equivalent to SV_Position; the closer -@@ -887,8 +890,8 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser * - && output && semantic->usage == VKD3D_DECL_USAGE_POSITION) - sysval = VKD3D_SHADER_SV_POSITION; - -- return add_signature_element(sm1, output, sm1_semantic_names[semantic->usage], -- semantic->usage_idx, sysval, reg->idx[0].offset, true, mask); -+ return add_signature_element(sm1, output, sm1_semantic_names[semantic->usage], semantic->usage_idx, sysval, -+ reg->idx[0].offset, true, mask, modifiers); - } - - static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, -@@ -932,7 +935,7 @@ static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, - break; - } - -- add_signature_element_from_register(sm1, reg, false, mask); -+ add_signature_element_from_register(sm1, reg, false, mask, 0); - } - - /* Read a parameter token from the input stream, and possibly a relative -@@ -1990,6 +1993,9 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str - - switch (ins->opcode) - { -+ case VSIR_OP_NOP: -+ break; -+ - case VSIR_OP_DEF: - d3dbc_write_vsir_def(d3dbc, ins); - break; -@@ -2097,6 +2103,8 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, - put_u32(buffer, token); - - reg.write_mask = element->mask; -+ if (element->interpolation_mode == VKD3DSIM_LINEAR_CENTROID) -+ reg.modifiers |= VKD3DSPDM_MSAMPCENTROID; - write_sm1_dst_register(buffer, ®); - } - -@@ -2147,6 +2155,9 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, - struct vkd3d_bytecode_buffer *buffer = &d3dbc.buffer; - int result; - -+ if ((result = vsir_program_optimize(program, config_flags, compile_info, message_context))) -+ return result; -+ - if ((result = vsir_allocate_temp_registers(program, message_context))) - return result; - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 8dbfd062177..6c6243db799 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -248,6 +248,7 @@ struct hlsl_semantic - const char *name; - uint32_t index; - uint32_t stream_index; -+ uint32_t modifiers; - - /* Name exactly as it appears in the sources. */ - const char *raw_name; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index d3004d7cc8a..37b116bed40 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -1082,7 +1082,7 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, - field->loc = v->loc; - field->name = v->name; - field->semantic = v->semantic; -- field->storage_modifiers = modifiers; -+ field->storage_modifiers = modifiers | v->semantic.modifiers; - if (v->initializer.args_count) - { - hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Illegal initializer on a struct field."); -@@ -1211,16 +1211,17 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i - static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters *parameters, - struct parse_parameter *param, const struct vkd3d_shader_location *loc) - { -+ uint32_t modifiers = param->modifiers | param->semantic.modifiers; - struct hlsl_ir_var *var; - - if (param->type->class == HLSL_CLASS_MATRIX) - VKD3D_ASSERT(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); - -- if ((param->modifiers & HLSL_STORAGE_OUT) && (param->modifiers & HLSL_STORAGE_UNIFORM)) -+ if ((modifiers & HLSL_STORAGE_OUT) && (modifiers & HLSL_STORAGE_UNIFORM)) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Parameter '%s' is declared as both \"out\" and \"uniform\".", param->name); - -- if ((param->modifiers & HLSL_STORAGE_OUT) && !(param->modifiers & HLSL_STORAGE_IN) -+ if ((modifiers & HLSL_STORAGE_OUT) && !(modifiers & HLSL_STORAGE_IN) - && (param->type->modifiers & HLSL_MODIFIER_CONST)) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Parameter '%s' is declared as both \"out\" and \"const\".", param->name); -@@ -1234,14 +1235,14 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, - "Missing default value for parameter '%s'.", param->name); - -- if (param->initializer.args_count && (param->modifiers & HLSL_STORAGE_OUT)) -+ if (param->initializer.args_count && (modifiers & HLSL_STORAGE_OUT)) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Output parameter '%s' has a default value.", param->name); - - if (hlsl_get_stream_output_type(param->type)) - check_invalid_stream_output_object(ctx, param->type, param->name, loc); - -- if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers, -+ if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, modifiers, - ¶m->reg_reservation))) - return false; - var->is_param = 1; -@@ -2408,10 +2409,10 @@ static void check_invalid_object_fields(struct hlsl_ctx *ctx, const struct hlsl_ - - static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) - { -+ uint32_t modifiers = v->modifiers | v->semantic.modifiers; - struct hlsl_type *basic_type = v->basic_type; - struct hlsl_ir_function_decl *func; - struct hlsl_semantic new_semantic; -- uint32_t modifiers = v->modifiers; - bool unbounded_res_array = false; - bool constant_buffer = false; - struct hlsl_ir_var *var; -@@ -7847,15 +7848,28 @@ colon_attributes: - semantic: - ':' any_identifier - { -+ static const char *centroid_suffix = "_centroid"; -+ uint32_t modifiers = 0; -+ size_t len; - char *p; - - if (!($$.raw_name = hlsl_strdup(ctx, $2))) - YYABORT; - -- for (p = $2 + strlen($2); p > $2 && isdigit(p[-1]); --p) -+ len = strlen($2); -+ if (ascii_strncasecmp($2, "sv_", 3) -+ && len > strlen(centroid_suffix) -+ && !ascii_strcasecmp($2 + (len - strlen(centroid_suffix)), centroid_suffix)) -+ { -+ modifiers = HLSL_STORAGE_CENTROID; -+ len -= strlen(centroid_suffix); -+ } -+ -+ for (p = $2 + len; p > $2 && isdigit(p[-1]); --p) - ; - $$.name = $2; - $$.index = atoi(p); -+ $$.modifiers = modifiers; - $$.reported_missing = false; - $$.reported_duplicated_output_next_index = 0; - $$.reported_duplicated_input_incompatible_next_index = 0; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 2138c3776a7..d22330cedb7 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -6756,8 +6756,8 @@ static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *bod - allocate_temp_registers_recurse(ctx, body); - } - --static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, -- unsigned int storage_modifiers) -+static enum vkd3d_shader_interpolation_mode get_interpolation_mode(const struct vkd3d_shader_version *version, -+ struct hlsl_type *type, unsigned int storage_modifiers) - { - unsigned int i; - -@@ -6779,6 +6779,9 @@ static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hl - - VKD3D_ASSERT(hlsl_is_numeric_type(type)); - -+ if (version->major < 4) -+ storage_modifiers &= HLSL_STORAGE_LINEAR | HLSL_STORAGE_CENTROID; -+ - if ((storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) - || base_type_get_semantic_equivalent(type->e.numeric.type) == HLSL_TYPE_UINT) - return VKD3DSIM_CONSTANT; -@@ -6885,12 +6888,11 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var - { - unsigned int component_count = is_primitive - ? var->data_type->e.array.type->e.numeric.dimx : var->data_type->e.numeric.dimx; -- int mode = (ctx->profile->major_version < 4) -- ? 0 : sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); - unsigned int reg_size = optimize ? component_count : 4; -+ int mode = VKD3DSIM_NONE; - -- if (special_interpolation) -- mode = VKD3DSIM_NONE; -+ if (version.major >= 4 && !special_interpolation) -+ mode = get_interpolation_mode(&version, var->data_type, var->storage_modifiers); - - var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, - reg_size, component_count, mode, var->force_align, vip_allocation); -@@ -8582,6 +8584,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog - struct shader_signature *signature, bool output, struct hlsl_ir_var *var) - { - enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_VOID; -+ enum vkd3d_shader_interpolation_mode interpolation_mode = VKD3DSIM_NONE; - bool is_primitive = hlsl_type_is_primitive_array(var->data_type); - enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; - unsigned int register_index, mask, use_mask; -@@ -8589,6 +8592,9 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog - enum vkd3d_shader_register_type type; - struct signature_element *element; - -+ if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) -+ interpolation_mode = get_interpolation_mode(&program->shader_version, var->data_type, var->storage_modifiers); -+ - if (hlsl_version_ge(ctx, 4, 0)) - { - struct vkd3d_string_buffer *string; -@@ -8668,6 +8674,13 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog - || (type == VKD3DSPR_INPUT && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)) - register_index += SM1_COLOR_REGISTER_OFFSET; - } -+ -+ if (interpolation_mode == VKD3DSIM_LINEAR_CENTROID -+ && (vkd3d_shader_ver_ge(&program->shader_version, 3, 0) || type != VKD3DSPR_TEXTURE)) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, -+ "The centroid interpolation mode is not supported by the '%s' semantic.", var->semantic.name); -+ } - } - else - { -@@ -8735,13 +8748,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog - element->register_count = 1; - element->mask = mask; - element->used_mask = use_mask; -- if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) -- { -- if (program->shader_version.major >= 4) -- element->interpolation_mode = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); -- else -- element->interpolation_mode = VKD3DSIM_LINEAR; -- } -+ element->interpolation_mode = interpolation_mode; - - switch (var->data_type->e.numeric.type) - { -@@ -9133,6 +9140,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p - reg->type = VKD3DSPR_RESOURCE; - reg->dimension = VSIR_DIMENSION_VEC4; - reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id; -+ if (vkd3d_shader_ver_le(version, 5, 0)) -+ reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); - 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; -@@ -9144,6 +9153,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p - reg->type = VKD3DSPR_UAV; - reg->dimension = VSIR_DIMENSION_VEC4; - reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id; -+ if (vkd3d_shader_ver_le(version, 5, 0)) -+ reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); - 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; -@@ -9155,6 +9166,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p - reg->type = VKD3DSPR_SAMPLER; - reg->dimension = VSIR_DIMENSION_NONE; - reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id; -+ if (vkd3d_shader_ver_le(version, 5, 0)) -+ reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); - 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; -@@ -10801,7 +10814,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs - dst_param->write_mask = write_mask; - - if (var->is_input_semantic && version->type == VKD3D_SHADER_TYPE_PIXEL) -- ins->flags = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); -+ ins->flags = get_interpolation_mode(version, var->data_type, var->storage_modifiers); - } - - static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_program *program, -@@ -12530,7 +12543,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un - extern_resources[*count].component_type = component_type; - - extern_resources[*count].regset = regset; -- extern_resources[*count].id = var->regs[regset].id; -+ extern_resources[*count].id = var->regs[regset].id + regset_offset; - extern_resources[*count].space = var->regs[regset].space; - extern_resources[*count].index = var->regs[regset].index + regset_offset; - extern_resources[*count].bind_count = 1; -@@ -12765,7 +12778,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, - ins->declaration.sampler.range.last = array_last; - ins->declaration.sampler.range.space = resource->space; - -- src_param->reg.idx[0].offset = resource->id; -+ src_param->reg.idx[0].offset = resource->id + i; - src_param->reg.idx[1].offset = array_first; - src_param->reg.idx[2].offset = array_last; - src_param->reg.idx_count = 3; -@@ -12923,13 +12936,11 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, - vsir_resource->range.last = array_last; - vsir_resource->range.space = resource->space; - -- vsir_resource->reg.reg.idx[0].offset = resource->id; -+ vsir_resource->reg.reg.idx[0].offset = resource->id + i; - 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 (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) - { - ins->raw = true; -@@ -12942,6 +12953,8 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, - } - else - { -+ ins->declaration.semantic.resource_type = sm4_generate_vsir_get_resource_type(resource->component_type); -+ - for (unsigned int j = 0; j < 4; ++j) - ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 453b79c75d2..670f6c31cf8 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -28,6 +28,7 @@ struct vsir_transformation_context - const struct vkd3d_shader_compile_info *compile_info; - struct vkd3d_shader_message_context *message_context; - struct vkd3d_shader_location null_location; -+ bool progress; - }; - - static void vsir_transformation_context_init(struct vsir_transformation_context *ctx, -@@ -8850,7 +8851,7 @@ struct liveness_tracker - bool written; - bool fixed_mask; - uint8_t mask; -- unsigned int first_write, last_access; -+ unsigned int first_write, last_access, last_read; - } *ssa_regs, *temp_regs; - }; - -@@ -8864,9 +8865,15 @@ static void liveness_track_src(struct liveness_tracker *tracker, - } - - if (src->reg.type == VKD3DSPR_SSA) -+ { -+ tracker->ssa_regs[src->reg.idx[0].offset].last_read = index; - tracker->ssa_regs[src->reg.idx[0].offset].last_access = index; -+ } - else if (src->reg.type == VKD3DSPR_TEMP) -+ { -+ tracker->temp_regs[src->reg.idx[0].offset].last_read = index; - tracker->temp_regs[src->reg.idx[0].offset].last_access = index; -+ } - } - - static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_shader_dst_param *dst, -@@ -9020,6 +9027,8 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv - reg->first_write = loop_start; - if (reg->last_access < i) - reg->last_access = i; -+ if (reg->last_read < i) -+ reg->last_read = i; - } - - for (unsigned int j = 0; j < program->temp_count; ++j) -@@ -9030,6 +9039,8 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv - reg->first_write = loop_start; - if (reg->last_access < i) - reg->last_access = i; -+ if (reg->last_read < i) -+ reg->last_read = i; - } - } - } -@@ -12888,6 +12899,8 @@ static void vsir_transform_( - struct vsir_transformation_context *ctx, const char *step_name, - enum vkd3d_result (*step)(struct vsir_program *program, struct vsir_transformation_context *ctx)) - { -+ ctx->progress = false; -+ - if (ctx->result < 0) - return; - -@@ -12905,6 +12918,422 @@ static void vsir_transform_( - } - } - -+static bool vsir_instruction_has_side_effects(const struct vkd3d_shader_instruction *ins) -+{ -+ switch (ins->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_BEM: -+ case VSIR_OP_BFI: -+ case VSIR_OP_BFREV: -+ case VSIR_OP_BUFINFO: -+ case VSIR_OP_CHECK_ACCESS_FULLY_MAPPED: -+ case VSIR_OP_CMP: -+ case VSIR_OP_CND: -+ case VSIR_OP_COS: -+ case VSIR_OP_COUNTBITS: -+ case VSIR_OP_CRS: -+ case VSIR_OP_DADD: -+ case VSIR_OP_DDIV: -+ case VSIR_OP_DEF: -+ case VSIR_OP_DEFB: -+ case VSIR_OP_DEFI: -+ case VSIR_OP_DEQO: -+ case VSIR_OP_DFMA: -+ case VSIR_OP_DGEO: -+ case VSIR_OP_DIV: -+ case VSIR_OP_DLT: -+ case VSIR_OP_DMAX: -+ case VSIR_OP_DMIN: -+ case VSIR_OP_DMOV: -+ case VSIR_OP_DMOVC: -+ case VSIR_OP_DMUL: -+ case VSIR_OP_DNE: -+ case VSIR_OP_DP2: -+ case VSIR_OP_DP2ADD: -+ case VSIR_OP_DP3: -+ case VSIR_OP_DP4: -+ case VSIR_OP_DRCP: -+ case VSIR_OP_DST: -+ 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_DTOF: -+ case VSIR_OP_DTOI: -+ case VSIR_OP_DTOU: -+ case VSIR_OP_EQO: -+ case VSIR_OP_EQU: -+ case VSIR_OP_EVAL_CENTROID: -+ case VSIR_OP_EVAL_SAMPLE_INDEX: -+ 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_GATHER4: -+ case VSIR_OP_GATHER4_C: -+ case VSIR_OP_GATHER4_C_S: -+ 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_GATHER4_S: -+ 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_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_STRUCTURED: -+ case VSIR_OP_LD_STRUCTURED_S: -+ case VSIR_OP_LD_UAV_TYPED: -+ case VSIR_OP_LD_UAV_TYPED_S: -+ case VSIR_OP_LIT: -+ case VSIR_OP_LOD: -+ case VSIR_OP_LOG: -+ case VSIR_OP_LOGP: -+ case VSIR_OP_LRP: -+ case VSIR_OP_LTO: -+ case VSIR_OP_LTU: -+ case VSIR_OP_M3x2: -+ case VSIR_OP_M3x3: -+ case VSIR_OP_M3x4: -+ case VSIR_OP_M4x3: -+ case VSIR_OP_M4x4: -+ 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: -+ case VSIR_OP_MUL: -+ case VSIR_OP_NEO: -+ case VSIR_OP_NEU: -+ case VSIR_OP_NOP: -+ case VSIR_OP_NOT: -+ case VSIR_OP_NRM: -+ 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_QUAD_READ_LANE_AT: -+ case VSIR_OP_RCP: -+ case VSIR_OP_RESINFO: -+ 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_B_CL_S: -+ case VSIR_OP_SAMPLE_C: -+ case VSIR_OP_SAMPLE_C_CL_S: -+ case VSIR_OP_SAMPLE_C_LZ: -+ case VSIR_OP_SAMPLE_C_LZ_S: -+ case VSIR_OP_SAMPLE_CL_S: -+ case VSIR_OP_SAMPLE_GRAD: -+ case VSIR_OP_SAMPLE_GRAD_CL_S: -+ case VSIR_OP_SAMPLE_INFO: -+ case VSIR_OP_SAMPLE_LOD: -+ case VSIR_OP_SAMPLE_LOD_S: -+ case VSIR_OP_SAMPLE_POS: -+ case VSIR_OP_SETP: -+ case VSIR_OP_SGE: -+ case VSIR_OP_SGN: -+ case VSIR_OP_SIN: -+ case VSIR_OP_SINCOS: -+ case VSIR_OP_SLT: -+ case VSIR_OP_SQRT: -+ case VSIR_OP_SUB: -+ case VSIR_OP_SWAPC: -+ case VSIR_OP_TAN: -+ 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: -+ 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_BALLOT: -+ 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_BIT_COUNT: -+ case VSIR_OP_WAVE_ALL_TRUE: -+ case VSIR_OP_WAVE_ANY_TRUE: -+ case VSIR_OP_WAVE_IS_FIRST_LANE: -+ 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_PREFIX_BIT_COUNT: -+ case VSIR_OP_WAVE_READ_LANE_AT: -+ case VSIR_OP_WAVE_READ_LANE_FIRST: -+ case VSIR_OP_XOR: -+ return false; -+ -+ 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_BRANCH: -+ case VSIR_OP_BREAK: -+ case VSIR_OP_BREAKC: -+ case VSIR_OP_BREAKP: -+ case VSIR_OP_CALL: -+ case VSIR_OP_CALLNZ: -+ case VSIR_OP_CASE: -+ case VSIR_OP_CONTINUE: -+ case VSIR_OP_CONTINUEP: -+ 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_INDEX_RANGE: -+ case VSIR_OP_DCL_INDEXABLE_TEMP: -+ 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_DEFAULT: -+ case VSIR_OP_DISCARD: -+ 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: -+ 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_PHASE: -+ case VSIR_OP_REP: -+ case VSIR_OP_RET: -+ case VSIR_OP_RETP: -+ 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_TEXKILL: -+ return true; -+ -+ case VSIR_OP_INVALID: -+ case VSIR_OP_COUNT: -+ break; -+ } -+ -+ vkd3d_unreachable(); -+} -+ -+static enum vkd3d_result vsir_program_dce(struct vsir_program *program, -+ struct vsir_transformation_context *ctx) -+{ -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vkd3d_shader_instruction *ins; -+ struct liveness_tracker tracker; -+ enum vkd3d_result ret; -+ unsigned int i; -+ -+ if ((ret = track_liveness(program, &tracker))) -+ return ret; -+ -+ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) -+ { -+ unsigned int used_dst_count = 0; -+ -+ /* FIXME: IMM_ATOMIC_* can still be effectively DCE'd by turning them -+ * into non-immediate ATOMIC_* instructions. */ -+ if (vsir_instruction_has_side_effects(ins)) -+ continue; -+ -+ for (unsigned int j = 0; j < ins->dst_count; ++j) -+ { -+ struct vkd3d_shader_dst_param *dst = &ins->dst[j]; -+ -+ if (dst->reg.type == VKD3DSPR_SSA && !tracker.ssa_regs[dst->reg.idx[0].offset].last_read) -+ { -+ vsir_dst_param_init_null(dst); -+ ctx->progress = true; -+ } -+ else if (dst->reg.type == VKD3DSPR_TEMP -+ && tracker.temp_regs[dst->reg.idx[0].offset].last_read <= i -+ && !(program->shader_version.major == 1 && dst->reg.idx[0].offset == 0)) -+ { -+ vsir_dst_param_init_null(dst); -+ ctx->progress = true; -+ } -+ else if (dst->reg.type != VKD3DSPR_NULL) -+ { -+ ++used_dst_count; -+ } -+ } -+ -+ if (!used_dst_count) -+ vkd3d_shader_instruction_make_nop(ins); -+ } -+ -+ liveness_tracker_cleanup(&tracker); -+ return VKD3D_OK; -+} -+ -+enum vkd3d_result vsir_program_optimize(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; -+ -+ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); -+ -+ do -+ vsir_transform(&ctx, vsir_program_dce); -+ while (ctx.progress); -+ -+ if (TRACE_ON()) -+ vsir_program_trace(program); -+ -+ return ctx.result; -+} -+ - /* Transformations which should happen at parse time, i.e. before scan - * information is returned to the user. - * -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 9c5f71ee11f..3deca660b00 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -3063,7 +3063,7 @@ struct spirv_compiler - struct vkd3d_shader_output_info - { - uint32_t id; -- enum vkd3d_shader_component_type component_type; -+ enum vsir_data_type data_type; - uint32_t array_element_mask; - } *output_info; - uint32_t private_output_variable[MAX_REG_OUTPUT + 1]; /* 1 entry for oDepth */ -@@ -3905,15 +3905,14 @@ static void spirv_compiler_emit_register_debug_name(struct vkd3d_spirv_builder * - } - - static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compiler, -- struct vkd3d_spirv_stream *stream, SpvStorageClass storage_class, -- enum vkd3d_shader_component_type component_type, unsigned int component_count, -- const unsigned int *array_lengths, unsigned int length_count) -+ struct vkd3d_spirv_stream *stream, SpvStorageClass storage_class, enum vsir_data_type data_type, -+ unsigned int component_count, const unsigned int *array_lengths, unsigned int length_count) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, length_id, ptr_type_id; - unsigned int i; - -- type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); -+ type_id = spirv_get_type_id(builder, data_type, component_count); - for (i = 0; i < length_count; ++i) - { - if (!array_lengths[i]) -@@ -3921,17 +3920,16 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil - length_id = spirv_compiler_get_constant_uint(compiler, array_lengths[i]); - type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - } -- - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); -+ - return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0); - } - --static uint32_t spirv_compiler_emit_variable(struct spirv_compiler *compiler, -- struct vkd3d_spirv_stream *stream, SpvStorageClass storage_class, -- enum vkd3d_shader_component_type component_type, unsigned int component_count) -+static uint32_t spirv_compiler_emit_variable(struct spirv_compiler *compiler, struct vkd3d_spirv_stream *stream, -+ SpvStorageClass storage_class, enum vsir_data_type data_type, unsigned int component_count) - { -- return spirv_compiler_emit_array_variable(compiler, stream, storage_class, -- component_type, component_count, NULL, 0); -+ return spirv_compiler_emit_array_variable(compiler, stream, -+ storage_class, data_type, component_count, NULL, 0); - } - - static const struct vkd3d_spec_constant_info -@@ -4404,7 +4402,7 @@ static uint32_t spirv_compiler_get_register_id(struct spirv_compiler *compiler, - } - - return spirv_compiler_emit_variable(compiler, &builder->global_stream, -- SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ SpvStorageClassPrivate, VSIR_DATA_F32, VKD3D_VEC4_SIZE); - } - - static bool vkd3d_swizzle_is_equal(uint32_t dst_write_mask, uint32_t swizzle, uint32_t write_mask) -@@ -4426,9 +4424,8 @@ static bool vkd3d_swizzle_is_scalar(uint32_t swizzle, const struct vkd3d_shader_ - && vsir_swizzle_get_component(swizzle, 3) == component_idx; - } - --static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, -- uint32_t val_id, uint32_t val_write_mask, enum vkd3d_shader_component_type component_type, -- uint32_t swizzle, uint32_t write_mask) -+static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, uint32_t val_id, -+ uint32_t val_write_mask, enum vsir_data_type data_type, uint32_t swizzle, uint32_t write_mask) - { - unsigned int i, component_idx, component_count, val_component_count; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -@@ -4441,7 +4438,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, - && (component_count == 1 || vkd3d_swizzle_is_equal(val_write_mask, swizzle, write_mask))) - return val_id; - -- type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); -+ type_id = spirv_get_type_id(builder, data_type, component_count); - - if (component_count == 1) - { -@@ -4469,13 +4466,14 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, - if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) - components[component_idx++] = vsir_swizzle_get_component(swizzle, i); - } -- return vkd3d_spirv_build_op_vector_shuffle(builder, -- type_id, val_id, val_id, components, component_count); -+ -+ return vkd3d_spirv_build_op_vector_shuffle(builder, type_id, -+ val_id, val_id, components, component_count); - } - - static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compiler, - uint32_t vector1_id, uint32_t vector2_id, uint32_t swizzle, uint32_t write_mask, -- enum vkd3d_shader_component_type component_type, unsigned int component_count) -+ enum vsir_data_type data_type, unsigned int component_count) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t components[VKD3D_VEC4_SIZE]; -@@ -4491,10 +4489,10 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil - else - components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle, i); - } -+ type_id = spirv_get_type_id(builder, data_type, component_count); - -- type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); -- return vkd3d_spirv_build_op_vector_shuffle(builder, -- type_id, vector1_id, vector2_id, components, component_count); -+ return vkd3d_spirv_build_op_vector_shuffle(builder, type_id, -+ vector1_id, vector2_id, components, component_count); - } - - static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, -@@ -4812,8 +4810,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle; - } - -- val_id = spirv_compiler_emit_swizzle(compiler, val_id, reg_info.write_mask, -- vkd3d_component_type_from_data_type(reg_info.data_type), swizzle, val_write_mask); -+ val_id = spirv_compiler_emit_swizzle(compiler, val_id, -+ reg_info.write_mask, reg_info.data_type, swizzle, val_write_mask); - if (reg->data_type == reg_info.data_type) - return val_id; - -@@ -4920,7 +4918,7 @@ static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *co - } - - static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, -- uint32_t dst_id, uint32_t dst_write_mask, enum vkd3d_shader_component_type component_type, -+ uint32_t dst_id, uint32_t dst_write_mask, enum vsir_data_type data_type, - SpvStorageClass storage_class, uint32_t write_mask, uint32_t val_id) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -@@ -4929,7 +4927,7 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, - - if (vsir_write_mask_component_count(dst_write_mask) > 1) - { -- type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); -+ type_id = spirv_get_type_id(builder, data_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); - component_idx = vsir_write_mask_get_component_idx(write_mask); - component_idx -= vsir_write_mask_get_component_idx(dst_write_mask); -@@ -4940,9 +4938,8 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, - vkd3d_spirv_build_op_store(builder, dst_id, val_id, SpvMemoryAccessMaskNone); - } - --static void spirv_compiler_emit_store(struct spirv_compiler *compiler, -- uint32_t dst_id, uint32_t dst_write_mask, enum vkd3d_shader_component_type component_type, -- SpvStorageClass storage_class, uint32_t write_mask, uint32_t val_id) -+static void spirv_compiler_emit_store(struct spirv_compiler *compiler, uint32_t dst_id, uint32_t dst_write_mask, -+ enum vsir_data_type data_type, SpvStorageClass storage_class, uint32_t write_mask, uint32_t val_id) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - unsigned int component_count, dst_component_count; -@@ -4957,7 +4954,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, - - if (dst_component_count == 1 && component_count != 1) - { -- type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); -+ type_id = spirv_get_type_id(builder, data_type, 1); - val_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, - vsir_write_mask_get_component_idx(dst_write_mask)); - write_mask &= dst_write_mask; -@@ -4965,14 +4962,12 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, - } - - if (component_count == 1) -- { -- return spirv_compiler_emit_store_scalar(compiler, -- dst_id, dst_write_mask, component_type, storage_class, write_mask, val_id); -- } -+ return spirv_compiler_emit_store_scalar(compiler, dst_id, -+ dst_write_mask, data_type, storage_class, write_mask, val_id); - - if (dst_component_count != component_count) - { -- type_id = spirv_get_type_id_for_component_type(builder, component_type, dst_component_count); -+ type_id = spirv_get_type_id(builder, data_type, dst_component_count); - dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); - - VKD3D_ASSERT(component_count <= ARRAY_SIZE(components)); -@@ -5031,7 +5026,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, - } - - spirv_compiler_emit_store(compiler, reg_info.id, reg_info.write_mask, -- vkd3d_component_type_from_data_type(data_type), reg_info.storage_class, src_write_mask, val_id); -+ data_type, reg_info.storage_class, src_write_mask, val_id); - } - - static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, -@@ -5089,13 +5084,14 @@ static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compil - const struct vkd3d_shader_dst_param *dst, uint32_t val_id, - enum vkd3d_shader_component_type component_type, uint32_t swizzle) - { -+ enum vsir_data_type data_type = vsir_data_type_from_component_type(component_type); - struct vkd3d_shader_dst_param typed_dst = *dst; -- val_id = spirv_compiler_emit_swizzle(compiler, -- val_id, VKD3DSP_WRITEMASK_ALL, component_type, swizzle, dst->write_mask); -+ -+ val_id = spirv_compiler_emit_swizzle(compiler, val_id, -+ VKD3DSP_WRITEMASK_ALL, data_type, swizzle, dst->write_mask); - /* 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 = vsir_data_type_from_component_type(component_type); -+ * shaders the data types are stored in instructions modifiers. */ -+ typed_dst.reg.data_type = data_type; - spirv_compiler_emit_store_dst(compiler, &typed_dst, val_id); - } - -@@ -5282,8 +5278,8 @@ static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler * - - vkd3d_spirv_enable_capability(builder, SpvCapabilityDrawParameters); - -- base_var_id = spirv_compiler_emit_variable(compiler, &builder->global_stream, -- SpvStorageClassInput, VKD3D_SHADER_COMPONENT_INT, 1); -+ base_var_id = spirv_compiler_emit_variable(compiler, -+ &builder->global_stream, SpvStorageClassInput, VSIR_DATA_I32, 1); - vkd3d_spirv_add_iface_variable(builder, base_var_id); - spirv_compiler_decorate_builtin(compiler, base_var_id, base); - -@@ -5646,7 +5642,7 @@ static uint32_t spirv_compiler_emit_builtin_variable_v(struct spirv_compiler *co - sizes[0] = max(sizes[0], builtin->spirv_array_size); - - id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, -- vkd3d_component_type_from_data_type(builtin->data_type), builtin->component_count, array_sizes, size_count); -+ builtin->data_type, builtin->component_count, array_sizes, size_count); - vkd3d_spirv_add_iface_variable(builder, id); - spirv_compiler_decorate_builtin(compiler, id, builtin->spirv_builtin); - -@@ -5834,7 +5830,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - unsigned int location = signature_element->target_location; - - input_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, -- storage_class, component_type, input_component_count, array_sizes, 2); -+ storage_class, data_type, input_component_count, array_sizes, 2); - vkd3d_spirv_add_iface_variable(builder, input_id); - if (reg_type == VKD3DSPR_PATCHCONST) - { -@@ -5854,7 +5850,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - { - storage_class = SpvStorageClassPrivate; - var_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, -- storage_class, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, array_sizes, 2); -+ storage_class, VSIR_DATA_F32, VKD3D_VEC4_SIZE, array_sizes, 2); - } - - vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, -@@ -5887,8 +5883,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - } - - val_id = spirv_compiler_emit_swizzle(compiler, val_id, -- vkd3d_write_mask_from_component_count(input_component_count), -- VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx); -+ vkd3d_write_mask_from_component_count(input_component_count), VSIR_DATA_F32, -+ VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx); - - spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask >> component_idx, val_id); - } -@@ -5979,13 +5975,13 @@ static void spirv_compiler_emit_shader_signature_outputs(struct spirv_compiler * - { - case VKD3D_SHADER_SV_CLIP_DISTANCE: - compiler->output_info[i].id = clip_distance_id; -- compiler->output_info[i].component_type = VKD3D_SHADER_COMPONENT_FLOAT; -+ compiler->output_info[i].data_type = VSIR_DATA_F32; - compiler->output_info[i].array_element_mask = clip_distance_mask; - break; - - case VKD3D_SHADER_SV_CULL_DISTANCE: - compiler->output_info[i].id = cull_distance_id; -- compiler->output_info[i].component_type = VKD3D_SHADER_COMPONENT_FLOAT; -+ compiler->output_info[i].data_type = VSIR_DATA_F32; - compiler->output_info[i].array_element_mask = cull_distance_mask; - break; - -@@ -6026,7 +6022,6 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - unsigned int component_idx, output_component_count; - const struct signature_element *signature_element; -- enum vkd3d_shader_component_type component_type; - const struct shader_signature *shader_signature; - const struct vkd3d_spirv_builtin *builtin; - enum vkd3d_shader_sysval_semantic sysval; -@@ -6063,14 +6058,12 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - if (builtin) - { - data_type = builtin->data_type; -- component_type = vkd3d_component_type_from_data_type(data_type); - if (!builtin->spirv_array_size) - output_component_count = builtin->component_count; - } - else - { -- component_type = signature_element->component_type; -- data_type = vsir_data_type_from_component_type(component_type); -+ data_type = vsir_data_type_from_component_type(signature_element->component_type); - } - - storage_class = SpvStorageClassOutput; -@@ -6111,7 +6104,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - { - storage_class = SpvStorageClassPrivate; - id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, -- storage_class, component_type, output_component_count, array_sizes, 2); -+ storage_class, data_type, output_component_count, array_sizes, 2); - } - else - { -@@ -6124,7 +6117,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - location = signature_element->semantic_index; - - id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, -- storage_class, component_type, output_component_count, array_sizes, 2); -+ storage_class, data_type, output_component_count, array_sizes, 2); - vkd3d_spirv_add_iface_variable(builder, id); - - if (is_dual_source_blending(compiler) && location < 2) -@@ -6149,7 +6142,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - if (!is_patch_constant) - { - compiler->output_info[element_idx].id = id; -- compiler->output_info[element_idx].component_type = component_type; -+ compiler->output_info[element_idx].data_type = data_type; - } - - var_id = id; -@@ -6157,7 +6150,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - { - storage_class = SpvStorageClassPrivate; - var_id = spirv_compiler_emit_variable(compiler, &builder->global_stream, -- storage_class, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ storage_class, VSIR_DATA_F32, VKD3D_VEC4_SIZE); - } - - vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, -@@ -6207,6 +6200,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - uint32_t type_id, zero_id, ptr_type_id, chain_id, object_id; - const struct signature_element *element; - unsigned int i, index, array_idx; -+ enum vsir_data_type data_type; - uint32_t output_id; - - dst_write_mask = output->mask; -@@ -6232,9 +6226,11 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - if (!write_mask) - return; - -- if (output_info->component_type != VKD3D_SHADER_COMPONENT_FLOAT) -+ data_type = output_info->data_type; -+ -+ if (data_type != VSIR_DATA_F32) - { -- type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(builder, data_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - -@@ -6244,35 +6240,32 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - { - /* Set values to 0 for not initialized shader output components. */ - write_mask |= uninit_mask; -- zero_id = spirv_compiler_get_constant_vector(compiler, -- vsir_data_type_from_component_type(output_info->component_type), VKD3D_VEC4_SIZE, 0); -- val_id = spirv_compiler_emit_vector_shuffle(compiler, -- zero_id, val_id, swizzle, uninit_mask, output_info->component_type, -- vsir_write_mask_component_count(write_mask)); -+ zero_id = spirv_compiler_get_constant_vector(compiler, data_type, VKD3D_VEC4_SIZE, 0); -+ val_id = spirv_compiler_emit_vector_shuffle(compiler, zero_id, val_id, swizzle, -+ uninit_mask, data_type, vsir_write_mask_component_count(write_mask)); - } - else - { -- val_id = spirv_compiler_emit_swizzle(compiler, -- val_id, VKD3DSP_WRITEMASK_ALL, output_info->component_type, swizzle, write_mask); -+ val_id = spirv_compiler_emit_swizzle(compiler, val_id, -+ VKD3DSP_WRITEMASK_ALL, data_type, swizzle, write_mask); - } - - output_id = output_info->id; - if (output_index_id) - { -- type_id = spirv_get_type_id_for_component_type(builder, -- output_info->component_type, vsir_write_mask_component_count(dst_write_mask)); -+ type_id = spirv_get_type_id(builder, data_type, vsir_write_mask_component_count(dst_write_mask)); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); - output_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, output_id, output_index_id); - } - - if (!output_info->array_element_mask) - { -- spirv_compiler_emit_store(compiler, -- output_id, dst_write_mask, output_info->component_type, SpvStorageClassOutput, write_mask, val_id); -+ spirv_compiler_emit_store(compiler, output_id, dst_write_mask, -+ data_type, SpvStorageClassOutput, write_mask, val_id); - return; - } - -- type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, 1); -+ type_id = spirv_get_type_id(builder, data_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); - mask = output_info->array_element_mask; - array_idx = spirv_compiler_get_output_array_index(compiler, output); -@@ -6285,9 +6278,9 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - chain_id = vkd3d_spirv_build_op_access_chain1(builder, - ptr_type_id, output_id, spirv_compiler_get_constant_uint(compiler, index)); - object_id = spirv_compiler_emit_swizzle(compiler, val_id, write_mask, -- output_info->component_type, VKD3D_SHADER_NO_SWIZZLE, VKD3DSP_WRITEMASK_0 << i); -- spirv_compiler_emit_store(compiler, chain_id, VKD3DSP_WRITEMASK_0, -- output_info->component_type, SpvStorageClassOutput, VKD3DSP_WRITEMASK_0 << i, object_id); -+ data_type, VKD3D_SHADER_NO_SWIZZLE, VKD3DSP_WRITEMASK_0 << i); -+ spirv_compiler_emit_store(compiler, chain_id, VKD3DSP_WRITEMASK_0, data_type, -+ SpvStorageClassOutput, VKD3DSP_WRITEMASK_0 << i, object_id); - ++index; - } - } -@@ -6494,7 +6487,7 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t - for (i = 0; i < compiler->temp_count; ++i) - { - id = spirv_compiler_emit_variable(compiler, &builder->global_stream, -- SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ SpvStorageClassPrivate, VSIR_DATA_F32, VKD3D_VEC4_SIZE); - if (!i) - compiler->temp_id = id; - VKD3D_ASSERT(id == compiler->temp_id + i); -@@ -9938,18 +9931,18 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, - } - - val_id = spirv_compiler_emit_swizzle(compiler, val_id, write_mask, -- VKD3D_SHADER_COMPONENT_UINT, src->swizzle, dst->write_mask); -+ VSIR_DATA_U32, src->swizzle, dst->write_mask); - spirv_compiler_emit_store_dst(compiler, dst, val_id); - } - - 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 vsir_data_type data_type = VSIR_DATA_U32; - uint32_t constituents[VKD3D_VEC4_SIZE]; - unsigned int i, size_component_count; - struct vkd3d_shader_image image; -@@ -9991,14 +9984,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - - if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) - { -- component_type = VKD3D_SHADER_COMPONENT_FLOAT; -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); -+ data_type = VSIR_DATA_F32; -+ type_id = spirv_get_type_id(builder, data_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); -+ val_id = spirv_compiler_emit_swizzle(compiler, val_id, -+ VKD3DSP_WRITEMASK_ALL, data_type, src[1].swizzle, dst->write_mask); - - spirv_compiler_emit_store_dst(compiler, dst, val_id); - } -@@ -10030,10 +10023,10 @@ 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; -+ enum vsir_data_type data_type = VSIR_DATA_U32; - uint32_t constituents[VKD3D_VEC4_SIZE]; - uint32_t type_id, val_id; - unsigned int i; -@@ -10054,14 +10047,14 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, - - if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) - { -- component_type = VKD3D_SHADER_COMPONENT_FLOAT; -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); -+ data_type = VSIR_DATA_F32; -+ type_id = spirv_get_type_id(builder, data_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); - if (instruction->flags & VKD3DSI_PRECISE_XYZW) - vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); - } -- val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, -- component_type, src->swizzle, dst->write_mask); -+ val_id = spirv_compiler_emit_swizzle(compiler, val_id, -+ VKD3DSP_WRITEMASK_ALL, data_type, src->swizzle, dst->write_mask); - - spirv_compiler_emit_store_dst(compiler, dst, val_id); - } -@@ -10158,7 +10151,7 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, - id = vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); - - id = spirv_compiler_emit_swizzle(compiler, id, VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1, -- VKD3D_SHADER_COMPONENT_FLOAT, instruction->src[0].swizzle, dst->write_mask); -+ VSIR_DATA_F32, instruction->src[0].swizzle, dst->write_mask); - spirv_compiler_emit_store_dst(compiler, dst, id); - } - -@@ -10205,7 +10198,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, op, src_ids, src_count); - - val_id = spirv_compiler_emit_swizzle(compiler, val_id, register_info.write_mask, -- VKD3D_SHADER_COMPONENT_FLOAT, src[0].swizzle, dst->write_mask); -+ VSIR_DATA_F32, src[0].swizzle, dst->write_mask); - - spirv_compiler_emit_store_dst(compiler, dst, val_id); - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index c6d239847c8..4798a75ce90 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -3874,8 +3874,11 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s - - if (ins->opcode == VSIR_OP_DCL || ins->opcode == VSIR_OP_DCL_UAV_TYPED) - { -+ enum vkd3d_sm4_resource_type resource_type = sm4_resource_dimension(ins->declaration.semantic.resource_type); -+ - instr.idx[0] = pack_resource_data_type(ins->declaration.semantic.resource_data_type); - instr.idx_count = 1; -+ instr.extra_bits |= resource_type << VKD3D_SM4_RESOURCE_TYPE_SHIFT; - instr.extra_bits |= ins->declaration.semantic.sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; - resource = &ins->declaration.semantic.resource; - } -@@ -3910,8 +3913,6 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s - if (uav) - instr.extra_bits |= ins->flags << VKD3D_SM5_UAV_FLAGS_SHIFT; - -- instr.extra_bits |= (sm4_resource_dimension(ins->resource_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); -- - write_sm4_instruction(tpf, &instr); - } - -@@ -4169,6 +4170,9 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ - { - switch (ins->opcode) - { -+ case VSIR_OP_NOP: -+ break; -+ - case VSIR_OP_DCL_CONSTANT_BUFFER: - tpf_dcl_constant_buffer(tpf, ins); - break; -@@ -4519,7 +4523,8 @@ static void tpf_write_section(struct tpf_compiler *tpf, uint32_t tag, const stru - add_section(tpf, tag, &buffer); - } - --int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_code *rdef, -+int tpf_compile(struct vsir_program *program, uint64_t config_flags, -+ const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_code *rdef, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) - { - enum vkd3d_shader_type shader_type = program->shader_version.type; -@@ -4528,6 +4533,9 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struc - size_t i; - int ret; - -+ if ((ret = vsir_program_optimize(program, config_flags, compile_info, message_context))) -+ return ret; -+ - if ((ret = vsir_allocate_temp_registers(program, message_context))) - return ret; - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 6087df80970..2b5badb8871 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -1874,7 +1874,7 @@ static int vsir_program_compile(struct vsir_program *program, const struct vkd3d - 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); -+ ret = tpf_compile(program, config_flags, compile_info, reflection_data, out, message_context); - break; - - case VKD3D_SHADER_TARGET_GLSL: -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 3637aa4fdb9..df0eb2ff789 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1645,6 +1645,8 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c - 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_optimize(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, -@@ -1860,7 +1862,8 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, - struct vkd3d_shader_message_context *message_context); - --int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_code *rdef, -+int tpf_compile(struct vsir_program *program, uint64_t config_flags, -+ const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_code *rdef, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); - - enum vkd3d_md5_variant --- -2.51.0 - diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-b5b5c67b34be0c54bb4ee8a5439d65c2d1d.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-b5b5c67b34be0c54bb4ee8a5439d65c2d1d.patch deleted file mode 100644 index 6f6b493d..00000000 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-b5b5c67b34be0c54bb4ee8a5439d65c2d1d.patch +++ /dev/null @@ -1,5282 +0,0 @@ -From 4d87ad9ccaeae715096c6248fe60ddaacc182575 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 14 Oct 2025 10:43:27 +1100 -Subject: [PATCH] Updated vkd3d to b5b5c67b34be0c54bb4ee8a5439d65c2d1d6ba5d. - ---- - libs/vkd3d/include/vkd3d_shader.h | 61 ++ - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 5 - - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 92 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 118 ++- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 54 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 4 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 4 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 - - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 54 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 897 ++++++++++-------- - libs/vkd3d/libs/vkd3d-shader/ir.c | 653 +++++++++++-- - libs/vkd3d/libs/vkd3d-shader/msl.c | 26 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 334 ++----- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 77 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 52 +- - 15 files changed, 1455 insertions(+), 977 deletions(-) - -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index 3a2f54c8f22..df1f5d5250d 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -125,6 +125,11 @@ enum vkd3d_shader_structure_type - * \since 1.18 - */ - VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO, -+ /** -+ * The structure is a vkd3d_shader_d3dbc_source_info structure. -+ * \since 1.18 -+ */ -+ VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), - }; -@@ -2312,6 +2317,61 @@ struct vkd3d_shader_scan_thread_group_size_info - unsigned int x, y, z; - }; - -+/** -+ * A chained structure containing legacy Direct3D bytecode compilation parameters. -+ * This structure specifies some information about the source environment that -+ * is not specified in the source shader format, but may be necessary for the -+ * target format. -+ * -+ * This structure is optional. -+ * -+ * This structure extends vkd3d_shader_compile_info. -+ * -+ * This structure contains only input parameters. -+ * -+ * \since 1.18 -+ */ -+struct vkd3d_shader_d3dbc_source_info -+{ -+ /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO. */ -+ enum vkd3d_shader_structure_type type; -+ /** Optional pointer to a structure containing further parameters. */ -+ const void *next; -+ -+ /** -+ * The dimension of each texture bound to the shader. -+ * -+ * If this structure is not specified, the dimension for all textures will -+ * be VKD3D_SHADER_RESOURCE_TEXTURE_2D. -+ * -+ * The dimension of textures in this array not used by the shader will be -+ * ignored. -+ * -+ * This field is ignored for shader models 2 and higher. -+ */ -+ enum vkd3d_shader_resource_type texture_dimensions[6]; -+ -+ /** -+ * A mask indicating which samplers should be shadow (i.e. comparison-mode) -+ * samplers. When legacy Direct3D shaders are used with the Direct3D 8 and 9 -+ * APIs, this is implied by the format of the sampled resource; e.g. a -+ * D3DFMT_D24S8 texture implies shadow sampling, while a D3DFMT_A8R8G8B8 -+ * or D3DFMT_INTZ texture does not. -+ * This information is necessary when converting to other formats -+ * (e.g. SPIR-V, GLSL) which specify this in the shader. -+ * -+ * For example, if bit 1 is set (so the value is 0x2), this indicates that -+ * the sampler at bind point 1 (and no others) should be a shadow sampler. -+ * -+ * Bits in this mask corresponding to textures not used by the shader will -+ * be ignored. -+ * -+ * If this structure is not specified, no samplers will be considered to -+ * be shadow samplers. -+ */ -+ uint32_t shadow_samplers; -+}; -+ - /** - * Data type of a shader varying, returned as part of struct - * vkd3d_shader_signature_element. -@@ -2805,6 +2865,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported - * - * Depending on the source and target types, this function may support the - * following chained structures: -+ * - vkd3d_shader_d3dbc_source_info - * - vkd3d_shader_descriptor_offset_info - * - vkd3d_shader_hlsl_source_info - * - vkd3d_shader_interface_info -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 6f8fbe84b90..4573cb67fb5 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -145,11 +145,6 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, en - - static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t atomic_flags) - { -- if (atomic_flags & VKD3DARF_SEQ_CST) -- { -- vkd3d_string_buffer_printf(&compiler->buffer, "_seqCst"); -- atomic_flags &= ~VKD3DARF_SEQ_CST; -- } - if (atomic_flags & VKD3DARF_VOLATILE) - { - vkd3d_string_buffer_printf(&compiler->buffer, "_volatile"); -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 2379efd3a02..b2d4ec23c6e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -248,6 +248,10 @@ struct vkd3d_shader_sm1_parser - struct vkd3d_shader_parser p; - struct vsir_program *program; - -+ const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info; -+ -+ uint16_t texture_descriptors; -+ - struct - { - #define MAX_CONSTANT_COUNT 8192 -@@ -938,6 +942,27 @@ static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, - add_signature_element_from_register(sm1, reg, false, mask, 0); - } - -+static void d3dbc_add_combined_sampler_descriptor(struct vkd3d_shader_sm1_parser *d3dbc, -+ unsigned int sampler_idx, enum vkd3d_shader_resource_type resource_type) -+{ -+ struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; -+ const struct vkd3d_shader_d3dbc_source_info *source_info = d3dbc->d3dbc_source_info; -+ struct vsir_program *program = d3dbc->program; -+ struct vkd3d_shader_descriptor_info1 *d; -+ -+ if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, -+ sampler_idx, &range, resource_type, VSIR_DATA_F32)) -+ vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, -+ "Failed to create SRV descriptor for combined sampler %u.", sampler_idx); -+ -+ if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, -+ sampler_idx, &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) -+ vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, -+ "Failed to create sampler descriptor for combined sampler %u.", sampler_idx); -+ else if (source_info && source_info->shadow_samplers & (1u << sampler_idx)) -+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; -+} -+ - /* Read a parameter token from the input stream, and possibly a relative - * addressing token. */ - static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, -@@ -1102,6 +1127,11 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, - range->first = range->last = semantic->resource.reg.reg.idx[0].offset; - - add_signature_element_from_semantic(sm1, semantic); -+ if (semantic->resource_type) -+ { -+ d3dbc_add_combined_sampler_descriptor(sm1, range->first, semantic->resource_type); -+ sm1->texture_descriptors |= (1u << range->first); -+ } - } - - static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, -@@ -1196,6 +1226,43 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1) - } - } - -+static void d3dbc_update_descriptors(struct vkd3d_shader_sm1_parser *d3dbc, -+ const struct vkd3d_shader_instruction *ins) -+{ -+ enum vkd3d_shader_resource_type type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -+ const struct vkd3d_shader_d3dbc_source_info *source_info; -+ unsigned int sampler_idx; -+ -+ switch (ins->opcode) -+ { -+ case VSIR_OP_TEX: -+ case VSIR_OP_TEXBEM: -+ case VSIR_OP_TEXBEML: -+ case VSIR_OP_TEXDP3TEX: -+ case VSIR_OP_TEXLD: -+ 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_idx = ins->dst[0].reg.idx[0].offset; -+ if ((d3dbc->texture_descriptors & (1u << sampler_idx))) -+ break; -+ -+ if ((source_info = d3dbc->d3dbc_source_info) -+ && sampler_idx < ARRAY_SIZE(source_info->texture_dimensions)) -+ type = source_info->texture_dimensions[sampler_idx]; -+ d3dbc_add_combined_sampler_descriptor(d3dbc, sampler_idx, type); -+ d3dbc->texture_descriptors |= (1u << sampler_idx); -+ break; -+ -+ default: -+ break; -+ } -+} -+ - static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins) - { - if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags) -@@ -1360,6 +1427,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - goto fail; - } - -+ if (program->shader_version.major == 1) -+ d3dbc_update_descriptors(sm1, ins); -+ - shader_sm1_validate_instruction(sm1, ins); - return; - -@@ -1397,6 +1467,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st - uint16_t shader_type; - size_t token_count; - -+ sm1->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO); -+ - token_count = code_size / sizeof(*sm1->start); - - if (token_count < 2) -@@ -1478,6 +1550,7 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c - struct vkd3d_shader_message_context *message_context, struct vsir_program *program) - { - struct vkd3d_shader_sm1_parser sm1 = {0}; -+ struct vkd3d_shader_descriptor_info1 *d; - struct vkd3d_shader_instruction *ins; - unsigned int i; - int ret; -@@ -1506,8 +1579,23 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c - } - } - -- for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) -- program->flat_constant_count[i] = get_external_constant_count(&sm1, i); -+ for (i = 0; i < 3; ++i) -+ { -+ struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; -+ unsigned int size = get_external_constant_count(&sm1, i); -+ -+ if (size) -+ { -+ if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, -+ i, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) -+ vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, -+ "Failed to create CBV descriptor."); -+ else -+ d->buffer_size = size * 16; -+ } -+ } -+ -+ program->has_descriptor_info = true; - - if (ret >= 0 && sm1.p.status < 0) - ret = sm1.p.status; -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index f82644d4679..c7af58118df 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -2430,9 +2430,9 @@ static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) - } - - static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins, -- enum vkd3d_shader_opcode handler_idx, const struct sm6_value *resource, struct sm6_parser *sm6) -+ enum vkd3d_shader_opcode opcode, const struct sm6_value *resource, struct sm6_parser *dxil) - { -- vsir_instruction_init(ins, &sm6->p.location, handler_idx); -+ vsir_instruction_init(ins, &dxil->p.location, opcode); - ins->resource_type = resource->u.handle.d->resource_type; - ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; - ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER; -@@ -4467,6 +4467,8 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ - /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */ - if ((code = record->operands[i++]) != ORDERING_SEQCST) - FIXME("Unhandled atomic ordering %"PRIu64".\n", code); -+ else -+ WARN("Ignoring atomic ordering %"PRIu64".\n", code); - - if ((code = record->operands[i]) != 1) - WARN("Ignoring synchronisation scope %"PRIu64".\n", code); -@@ -4484,7 +4486,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ - - ins = state->ins; - vsir_instruction_init(ins, &sm6->p.location, op); -- ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST; -+ ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0; - - if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) - return; -@@ -4509,7 +4511,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ - } - - static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, -- const struct sm6_type *type_b, struct sm6_parser *sm6) -+ const struct sm6_type *type_b, struct sm6_parser *sm6, enum vkd3d_shader_opcode *aux_opcode) - { - bool is_int = sm6_type_is_bool_i16_i32_i64(type_a); - bool is_double = sm6_type_is_double(type_a); -@@ -4532,12 +4534,17 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty - "Type mismatch in binary operation arguments."); - } - -+ *aux_opcode = VSIR_OP_NOP; -+ - switch (code) - { - case BINOP_ADD: -+ op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD); -+ is_valid = !is_bool; -+ break; - case BINOP_SUB: -- /* NEG is applied later for subtraction. */ - op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD); -+ *aux_opcode = is_int ? VSIR_OP_INEG : VSIR_OP_NEG; - is_valid = !is_bool; - break; - case BINOP_AND: -@@ -4601,12 +4608,13 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty - } - - static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_record *record, -- struct vkd3d_shader_instruction *ins, struct sm6_value *dst) -+ struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) - { -+ enum vkd3d_shader_opcode opcode, aux_opcode; - struct vkd3d_shader_src_param *src_params; -- enum vkd3d_shader_opcode handler_idx; -+ struct vkd3d_shader_dst_param *dst_params; -+ uint32_t type_flags = 0, aux_id = 0; - const struct sm6_value *a, *b; -- uint32_t type_flags = 0; - uint64_t code, flags; - bool silence_warning; - unsigned int i = 0; -@@ -4622,15 +4630,34 @@ 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)) == VSIR_OP_INVALID) -+ if ((opcode = map_binary_op(code, a->type, b->type, sm6, &aux_opcode)) == VSIR_OP_INVALID) - return; - -- vsir_instruction_init(ins, &sm6->p.location, handler_idx); -+ if (aux_opcode != VSIR_OP_NOP) -+ { -+ vsir_instruction_init(ins, &sm6->p.location, aux_opcode); -+ -+ if (!(dst_params = instruction_dst_params_alloc(ins, 1, sm6)) -+ || !(src_params = instruction_src_params_alloc(ins, 1, sm6))) -+ return; -+ -+ aux_id = sm6_parser_alloc_ssa_id(sm6); -+ -+ src_param_init_from_value(&src_params[0], b, DXIL_TYPE_SIGNED, sm6); -+ -+ dst_param_init(&dst_params[0]); -+ register_init_with_id(&dst_params[0].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id); -+ -+ ++ins; -+ ++code_block->instruction_count; -+ } -+ -+ vsir_instruction_init(ins, &sm6->p.location, opcode); - - flags = (record->operand_count > i) ? record->operands[i] : 0; - silence_warning = false; - -- switch (handler_idx) -+ switch (opcode) - { - case VSIR_OP_ADD: - case VSIR_OP_MUL: -@@ -4674,14 +4701,22 @@ 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, type_flags, sm6); -- src_param_init_from_value(&src_params[1], b, type_flags, sm6); -- if (code == BINOP_SUB) -- src_params[1].modifiers = VKD3DSPSM_NEG; -+ -+ if (aux_opcode == VSIR_OP_NOP) -+ { -+ src_param_init_from_value(&src_params[1], b, type_flags, sm6); -+ } -+ else -+ { -+ src_param_init(&src_params[1]); -+ register_init_with_id(&src_params[1].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id); -+ } - - dst->type = a->type; - -- if (handler_idx == VSIR_OP_ISHL || handler_idx == VSIR_OP_ISHR || handler_idx == VSIR_OP_USHR) -+ if (opcode == VSIR_OP_ISHL || opcode == VSIR_OP_ISHR || opcode == VSIR_OP_USHR) - { - /* DXC emits AND instructions where necessary to mask shift counts. - * Shift binops do not imply masking the shift as the TPF equivalents -@@ -5041,18 +5076,18 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr - unsigned int i, coord_idx, coord_count = 1; - struct vkd3d_shader_dst_param *dst_params; - struct vkd3d_shader_src_param *src_params; -- enum vkd3d_shader_opcode handler_idx; - struct vkd3d_shader_instruction *ins; - const struct sm6_value *resource; - struct vkd3d_shader_register reg; -+ enum vkd3d_shader_opcode opcode; - - resource = operands[0]; - if (!sm6_value_validate_is_handle(resource, sm6)) - return; - - if (is_cmp_xchg) -- handler_idx = VSIR_OP_IMM_ATOMIC_CMP_EXCH; -- else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID) -+ opcode = VSIR_OP_IMM_ATOMIC_CMP_EXCH; -+ else if ((opcode = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID) - return; - - coord_idx = 2 - is_cmp_xchg; -@@ -5074,13 +5109,13 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr - { - WARN("Ignoring unexpected operand.\n"); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, -- "Ignoring an unexpected defined operand value for atomic instruction %u.", handler_idx); -+ "Ignoring an unexpected defined operand value for atomic instruction %u.", opcode); - break; - } - } - - ins = state->ins; -- vsir_instruction_init(ins, &sm6->p.location, handler_idx); -+ vsir_instruction_init(ins, &sm6->p.location, opcode); - - if (!(src_params = instruction_src_params_alloc(ins, 2 + is_cmp_xchg, sm6))) - return; -@@ -5223,16 +5258,16 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr - 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, -+static void sm6_parser_dcl_register_builtin(struct sm6_parser *dxil, enum vkd3d_shader_opcode opcode, - 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; - -- if (!bitmap_is_set(sm6->io_regs_declared, reg_type)) -+ if (!bitmap_is_set(dxil->io_regs_declared, reg_type)) - { -- bitmap_set(sm6->io_regs_declared, reg_type); -- if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) -+ bitmap_set(dxil->io_regs_declared, reg_type); -+ if (!(ins = sm6_parser_add_instruction(dxil, opcode))) - return; - dst_param = &ins->declaration.dst; - vsir_register_init(&dst_param->reg, reg_type, data_type, 0); -@@ -5394,21 +5429,21 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc - struct vkd3d_shader_src_param *src_params; - struct vkd3d_shader_instruction *ins; - struct vkd3d_shader_register regs[2]; -- enum vkd3d_shader_opcode handler_idx; -+ enum vkd3d_shader_opcode opcode; - unsigned int component_count; - - switch (op) - { - case DX_DOT2: -- handler_idx = VSIR_OP_DP2; -+ opcode = VSIR_OP_DP2; - component_count = 2; - break; - case DX_DOT3: -- handler_idx = VSIR_OP_DP3; -+ opcode = VSIR_OP_DP3; - component_count = 3; - break; - case DX_DOT4: -- handler_idx = VSIR_OP_DP4; -+ opcode = VSIR_OP_DP4; - component_count = 4; - break; - default: -@@ -5421,7 +5456,7 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc - return; - - ins = state->ins; -- vsir_instruction_init(ins, &sm6->p.location, handler_idx); -+ vsir_instruction_init(ins, &sm6->p.location, opcode); - if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) - return; - src_param_init_vector_from_reg(&src_params[0], ®s[0]); -@@ -5483,11 +5518,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, VSIR_OP_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_ABS); - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; - src_param_init_from_value(src_param, operands[0], 0, sm6); -- src_param->modifiers = VKD3DSPSM_ABS; - - instruction_dst_param_init_ssa_scalar(ins, 0, sm6); - } -@@ -7125,7 +7159,7 @@ static void sm6_parser_emit_cast(struct sm6_parser *dxil, const struct dxil_reco - - struct sm6_cmp_info - { -- enum vkd3d_shader_opcode handler_idx; -+ enum vkd3d_shader_opcode opcode; - bool src_swap; - uint32_t type_flags; - }; -@@ -7227,7 +7261,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 == VSIR_OP_INVALID) -+ if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->opcode || cmp->opcode == VSIR_OP_INVALID) - { - FIXME("Unhandled operation %"PRIu64".\n", code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -7235,7 +7269,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor - return; - } - -- vsir_instruction_init(ins, &sm6->p.location, cmp->handler_idx); -+ vsir_instruction_init(ins, &sm6->p.location, cmp->opcode); - - flags = (record->operand_count > i) ? record->operands[i] : 0; - silence_warning = false; -@@ -7327,6 +7361,8 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re - /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */ - if (success_ordering != ORDERING_SEQCST) - FIXME("Unhandled success ordering %"PRIu64".\n", success_ordering); -+ else -+ WARN("Ignoring success ordering %"PRIu64".\n", success_ordering); - if (success_ordering != failure_ordering) - FIXME("Unhandled failure ordering %"PRIu64".\n", failure_ordering); - -@@ -7334,7 +7370,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re - FIXME("Ignoring weak cmpxchg.\n"); - - 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; -+ ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0; - - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - return; -@@ -8342,7 +8378,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - break; - } - case FUNC_CODE_INST_BINOP: -- sm6_parser_emit_binop(sm6, record, ins, dst); -+ sm6_parser_emit_binop(sm6, record, code_block, ins, dst); - break; - case FUNC_CODE_INST_BR: - sm6_parser_emit_br(sm6, record, function, code_block, ins); -@@ -10121,22 +10157,22 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co - return VKD3D_OK; - } - --static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, unsigned int count) -+static void sm6_parser_emit_dcl_count(struct sm6_parser *dxil, enum vkd3d_shader_opcode opcode, unsigned int count) - { - struct vkd3d_shader_instruction *ins; - -- if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) -+ if (!(ins = sm6_parser_add_instruction(dxil, opcode))) - return; - ins->declaration.count = count; - } - --static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *sm6, -- enum vkd3d_shader_opcode handler_idx, enum vkd3d_primitive_type primitive_type, -+static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *dxil, -+ enum vkd3d_shader_opcode opcode, enum vkd3d_primitive_type primitive_type, - unsigned int patch_vertex_count) - { - struct vkd3d_shader_instruction *ins; - -- if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) -+ if (!(ins = sm6_parser_add_instruction(dxil, opcode))) - return; - ins->declaration.primitive_type.type = primitive_type; - ins->declaration.primitive_type.patch_vertex_count = patch_vertex_count; -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index b2679beff9f..88c87ae33ee 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -280,7 +280,7 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, - break; - - case VKD3DSPR_THREADID: -- vkd3d_string_buffer_printf(buffer, "gl_GlobalInvocationID"); -+ vkd3d_string_buffer_printf(buffer, "uvec4(gl_GlobalInvocationID, 0)"); - break; - - case VKD3DSPR_IDXTEMP: -@@ -419,25 +419,11 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd - if (reg->dimension == VSIR_DIMENSION_VEC4) - shader_glsl_print_swizzle(str, vsir_src->swizzle, mask); - -- switch (vsir_src->modifiers) -+ if (vsir_src->modifiers) - { -- case VKD3DSPSM_NONE: -- break; -- case VKD3DSPSM_NEG: -- vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); -- break; -- 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); -- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); -- break; -+ vkd3d_string_buffer_printf(buffer, "(%s)", vsir_src->modifiers, str->buffer); -+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -+ "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); - } - - if (str != buffer) -@@ -1240,25 +1226,33 @@ static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d - - static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) - { -+ struct vkd3d_string_buffer *src1, *src2; - unsigned int component_count; -- struct glsl_src src[3]; -+ struct glsl_src src[1]; - struct glsl_dst dst; - uint32_t mask; - -+ /* Sadly, mix() in unextended GLSL 4.40 can only select between -+ * floating-point sources. The earliest version able to select between -+ * integer sources is version 4.50; the same functionality is also -+ * provided by the EXT_shader_integer_mix extension. */ -+ - mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); - glsl_src_init(&src[0], gen, &ins->src[0], mask); -- glsl_src_init(&src[1], gen, &ins->src[1], mask); -- glsl_src_init(&src[2], gen, &ins->src[2], mask); -+ src1 = vkd3d_string_buffer_get(&gen->string_buffers); -+ src2 = vkd3d_string_buffer_get(&gen->string_buffers); -+ shader_glsl_print_src(src1, gen, &ins->src[1], mask, VSIR_DATA_F32); -+ shader_glsl_print_src(src2, gen, &ins->src[2], mask, VSIR_DATA_F32); - - if ((component_count = vsir_write_mask_component_count(mask)) > 1) -- shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bvec%u(%s))", -- src[2].str->buffer, src[1].str->buffer, component_count, src[0].str->buffer); -+ shader_glsl_print_assignment_ext(gen, &dst, VSIR_DATA_F32, "mix(%s, %s, bvec%u(%s))", -+ src2->buffer, src1->buffer, component_count, src[0].str->buffer); - else -- shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bool(%s))", -- src[2].str->buffer, src[1].str->buffer, src[0].str->buffer); -+ shader_glsl_print_assignment_ext(gen, &dst, VSIR_DATA_F32, "mix(%s, %s, bool(%s))", -+ src2->buffer, src1->buffer, src[0].str->buffer); - -- glsl_src_cleanup(&src[2], &gen->string_buffers); -- glsl_src_cleanup(&src[1], &gen->string_buffers); -+ vkd3d_string_buffer_release(&gen->string_buffers, src2); -+ vkd3d_string_buffer_release(&gen->string_buffers, src1); - glsl_src_cleanup(&src[0], &gen->string_buffers); - glsl_dst_cleanup(&dst, &gen->string_buffers); - } -@@ -1485,6 +1479,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - - switch (ins->opcode) - { -+ case VSIR_OP_ABS: -+ shader_glsl_intrinsic(gen, ins, "abs"); -+ break; - case VSIR_OP_ADD: - case VSIR_OP_IADD: - shader_glsl_binop(gen, ins, "+"); -@@ -1597,6 +1594,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - shader_glsl_relop(gen, ins, "!=", "notEqual"); - break; - case VSIR_OP_INEG: -+ case VSIR_OP_NEG: - shader_glsl_unary_op(gen, ins, "-"); - break; - case VSIR_OP_ISHL: -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index ec1e27d9496..3b0a7acb52a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -2205,11 +2205,11 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, - return &store->node; - } - --void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, -+struct hlsl_ir_node *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, uint32_t writemask, const struct vkd3d_shader_location *loc) - { -- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc)); -+ return 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, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 6c6243db799..829fcba0aab 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -534,6 +534,8 @@ struct hlsl_ir_var - struct - { - bool used; -+ bool uav_read; -+ bool uav_atomics; - enum hlsl_sampler_dim sampler_dim; - struct vkd3d_shader_location first_sampler_dim_loc; - } *objects_usage[HLSL_REGSET_LAST_OBJECT + 1]; -@@ -1599,7 +1601,7 @@ void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block, - unsigned int unroll_limit, const struct vkd3d_shader_location *loc); - 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); --void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, -+struct hlsl_ir_node *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, 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, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -index da9f0d39136..c41d807cca1 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -@@ -83,7 +83,6 @@ ComputeShader {return KW_COMPUTESHADER; } - compile {return KW_COMPILE; } - CompileShader {return KW_COMPILESHADER; } - const {return KW_CONST; } --ConstructGSWithSO {return KW_CONSTRUCTGSWITHSO; } - continue {return KW_CONTINUE; } - DepthStencilState {return KW_DEPTHSTENCILSTATE; } - DepthStencilView {return KW_DEPTHSTENCILVIEW; } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 37b116bed40..27afac71320 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -5337,6 +5337,23 @@ static bool intrinsic_AllMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, - | VKD3DSSF_GROUP_SHARED_MEMORY | VKD3DSSF_THREAD_GROUP, loc); - } - -+static bool intrinsic_ConstructGSWithSO(struct hlsl_ctx *ctx, -+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_ir_node *compile; -+ -+ if (params->args_count != 2 && params->args_count != 6) -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, -+ "Wrong number of arguments to ConstructGSWithSO(): expected 2 or 6, but got %u.", params->args_count); -+ -+ if (!(compile = hlsl_new_compile(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, -+ NULL, params->args, params->args_count, params->instrs, loc))) -+ return false; -+ -+ hlsl_block_add_instr(params->instrs, compile); -+ return true; -+} -+ - static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -5386,6 +5403,7 @@ intrinsic_functions[] = - /* Note: these entries should be kept in alphabetical order. */ - {"AllMemoryBarrier", 0, true, intrinsic_AllMemoryBarrier}, - {"AllMemoryBarrierWithGroupSync", 0, true, intrinsic_AllMemoryBarrierWithGroupSync}, -+ {"ConstructGSWithSO", -1, false, intrinsic_ConstructGSWithSO}, - {"D3DCOLORtoUBYTE4", 1, true, intrinsic_d3dcolor_to_ubyte4}, - {"DeviceMemoryBarrier", 0, true, intrinsic_DeviceMemoryBarrier}, - {"DeviceMemoryBarrierWithGroupSync", 0, true, intrinsic_DeviceMemoryBarrierWithGroupSync}, -@@ -5629,36 +5647,6 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha - return make_block(ctx, compile); - } - --static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, -- struct parse_initializer *args, const struct vkd3d_shader_location *loc) --{ -- struct hlsl_ir_node *compile; -- -- switch (compile_type) -- { -- case HLSL_COMPILE_TYPE_COMPILE: -- vkd3d_unreachable(); -- -- case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO: -- if (args->args_count != 2 && args->args_count != 6) -- { -- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, -- "Wrong number of arguments to ConstructGSWithSO: expected 2 or 6, but got %u.", -- args->args_count); -- } -- break; -- } -- -- if (!(compile = hlsl_new_compile(ctx, compile_type, NULL, args->args, args->args_count, args->instrs, loc))) -- { -- free_parse_initializer(args); -- return NULL; -- } -- -- free_parse_initializer(args); -- return make_block(ctx, compile); --} -- - static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, - struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -6939,7 +6927,6 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, - %token KW_COMPILESHADER - %token KW_COMPUTESHADER - %token KW_CONST --%token KW_CONSTRUCTGSWITHSO - %token KW_CONTINUE - %token KW_DEFAULT - %token KW_DEPTHSTENCILSTATE -@@ -9453,11 +9440,6 @@ primary_expr: - vkd3d_free($3); - vkd3d_free($5); - } -- | KW_CONSTRUCTGSWITHSO '(' func_arguments ')' -- { -- if (!($$ = add_compile_variant(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, &$3, &@1))) -- YYABORT; -- } - | var_identifier '(' func_arguments ')' - { - if (!($$ = add_call(ctx, $1, &$3, &@1))) -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index d22330cedb7..8f4e4cda73f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -926,18 +926,17 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, - return progress; - } - --typedef bool (*PFN_lower_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *); -+typedef struct hlsl_ir_node *(*PFN_replace_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *); - --static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+static bool call_replace_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) - { -- PFN_lower_func func = context; -+ struct hlsl_ir_node *replacement; -+ PFN_replace_func func = context; - struct hlsl_block block; - - hlsl_block_init(&block); -- if (func(ctx, instr, &block)) -+ if ((replacement = func(ctx, instr, &block))) - { -- struct hlsl_ir_node *replacement = LIST_ENTRY(list_tail(&block.instrs), struct hlsl_ir_node, entry); -- - list_move_before(&instr->entry, &block.instrs); - hlsl_replace_node(instr, replacement); - return true; -@@ -949,12 +948,17 @@ static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, vo - } - } - --/* Specific form of transform_ir() for passes which convert a single instruction -- * to a block of one or more instructions. This helper takes care of setting up -- * the block and calling hlsl_replace_node_with_block(). */ --static bool lower_ir(struct hlsl_ctx *ctx, PFN_lower_func func, struct hlsl_block *block) -+/* Specific form of transform_ir() for passes which replace a single instruction -+ * with another instruction. This includes passes which lower an instruction -+ * to one or more new instructions, and passes which fold away a redundant -+ * instruction. -+ * -+ * New instructions should be added to "block", and the replacement instruction -+ * should be returned. If the instruction should be left alone, NULL should be -+ * returned instead. */ -+static bool replace_ir(struct hlsl_ctx *ctx, PFN_replace_func func, struct hlsl_block *block) - { -- return hlsl_transform_ir(ctx, call_lower_func, block, func); -+ return hlsl_transform_ir(ctx, call_replace_func, block, func); - } - - static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -1295,7 +1299,8 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h - return hlsl_block_add_simple_load(ctx, block, coords, loc); - } - --static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_complex_casts(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - unsigned int src_comp_count, dst_comp_count; - struct hlsl_type *src_type, *dst_type; -@@ -1306,17 +1311,17 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - unsigned int dst_idx; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - if (hlsl_ir_expr(instr)->op != HLSL_OP1_CAST) -- return false; -+ return NULL; - - arg = hlsl_ir_expr(instr)->operands[0].node; - dst_type = instr->data_type; - src_type = arg->data_type; - - if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR) -- return false; -+ return NULL; - - src_comp_count = hlsl_type_component_count(src_type); - dst_comp_count = hlsl_type_component_count(dst_type); -@@ -1332,7 +1337,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - } - - if (!(var = hlsl_new_synthetic_var(ctx, "cast", dst_type, &instr->loc))) -- return false; -+ return NULL; - hlsl_init_simple_deref_from_var(&var_deref, var); - - for (dst_idx = 0; dst_idx < dst_comp_count; ++dst_idx) -@@ -1363,8 +1368,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - hlsl_block_add_store_component(ctx, block, &var_deref, dst_idx, cast); - } - -- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); -- return true; -+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - } - - /* hlsl_ir_swizzle nodes that directly point to a matrix value are only a parse-time construct that -@@ -1372,7 +1376,8 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - * an assignment or as a value made from different components of the matrix. The former cases should - * have already been split into several separate assignments, but the latter are lowered by this - * pass. */ --static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_matrix_swizzles(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_swizzle *swizzle; - struct hlsl_deref var_deref; -@@ -1381,14 +1386,14 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - unsigned int k, i; - - if (instr->type != HLSL_IR_SWIZZLE) -- return false; -+ return NULL; - swizzle = hlsl_ir_swizzle(instr); - matrix_type = swizzle->val.node->data_type; - if (matrix_type->class != HLSL_CLASS_MATRIX) -- return false; -+ return NULL; - - if (!(var = hlsl_new_synthetic_var(ctx, "matrix-swizzle", instr->data_type, &instr->loc))) -- return false; -+ return NULL; - hlsl_init_simple_deref_from_var(&var_deref, var); - - for (i = 0; i < instr->data_type->e.numeric.dimx; ++i) -@@ -1401,8 +1406,7 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - hlsl_block_add_store_component(ctx, block, &var_deref, i, load); - } - -- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); -- return true; -+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - } - - /* hlsl_ir_index nodes are a parse-time construct used to represent array indexing and struct -@@ -1411,7 +1415,8 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - * For the latter case, this pass takes care of lowering hlsl_ir_indexes into individual - * hlsl_ir_loads, or individual hlsl_ir_resource_loads, in case the indexing is a - * resource access. */ --static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_index_loads(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_deref var_deref; - struct hlsl_ir_index *index; -@@ -1420,7 +1425,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - struct hlsl_ir_var *var; - - if (instr->type != HLSL_IR_INDEX) -- return false; -+ return NULL; - index = hlsl_ir_index(instr); - val = index->val.node; - -@@ -1435,14 +1440,13 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count); - - if (!(coords = add_zero_mipmap_level(ctx, block, coords, &instr->loc))) -- return false; -+ return NULL; - - params.type = HLSL_RESOURCE_LOAD; - params.resource = val; - params.coords = coords; - params.format = val->data_type->e.resource.format; -- hlsl_block_add_resource_load(ctx, block, ¶ms, &instr->loc); -- return true; -+ return hlsl_block_add_resource_load(ctx, block, ¶ms, &instr->loc); - } - - if (val->type == HLSL_IR_RESOURCE_LOAD) -@@ -1459,7 +1463,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - struct hlsl_deref row_deref; - - if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) -- return false; -+ return NULL; - hlsl_init_simple_deref_from_var(&row_deref, var); - - for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i) -@@ -1488,7 +1492,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node); - } - -- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); -+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - } - else - { -@@ -1506,14 +1510,13 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - appended_load->node.data_type = type; - - hlsl_block_add_instr(block, &appended_load->node); -+ return &appended_load->node; - } -- -- return true; - } - } - - if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc))) -- return false; -+ return NULL; - hlsl_init_simple_deref_from_var(&var_deref, var); - - hlsl_block_add_simple_store(ctx, block, var, val); -@@ -1527,7 +1530,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - VKD3D_ASSERT(!hlsl_type_is_row_major(mat->data_type)); - - if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) -- return false; -+ return NULL; - hlsl_init_simple_deref_from_var(&row_deref, var); - - for (i = 0; i < mat->data_type->e.numeric.dimx; ++i) -@@ -1537,37 +1540,34 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc); - - if (!(load = hlsl_new_load_index(ctx, &var_deref, c, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, &load->node); - - if (!(load = hlsl_new_load_index(ctx, &load->src, index->idx.node, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, &load->node); - - hlsl_block_add_store_index(ctx, block, &row_deref, c, &load->node, 0, &instr->loc); - } - -- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); -- } -- else -- { -- hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc); -+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - } -- return true; -+ -+ return hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc); - } - - /* Lower casts from vec1 to vecN to swizzles. */ --static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - const struct hlsl_type *src_type, *dst_type; - struct hlsl_type *dst_scalar_type; - struct hlsl_ir_expr *cast; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - cast = hlsl_ir_expr(instr); - if (cast->op != HLSL_OP1_CAST) -- return false; -+ return NULL; - src_type = cast->operands[0].node->data_type; - dst_type = cast->node.data_type; - -@@ -1581,17 +1581,17 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s - new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_scalar_type, &cast->node.loc); - - if (dst_type->e.numeric.dimx != 1) -- hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), -+ return hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), - dst_type->e.numeric.dimx, new_cast, &cast->node.loc); - -- return true; -+ return new_cast; - } - -- return false; -+ return NULL; - } - - /* 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) -+static struct hlsl_ir_node *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; -@@ -1599,29 +1599,28 @@ static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s - struct hlsl_deref *deref; - - if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type)) -- return false; -+ return NULL; - load = hlsl_ir_load(instr); - deref = &load->src; - - if (!deref->var->is_tgsm) -- return false; -+ return NULL; - - if (deref->path_len) - { - hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM."); -- return false; -+ return NULL; - } - - 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; -+ return hlsl_block_add_resource_load(ctx, block, ¶ms, loc); - } - - /* 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) -+static struct hlsl_ir_node *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; -@@ -1629,26 +1628,24 @@ static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - struct hlsl_deref *deref; - - if (instr->type != HLSL_IR_STORE) -- return false; -+ return NULL; - store = hlsl_ir_store(instr); - deref = &store->lhs; - - if (!deref->var->is_tgsm) -- return false; -+ return NULL; - - if (deref->path_len) - { - hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM."); -- return false; -+ return NULL; - } - - 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, -+ return 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 -@@ -3567,7 +3564,8 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - return false; - } - --static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+static struct hlsl_ir_node *fold_redundant_casts(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - if (instr->type == HLSL_IR_EXPR) - { -@@ -3576,20 +3574,17 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst - const struct hlsl_type *src_type; - - if (expr->op != HLSL_OP1_CAST) -- return false; -+ return NULL; - - src_type = expr->operands[0].node->data_type; - - if (hlsl_types_are_equal(src_type, dst_type) - || (src_type->e.numeric.type == dst_type->e.numeric.type - && hlsl_is_vec1(src_type) && hlsl_is_vec1(dst_type))) -- { -- hlsl_replace_node(&expr->node, expr->operands[0].node); -- return true; -- } -+ return expr->operands[0].node; - } - -- return false; -+ return NULL; - } - - /* Copy an element of a complex variable. Helper for -@@ -3824,17 +3819,18 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - return true; - } - --static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_narrowing_casts(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - const struct hlsl_type *src_type, *dst_type; - struct hlsl_type *dst_vector_type; - struct hlsl_ir_expr *cast; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - cast = hlsl_ir_expr(instr); - if (cast->op != HLSL_OP1_CAST) -- return false; -+ return NULL; - src_type = cast->operands[0].node->data_type; - dst_type = cast->node.data_type; - -@@ -3847,65 +3843,58 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - /* We need to preserve the cast since it might be doing more than just - * narrowing the vector. */ - new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc); -- hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W), -+ return hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W), - dst_type->e.numeric.dimx, new_cast, &cast->node.loc); -- return true; - } - -- return false; -+ return NULL; - } - --static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+static struct hlsl_ir_node *fold_swizzle_chains(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_swizzle *swizzle; - struct hlsl_ir_node *next_instr; - - if (instr->type != HLSL_IR_SWIZZLE) -- return false; -+ return NULL; - swizzle = hlsl_ir_swizzle(instr); - - next_instr = swizzle->val.node; - - if (next_instr->type == HLSL_IR_SWIZZLE) - { -- struct hlsl_ir_node *new_swizzle; - uint32_t combined_swizzle; - - combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->u.vector, - swizzle->u.vector, instr->data_type->e.numeric.dimx); - next_instr = hlsl_ir_swizzle(next_instr)->val.node; - -- if (!(new_swizzle = hlsl_new_swizzle(ctx, combined_swizzle, -- instr->data_type->e.numeric.dimx, next_instr, &instr->loc))) -- return false; -- -- list_add_before(&instr->entry, &new_swizzle->entry); -- hlsl_replace_node(instr, new_swizzle); -- return true; -+ return hlsl_block_add_swizzle(ctx, block, combined_swizzle, -+ instr->data_type->e.numeric.dimx, next_instr, &instr->loc); - } - -- return false; -+ return NULL; - } - --static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+static struct hlsl_ir_node *fold_trivial_swizzles(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_swizzle *swizzle; - unsigned int i; - - if (instr->type != HLSL_IR_SWIZZLE) -- return false; -+ return NULL; - swizzle = hlsl_ir_swizzle(instr); - - if (instr->data_type->e.numeric.dimx != swizzle->val.node->data_type->e.numeric.dimx) -- return false; -+ return NULL; - - for (i = 0; i < instr->data_type->e.numeric.dimx; ++i) - if (hlsl_swizzle_get_component(swizzle->u.vector, i) != i) -- return false; -- -- hlsl_replace_node(instr, swizzle->val.node); -+ return NULL; - -- return true; -+ return swizzle->val.node; - } - - static bool remove_trivial_conditional_branches(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -4028,7 +4017,8 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - return true; - } - --static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *idx; - struct hlsl_deref *deref; -@@ -4036,13 +4026,13 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir - unsigned int i; - - if (instr->type != HLSL_IR_LOAD) -- return false; -+ return NULL; - - deref = &hlsl_ir_load(instr)->src; - VKD3D_ASSERT(deref->var); - - if (deref->path_len == 0) -- return false; -+ return NULL; - - type = deref->var->data_type; - for (i = 0; i < deref->path_len - 1; ++i) -@@ -4059,7 +4049,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir - enum hlsl_ir_expr_op op; - - if (!(vector_load = hlsl_new_load_parent(ctx, deref, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, &vector_load->node); - - swizzle = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc); -@@ -4069,7 +4059,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir - value.u[2].u = 2; - value.u[3].u = 3; - if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, c); - - operands[0] = swizzle; -@@ -4086,14 +4076,14 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir - * LOGIC_OR + LOGIC_AND. */ - operands[0] = &vector_load->node; - operands[1] = eq; -- hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc); -- return true; -+ return hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc); - } - -- return false; -+ return NULL; - } - --static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *idx; - struct hlsl_deref *deref; -@@ -4101,13 +4091,13 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc - unsigned int i; - - if (instr->type != HLSL_IR_STORE) -- return false; -+ return NULL; - - deref = &hlsl_ir_store(instr)->lhs; - VKD3D_ASSERT(deref->var); - - if (deref->path_len == 0) -- return false; -+ return NULL; - - type = deref->var->data_type; - for (i = 0; i < deref->path_len - 1; ++i) -@@ -4122,7 +4112,7 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc - hlsl_fixme(ctx, &instr->loc, "Non-constant vector addressing on store. Unrolling may be missing."); - } - -- return false; -+ return NULL; - } - - static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) -@@ -4136,8 +4126,8 @@ static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const s - * This is achieved through a synthetic variable. The non-constant index is compared for equality - * with every possible value it can have within the array bounds, and the ternary operator is used - * to update the value of the synthetic var when the equality check passes. */ --static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, -- struct hlsl_block *block) -+static struct hlsl_ir_node *lower_nonconstant_array_loads(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_constant_value zero_value = {0}; - struct hlsl_ir_node *cut_index, *zero; -@@ -4149,15 +4139,15 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n - bool row_major; - - if (instr->type != HLSL_IR_LOAD) -- return false; -+ return NULL; - load = hlsl_ir_load(instr); - deref = &load->src; - - if (deref->path_len == 0) -- return false; -+ return NULL; - - if (deref_supports_sm1_indirect_addressing(ctx, deref)) -- return false; -+ return NULL; - - for (i = deref->path_len - 1; ; --i) - { -@@ -4168,7 +4158,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n - } - - if (i == 0) -- return false; -+ return NULL; - } - - cut_index = deref->path[i_cut].node; -@@ -4180,10 +4170,10 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n - VKD3D_ASSERT(cut_type->class == HLSL_CLASS_ARRAY || row_major); - - if (!(var = hlsl_new_synthetic_var(ctx, row_major ? "row_major-load" : "array-load", instr->data_type, &instr->loc))) -- return false; -+ return NULL; - - if (!(zero = hlsl_new_constant(ctx, instr->data_type, &zero_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, zero); - - hlsl_block_add_simple_store(ctx, block, var, zero); -@@ -4209,7 +4199,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n - var_load = hlsl_block_add_simple_load(ctx, block, var, &cut_index->loc); - - if (!hlsl_copy_deref(ctx, &deref_copy, deref)) -- return false; -+ return NULL; - hlsl_src_remove(&deref_copy.path[i_cut]); - hlsl_src_from_node(&deref_copy.path[i_cut], const_i); - specific_load = hlsl_block_add_load_index(ctx, block, &deref_copy, NULL, &cut_index->loc); -@@ -4223,8 +4213,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n - hlsl_block_add_simple_store(ctx, block, var, ternary); - } - -- hlsl_block_add_simple_load(ctx, block, var, &instr->loc); -- return true; -+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - } - - static struct hlsl_type *clone_texture_array_as_combined_sampler_array(struct hlsl_ctx *ctx, struct hlsl_type *type) -@@ -4495,31 +4484,30 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx) - } - - /* Turn CAST to int or uint into TRUNC + REINTERPRET */ --static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_casts_to_int(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; - struct hlsl_ir_node *arg, *trunc; - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP1_CAST) -- return false; -+ return NULL; - - arg = expr->operands[0].node; - if (!hlsl_type_is_integer(instr->data_type) || instr->data_type->e.numeric.type == HLSL_TYPE_BOOL) -- return false; -+ return NULL; - if (!hlsl_type_is_floating_point(arg->data_type)) -- return false; -+ return NULL; - - trunc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_TRUNC, arg, &instr->loc); - - memset(operands, 0, sizeof(operands)); - operands[0] = trunc; -- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); -- -- return true; -+ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); - } - - /* Turn TRUNC into: -@@ -4533,16 +4521,16 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - * where the comparisons in the extra term are performed using CMP or SLT - * depending on whether this is a pixel or vertex shader, respectively. - */ --static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg, *res; - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP1_TRUNC) -- return false; -+ return NULL; - - arg = expr->operands[0].node; - -@@ -4553,7 +4541,7 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - - memset(&zero_value, 0, sizeof(zero_value)); - if (!(zero = hlsl_new_constant(ctx, arg->data_type, &zero_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, zero); - - one_value.u[0].f = 1.0; -@@ -4561,22 +4549,22 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, arg->data_type, &one_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, one); - - fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); - neg_fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, fract, &instr->loc); - - if (!(has_fract = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, neg_fract, zero, one))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, has_fract); - - if (!(extra = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, arg, zero, has_fract))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, extra); - - floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract); -- res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra); -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra); - } - else - { -@@ -4590,11 +4578,10 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract); - - if (!(res = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, is_neg, has_fract, floor))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, res); -+ return res; - } -- -- return true; - } - - /* Lower modulus using: -@@ -4602,7 +4589,8 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - * mod(x, y) = x - trunc(x / y) * y; - * - */ --static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_int_modulus_sm1(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *div, *trunc, *mul, *neg, *operands[2], *ret; - struct hlsl_type *float_type; -@@ -4610,15 +4598,15 @@ static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - bool is_float; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP2_MOD) -- return false; -+ return NULL; - - is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT - || instr->data_type->e.numeric.type == HLSL_TYPE_HALF; - if (is_float) -- return false; -+ return NULL; - float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); - - for (unsigned int i = 0; i < 2; ++i) -@@ -4631,13 +4619,11 @@ static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, trunc, operands[1]); - neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul, &instr->loc); - ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, operands[0], neg); -- hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); -- -- return true; -+ return hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); - } - - /* Lower DIV to RCP + MUL. */ --static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *rcp, *ret, *operands[2]; - struct hlsl_type *float_type; -@@ -4645,10 +4631,10 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str - bool is_float; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP2_DIV) -- return false; -+ return NULL; - - is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT - || instr->data_type->e.numeric.type == HLSL_TYPE_HALF; -@@ -4665,42 +4651,40 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str - ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, operands[0], rcp); - if (!is_float) - ret = hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); -- -- return true; -+ return ret; - } - - /* Lower SQRT to RSQ + RCP. */ --static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_expr *expr; - struct hlsl_ir_node *rsq; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP1_SQRT) -- return false; -+ return NULL; - - rsq = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RSQ, expr->operands[0].node, &instr->loc); -- hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc); -- return true; -+ return hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc); - } - - /* Lower DP2 to MUL + ADD */ --static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg1, *arg2, *mul, *add_x, *add_y; - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - arg1 = expr->operands[0].node; - arg2 = expr->operands[1].node; - if (expr->op != HLSL_OP2_DOT) -- return false; -+ return NULL; - if (arg1->data_type->e.numeric.dimx != 2) -- return false; -+ return NULL; - - if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) - { -@@ -4710,7 +4694,7 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - operands[1] = arg2; - operands[2] = hlsl_block_add_float_constant(ctx, block, 0.0f, &expr->node.loc); - -- hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc); -+ return hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc); - } - else - { -@@ -4720,32 +4704,29 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - instr->data_type->e.numeric.dimx, mul, &expr->node.loc); - add_y = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(Y, Y, Y, Y), - instr->data_type->e.numeric.dimx, mul, &expr->node.loc); -- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); - } -- -- return true; - } - - /* Lower ABS to MAX */ --static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg, *neg; - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - arg = expr->operands[0].node; - if (expr->op != HLSL_OP1_ABS) -- return false; -+ return NULL; - - neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); -- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg); -- return true; -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg); - } - - /* Lower ROUND using FRC, ROUND(x) -> ((x + 0.5) - FRC(x + 0.5)). */ --static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg, *neg, *sum, *frc, *half; - struct hlsl_type *type = instr->data_type; -@@ -4754,69 +4735,66 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(instr); - arg = expr->operands[0].node; - if (expr->op != HLSL_OP1_ROUND) -- return false; -+ return NULL; - - component_count = hlsl_type_component_count(type); - for (i = 0; i < component_count; ++i) - half_value.u[i].f = 0.5f; - if (!(half = hlsl_new_constant(ctx, type, &half_value, &expr->node.loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, half); - - sum = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, half); - frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, sum, &instr->loc); - neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc); -- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg); -- return true; -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg); - } - - /* Lower CEIL to FRC */ --static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg, *neg, *frc; - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(instr); - arg = expr->operands[0].node; - if (expr->op != HLSL_OP1_CEIL) -- return false; -+ return NULL; - - neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); - frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, neg, &instr->loc); -- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg); -- return true; -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg); - } - - /* Lower FLOOR to FRC */ --static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg, *neg, *frc; - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(instr); - arg = expr->operands[0].node; - if (expr->op != HLSL_OP1_FLOOR) -- return false; -+ return NULL; - - frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); - neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc); -- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg); -- return true; -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg); - } - - /* Lower SIN/COS to SINCOS for SM1. */ --static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg, *half, *two_pi, *reciprocal_two_pi, *neg_pi; - struct hlsl_constant_value half_value, two_pi_value, reciprocal_two_pi_value, neg_pi_value; -@@ -4828,7 +4806,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - int i; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - - if (expr->op == HLSL_OP1_SIN) -@@ -4836,7 +4814,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - else if (expr->op == HLSL_OP1_COS) - op = HLSL_OP1_COS_REDUCED; - else -- return false; -+ return NULL; - - arg = expr->operands[0].node; - type = arg->data_type; -@@ -4854,23 +4832,23 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - || !(two_pi = hlsl_new_constant(ctx, type, &two_pi_value, &instr->loc)) - || !(reciprocal_two_pi = hlsl_new_constant(ctx, type, &reciprocal_two_pi_value, &instr->loc)) - || !(neg_pi = hlsl_new_constant(ctx, type, &neg_pi_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, half); - hlsl_block_add_instr(block, two_pi); - hlsl_block_add_instr(block, reciprocal_two_pi); - hlsl_block_add_instr(block, neg_pi); - - if (!(mad = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, arg, reciprocal_two_pi, half))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, mad); - frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mad, &instr->loc); - if (!(reduced = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, frc, two_pi, neg_pi))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, reduced); - - if (type->e.numeric.dimx == 1) - { -- sincos = hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc); -+ return hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc); - } - else - { -@@ -4886,7 +4864,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - } - - if (!(var = hlsl_new_synthetic_var(ctx, "sincos", type, &instr->loc))) -- return false; -+ return NULL; - hlsl_init_simple_deref_from_var(&var_deref, var); - - for (i = 0; i < type->e.numeric.dimx; ++i) -@@ -4895,13 +4873,11 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct - hlsl_block_add_store_component(ctx, block, &var_deref, i, sincos); - } - -- hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc); -+ return hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc); - } -- -- return true; - } - --static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg, *arg_cast, *neg, *one, *sub; - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; -@@ -4910,10 +4886,10 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP1_LOGIC_NOT) -- return false; -+ return NULL; - - arg = expr->operands[0].node; - float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->e.numeric.dimx); -@@ -4930,19 +4906,18 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, one); - - sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg); - - memset(operands, 0, sizeof(operands)); - operands[0] = sub; -- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); -- return true; -+ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); - } - - /* Lower TERNARY to CMP for SM1. */ --static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *cond, *first, *second, *float_cond, *neg; - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; -@@ -4950,11 +4925,11 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru - struct hlsl_type *type; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP3_TERNARY) -- return false; -+ return NULL; - - cond = expr->operands[0].node; - first = expr->operands[1].node; -@@ -4963,7 +4938,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru - if (cond->data_type->class > HLSL_CLASS_VECTOR || instr->data_type->class > HLSL_CLASS_VECTOR) - { - hlsl_fixme(ctx, &instr->loc, "Lower ternary of type other than scalar or vector."); -- return false; -+ return NULL; - } - - VKD3D_ASSERT(cond->data_type->e.numeric.type == HLSL_TYPE_BOOL); -@@ -4977,8 +4952,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru - operands[0] = neg; - operands[1] = second; - operands[2] = first; -- hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc); -- return true; -+ return hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc); - } - - static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -5026,7 +5000,7 @@ static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node * - return true; - } - --static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, -+static struct hlsl_ir_node *lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - struct hlsl_block *block) - { - struct hlsl_ir_node *arg1, *arg1_cast, *arg2, *arg2_cast, *slt, *res; -@@ -5036,10 +5010,10 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node - bool negate = false; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (!hlsl_is_comparison_op(expr->op)) -- return false; -+ return NULL; - - arg1 = expr->operands[0].node; - arg2 = expr->operands[1].node; -@@ -5096,7 +5070,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, one); - - slt_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); -@@ -5111,8 +5085,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node - * and casts to BOOL have already been lowered to "!= 0". */ - memset(operands, 0, sizeof(operands)); - operands[0] = res; -- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); -- return true; -+ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); - } - - /* Intended to be used for SM1-SM3, lowers SLT instructions (only available in vertex shaders) to -@@ -5123,7 +5096,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node - * = ((x - y) >= 0) ? 0.0 : 1.0 - * = CMP(x - y, 0.0, 1.0) - */ --static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg1, *arg2, *arg1_cast, *arg2_cast, *neg, *sub, *zero, *one, *cmp; - struct hlsl_constant_value zero_value, one_value; -@@ -5131,10 +5104,10 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP2_SLT) -- return false; -+ return NULL; - - arg1 = expr->operands[0].node; - arg2 = expr->operands[1].node; -@@ -5147,7 +5120,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - - memset(&zero_value, 0, sizeof(zero_value)); - if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, zero); - - one_value.u[0].f = 1.0; -@@ -5155,14 +5128,13 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, one); - - if (!(cmp = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, sub, zero, one))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, cmp); -- -- return true; -+ return cmp; - } - - /* Intended to be used for SM1-SM3, lowers CMP instructions (only available in pixel shaders) to -@@ -5173,7 +5145,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - * = z * ((x < 0) ? 1.0 : 0.0) + y * ((x < 0) ? 0.0 : 1.0) - * = z * SLT(x, 0.0) + y * (1 - SLT(x, 0.0)) - */ --static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *args[3], *args_cast[3], *slt, *neg_slt, *sub, *zero, *one, *mul1, *mul2; - struct hlsl_constant_value zero_value, one_value; -@@ -5182,10 +5154,10 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - unsigned int i; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP3_CMP) -- return false; -+ return NULL; - - float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); - -@@ -5197,7 +5169,7 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - - memset(&zero_value, 0, sizeof(zero_value)); - if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, zero); - - one_value.u[0].f = 1.0; -@@ -5205,7 +5177,7 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, one); - - slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, args_cast[0], zero); -@@ -5213,11 +5185,11 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h - neg_slt = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); - sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg_slt); - mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[1], sub); -- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2); -- return true; -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2); - } - --static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_casts_to_bool(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_type *type = instr->data_type, *arg_type; - static const struct hlsl_constant_value zero_value; -@@ -5225,28 +5197,27 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP1_CAST) -- return false; -+ return NULL; - arg_type = expr->operands[0].node->data_type; - if (type->class > HLSL_CLASS_VECTOR || arg_type->class > HLSL_CLASS_VECTOR) -- return false; -+ return NULL; - if (type->e.numeric.type != HLSL_TYPE_BOOL) -- return false; -+ return NULL; - - /* Narrowing casts should have already been lowered. */ - VKD3D_ASSERT(type->e.numeric.dimx == arg_type->e.numeric.dimx); - - zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc); - if (!zero) -- return false; -+ return NULL; - hlsl_block_add_instr(block, zero); - - neq = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_NEQUAL, expr->operands[0].node, zero); - neq->data_type = expr->node.data_type; -- -- return true; -+ return neq; - } - - struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *instrs, -@@ -5270,7 +5241,8 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc - return hlsl_block_add_expr(ctx, instrs, HLSL_OP3_TERNARY, operands, if_true->data_type, &condition->loc); - } - --static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_int_division_sm4(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; - struct hlsl_type *type = instr->data_type, *utype; -@@ -5279,16 +5251,16 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - unsigned int i; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - arg1 = expr->operands[0].node; - arg2 = expr->operands[1].node; - if (expr->op != HLSL_OP2_DIV) -- return false; -+ return NULL; - if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) -- return false; -+ return NULL; - if (type->e.numeric.type != HLSL_TYPE_INT) -- return false; -+ return NULL; - utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); - - xor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_XOR, arg1, arg2); -@@ -5296,7 +5268,7 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - for (i = 0; i < type->e.numeric.dimx; ++i) - high_bit_value.u[i].u = 0x80000000; - if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, high_bit); - - and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, xor, high_bit); -@@ -5310,7 +5282,8 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - return hlsl_add_conditional(ctx, block, and, neg, cast3); - } - --static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_int_modulus_sm4(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; - struct hlsl_type *type = instr->data_type, *utype; -@@ -5319,22 +5292,22 @@ static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - unsigned int i; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - arg1 = expr->operands[0].node; - arg2 = expr->operands[1].node; - if (expr->op != HLSL_OP2_MOD) -- return false; -+ return NULL; - if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) -- return false; -+ return NULL; - if (type->e.numeric.type != HLSL_TYPE_INT) -- return false; -+ return NULL; - utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); - - for (i = 0; i < type->e.numeric.dimx; ++i) - high_bit_value.u[i].u = 0x80000000; - if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, high_bit); - - and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, arg1, high_bit); -@@ -5348,31 +5321,30 @@ static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins - return hlsl_add_conditional(ctx, block, and, neg, cast3); - } - --static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_type *type = instr->data_type; - struct hlsl_ir_node *arg, *neg; - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - - if (expr->op != HLSL_OP1_ABS) -- return false; -+ return NULL; - if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) -- return false; -+ return NULL; - if (type->e.numeric.type != HLSL_TYPE_INT) -- return false; -+ return NULL; - - arg = expr->operands[0].node; - - neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); -- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg); -- return true; -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg); - } - --static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg1, *arg2, *mult, *comps[4] = {0}, *res; - struct hlsl_type *type = instr->data_type; -@@ -5381,11 +5353,11 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru - bool is_bool; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - - if (expr->op != HLSL_OP2_DOT) -- return false; -+ return NULL; - - if (hlsl_type_is_integer(type)) - { -@@ -5407,14 +5379,14 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru - res = comps[0]; - for (i = 1; i < dimx; ++i) - res = hlsl_block_add_binary_expr(ctx, block, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]); -- -- return true; -+ return res; - } - -- return false; -+ return NULL; - } - --static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_float_modulus(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one; - struct hlsl_type *type = instr->data_type, *btype; -@@ -5423,16 +5395,16 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - unsigned int i; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - arg1 = expr->operands[0].node; - arg2 = expr->operands[1].node; - if (expr->op != HLSL_OP2_MOD) -- return false; -+ return NULL; - if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) -- return false; -+ return NULL; - if (type->e.numeric.type != HLSL_TYPE_FLOAT) -- return false; -+ return NULL; - btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); - - mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, arg2, arg1); -@@ -5447,14 +5419,13 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - for (i = 0; i < type->e.numeric.dimx; ++i) - one_value.u[i].f = 1.0f; - if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, one); - - div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond); - mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1); - frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc); -- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); -- return true; -+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); - } - - static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -6167,7 +6138,7 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls - return false; - } - --static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) -+static void register_deref_usage(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) - { - struct hlsl_ir_var *var = deref->var; - enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); -@@ -6215,18 +6186,43 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - } - - case HLSL_IR_RESOURCE_LOAD: -- register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->resource); -- if (hlsl_ir_resource_load(instr)->sampler.var) -- register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->sampler); -+ { -+ const struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); -+ -+ register_deref_usage(ctx, &load->resource); -+ if (load->sampler.var) -+ register_deref_usage(ctx, &load->sampler); -+ -+ if (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS) -+ { -+ unsigned int index; -+ -+ hlsl_regset_index_from_deref(ctx, &load->resource, HLSL_REGSET_UAVS, &index); -+ load->resource.var->objects_usage[HLSL_REGSET_UAVS][index].uav_read = true; -+ } - break; -+ } - - case HLSL_IR_RESOURCE_STORE: - register_deref_usage(ctx, &hlsl_ir_resource_store(instr)->resource); - break; - - case HLSL_IR_INTERLOCKED: -- register_deref_usage(ctx, &hlsl_ir_interlocked(instr)->dst); -+ { -+ const struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr); -+ -+ register_deref_usage(ctx, &interlocked->dst); -+ -+ if (hlsl_deref_get_regset(ctx, &interlocked->dst) == HLSL_REGSET_UAVS) -+ { -+ unsigned int index; -+ -+ hlsl_regset_index_from_deref(ctx, &interlocked->dst, HLSL_REGSET_UAVS, &index); -+ interlocked->dst.var->objects_usage[HLSL_REGSET_UAVS][index].uav_read = true; -+ interlocked->dst.var->objects_usage[HLSL_REGSET_UAVS][index].uav_atomics = true; -+ } - break; -+ } - - default: - break; -@@ -8234,7 +8230,7 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod - - void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) - { -- lower_ir(ctx, lower_index_loads, body); -+ replace_ir(ctx, lower_index_loads, body); - } - - static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op) -@@ -8537,27 +8533,27 @@ static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *bod - { - bool progress; - -- hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); -+ replace_ir(ctx, fold_redundant_casts, body); - do - { - progress = simplify_exprs(ctx, body); - progress |= hlsl_copy_propagation_execute(ctx, body); -- progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); -- progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); -+ progress |= replace_ir(ctx, fold_swizzle_chains, body); -+ progress |= replace_ir(ctx, fold_trivial_swizzles, body); - progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); - } while (progress); -- hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); -+ replace_ir(ctx, fold_redundant_casts, body); - } - - void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) - { - bool progress; - -- lower_ir(ctx, lower_complex_casts, body); -- lower_ir(ctx, lower_matrix_swizzles, body); -+ replace_ir(ctx, lower_complex_casts, body); -+ replace_ir(ctx, lower_matrix_swizzles, body); - -- lower_ir(ctx, lower_broadcasts, body); -- while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL)); -+ replace_ir(ctx, lower_broadcasts, body); -+ while (replace_ir(ctx, fold_redundant_casts, body)); - do - { - progress = hlsl_transform_ir(ctx, split_array_copies, body, NULL); -@@ -8566,16 +8562,16 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) - while (progress); - hlsl_transform_ir(ctx, split_matrix_copies, body, NULL); - -- lower_ir(ctx, lower_narrowing_casts, body); -- lower_ir(ctx, lower_int_dot, body); -+ replace_ir(ctx, lower_narrowing_casts, body); -+ replace_ir(ctx, lower_int_dot, body); - if (hlsl_version_ge(ctx, 4, 0)) - { -- lower_ir(ctx, lower_int_modulus_sm4, body); -- lower_ir(ctx, lower_int_division_sm4, body); -+ replace_ir(ctx, lower_int_modulus_sm4, body); -+ replace_ir(ctx, lower_int_division_sm4, body); - } -- lower_ir(ctx, lower_int_abs, body); -- lower_ir(ctx, lower_casts_to_bool, body); -- lower_ir(ctx, lower_float_modulus, body); -+ replace_ir(ctx, lower_int_abs, body); -+ replace_ir(ctx, lower_casts_to_bool, body); -+ replace_ir(ctx, lower_float_modulus, body); - - hlsl_run_folding_passes(ctx, body); - } -@@ -10189,10 +10185,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co - struct hlsl_ir_function_decl *func, struct list *semantic_vars, - struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) - { -- struct hlsl_ir_var *var; - struct hlsl_block block; -- struct hlsl_reg *reg; -- unsigned int *count; - - program->ssa_count = 0; - program->temp_count = 0; -@@ -10207,17 +10200,6 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co - - sm1_generate_vsir_block(ctx, body, program); - -- count = &program->flat_constant_count[VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER]; -- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -- { -- if (!var->is_uniform) -- continue; -- -- if (!(reg = &var->regs[HLSL_REGSET_NUMERIC])->allocation_size) -- continue; -- -- *count = max(*count, reg->id + reg->allocation_size); -- } - program->ssa_count = ctx->ssa_count; - program->temp_count = ctx->temp_count; - -@@ -12785,9 +12767,9 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, - } - } - --static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const struct hlsl_type *type) -+static enum vkd3d_shader_resource_type get_vsir_resource_type(enum hlsl_sampler_dim sampler_dim) - { -- switch (type->sampler_dim) -+ switch (sampler_dim) - { - case HLSL_SAMPLER_DIM_1D: - return VKD3D_SHADER_RESOURCE_TEXTURE_1D; -@@ -12816,7 +12798,7 @@ static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const - } - } - --static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) -+static enum vsir_data_type get_vsir_resource_data_type(const struct hlsl_type *type) - { - const struct hlsl_type *format = type->e.resource.format; - -@@ -12953,10 +12935,10 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, - } - else - { -- ins->declaration.semantic.resource_type = sm4_generate_vsir_get_resource_type(resource->component_type); -+ ins->declaration.semantic.resource_type = get_vsir_resource_type(resource->component_type->sampler_dim); - - for (unsigned int j = 0; j < 4; ++j) -- ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); -+ ins->declaration.semantic.resource_data_type[j] = get_vsir_resource_data_type(component_type); - - if (multisampled) - ins->declaration.semantic.sample_count = component_type->sample_count; -@@ -13108,6 +13090,140 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - program->temp_count = ctx->temp_count; - } - -+static void generate_vsir_descriptors_for_var(struct hlsl_ctx *ctx, struct vsir_program *program, -+ const struct hlsl_ir_var *var, enum hlsl_regset r, enum vkd3d_shader_descriptor_type type) -+{ -+ unsigned int component_count = hlsl_type_component_count(var->data_type); -+ -+ for (unsigned int k = 0; k < component_count; ++k) -+ { -+ const struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k); -+ struct vkd3d_shader_register_range range; -+ struct vkd3d_shader_descriptor_info1 *d; -+ unsigned int regset_offset; -+ enum hlsl_regset regset; -+ uint32_t id; -+ -+ if (!hlsl_type_is_resource(component_type)) -+ continue; -+ regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); -+ if (regset != r) -+ continue; -+ if (regset_offset > var->regs[r].allocation_size) -+ continue; -+ -+ if (!var->objects_usage[r][regset_offset].used) -+ continue; -+ -+ id = var->regs[r].id + regset_offset; -+ range.space = var->regs[r].space; -+ range.first = var->regs[r].index + regset_offset; -+ /* FIXME: 5.1 arrays. */ -+ range.last = var->regs[r].index + regset_offset; -+ -+ if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) -+ { -+ if (!(d = vsir_program_add_descriptor(program, type, id, -+ &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) -+ return; -+ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) -+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; -+ } -+ else -+ { -+ if (component_type->class == HLSL_CLASS_SAMPLER) -+ d = vsir_program_add_descriptor(program, type, id, &range, -+ get_vsir_resource_type(var->objects_usage[r][regset_offset].sampler_dim), VSIR_DATA_F32); -+ else -+ d = vsir_program_add_descriptor(program, type, id, &range, -+ get_vsir_resource_type(component_type->sampler_dim), -+ get_vsir_resource_data_type(component_type)); -+ if (!d) -+ return; -+ -+ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) -+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; -+ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ d->structure_stride = hlsl_type_get_packed_size(component_type->e.resource.format); -+ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS -+ || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) -+ d->sample_count = component_type->sample_count; -+ -+ if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV && component_type->e.resource.rasteriser_ordered) -+ d->uav_flags |= VKD3DSUF_RASTERISER_ORDERED_VIEW; -+ -+ if (var->objects_usage[r][regset_offset].uav_read) -+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ; -+ if (var->objects_usage[r][regset_offset].uav_atomics) -+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS; -+ } -+ } -+} -+ -+static void generate_vsir_descriptors(struct hlsl_ctx *ctx, struct vsir_program *program) -+{ -+ struct vkd3d_shader_register_range range; -+ struct vkd3d_shader_descriptor_info1 *d; -+ const struct hlsl_ir_var *var; -+ -+ if (program->shader_version.major < 4) -+ { -+ uint32_t flat_constant_count = 0; -+ -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ const struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC]; -+ -+ if (var->is_uniform && reg->allocation_size) -+ flat_constant_count = max(flat_constant_count, reg->id + reg->allocation_size); -+ -+ generate_vsir_descriptors_for_var(ctx, program, var, -+ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER); -+ generate_vsir_descriptors_for_var(ctx, program, var, -+ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV); -+ } -+ -+ if (flat_constant_count) -+ { -+ range.space = 0; -+ range.first = range.last = VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER; -+ if ((d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, -+ range.first, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) -+ d->buffer_size = flat_constant_count * 16; -+ } -+ } -+ else -+ { -+ struct hlsl_buffer *buffer; -+ -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ generate_vsir_descriptors_for_var(ctx, program, var, -+ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER); -+ generate_vsir_descriptors_for_var(ctx, program, var, -+ HLSL_REGSET_TEXTURES, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV); -+ generate_vsir_descriptors_for_var(ctx, program, var, -+ HLSL_REGSET_UAVS, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV); -+ } -+ -+ LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) -+ { -+ if (!buffer->reg.allocated) -+ continue; -+ -+ range.space = buffer->reg.space; -+ range.first = buffer->reg.index; -+ /* FIXME: 5.1 arrays. */ -+ range.last = buffer->reg.index; -+ if ((d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, -+ buffer->reg.id, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) -+ d->buffer_size = align(buffer->size, 4) * sizeof(float); -+ } -+ } -+ -+ program->has_descriptor_info = true; -+} -+ - /* For some reason, for matrices, values from default value initializers end - * up in different components than from regular initializers. Default value - * initializers fill the matrix in vertical reading order -@@ -13877,8 +13993,8 @@ static void loop_unrolling_simplify(struct hlsl_ctx *ctx, struct hlsl_block *blo - current_index = index_instructions(block, *index); - progress |= copy_propagation_transform_block(ctx, block, state); - -- progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, block, NULL); -- progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, block, NULL); -+ progress |= replace_ir(ctx, fold_swizzle_chains, block); -+ progress |= replace_ir(ctx, fold_trivial_swizzles, block); - progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, block, NULL); - } while (progress); - -@@ -14131,7 +14247,7 @@ static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc - hlsl_transform_ir(ctx, resolve_loops, block, NULL); - } - --static bool lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) - { - struct hlsl_ir_function_decl *func; - struct hlsl_ir_node *call, *rhs; -@@ -14150,33 +14266,31 @@ static bool lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, str - "}\n"; - - if (node->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(node); - if (expr->op != HLSL_OP1_COUNTBITS) -- return false; -+ return NULL; - - rhs = expr->operands[0].node; - if (!(body = hlsl_sprintf_alloc(ctx, template, hlsl_type_component_count(rhs->data_type)))) -- return false; -+ return NULL; - func = hlsl_compile_internal_function(ctx, "countbits", body); - vkd3d_free(body); - if (!func) -- return false; -+ return NULL; - - lhs = func->parameters.vars[0]; - hlsl_block_add_simple_store(ctx, block, lhs, rhs); - - if (!(call = hlsl_new_call(ctx, func, &node->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, call); - -- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -- -- return true; -+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - } - --static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) - { - struct hlsl_ir_function_decl *func; - struct hlsl_ir_node *call, *rhs; -@@ -14201,11 +14315,11 @@ static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hl - "}\n"; - - if (node->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(node); - if (expr->op != HLSL_OP1_CTZ) -- return false; -+ return NULL; - - rhs = expr->operands[0].node; - if (!(body = hlsl_sprintf_alloc(ctx, template, hlsl_type_component_count(rhs->data_type)))) -@@ -14213,21 +14327,19 @@ static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hl - func = hlsl_compile_internal_function(ctx, "ctz", body); - vkd3d_free(body); - if (!func) -- return false; -+ return NULL; - - lhs = func->parameters.vars[0]; - hlsl_block_add_simple_store(ctx, block, lhs, rhs); - - if (!(call = hlsl_new_call(ctx, func, &node->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, call); - -- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -- -- return true; -+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - } - --static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) - { - struct hlsl_ir_function_decl *func; - struct hlsl_ir_node *call, *rhs; -@@ -14282,29 +14394,28 @@ static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru - expr = hlsl_ir_expr(node); - - if (expr->op != HLSL_OP1_F16TOF32) -- return false; -+ return NULL; - - rhs = expr->operands[0].node; - component_count = hlsl_type_component_count(rhs->data_type); - - if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) -- return false; -+ return NULL; - - if (!(func = hlsl_compile_internal_function(ctx, "soft_f16tof32", body))) -- return false; -+ return NULL; - - lhs = func->parameters.vars[0]; - hlsl_block_add_simple_store(ctx, block, lhs, rhs); - - if (!(call = hlsl_new_call(ctx, func, &node->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, call); - -- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -- return true; -+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - } - --static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) - { - struct hlsl_ir_function_decl *func; - struct hlsl_ir_node *call, *rhs; -@@ -14342,34 +14453,33 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru - "}\n"; - - if (node->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(node); - - if (expr->op != HLSL_OP1_F32TOF16) -- return false; -+ return NULL; - - rhs = expr->operands[0].node; - component_count = hlsl_type_component_count(rhs->data_type); - - if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) -- return false; -+ return NULL; - - if (!(func = hlsl_compile_internal_function(ctx, "soft_f32tof16", body))) -- return false; -+ return NULL; - - lhs = func->parameters.vars[0]; - hlsl_block_add_simple_store(ctx, block, lhs, rhs); - - if (!(call = hlsl_new_call(ctx, func, &node->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, call); - -- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -- return true; -+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - } - --static bool lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) - { - struct hlsl_ir_function_decl *func; - struct hlsl_ir_node *call, *rhs; -@@ -14406,33 +14516,31 @@ static bool lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru - "}\n"; - - if (node->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(node); - if (expr->op != HLSL_OP1_FIND_MSB) -- return false; -+ return NULL; - - rhs = expr->operands[0].node; - if (!(body = hlsl_sprintf_alloc(ctx, template, rhs->data_type->name, hlsl_type_component_count(rhs->data_type)))) -- return false; -+ return NULL; - func = hlsl_compile_internal_function(ctx, "find_msb", body); - vkd3d_free(body); - if (!func) -- return false; -+ return NULL; - - lhs = func->parameters.vars[0]; - hlsl_block_add_simple_store(ctx, block, lhs, rhs); - - if (!(call = hlsl_new_call(ctx, func, &node->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, call); - -- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -- -- return true; -+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - } - --static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) -+static struct hlsl_ir_node *lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) - { - struct hlsl_ir_function_decl *func; - struct hlsl_ir_node *call, *rhs; -@@ -14477,12 +14585,12 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct - "}"; - - if (node->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(node); - - if (expr->op != HLSL_OP1_ISINF) -- return false; -+ return NULL; - - rhs = expr->operands[0].node; - -@@ -14497,19 +14605,18 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct - - component_count = hlsl_type_component_count(rhs->data_type); - if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) -- return false; -+ return NULL; - - if (!(func = hlsl_compile_internal_function(ctx, "isinf", body))) -- return false; -+ return NULL; - - hlsl_block_add_simple_store(ctx, block, func->parameters.vars[0], rhs); - - if (!(call = hlsl_new_call(ctx, func, &node->loc))) -- return false; -+ return NULL; - hlsl_block_add_instr(block, call); - -- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); -- return true; -+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - } - - static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *body, -@@ -14548,25 +14655,25 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v - - if (hlsl_version_ge(ctx, 4, 0) && hlsl_version_lt(ctx, 5, 0)) - { -- lower_ir(ctx, lower_countbits, body); -- lower_ir(ctx, lower_ctz, body); -- lower_ir(ctx, lower_f16tof32, body); -- lower_ir(ctx, lower_f32tof16, body); -- lower_ir(ctx, lower_find_msb, body); -+ replace_ir(ctx, lower_countbits, body); -+ replace_ir(ctx, lower_ctz, body); -+ replace_ir(ctx, lower_f16tof32, body); -+ replace_ir(ctx, lower_f32tof16, body); -+ replace_ir(ctx, lower_find_msb, body); - } - -- lower_ir(ctx, lower_isinf, body); -+ replace_ir(ctx, lower_isinf, body); - - lower_return(ctx, entry_func, body, false); - - while (hlsl_transform_ir(ctx, lower_calls, body, NULL)); - -- lower_ir(ctx, lower_complex_casts, body); -- lower_ir(ctx, lower_matrix_swizzles, body); -- lower_ir(ctx, lower_index_loads, body); -+ replace_ir(ctx, lower_complex_casts, body); -+ replace_ir(ctx, lower_matrix_swizzles, body); -+ replace_ir(ctx, lower_index_loads, body); - -- lower_ir(ctx, lower_tgsm_loads, body); -- lower_ir(ctx, lower_tgsm_stores, body); -+ replace_ir(ctx, lower_tgsm_loads, body); -+ replace_ir(ctx, lower_tgsm_stores, body); - - if (entry_func->return_var) - { -@@ -14739,9 +14846,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v - remove_unreachable_code(ctx, body); - hlsl_transform_ir(ctx, normalize_switch_cases, body, NULL); - -- lower_ir(ctx, lower_nonconstant_vector_derefs, body); -- lower_ir(ctx, lower_casts_to_bool, body); -- lower_ir(ctx, lower_int_dot, body); -+ replace_ir(ctx, lower_nonconstant_vector_derefs, body); -+ replace_ir(ctx, lower_casts_to_bool, body); -+ replace_ir(ctx, lower_int_dot, body); - - if (hlsl_version_lt(ctx, 4, 0)) - hlsl_transform_ir(ctx, lower_separate_samples, body, NULL); -@@ -14753,8 +14860,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v - progress = vectorize_exprs(ctx, body); - 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); -+ progress |= replace_ir(ctx, fold_swizzle_chains, body); -+ progress |= replace_ir(ctx, fold_trivial_swizzles, body); - progress |= vectorize_stores(ctx, body); - } while (progress); - -@@ -14782,37 +14889,37 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v - - if (profile->major_version < 4) - { -- while (lower_ir(ctx, lower_nonconstant_array_loads, body)); -+ while (replace_ir(ctx, lower_nonconstant_array_loads, body)); - -- lower_ir(ctx, lower_ternary, body); -- lower_ir(ctx, lower_int_modulus_sm1, body); -- lower_ir(ctx, lower_division, body); -+ replace_ir(ctx, lower_ternary, body); -+ replace_ir(ctx, lower_int_modulus_sm1, body); -+ replace_ir(ctx, lower_division, body); - /* Constants casted to float must be folded, and new casts to bool also need to be lowered. */ - hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); -- lower_ir(ctx, lower_casts_to_bool, body); -- -- lower_ir(ctx, lower_casts_to_int, body); -- lower_ir(ctx, lower_trunc, body); -- lower_ir(ctx, lower_sqrt, body); -- lower_ir(ctx, lower_dot, body); -- lower_ir(ctx, lower_round, body); -- lower_ir(ctx, lower_ceil, body); -- lower_ir(ctx, lower_floor, body); -- lower_ir(ctx, lower_trig, body); -- lower_ir(ctx, lower_comparison_operators, body); -- lower_ir(ctx, lower_logic_not, body); -+ replace_ir(ctx, lower_casts_to_bool, body); -+ -+ replace_ir(ctx, lower_casts_to_int, body); -+ replace_ir(ctx, lower_trunc, body); -+ replace_ir(ctx, lower_sqrt, body); -+ replace_ir(ctx, lower_dot, body); -+ replace_ir(ctx, lower_round, body); -+ replace_ir(ctx, lower_ceil, body); -+ replace_ir(ctx, lower_floor, body); -+ replace_ir(ctx, lower_trig, body); -+ replace_ir(ctx, lower_comparison_operators, body); -+ replace_ir(ctx, lower_logic_not, body); - if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) -- lower_ir(ctx, lower_slt, body); -+ replace_ir(ctx, lower_slt, body); - else -- lower_ir(ctx, lower_cmp, body); -+ replace_ir(ctx, lower_cmp, body); - } - - if (profile->major_version < 2) - { -- lower_ir(ctx, lower_abs, body); -+ replace_ir(ctx, lower_abs, body); - } - -- lower_ir(ctx, validate_nonconstant_vector_store_derefs, body); -+ replace_ir(ctx, validate_nonconstant_vector_store_derefs, body); - - hlsl_run_folding_passes(ctx, body); - -@@ -14930,6 +15037,8 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info - if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL) - generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars); - -+ generate_vsir_descriptors(ctx, program); -+ - if (program->shader_version.major < 4) - sm1_generate_ctab(ctx, reflection_data); - else -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 670f6c31cf8..13ea8a433a6 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -299,6 +299,7 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) - [VSIR_OP_MOVC ] = "movc", - [VSIR_OP_MSAD ] = "msad", - [VSIR_OP_MUL ] = "mul", -+ [VSIR_OP_NEG ] = "neg", - [VSIR_OP_NEO ] = "ne_ord", - [VSIR_OP_NEU ] = "ne", - [VSIR_OP_NOP ] = "nop", -@@ -747,6 +748,38 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature, - return false; - } - -+struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program, -+ enum vkd3d_shader_descriptor_type type, unsigned int register_id, -+ const struct vkd3d_shader_register_range *range, -+ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type) -+{ -+ struct vkd3d_shader_scan_descriptor_info1 *info = &program->descriptors; -+ struct vkd3d_shader_descriptor_info1 *d; -+ -+ if (!info) -+ return NULL; -+ -+ if (!vkd3d_array_reserve((void **)&info->descriptors, &program->descriptors_size, -+ info->descriptor_count + 1, sizeof(*info->descriptors))) -+ { -+ ERR("Failed to allocate descriptor info.\n"); -+ return NULL; -+ } -+ -+ d = &info->descriptors[info->descriptor_count]; -+ memset(d, 0, sizeof(*d)); -+ d->type = type; -+ d->register_id = register_id; -+ d->register_space = range->space; -+ d->register_index = range->first; -+ d->resource_type = resource_type; -+ d->resource_data_type = resource_data_type; -+ d->count = (range->last == ~0u) ? ~0u : range->last - range->first + 1; -+ ++info->descriptor_count; -+ -+ return d; -+} -+ - const char *debug_vsir_writemask(unsigned int writemask) - { - static const char components[] = {'x', 'y', 'z', 'w'}; -@@ -1422,8 +1455,8 @@ static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program, - static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) - { -+ unsigned int count = 3, src0_id, src1_id, divisor_id; - struct vkd3d_shader_instruction *udiv, *ins, *mov; -- unsigned int count = 2; - - udiv = vsir_program_iterator_current(it); - -@@ -1437,9 +1470,9 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - } - - if (udiv->dst[0].reg.type != VKD3DSPR_NULL) -- ++count; -+ count += 2; - if (udiv->dst[1].reg.type != VKD3DSPR_NULL) -- ++count; -+ count += 2; - - if (!vsir_program_iterator_insert_after(it, count)) - return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -1451,14 +1484,33 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - 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); -+ src0_id = program->ssa_count++; -+ dst_param_init_ssa(&mov->dst[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); - - 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[1]; -- dst_param_init_ssa(&mov->dst[0], program->ssa_count + 1, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ src1_id = program->ssa_count++; -+ dst_param_init_ssa(&mov->dst[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ -+ mov = vsir_program_iterator_next(it); -+ if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOVC, 1, 3))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ src_param_init_ssa(&mov->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ src_param_init_ssa(&mov->src[1], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ vsir_register_init(&mov->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); -+ mov->src[2].reg.dimension = udiv->src[1].reg.dimension; -+ mov->src[2].reg.u.immconst_u32[0] = 1; -+ mov->src[2].reg.u.immconst_u32[1] = 1; -+ mov->src[2].reg.u.immconst_u32[2] = 1; -+ mov->src[2].reg.u.immconst_u32[3] = 1; -+ if (mov->src[2].reg.dimension == VSIR_DIMENSION_VEC4) -+ mov->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; -+ divisor_id = program->ssa_count++; -+ dst_param_init_ssa(&mov->dst[0], divisor_id, mov->src[1].reg.data_type, mov->src[1].reg.dimension); - - if (udiv->dst[0].reg.type != VKD3DSPR_NULL) - { -@@ -1469,11 +1521,30 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - - 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); -+ src_param_init_ssa(&ins->src[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); -+ src_param_init_ssa(&ins->src[1], divisor_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ dst_param_init_ssa(&ins->dst[0], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ -+ /* Like its TPF equivalent, division by zero is well-defined for -+ * VSIR_OP_UDIV, and returns UINT_MAX. Division by zero is undefined -+ * for VSIR_OP_UDIV_SIMPLE and VSIR_OP_UREM, so handle it here. */ -+ ins = vsir_program_iterator_next(it); -+ if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_MOVC, 1, 3))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ src_param_init_ssa(&ins->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ src_param_init_ssa(&ins->src[1], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ vsir_register_init(&ins->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); -+ ins->src[2].reg.dimension = udiv->src[1].reg.dimension; -+ ins->src[2].reg.u.immconst_u32[0] = UINT_MAX; -+ ins->src[2].reg.u.immconst_u32[1] = UINT_MAX; -+ ins->src[2].reg.u.immconst_u32[2] = UINT_MAX; -+ ins->src[2].reg.u.immconst_u32[3] = UINT_MAX; -+ if (ins->src[2].reg.dimension == VSIR_DIMENSION_VEC4) -+ ins->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; - ins->dst[0] = udiv->dst[0]; -+ -+ ++program->ssa_count; - } - - if (udiv->dst[1].reg.type != VKD3DSPR_NULL) -@@ -1485,15 +1556,30 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, - - 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); -+ src_param_init_ssa(&ins->src[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); -+ src_param_init_ssa(&ins->src[1], divisor_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ dst_param_init_ssa(&ins->dst[0], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ -+ ins = vsir_program_iterator_next(it); -+ if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_MOVC, 1, 3))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ src_param_init_ssa(&ins->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ src_param_init_ssa(&ins->src[1], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); -+ vsir_register_init(&ins->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); -+ ins->src[2].reg.dimension = udiv->src[1].reg.dimension; -+ ins->src[2].reg.u.immconst_u32[0] = UINT_MAX; -+ ins->src[2].reg.u.immconst_u32[1] = UINT_MAX; -+ ins->src[2].reg.u.immconst_u32[2] = UINT_MAX; -+ ins->src[2].reg.u.immconst_u32[3] = UINT_MAX; -+ if (ins->src[2].reg.dimension == VSIR_DIMENSION_VEC4) -+ ins->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; - ins->dst[0] = udiv->dst[1]; -+ -+ ++program->ssa_count; - } - - vkd3d_shader_instruction_make_nop(udiv); -- program->ssa_count += 2; - - return VKD3D_OK; - } -@@ -1648,6 +1734,7 @@ static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program, - 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) - { -+ const struct vkd3d_shader_descriptor_info1 *sampler; - unsigned int idx = ins->src[0].reg.idx[0].offset; - struct vkd3d_shader_src_param *srcs; - -@@ -1660,7 +1747,7 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - -- if (!(srcs = vsir_program_get_src_params(program, 3))) -+ if (!(srcs = vsir_program_get_src_params(program, 4))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - /* Note we run before I/O normalization. */ -@@ -1668,9 +1755,26 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr - 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; -+ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); -+ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) -+ { -+ enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2); -+ -+ ins->opcode = VSIR_OP_SAMPLE_C; -+ ins->src = srcs; -+ ins->src_count = 4; -+ -+ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ -+ srcs[3] = srcs[0]; -+ srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref); -+ } -+ else -+ { -+ ins->opcode = VSIR_OP_SAMPLE; -+ ins->src = srcs; -+ ins->src_count = 3; -+ } - - return VKD3D_OK; - } -@@ -1730,6 +1834,7 @@ static enum vkd3d_result vsir_program_lower_texldp(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) - { -+ const struct vkd3d_shader_descriptor_info1 *sampler; - unsigned int idx = tex->src[1].reg.idx[0].offset; - struct vkd3d_shader_src_param *srcs; - -@@ -1743,7 +1848,21 @@ static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program, - vsir_src_param_init_resource(&srcs[1], idx, idx); - vsir_src_param_init_sampler(&srcs[2], idx, idx); - -- if (!tex->flags) -+ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); -+ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) -+ { -+ enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2); -+ -+ tex->opcode = VSIR_OP_SAMPLE_C; -+ tex->src = srcs; -+ tex->src_count = 4; -+ -+ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ -+ srcs[3] = srcs[0]; -+ srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref); -+ } -+ else if (!tex->flags) - { - tex->opcode = VSIR_OP_SAMPLE; - tex->src = srcs; -@@ -1825,6 +1944,7 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, - - static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *ins) - { -+ const struct vkd3d_shader_descriptor_info1 *sampler; - unsigned int idx = ins->dst[0].reg.idx[0].offset; - struct vkd3d_shader_src_param *srcs; - -@@ -1834,7 +1954,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st - /* We run before I/O normalization. */ - VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6); - -- if (!(srcs = vsir_program_get_src_params(program, 3))) -+ if (!(srcs = vsir_program_get_src_params(program, 4))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); -@@ -1845,9 +1965,24 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st - 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; -+ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); -+ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) -+ { -+ ins->opcode = VSIR_OP_SAMPLE_C; -+ ins->src = srcs; -+ ins->src_count = 4; -+ -+ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ -+ srcs[3] = srcs[0]; -+ srcs[3].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); -+ } -+ else -+ { -+ ins->opcode = VSIR_OP_SAMPLE; -+ ins->src = srcs; -+ ins->src_count = 3; -+ } - - return VKD3D_OK; - } -@@ -2039,6 +2174,72 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr - return VKD3D_OK; - } - -+static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *program, -+ struct vsir_transformation_context *ctx) -+{ -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), new_it; -+ struct vkd3d_shader_instruction *ins, *new_ins; -+ unsigned int i, j; -+ -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -+ { -+ for (i = 0; i < ins->src_count; ++i) -+ { -+ enum vkd3d_shader_opcode new_opcodes[2] = {VSIR_OP_NOP, VSIR_OP_NOP}; -+ struct vkd3d_shader_src_param *src = &ins->src[i]; -+ -+ /* TODO: support other modifiers, including destination modifiers. */ -+ switch (src->modifiers) -+ { -+ case VKD3DSPSM_ABS: -+ new_opcodes[0] = VSIR_OP_ABS; -+ break; -+ -+ case VKD3DSPSM_NEG: -+ new_opcodes[0] = data_type_is_integer(src->reg.data_type) ? VSIR_OP_INEG : VSIR_OP_NEG; -+ break; -+ -+ case VKD3DSPSM_ABSNEG: -+ new_opcodes[0] = VSIR_OP_ABS; -+ new_opcodes[1] = VSIR_OP_NEG; -+ break; -+ -+ default: -+ continue; -+ } -+ -+ for (j = 0; j < 2 && new_opcodes[j] != VSIR_OP_NOP; ++j) -+ { -+ if (!(new_ins = vsir_program_iterator_insert_before(&it, &new_it, 1))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ ins = vsir_program_iterator_current(&it); -+ -+ if (!vsir_instruction_init_with_params(program, new_ins, &ins->location, new_opcodes[j], 1, 1)) -+ { -+ vkd3d_shader_instruction_make_nop(new_ins); -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ } -+ -+ new_ins->src[0] = *src; -+ new_ins->src[0].modifiers = VKD3DSPSM_NONE; -+ -+ dst_param_init_ssa(&new_ins->dst[0], program->ssa_count, src->reg.data_type, src->reg.dimension); -+ src_param_init_ssa(src, program->ssa_count, src->reg.data_type, src->reg.dimension); -+ -+ if (data_type_is_64_bit(src->reg.data_type)) -+ { -+ new_ins->dst[0].write_mask = vsir_write_mask_64_from_32(new_ins->dst[0].write_mask); -+ src->swizzle = vsir_swizzle_64_from_32(src->swizzle); -+ } -+ -+ ++program->ssa_count; -+ } -+ } -+ } -+ -+ return VKD3D_OK; -+} -+ - static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -@@ -3936,6 +4137,19 @@ static void cf_flattener_set_error(struct cf_flattener *flattener, enum vkd3d_re - flattener->status = error; - } - -+static struct vkd3d_shader_instruction *cf_flattener_instruction_append(struct cf_flattener *flattener) -+{ -+ struct vkd3d_shader_instruction *ins; -+ -+ if (!(ins = shader_instruction_array_append(&flattener->instructions))) -+ { -+ ERR("Failed to allocate instructions.\n"); -+ cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); -+ return NULL; -+ } -+ return ins; -+} -+ - static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, - const struct vkd3d_shader_instruction *instruction) - { -@@ -3944,7 +4158,7 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, - if (instruction->opcode == VSIR_OP_NOP) - return true; - -- if (!(dst_ins = shader_instruction_array_append(&flattener->instructions))) -+ if (!(dst_ins = cf_flattener_instruction_append(flattener))) - return false; - - *dst_ins = *instruction; -@@ -3975,7 +4189,7 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int - { - struct vkd3d_shader_instruction *ins; - -- if (!(ins = shader_instruction_array_append(&flattener->instructions))) -+ if (!(ins = cf_flattener_instruction_append(flattener))) - return; - if (!vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->program)) - { -@@ -3993,7 +4207,7 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten - struct vkd3d_shader_src_param *src_params, *false_branch_param; - struct vkd3d_shader_instruction *ins; - -- if (!(ins = shader_instruction_array_append(&flattener->instructions))) -+ if (!(ins = cf_flattener_instruction_append(flattener))) - return NULL; - vsir_instruction_init(ins, &flattener->location, VSIR_OP_BRANCH); - -@@ -4144,13 +4358,6 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte - is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL; - after_declarations_section = is_hull_shader; - -- if (!shader_instruction_array_reserve(&flattener->instructions, instructions->count + 1)) -- { -- ERR("Failed to allocate instructions.\n"); -- cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); -- return VKD3D_ERROR_OUT_OF_MEMORY; -- } -- - it = vsir_program_iterator(instructions); - for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it)) - { -@@ -4609,16 +4816,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs - vsir_src_param_init_label(&dst_ins->src[0], default_label); - } - -- if (!shader_instruction_array_reserve(&instructions, instructions.count + 3 * case_count - 1)) -- goto fail; -- - if_label = current_label; - - for (j = 0; j < case_count; ++j) - { - unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]); - -- dst_ins = shader_instruction_array_append(&instructions); -+ if (!(dst_ins = shader_instruction_array_append(&instructions))) -+ goto fail; - if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_IEQ, 1, 2)) - { - vkd3d_shader_instruction_make_nop(dst_ins); -@@ -4636,7 +4841,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs - else - fallthrough_label = block_count + 1; - -- dst_ins = shader_instruction_array_append(&instructions); -+ if (!(dst_ins = shader_instruction_array_append(&instructions))) -+ goto fail; - if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_BRANCH, 0, 3)) - { - vkd3d_shader_instruction_make_nop(dst_ins); -@@ -4660,7 +4866,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs - } - else - { -- dst_ins = shader_instruction_array_append(&instructions); -+ if (!(dst_ins = shader_instruction_array_append(&instructions))) -+ goto fail; - if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_LABEL, 0, 1)) - { - vkd3d_shader_instruction_make_nop(dst_ins); -@@ -4755,8 +4962,8 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( - struct vsir_program_iterator it_begin = *it; - struct ssas_to_temps_alloc alloc = {0}; - struct vkd3d_shader_instruction *ins; -- size_t phi_count, incoming_count; - unsigned int current_label = 0; -+ size_t phi_count; - - VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); - -@@ -4770,7 +4977,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( - goto fail; - - phi_count = 0; -- incoming_count = 0; - for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) - { - unsigned int j, temp_idx; -@@ -4819,8 +5025,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( - incoming->dst = ins->dst; - - alloc.table[ins->dst->reg.idx[0].offset] = temp_idx; -- -- ++incoming_count; - } - - materialize_ssas_to_temps_process_reg(program, &alloc, &ins->dst->reg); -@@ -4829,9 +5033,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( - if (!phi_count) - goto done; - -- if (!shader_instruction_array_reserve(&program->instructions, program->instructions.count + incoming_count)) -- goto fail; -- - *it = it_begin; - - for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) -@@ -4856,7 +5057,8 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( - case VSIR_OP_SWITCH_MONOLITHIC: - info = &block_info[current_label - 1]; - -- mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count); -+ if (!(mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count))) -+ goto fail; - VKD3D_ASSERT(mov_ins); - - for (j = 0; j < info->incoming_count; ++j) -@@ -6782,23 +6984,14 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_block(struct vsir_cfg *cfg - struct vsir_cfg_emit_target *target = cfg->target; - struct vkd3d_shader_instruction *ins, *end, *dst; - struct vsir_program_iterator it; -- size_t ins_count = 0; - - it = block->begin; - end = vsir_program_iterator_current(&block->end); - - for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) - { -- ++ins_count; -- } -- -- if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + ins_count)) -- return VKD3D_ERROR_OUT_OF_MEMORY; -- -- it = block->begin; -- for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) -- { -- dst = shader_instruction_array_append(&target->instructions); -+ if (!(dst = shader_instruction_array_append(&target->instructions))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; - VKD3D_ASSERT(dst); - *dst = *ins; - } -@@ -6822,10 +7015,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, - if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0) - return ret; - -- if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 5)) -+ if (!(ins = shader_instruction_array_append(&target->instructions))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- -- ins = shader_instruction_array_append(&target->instructions); - vsir_instruction_init(ins, &no_loc, VSIR_OP_ENDLOOP); - - /* Add a trampoline to implement multilevel jumping depending on the stored -@@ -6840,7 +7031,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, - * we have to reach an outer loop, so we keep breaking. */ - const unsigned int inner_break_target = loop->idx << 1; - -- ins = shader_instruction_array_append(&target->instructions); -+ if (!(ins = shader_instruction_array_append(&target->instructions))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; - if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_IEQ, 1, 2)) - { - vkd3d_shader_instruction_make_nop(ins); -@@ -6853,7 +7045,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, - src_param_init_temp_uint(&ins->src[0], target->jump_target_temp_idx); - src_param_init_const_uint(&ins->src[1], outer_continue_target); - -- ins = shader_instruction_array_append(&target->instructions); -+ if (!(ins = shader_instruction_array_append(&target->instructions))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; - if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_CONTINUEP, 0, 1)) - { - vkd3d_shader_instruction_make_nop(ins); -@@ -6875,7 +7068,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, - src_param_init_temp_uint(&ins->src[0], target->jump_target_temp_idx); - src_param_init_const_uint(&ins->src[1], inner_break_target); - -- ins = shader_instruction_array_append(&target->instructions); -+ if (!(ins = shader_instruction_array_append(&target->instructions))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; - if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_BREAKP, 0, 1)) - { - vkd3d_shader_instruction_make_nop(ins); -@@ -6971,12 +7165,10 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, - vkd3d_unreachable(); - } - -- if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 2)) -- return VKD3D_ERROR_OUT_OF_MEMORY; -- - if (jump->needs_launcher) - { -- ins = shader_instruction_array_append(&target->instructions); -+ if (!(ins = shader_instruction_array_append(&target->instructions))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; - if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_MOV, 1, 1)) - { - vkd3d_shader_instruction_make_nop(ins); -@@ -6987,7 +7179,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, - src_param_init_const_uint(&ins->src[0], jump_target); - } - -- ins = shader_instruction_array_append(&target->instructions); -+ if (!(ins = shader_instruction_array_append(&target->instructions))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; - if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, opcode, 0, !!jump->condition)) - { - vkd3d_shader_instruction_make_nop(ins); -@@ -8097,35 +8290,41 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); - struct vkd3d_shader_location loc = ins->location; - uint32_t ssa_factor = program->ssa_count++; -- uint32_t ssa_temp, ssa_temp2; -+ uint32_t ssa_temp, ssa_temp2, ssa_temp3; - - switch (mode) - { - case VKD3D_SHADER_FOG_FRAGMENT_LINEAR: - /* We generate the following code: - * -- * add sr0, FOG_END, -vFOG.x -- * mul_sat srFACTOR, sr0, FOG_SCALE -+ * neg sr0, vFOG.x -+ * add sr1, FOG_END, sr0 -+ * mul_sat srFACTOR, sr1, FOG_SCALE - */ -- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - ssa_temp = program->ssa_count++; -+ ssa_temp2 = program->ssa_count++; - -- vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); -+ vsir_src_param_init(&ins->src[0], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); -+ ins->src[0].reg.idx[0].offset = fog_signature_idx; -+ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; -+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ ins = vsir_program_iterator_next(it); -+ -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); -+ dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); - 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; -+ src_param_init_ssa_float(&ins->src[1], ssa_temp); - ins = vsir_program_iterator_next(it); - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_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_ssa_float(&ins->src[0], ssa_temp2); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); - ins = vsir_program_iterator_next(it); - -@@ -8135,12 +8334,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - /* We generate the following code: - * - * mul sr0, FOG_SCALE, vFOG.x -- * exp_sat srFACTOR, -sr0 -+ * neg sr1, sr0 -+ * exp_sat srFACTOR, sr1 - */ -- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - ssa_temp = program->ssa_count++; -+ ssa_temp2 = program->ssa_count++; - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); -@@ -8151,11 +8352,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); - ins = vsir_program_iterator_next(it); - -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); -+ dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); -+ src_param_init_ssa_float(&ins->src[0], ssa_temp); -+ ins = vsir_program_iterator_next(it); -+ - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; -- src_param_init_ssa_float(&ins->src[0], ssa_temp); -- ins->src[0].modifiers = VKD3DSPSM_NEG; -+ src_param_init_ssa_float(&ins->src[0], ssa_temp2); - ins = vsir_program_iterator_next(it); - break; - -@@ -8164,13 +8369,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * - * mul sr0, FOG_SCALE, vFOG.x - * mul sr1, sr0, sr0 -- * exp_sat srFACTOR, -sr1 -+ * neg sr2, sr1 -+ * exp_sat srFACTOR, sr2 - */ -- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 5))) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - ssa_temp = program->ssa_count++; - ssa_temp2 = program->ssa_count++; -+ ssa_temp3 = program->ssa_count++; - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); -@@ -8187,11 +8394,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - src_param_init_ssa_float(&ins->src[1], ssa_temp); - ins = vsir_program_iterator_next(it); - -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); -+ dst_param_init_ssa_float(&ins->dst[0], ssa_temp3); -+ src_param_init_ssa_float(&ins->src[0], ssa_temp2); -+ ins = vsir_program_iterator_next(it); -+ - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; -- src_param_init_ssa_float(&ins->src[0], ssa_temp2); -- ins->src[0].modifiers = VKD3DSPSM_NEG; -+ src_param_init_ssa_float(&ins->src[0], ssa_temp3); - ins = vsir_program_iterator_next(it); - break; - -@@ -8201,21 +8412,28 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - - /* We generate the following code: - * -- * add sr0, FRAG_COLOUR, -FOG_COLOUR -- * mad oC0, sr0, srFACTOR, FOG_COLOUR -+ * neg sr0, FOG_COLOUR -+ * add sr1, FRAG_COLOUR, sr0 -+ * mad oC0, sr1, srFACTOR, FOG_COLOUR - */ -+ ssa_temp = program->ssa_count++; -+ ssa_temp2 = program->ssa_count++; -+ -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); -+ dst_param_init_ssa_float4(&ins->dst[0], ssa_temp); -+ src_param_init_parameter_vec4(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); -+ ins = vsir_program_iterator_next(it); - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); -- dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); -+ dst_param_init_ssa_float4(&ins->dst[0], ssa_temp2); - src_param_init_temp_float4(&ins->src[0], colour_temp); -- src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); -- ins->src[1].modifiers = VKD3DSPSM_NEG; -+ src_param_init_ssa_float4(&ins->src[1], ssa_temp); - ins = vsir_program_iterator_next(it); - - 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_float4(&ins->src[0], ssa_temp2); - src_param_init_ssa_float(&ins->src[1], ssa_factor); - src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); - ins = vsir_program_iterator_next(it); -@@ -8560,6 +8778,7 @@ static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src - case VSIR_OP_MOVC: - case VSIR_OP_MSAD: /* FIXME: Is this correct? */ - case VSIR_OP_MUL: -+ case VSIR_OP_NEG: - case VSIR_OP_NEO: - case VSIR_OP_NEU: - case VSIR_OP_NOT: -@@ -11482,6 +11701,18 @@ static void vsir_validate_float_elementwise_operation(struct validation_context - vsir_validate_elementwise_operation(ctx, instruction, types); - } - -+static void vsir_validate_float_or_double_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_DATA_F64] = 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) - { -@@ -12534,7 +12765,7 @@ struct vsir_validator_instruction_desc - - static const struct vsir_validator_instruction_desc vsir_validator_instructions[] = - { -- [VSIR_OP_ABS] = {1, 1, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_ABS] = {1, 1, vsir_validate_float_or_double_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}, -@@ -12629,6 +12860,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation}, - [VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation}, - [VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation}, -+ [VSIR_OP_NEG] = {1, 1, vsir_validate_float_or_double_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}, -@@ -12899,8 +13131,6 @@ static void vsir_transform_( - struct vsir_transformation_context *ctx, const char *step_name, - enum vkd3d_result (*step)(struct vsir_program *program, struct vsir_transformation_context *ctx)) - { -- ctx->progress = false; -- - if (ctx->result < 0) - return; - -@@ -13050,6 +13280,7 @@ static bool vsir_instruction_has_side_effects(const struct vkd3d_shader_instruct - case VSIR_OP_MOVC: - case VSIR_OP_MSAD: - case VSIR_OP_MUL: -+ case VSIR_OP_NEG: - case VSIR_OP_NEO: - case VSIR_OP_NEU: - case VSIR_OP_NOP: -@@ -13317,6 +13548,229 @@ static enum vkd3d_result vsir_program_dce(struct vsir_program *program, - return VKD3D_OK; - } - -+/* -+ * This pass attempts to reduce redundant MOVs (copies) by combining them with -+ * adjacent instructions. The resulting MOVs will subsequently be removed by -+ * DCE if no longer used. -+ * -+ * We attempt to combine two instructions, not necessarily consecutive, -+ * of the form -+ * -+ * mov aaa.bbb, ccc -+ * XXX ..., aaa.ddd -+ * -+ * into -+ * -+ * XXX ..., ccc -+ * -+ * There are many constraints, including: -+ * -+ * - The ddd components of aaa must not have been modified between the -+ * two instructions. -+ * Currently, only SSA is supported, so this is trivial. -+ * -+ * - The relevant components of ccc must not have been modified between the -+ * two instructions. -+ * Currently, we require ccc to be a read-only register, so this is trivial. -+ * -+ * - ddd must be a subset of bbb. This is again trivial for SSA. -+ */ -+ -+struct vsir_copy_propagation_state -+{ -+ /* The sources for each SSA register, if it was written by a -+ * MOV instruction, or NULL if not. -+ * -+ * We do not add or remove instructions in this pass, only modifying their -+ * content, so these pointers are safe to store. -+ */ -+ const struct vkd3d_shader_instruction **ssa_sources; -+}; -+ -+static bool is_read_only(const struct vsir_program *program, enum vkd3d_shader_register_type type) -+{ -+ switch (type) -+ { -+ case VKD3DSPR_ADDR: -+ case VKD3DSPR_IDXTEMP: -+ case VKD3DSPR_LOOP: -+ case VKD3DSPR_TEMP: -+ case VKD3DSPR_TEMPFLOAT16: -+ return false; -+ -+ case VKD3DSPR_TEXTURE: -+ return vkd3d_shader_ver_ge(&program->shader_version, 1, 4); -+ -+ /* Not applicable since they're not numeric or can't be sources. */ -+ case VKD3DSPR_ATTROUT: -+ case VKD3DSPR_COLOROUT: -+ case VKD3DSPR_COMBINED_SAMPLER: -+ case VKD3DSPR_COUNT: -+ case VKD3DSPR_DEPTHOUT: -+ case VKD3DSPR_DEPTHOUTGE: -+ case VKD3DSPR_DEPTHOUTLE: -+ case VKD3DSPR_FUNCTIONBODY: -+ case VKD3DSPR_FUNCTIONPOINTER: -+ case VKD3DSPR_GROUPSHAREDMEM: -+ case VKD3DSPR_INVALID: -+ case VKD3DSPR_LABEL: -+ case VKD3DSPR_NULL: -+ case VKD3DSPR_OUTPUT: -+ case VKD3DSPR_OUTSTENCILREF: -+ case VKD3DSPR_PREDICATE: -+ case VKD3DSPR_RASTERIZER: -+ case VKD3DSPR_RASTOUT: -+ case VKD3DSPR_RESOURCE: -+ case VKD3DSPR_SAMPLER: -+ case VKD3DSPR_STREAM: -+ case VKD3DSPR_TEXCRDOUT: -+ case VKD3DSPR_UAV: -+ return false; -+ -+ case VKD3DSPR_CONST: -+ case VKD3DSPR_CONSTBOOL: -+ case VKD3DSPR_CONSTBUFFER: -+ case VKD3DSPR_CONSTINT: -+ case VKD3DSPR_COVERAGE: -+ case VKD3DSPR_FORKINSTID: -+ case VKD3DSPR_GSINSTID: -+ case VKD3DSPR_IMMCONST: -+ case VKD3DSPR_IMMCONST64: -+ case VKD3DSPR_IMMCONSTBUFFER: -+ case VKD3DSPR_INCONTROLPOINT: -+ case VKD3DSPR_INPUT: -+ case VKD3DSPR_JOININSTID: -+ case VKD3DSPR_LOCALTHREADID: -+ case VKD3DSPR_LOCALTHREADINDEX: -+ case VKD3DSPR_MISCTYPE: -+ case VKD3DSPR_OUTCONTROLPOINT: -+ case VKD3DSPR_OUTPOINTID: -+ case VKD3DSPR_PARAMETER: -+ case VKD3DSPR_PATCHCONST: -+ case VKD3DSPR_POINT_COORD: -+ case VKD3DSPR_PRIMID: -+ case VKD3DSPR_SAMPLEMASK: -+ case VKD3DSPR_SSA: -+ case VKD3DSPR_TESSCOORD: -+ case VKD3DSPR_THREADGROUPID: -+ case VKD3DSPR_THREADID: -+ case VKD3DSPR_UNDEF: -+ case VKD3DSPR_WAVELANECOUNT: -+ case VKD3DSPR_WAVELANEINDEX: -+ return true; -+ } -+ -+ vkd3d_unreachable(); -+} -+ -+static bool can_propagate_ssa_source(const struct vsir_program *program, const struct vkd3d_shader_instruction *ins) -+{ -+ if (ins->opcode != VSIR_OP_MOV) -+ return false; -+ /* TODO: Propagate copies for other register types. */ -+ if (ins->dst[0].reg.type != VKD3DSPR_SSA) -+ return false; -+ if (ins->dst[0].modifiers || ins->dst[0].shift) -+ return false; -+ -+ /* TODO: We can perform copy-prop for read-write register types, but we -+ * have to be sure that the register wasn't modified between the two -+ * instructions. */ -+ if (!is_read_only(program, ins->src[0].reg.type)) -+ return false; -+ for (unsigned int k = 0; k < ins->src[0].reg.idx_count; ++k) -+ { -+ if (ins->src[0].reg.idx[k].rel_addr && !is_read_only(program, ins->src[0].reg.idx[k].rel_addr->reg.type)) -+ return false; -+ } -+ -+ /* Don't bother with other source modifiers for now; the HLSL compiler -+ * doesn't emit them. */ -+ switch (ins->src[0].modifiers) -+ { -+ case VKD3DSPSM_ABS: -+ case VKD3DSPSM_ABSNEG: -+ case VKD3DSPSM_NEG: -+ case VKD3DSPSM_NONE: -+ break; -+ -+ default: -+ return false; -+ } -+ return true; -+} -+ -+static enum vkd3d_result vsir_program_copy_propagation(struct vsir_program *program, -+ struct vsir_transformation_context *ctx) -+{ -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vsir_copy_propagation_state state = {0}; -+ struct vkd3d_shader_instruction *ins; -+ -+ if (!(state.ssa_sources = vkd3d_calloc(program->ssa_count, sizeof(*state.ssa_sources)))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -+ { -+ for (unsigned int j = 0; j < ins->src_count; ++j) -+ { -+ struct vkd3d_shader_src_param *src = &ins->src[j]; -+ const struct vkd3d_shader_src_param *mov_src; -+ const struct vkd3d_shader_instruction *mov; -+ enum vsir_data_type data_type; -+ uint32_t new_swizzle = 0; -+ -+ if (src->reg.type != VKD3DSPR_SSA) -+ continue; -+ if (data_type_is_64_bit(src->reg.data_type)) -+ continue; -+ if (!(mov = state.ssa_sources[src->reg.idx[0].offset])) -+ continue; -+ mov_src = &mov->src[0]; -+ data_type = src->reg.data_type; -+ -+ src->reg = mov_src->reg; -+ src->reg.data_type = data_type; -+ -+ if (!shader_register_clone_relative_addresses(&src->reg, program)) -+ { -+ vkd3d_free(state.ssa_sources); -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ } -+ -+ for (unsigned int k = 0; k < 4; ++k) -+ { -+ unsigned int s = vsir_swizzle_get_component(src->swizzle, k); -+ -+ if (mov_src->reg.type == VKD3DSPR_IMMCONST) -+ src->reg.u.immconst_u32[k] = mov_src->reg.u.immconst_u32[s]; -+ else -+ vsir_swizzle_set_component(&new_swizzle, k, vsir_swizzle_get_component(mov_src->swizzle, s)); -+ } -+ if (mov_src->reg.type != VKD3DSPR_IMMCONST) -+ src->swizzle = new_swizzle; -+ -+ if (src->modifiers == VKD3DSPSM_NONE) -+ src->modifiers = mov_src->modifiers; -+ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_ABS) -+ src->modifiers = VKD3DSPSM_ABSNEG; -+ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_ABSNEG) -+ src->modifiers = VKD3DSPSM_ABS; -+ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_NEG) -+ src->modifiers = VKD3DSPSM_NONE; -+ /* Otherwise no change is necessary. */ -+ -+ ctx->progress = true; -+ } -+ -+ if (can_propagate_ssa_source(program, ins)) -+ state.ssa_sources[ins->dst[0].reg.idx[0].offset] = ins; -+ } -+ -+ vkd3d_free(state.ssa_sources); -+ return VKD3D_OK; -+} -+ - enum vkd3d_result vsir_program_optimize(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) - { -@@ -13325,7 +13779,11 @@ enum vkd3d_result vsir_program_optimize(struct vsir_program *program, uint64_t c - vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); - - do -+ { -+ ctx.progress = false; -+ vsir_transform(&ctx, vsir_program_copy_propagation); - vsir_transform(&ctx, vsir_program_dce); -+ } - while (ctx.progress); - - if (TRACE_ON()) -@@ -13388,6 +13846,7 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t - struct vsir_transformation_context ctx; - - vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); -+ vsir_transform(&ctx, vsir_program_lower_modifiers); - vsir_transform(&ctx, vsir_program_lower_instructions); - - if (program->shader_version.major >= 6) -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index 8a89dcabd5e..fc136e3ac98 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -602,25 +602,11 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m - if (reg->dimension == VSIR_DIMENSION_VEC4) - msl_print_swizzle(str, vsir_src->swizzle, mask); - -- switch (vsir_src->modifiers) -+ if (vsir_src->modifiers) - { -- case VKD3DSPSM_NONE: -- break; -- case VKD3DSPSM_NEG: -- vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); -- break; -- 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); -- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); -- break; -+ vkd3d_string_buffer_printf(buffer, "(%s)", vsir_src->modifiers, str->buffer); -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); - } - - if (str != buffer) -@@ -1472,6 +1458,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d - - switch (ins->opcode) - { -+ case VSIR_OP_ABS: -+ msl_intrinsic(gen, ins, "abs"); -+ break; - case VSIR_OP_ACOS: - msl_intrinsic(gen, ins, "acos"); - break; -@@ -1624,6 +1613,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d - msl_relop(gen, ins, "!="); - break; - case VSIR_OP_INEG: -+ case VSIR_OP_NEG: - msl_unary_op(gen, ins, "-"); - break; - case VSIR_OP_ITOF: -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 3deca660b00..31271660e4f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -989,7 +989,7 @@ struct vkd3d_spirv_builder - uint32_t type_bool_id; - uint32_t type_void_id; - uint32_t scope_subgroup_id; -- uint32_t numeric_type_ids[VKD3D_SHADER_COMPONENT_TYPE_COUNT][VKD3D_VEC4_SIZE]; -+ uint32_t numeric_type_ids[VSIR_DATA_TYPE_COUNT][VKD3D_VEC4_SIZE]; - - struct vkd3d_spirv_stream debug_stream; /* debug instructions */ - struct vkd3d_spirv_stream annotation_stream; /* decoration instructions */ -@@ -2116,20 +2116,6 @@ static uint32_t vkd3d_spirv_build_op_fdiv(struct vkd3d_spirv_builder *builder, - SpvOpFDiv, result_type, operand0, operand1); - } - --static uint32_t vkd3d_spirv_build_op_fnegate(struct vkd3d_spirv_builder *builder, -- uint32_t result_type, uint32_t operand) --{ -- return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, -- SpvOpFNegate, result_type, operand); --} -- --static uint32_t vkd3d_spirv_build_op_snegate(struct vkd3d_spirv_builder *builder, -- uint32_t result_type, uint32_t operand) --{ -- return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, -- SpvOpSNegate, result_type, operand); --} -- - static uint32_t vkd3d_spirv_build_op_and(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t operand0, uint32_t operand1) - { -@@ -2478,19 +2464,6 @@ static uint32_t vkd3d_spirv_build_op_group_nonuniform_broadcast_first(struct vkd - result_type, vkd3d_spirv_get_op_scope_subgroup(builder), val_id); - } - --static uint32_t vkd3d_spirv_build_op_glsl_std450_tr1(struct vkd3d_spirv_builder *builder, -- enum GLSLstd450 op, uint32_t result_type, uint32_t operand) --{ -- uint32_t id = vkd3d_spirv_get_glsl_std450_instr_set(builder); -- return vkd3d_spirv_build_op_ext_inst(builder, result_type, id, op, &operand, 1); --} -- --static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder *builder, -- uint32_t result_type, uint32_t operand) --{ -- return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450FAbs, 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) - { -@@ -2518,71 +2491,69 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build - GLSLstd450NClamp, operands, ARRAY_SIZE(operands)); - } - --static uint32_t spirv_get_type_id_for_component_type(struct vkd3d_spirv_builder *builder, -- enum vkd3d_shader_component_type component_type, unsigned int component_count) -+static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, -+ enum vsir_data_type data_type, unsigned int component_count) - { - uint32_t scalar_id, type_id; - -- VKD3D_ASSERT(component_type < VKD3D_SHADER_COMPONENT_TYPE_COUNT); -+ VKD3D_ASSERT(data_type < VSIR_DATA_TYPE_COUNT); - if (!component_count || component_count > VKD3D_VEC4_SIZE) - { - ERR("Invalid component count %u.\n", component_count); - return 0; - } - -- if ((type_id = builder->numeric_type_ids[component_type][component_count - 1])) -+ if ((type_id = builder->numeric_type_ids[data_type][component_count - 1])) - return type_id; - - if (component_count == 1) - { -- switch (component_type) -+ switch (data_type) - { -- case VKD3D_SHADER_COMPONENT_VOID: -- type_id = vkd3d_spirv_get_op_type_void(builder); -+ case VSIR_DATA_BOOL: -+ type_id = vkd3d_spirv_get_op_type_bool(builder); - break; -- case VKD3D_SHADER_COMPONENT_FLOAT: -+ -+ case VSIR_DATA_F32: - type_id = vkd3d_spirv_get_op_type_float(builder, 32); - break; -- case VKD3D_SHADER_COMPONENT_INT: -- case VKD3D_SHADER_COMPONENT_UINT: -- type_id = vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT); -+ -+ case VSIR_DATA_F64: -+ type_id = vkd3d_spirv_get_op_type_float(builder, 64); - break; -- case VKD3D_SHADER_COMPONENT_BOOL: -- type_id = vkd3d_spirv_get_op_type_bool(builder); -+ -+ case VSIR_DATA_I32: -+ case VSIR_DATA_U32: -+ type_id = vkd3d_spirv_get_op_type_int(builder, 32, data_type == VSIR_DATA_I32); - break; -- case VKD3D_SHADER_COMPONENT_DOUBLE: -- type_id = vkd3d_spirv_get_op_type_float(builder, 64); -+ -+ case VSIR_DATA_I64: -+ case VSIR_DATA_U64: -+ type_id = vkd3d_spirv_get_op_type_int(builder, 64, data_type == VSIR_DATA_I64); - break; -- case VKD3D_SHADER_COMPONENT_INT64: -- case VKD3D_SHADER_COMPONENT_UINT64: -- type_id = vkd3d_spirv_get_op_type_int(builder, 64, component_type == VKD3D_SHADER_COMPONENT_INT64); -+ -+ case VSIR_DATA_UNUSED: -+ type_id = vkd3d_spirv_get_op_type_void(builder); - break; -+ - default: -- FIXME("Unhandled component type %#x.\n", component_type); -+ FIXME("Unhandled data type \"%s\" (%#x).\n", -+ vsir_data_type_get_name(data_type, ""), data_type); - return 0; - } - } - else - { -- VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID); -- scalar_id = spirv_get_type_id_for_component_type(builder, component_type, 1); -+ VKD3D_ASSERT(data_type != VSIR_DATA_UNUSED); -+ scalar_id = spirv_get_type_id(builder, data_type, 1); - type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); - } - -- builder->numeric_type_ids[component_type][component_count - 1] = type_id; -+ builder->numeric_type_ids[data_type][component_count - 1] = type_id; - - return type_id; - } - --static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, -- enum vsir_data_type data_type, unsigned int component_count) --{ -- enum vkd3d_shader_component_type component_type; -- -- component_type = vkd3d_component_type_from_data_type(data_type); -- return spirv_get_type_id_for_component_type(builder, component_type, component_count); --} -- - static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, - const char *entry_point, const char *source_name) - { -@@ -4846,74 +4817,23 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler, - spirv_compiler_emit_execution_mode(compiler, mode, &literal, 1); - } - --static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler, -- const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id) --{ -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- uint32_t type_id; -- -- type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); -- if (data_type_is_floating_point(reg->data_type)) -- return vkd3d_spirv_build_op_glsl_std450_fabs(builder, type_id, val_id); -- -- FIXME("Unhandled data type %#x.\n", reg->data_type); -- return val_id; --} -- --static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, -- const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id) --{ -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- uint32_t type_id; -- -- type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); -- if (data_type_is_floating_point(reg->data_type)) -- return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id); -- else if (data_type_is_integer(reg->data_type)) -- return vkd3d_spirv_build_op_snegate(builder, type_id, val_id); -- -- FIXME("Unhandled data type %#x.\n", reg->data_type); -- return val_id; --} -- --static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler, -- const struct vkd3d_shader_register *reg, uint32_t write_mask, -- enum vkd3d_shader_src_modifier modifier, uint32_t val_id) --{ -- switch (modifier) -- { -- case VKD3DSPSM_NONE: -- break; -- case VKD3DSPSM_NEG: -- return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); -- case VKD3DSPSM_ABS: -- return spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); -- case VKD3DSPSM_ABSNEG: -- val_id = spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); -- return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); -- default: -- FIXME("Unhandled src modifier %#x.\n", modifier); -- break; -- } -- -- return val_id; --} -- - static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, - const struct vkd3d_shader_src_param *src, uint32_t write_mask) - { -- uint32_t val_id; -+ if (src->modifiers) -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled source modifier(s) %#x.", src->modifiers); - -- val_id = spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); -- return spirv_compiler_emit_src_modifier(compiler, &src->reg, write_mask, src->modifiers, val_id); -+ return spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); - } - - static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *compiler, -- const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vkd3d_shader_component_type component_type) -+ const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vsir_data_type data_type) - { - struct vkd3d_shader_src_param src_param = *src; - -- src_param.reg.data_type = vsir_data_type_from_component_type(component_type); -+ src_param.reg.data_type = data_type; -+ - return spirv_compiler_emit_load_src(compiler, &src_param, write_mask); - } - -@@ -5081,10 +5001,8 @@ static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler, - } - - static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compiler, -- const struct vkd3d_shader_dst_param *dst, uint32_t val_id, -- enum vkd3d_shader_component_type component_type, uint32_t swizzle) -+ const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vsir_data_type data_type, uint32_t swizzle) - { -- enum vsir_data_type data_type = vsir_data_type_from_component_type(component_type); - struct vkd3d_shader_dst_param typed_dst = *dst; - - val_id = spirv_compiler_emit_swizzle(compiler, val_id, -@@ -5096,23 +5014,17 @@ static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compil - } - - static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *compiler, -- const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_component_type component_type, -- uint32_t *component_ids) -+ const struct vkd3d_shader_dst_param *dst, enum vsir_data_type data_type, uint32_t *component_ids) - { - unsigned int component_count = vsir_write_mask_component_count(dst->write_mask); - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, dst_type_id, val_id; - -- type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); -+ type_id = spirv_get_type_id(builder, data_type, component_count); - if (component_count > 1) -- { -- val_id = vkd3d_spirv_build_op_composite_construct(builder, -- type_id, component_ids, component_count); -- } -+ val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, component_ids, component_count); - else -- { - val_id = *component_ids; -- } - - dst_type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); - if (dst_type_id != type_id) -@@ -5122,8 +5034,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp - } - - static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler, -- const struct vkd3d_shader_dst_param *dst, uint32_t val_id, -- enum vkd3d_shader_component_type component_type, uint32_t swizzle) -+ const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vsir_data_type data_type, uint32_t swizzle) - { - unsigned int component_count = vsir_write_mask_component_count(dst->write_mask); - uint32_t component_ids[VKD3D_VEC4_SIZE]; -@@ -5137,7 +5048,7 @@ static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler - - component_ids[i] = val_id; - } -- spirv_compiler_emit_store_dst_components(compiler, dst, component_type, component_ids); -+ spirv_compiler_emit_store_dst_components(compiler, dst, data_type, component_ids); - } - - static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, -@@ -5229,7 +5140,7 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, - } - - static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler *compiler, -- enum vkd3d_shader_component_type component_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode) -+ enum vsir_data_type data_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - -@@ -5238,7 +5149,7 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler - case VKD3DSIM_NONE: - /* VUID-StandaloneSpirv-Flat-04744: integer or double types must be - * decorated 'Flat' for fragment shaders. */ -- if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || component_type == VKD3D_SHADER_COMPONENT_FLOAT) -+ if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || data_type == VSIR_DATA_F32) - break; - /* fall through */ - case VKD3DSIM_CONSTANT: -@@ -5724,7 +5635,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - unsigned int component_idx, input_component_count; - 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; -@@ -5782,13 +5692,11 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - if (builtin) - { - data_type = builtin->data_type; -- component_type = vkd3d_component_type_from_data_type(data_type); - input_component_count = builtin->component_count; - } - else - { -- component_type = signature_element->component_type; -- data_type = vsir_data_type_from_component_type(component_type); -+ data_type = vsir_data_type_from_component_type(signature_element->component_type); - input_component_count = vsir_write_mask_component_count(signature_element->mask); - } - -@@ -5841,8 +5749,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - if (component_idx) - vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); - -- spirv_compiler_emit_interpolation_decorations(compiler, component_type, input_id, -- signature_element->interpolation_mode); -+ spirv_compiler_emit_interpolation_decorations(compiler, data_type, -+ input_id, signature_element->interpolation_mode); - } - - var_id = input_id; -@@ -6879,7 +6787,7 @@ static const struct vkd3d_spirv_resource_type *spirv_compiler_enable_resource_ty - return resource_type_info; - } - --static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_type data_type) -+static SpvImageFormat image_format_for_image_read(enum vsir_data_type data_type) - { - /* The following formats are supported by Direct3D 11 hardware for UAV - * typed loads. A newer hardware may support more formats for UAV typed -@@ -6887,11 +6795,11 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty - */ - switch (data_type) - { -- case VKD3D_SHADER_COMPONENT_FLOAT: -+ case VSIR_DATA_F32: - return SpvImageFormatR32f; -- case VKD3D_SHADER_COMPONENT_INT: -+ case VSIR_DATA_I32: - return SpvImageFormatR32i; -- case VKD3D_SHADER_COMPONENT_UINT: -+ case VSIR_DATA_U32: - return SpvImageFormatR32ui; - default: - FIXME("Unhandled type %#x.\n", data_type); -@@ -6901,8 +6809,7 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty - - static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, -- const struct vkd3d_spirv_resource_type *resource_type_info, enum vkd3d_shader_component_type data_type, -- bool raw_structured) -+ const struct vkd3d_spirv_resource_type *resource_type_info, enum vsir_data_type data_type, bool raw_structured) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_descriptor_info1 *d; -@@ -6923,15 +6830,15 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler - vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat); - } - -- sampled_type_id = spirv_get_type_id_for_component_type(builder, data_type, 1); -- return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, -- 2, resource_type_info->arrayed, resource_type_info->ms, -- reg->type == VKD3DSPR_UAV ? 2 : 1, format); -+ sampled_type_id = spirv_get_type_id(builder, data_type, 1); -+ -+ return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, 2, -+ resource_type_info->arrayed, resource_type_info->ms, reg->type == VKD3DSPR_UAV ? 2 : 1, format); - } - - static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register_range *resource_range, -- enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_component_type sampled_type, -+ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type sampled_type, - unsigned int structure_stride, bool raw, const struct vkd3d_spirv_resource_type *resource_type_info) - { - const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; -@@ -6992,7 +6899,7 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi - symbol.id = var_id; - symbol.descriptor_array = NULL; - symbol.info.resource.range = *resource_range; -- symbol.info.resource.sampled_type = vsir_data_type_from_component_type(sampled_type); -+ symbol.info.resource.sampled_type = sampled_type; - symbol.info.resource.type_id = image_type_id; - symbol.info.resource.resource_type_info = resource_type_info; - symbol.info.resource.structure_stride = structure_stride; -@@ -7017,9 +6924,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - uint32_t counter_type_id, type_id, var_id, counter_var_id = 0; - const struct vkd3d_spirv_resource_type *resource_type_info; - unsigned int sample_count = descriptor->sample_count; -- enum vkd3d_shader_component_type sampled_type; - struct vkd3d_symbol resource_symbol; - struct vkd3d_shader_register reg; -+ enum vsir_data_type sampled_type; - - vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_F32, 1); - reg.idx[0].offset = descriptor->register_id; -@@ -7036,7 +6943,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - return; - } - -- sampled_type = vkd3d_component_type_from_data_type(descriptor->resource_data_type); -+ sampled_type = descriptor->resource_data_type; - - if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range)) - { -@@ -7049,7 +6956,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - { - uint32_t array_type_id, struct_id; - -- type_id = spirv_get_type_id(builder, descriptor->resource_data_type, 1); -+ type_id = spirv_get_type_id(builder, sampled_type, 1); - - array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id); - vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4); -@@ -7122,7 +7029,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - resource_symbol.id = var_id; - resource_symbol.descriptor_array = var_info.array_symbol; - resource_symbol.info.resource.range = *range; -- resource_symbol.info.resource.sampled_type = descriptor->resource_data_type; -+ resource_symbol.info.resource.sampled_type = sampled_type; - resource_symbol.info.resource.type_id = type_id; - resource_symbol.info.resource.resource_type_info = resource_type_info; - resource_symbol.info.resource.structure_stride = structure_stride; -@@ -7564,6 +7471,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru - {VSIR_OP_ITOF, SpvOpConvertSToF}, - {VSIR_OP_ITOI, SpvOpSConvert}, - {VSIR_OP_MUL, SpvOpFMul}, -+ {VSIR_OP_NEG, SpvOpFNegate}, - {VSIR_OP_NOT, SpvOpNot}, - {VSIR_OP_OR, SpvOpBitwiseOr}, - {VSIR_OP_UDIV_SIMPLE, SpvOpUDiv}, -@@ -7641,14 +7549,13 @@ 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; -- unsigned int i, component_count; -+ uint32_t src_ids[SPIRV_MAX_SRC_COUNT]; - uint32_t type_id, val_id; - SpvOp op = SpvOpMax; -- bool check_zero; -+ unsigned int i; - - if (src->reg.data_type == VSIR_DATA_U64 && instruction->opcode == VSIR_OP_COUNTBITS) - { -@@ -7688,44 +7595,14 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil - 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 (data_type_is_64_bit(dst[0].reg.data_type)) -- 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. -@@ -7746,9 +7623,6 @@ 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; - } -@@ -8230,16 +8104,16 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - 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; -- enum vkd3d_shader_component_type component_type; - unsigned int i, j, k, src_count, size; -+ enum vsir_data_type data_type; - uint32_t write_mask; - SpvOp op; - - src_count = instruction->src_count; - VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids)); - -- component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); -- type_id = spirv_get_type_id(builder, dst->reg.data_type, 1); -+ data_type = dst->reg.data_type; -+ type_id = spirv_get_type_id(builder, data_type, 1); - size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20; - mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); - size_id = spirv_compiler_get_constant_uint(compiler, size); -@@ -8265,7 +8139,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - for (j = 0; j < src_count; ++j) - { - src_ids[src_count - j - 1] = spirv_compiler_emit_load_src_with_type(compiler, -- &src[j], write_mask, component_type); -+ &src[j], write_mask, data_type); - } - - /* In SPIR-V, the last two operands are Offset and Count. */ -@@ -8281,7 +8155,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - op, type_id, src_ids, src_count); - } - -- spirv_compiler_emit_store_dst_components(compiler, dst, component_type, constituents); -+ spirv_compiler_emit_store_dst_components(compiler, dst, data_type, constituents); - } - - static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, -@@ -8313,8 +8187,7 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, - scalar_type_id, result_id, 0); - } - -- spirv_compiler_emit_store_dst_components(compiler, -- dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); -+ spirv_compiler_emit_store_dst_components(compiler, dst, dst->reg.data_type, components); - } - - static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, -@@ -8349,8 +8222,7 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, - instr_set_id, GLSLstd450PackHalf2x16, &src_id, 1); - } - -- spirv_compiler_emit_store_dst_components(compiler, -- dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); -+ spirv_compiler_emit_store_dst_components(compiler, dst, dst->reg.data_type, components); - } - - static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *compiler, -@@ -8918,8 +8790,7 @@ static void spirv_compiler_prepare_image(struct spirv_compiler *compiler, - } - - image->image_type_id = spirv_compiler_get_image_type_id(compiler, resource_reg, &symbol->info.resource.range, -- image->resource_type_info, vkd3d_component_type_from_data_type(image->sampled_type), -- image->structure_stride || image->raw); -+ image->resource_type_info, image->sampled_type, image->structure_stride || image->raw); - - if (sampled) - { -@@ -9014,8 +8885,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_image_fetch(builder, type_id, - image.image_id, coordinate_id, operands_mask, image_operands, image_operand_count); - -- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -- vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle); - } - - static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, -@@ -9040,8 +8910,7 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_image_query_lod(builder, - type_id, image.sampled_image_id, coordinate_id); - -- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -- vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); - } - - static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, -@@ -9111,8 +8980,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, - image.sampled_image_id, coordinate_id, operands_mask, image_operands, image_operand_count); - -- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -- vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); - } - - static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, -@@ -9157,8 +9025,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, - image.sampled_image_id, coordinate_id, dref_id, operands_mask, - image_operands, image_operand_count); - -- spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id, -- vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); -+ spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id, image.sampled_type, src[1].swizzle); - } - - static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, -@@ -9230,8 +9097,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, - operands_mask, image_operands, image_operand_count); - } - -- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -- vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); - } - - static uint32_t spirv_compiler_emit_raw_structured_addressing( -@@ -9293,7 +9159,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler - texel_type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id); - -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, resource_symbol->info.resource.structure_stride, - &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9325,7 +9191,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler - - spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); - -@@ -9348,7 +9214,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler - type_id, val_id, 0); - } - } -- spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); -+ spirv_compiler_emit_store_dst_components(compiler, dst, VSIR_DATA_U32, constituents); - } - - static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, -@@ -9388,7 +9254,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, - ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id); - constituents[j++] = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); - } -- spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); -+ spirv_compiler_emit_store_dst_components(compiler, dst, VSIR_DATA_U32, constituents); - } - - static void spirv_compiler_emit_ld_raw_structured(struct spirv_compiler *compiler, -@@ -9430,7 +9296,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * - type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, resource_symbol->info.resource.structure_stride, - &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9458,7 +9324,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * - } - else - { -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); - spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9569,7 +9435,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); - - spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -- vkd3d_component_type_from_data_type(resource_symbol->info.resource.sampled_type), src[1].swizzle); -+ resource_symbol->info.resource.sampled_type, src[1].swizzle); - } - else - { -@@ -9581,8 +9447,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_image_read(builder, type_id, - image.image_id, coordinate_id, SpvImageOperandsMaskNone, NULL, 0); - -- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, -- vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); -+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle); - } - } - -@@ -9608,8 +9473,8 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, - indices[0] = spirv_compiler_get_constant_uint(compiler, 0); - indices[1] = coordinate_id; - -- val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, -- vkd3d_component_type_from_data_type(resource_symbol->info.resource.sampled_type)); -+ val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], -+ VKD3DSP_WRITEMASK_0, resource_symbol->info.resource.sampled_type); - ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); - vkd3d_spirv_build_op_store(builder, ptr_id, val_id, SpvMemoryAccessMaskNone); - } -@@ -9620,8 +9485,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, - spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); -- texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], -- dst->write_mask, vkd3d_component_type_from_data_type(image.sampled_type)); -+ texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], dst->write_mask, image.sampled_type); - - vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, texel_id, - SpvImageOperandsMaskNone, NULL, 0); -@@ -9756,11 +9620,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - const struct vkd3d_shader_src_param *src = instruction->src; - const struct vkd3d_symbol *resource_symbol = NULL; - uint32_t ptr_type_id, type_id, val_id, result_id; -- enum vkd3d_shader_component_type component_type; - const struct vkd3d_shader_dst_param *resource; - uint32_t coordinate_id, sample_id, pointer_id; - struct vkd3d_shader_register_info reg_info; -- SpvMemorySemanticsMask memory_semantic; - struct vkd3d_shader_image image; - enum vsir_data_type data_type; - unsigned int structure_stride; -@@ -9811,7 +9673,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - } - } - -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); - if (structure_stride || raw) - { - VKD3D_ASSERT(!raw != !structure_stride); -@@ -9853,8 +9715,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - } - } - -- component_type = vkd3d_component_type_from_data_type(data_type); -- val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type); -+ val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, data_type); - - if (instruction->flags & VKD3DARF_VOLATILE) - { -@@ -9863,17 +9724,13 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - } - -- memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) -- ? SpvMemorySemanticsSequentiallyConsistentMask -- : SpvMemorySemanticsMaskNone; -- - operands[i++] = pointer_id; - operands[i++] = spirv_compiler_get_constant_uint(compiler, scope); -- operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic); -+ operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); - if (instruction->src_count >= 3) - { -- operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic); -- operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, component_type); -+ operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); -+ operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, data_type); - } - operands[i++] = val_id; - result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, -@@ -10648,6 +10505,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - case VSIR_OP_ITOF: - case VSIR_OP_ITOI: - case VSIR_OP_MUL: -+ case VSIR_OP_NEG: - case VSIR_OP_NOT: - case VSIR_OP_OR: - case VSIR_OP_UDIV_SIMPLE: -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 2b5badb8871..821c639ee16 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -950,6 +950,7 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig - struct vkd3d_shader_scan_context - { - const struct vkd3d_shader_version *version; -+ const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info; - - struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info; - size_t descriptors_size; -@@ -1017,6 +1018,7 @@ static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *con - context->location.line = 2; /* Line 1 is the version token. */ - context->api_version = VKD3D_SHADER_API_VERSION_1_2; - context->combined_sampler_info = combined_sampler_info; -+ context->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO); - - for (i = 0; i < compile_info->option_count; ++i) - { -@@ -1218,15 +1220,6 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte - d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; - } - --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, VSIR_DATA_UNUSED); -- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, -- &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32); --} -- - const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( - const struct vkd3d_shader_scan_descriptor_info1 *info, - enum vkd3d_shader_descriptor_type type, unsigned int register_id) -@@ -1312,40 +1305,6 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co - s->sampler_index = sampler_idx; - } - --static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context, -- const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler) --{ -- unsigned int resource_idx = resource->idx[0].offset; -- unsigned int sampler_idx = sampler->idx[0].offset; -- -- vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler); -- -- if (!context->scan_descriptor_info) -- return; -- -- /* Sample instructions lowered from 1.x texture instructions have no -- * DCL, so we need to add the resource if it didn't already exist. -- * Such descriptors have a fixed count, type, etc. */ -- -- if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, -- VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx)) -- { -- struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx}; -- -- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource, -- &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32); -- } -- -- if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, -- VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx)) -- { -- struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; -- -- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource, -- &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); -- } --} -- - static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, - const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, - enum vsir_data_type resource_data_type, unsigned int sample_count, -@@ -1403,14 +1362,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - vkd3d_shader_scan_sampler_declaration(context, instruction); - break; - case VSIR_OP_DCL: -- if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE) -- break; -- -- if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) -- { -- vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic); -+ if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE -+ || instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) - break; -- } - /* fall through */ - case VSIR_OP_DCL_UAV_TYPED: - vkd3d_shader_scan_typed_resource_declaration(context, instruction); -@@ -1564,6 +1518,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - break; - case VSIR_OP_GATHER4: - case VSIR_OP_GATHER4_C: -+ case VSIR_OP_SAMPLE: - case VSIR_OP_SAMPLE_B: - case VSIR_OP_SAMPLE_C: - case VSIR_OP_SAMPLE_C_LZ: -@@ -1571,9 +1526,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - case VSIR_OP_SAMPLE_LOD: - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg); - break; -- case VSIR_OP_SAMPLE: -- vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg); -- break; - case VSIR_OP_GATHER4_PO: - case VSIR_OP_GATHER4_PO_C: - vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg); -@@ -1714,7 +1666,6 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - struct vkd3d_shader_scan_context context; - struct vkd3d_shader_instruction *ins; - int ret = VKD3D_OK; -- unsigned int i; - - descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO); - if (descriptor_info) -@@ -1729,6 +1680,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - add_descriptor_info = true; - } - -+ if (program->has_descriptor_info) -+ add_descriptor_info = false; -+ - tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO); - thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO); - -@@ -1747,21 +1701,6 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - break; - } - -- for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) -- { -- struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; -- struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1}; -- unsigned int size = program->flat_constant_count[i]; -- struct vkd3d_shader_descriptor_info1 *d; -- -- if (size) -- { -- 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; -- } -- } -- - if (!ret && signature_info) - { - if (!vkd3d_shader_signature_from_shader_signature(&signature_info->input, &program->input_signature) -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index df0eb2ff789..c70096f1f75 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -503,6 +503,7 @@ enum vkd3d_shader_opcode - VSIR_OP_MOVC, - VSIR_OP_MSAD, - VSIR_OP_MUL, -+ VSIR_OP_NEG, - VSIR_OP_NEO, - VSIR_OP_NEU, - VSIR_OP_NOP, -@@ -878,8 +879,7 @@ enum vkd3d_shader_uav_flags - - enum vkd3d_shader_atomic_rmw_flags - { -- VKD3DARF_SEQ_CST = 0x1, -- VKD3DARF_VOLATILE = 0x2, -+ VKD3DARF_VOLATILE = 0x1, - }; - - enum vkd3d_tessellator_domain -@@ -1590,6 +1590,7 @@ struct vsir_program - - struct vkd3d_shader_scan_descriptor_info1 descriptors; - bool has_descriptor_info; -+ size_t descriptors_size; - - unsigned int parameter_count; - const struct vkd3d_shader_parameter1 *parameters; -@@ -1597,7 +1598,6 @@ struct vsir_program - - unsigned int input_control_point_count, output_control_point_count; - struct vsir_thread_group_size thread_group_size; -- unsigned int flat_constant_count[3]; - unsigned int block_count; /* maximum block count in any function */ - unsigned int temp_count; - unsigned int ssa_count; -@@ -1636,6 +1636,10 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context); - -+struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program, -+ enum vkd3d_shader_descriptor_type type, unsigned int register_id, -+ const struct vkd3d_shader_register_range *range, -+ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type); - bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb); - void vsir_program_cleanup(struct vsir_program *program); - const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( -@@ -1883,42 +1887,6 @@ int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context, - struct vsir_program *program, struct vkd3d_shader_code *reflection_data); - --static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) --{ -- switch (data_type) -- { -- case VSIR_DATA_BOOL: -- return VKD3D_SHADER_COMPONENT_BOOL; -- case VSIR_DATA_F16: -- return VKD3D_SHADER_COMPONENT_FLOAT16; -- case VSIR_DATA_F32: -- case VSIR_DATA_SNORM: -- case VSIR_DATA_UNORM: -- return VKD3D_SHADER_COMPONENT_FLOAT; -- case VSIR_DATA_F64: -- return VKD3D_SHADER_COMPONENT_DOUBLE; -- case VSIR_DATA_I16: -- return VKD3D_SHADER_COMPONENT_INT16; -- case VSIR_DATA_I32: -- return VKD3D_SHADER_COMPONENT_INT; -- case VSIR_DATA_I64: -- return VKD3D_SHADER_COMPONENT_INT64; -- case VSIR_DATA_U16: -- return VKD3D_SHADER_COMPONENT_UINT16; -- case VSIR_DATA_U32: -- return VKD3D_SHADER_COMPONENT_UINT; -- case VSIR_DATA_U64: -- return VKD3D_SHADER_COMPONENT_UINT64; -- case VSIR_DATA_UNUSED: -- return VKD3D_SHADER_COMPONENT_VOID; -- default: -- FIXME("Unhandled data type %#x.\n", data_type); -- /* fall-through */ -- case VSIR_DATA_MIXED: -- return VKD3D_SHADER_COMPONENT_UINT; -- } --} -- - static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_shader_component_type component_type) - { - switch (component_type) -@@ -1954,12 +1922,6 @@ static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_ - return VSIR_DATA_UNUSED; - } - --static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) --{ -- return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_INT64 -- || component_type == VKD3D_SHADER_COMPONENT_UINT64; --} -- - static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) - { - unsigned int i; --- -2.51.0 - diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-40bdaa43af3414d25e43b477bf813b81827.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-40bdaa43af3414d25e43b477bf813b81827.patch deleted file mode 100644 index 3deb31ca..00000000 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-40bdaa43af3414d25e43b477bf813b81827.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 5866455f54b6310fdc5e7e3c8f3503aa55118657 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Wed, 15 Oct 2025 07:43:18 +1100 -Subject: [PATCH] Updated vkd3d to 40bdaa43af3414d25e43b477bf813b81827633b3. - ---- - libs/vkd3d/Makefile.in | 4 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 9 ++--- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 18 +++++++++ - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 4 -- - libs/vkd3d/libs/vkd3d-shader/ir.c | 40 ++++++++++++++++++- - libs/vkd3d/libs/vkd3d-shader/msl.c | 11 +++++ - libs/vkd3d/libs/vkd3d-shader/spirv.c | 16 ++++++++ - .../libs/vkd3d-shader/vkd3d_shader_private.h | 7 ++-- - libs/vkd3d/libs/vkd3d/state.c | 2 +- - 9 files changed, 95 insertions(+), 16 deletions(-) - -diff --git a/libs/vkd3d/Makefile.in b/libs/vkd3d/Makefile.in -index 9ad9ed850b6..868f4582380 100644 ---- a/libs/vkd3d/Makefile.in -+++ b/libs/vkd3d/Makefile.in -@@ -7,7 +7,6 @@ EXTRADEFS = \ - -DLIBVKD3D_UTILS_SOURCE - - SOURCES = \ -- config.h \ - libs/vkd3d-common/blob.c \ - libs/vkd3d-common/debug.c \ - libs/vkd3d-common/error.c \ -@@ -40,4 +39,5 @@ SOURCES = \ - libs/vkd3d/resource.c \ - libs/vkd3d/state.c \ - libs/vkd3d/utils.c \ -- libs/vkd3d/vkd3d_main.c -+ libs/vkd3d/vkd3d_main.c \ -+ config.h -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index c7af58118df..7861efc16d2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -4674,13 +4674,13 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco - case VSIR_OP_ISHL: - silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP)); - break; -+ case VSIR_OP_IDIV: -+ case VSIR_OP_IREM: - case VSIR_OP_ISHR: - type_flags |= DXIL_TYPE_SIGNED; - /* fall through */ - 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; -@@ -6252,13 +6252,12 @@ 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, VSIR_OP_MOV); -+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SATURATE); - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; - src_param_init_from_value(src_param, operands[0], 0, sm6); - -- if (instruction_dst_param_init_ssa_scalar(ins, 0, sm6)) -- ins->dst->modifiers = VKD3DSPDM_SATURATE; -+ instruction_dst_param_init_ssa_scalar(ins, 0, sm6); - } - - static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index 88c87ae33ee..91a96a5547e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -605,6 +605,21 @@ static void shader_glsl_dot(struct vkd3d_glsl_generator *gen, - glsl_dst_cleanup(&dst, &gen->string_buffers); - } - -+static void shader_glsl_saturate(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) -+{ -+ struct glsl_src src; -+ struct glsl_dst dst; -+ uint32_t mask; -+ -+ mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); -+ glsl_src_init(&src, gen, &ins->src[0], mask); -+ -+ shader_glsl_print_assignment(gen, &dst, "clamp(%s, 0.0, 1.0)", src.str->buffer); -+ -+ glsl_src_cleanup(&src, &gen->string_buffers); -+ glsl_dst_cleanup(&dst, &gen->string_buffers); -+} -+ - static void shader_glsl_intrinsic(struct vkd3d_glsl_generator *gen, - const struct vkd3d_shader_instruction *ins, const char *op) - { -@@ -1654,6 +1669,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - case VSIR_OP_RSQ: - shader_glsl_intrinsic(gen, ins, "inversesqrt"); - break; -+ case VSIR_OP_SATURATE: -+ shader_glsl_saturate(gen, ins); -+ break; - case VSIR_OP_SIN: - shader_glsl_intrinsic(gen, ins, "sin"); - break; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 27afac71320..759dadf8a58 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -614,10 +614,6 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx - if (!(ret.string = vkd3d_strdup(string->string))) - return ret; - } -- else if (node->type == HLSL_IR_STRING_CONSTANT) -- { -- hlsl_fixme(ctx, &node->loc, "Evaluate string constants as static expressions."); -- } - else - { - hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 13ea8a433a6..c013c9e61bd 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -338,6 +338,7 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) - [VSIR_OP_SAMPLE_LOD ] = "sample_l", - [VSIR_OP_SAMPLE_LOD_S ] = "sample_l_s", - [VSIR_OP_SAMPLE_POS ] = "sample_pos", -+ [VSIR_OP_SATURATE ] = "saturate", - [VSIR_OP_SETP ] = "setp", - [VSIR_OP_SGE ] = "sge", - [VSIR_OP_SGN ] = "sgn", -@@ -2235,6 +2236,39 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr - ++program->ssa_count; - } - } -+ -+ for (i = 0; i < ins->dst_count; ++i) -+ { -+ struct vkd3d_shader_dst_param *dst = &ins->dst[i]; -+ -+ if (dst->modifiers & VKD3DSPDM_SATURATE) -+ { -+ if (!vsir_program_iterator_insert_after(&it, 1)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ ins = vsir_program_iterator_current(&it); -+ new_ins = vsir_program_iterator_next(&it); -+ -+ if (!vsir_instruction_init_with_params(program, new_ins, &ins->location, VSIR_OP_SATURATE, 1, 1)) -+ { -+ vkd3d_shader_instruction_make_nop(new_ins); -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ } -+ -+ new_ins->dst[0] = *dst; -+ new_ins->dst[0].modifiers &= ~VKD3DSPDM_NONE; -+ -+ dst_param_init_ssa(dst, program->ssa_count, dst->reg.data_type, dst->reg.dimension); -+ src_param_init_ssa(&new_ins->src[0], program->ssa_count, dst->reg.data_type, dst->reg.dimension); -+ -+ if (data_type_is_64_bit(dst->reg.data_type)) -+ { -+ dst->write_mask = vsir_write_mask_64_from_32(dst->write_mask); -+ new_ins->src[0].swizzle = vsir_swizzle_64_from_32(new_ins->src[0].swizzle); -+ } -+ -+ ++program->ssa_count; -+ } -+ } - } - - return VKD3D_OK; -@@ -8795,6 +8829,7 @@ static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src - case VSIR_OP_ROUND_PI: - case VSIR_OP_ROUND_Z: - case VSIR_OP_RSQ: -+ case VSIR_OP_SATURATE: - case VSIR_OP_SETP: - case VSIR_OP_SGE: - case VSIR_OP_SGN: -@@ -12833,6 +12868,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [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_IDIV] = {1, 2, vsir_validate_signed_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}, -@@ -12843,7 +12879,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_IMIN] = {1, 2, vsir_validate_signed_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_IREM] = {1, 2, vsir_validate_signed_integer_elementwise_operation}, - [VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation}, - [VSIR_OP_ISHL] = {1, 2, vsir_validate_ishl}, - [VSIR_OP_ISHR] = {1, 2, vsir_validate_ishr}, -@@ -12875,6 +12911,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [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_SATURATE] = {1, 1, vsir_validate_float_or_double_elementwise_operation}, - [VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch}, - [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, - [VSIR_OP_USHR] = {1, 2, vsir_validate_ushr}, -@@ -13315,6 +13352,7 @@ static bool vsir_instruction_has_side_effects(const struct vkd3d_shader_instruct - case VSIR_OP_SAMPLE_LOD: - case VSIR_OP_SAMPLE_LOD_S: - case VSIR_OP_SAMPLE_POS: -+ case VSIR_OP_SATURATE: - case VSIR_OP_SETP: - case VSIR_OP_SGE: - case VSIR_OP_SGN: -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index fc136e3ac98..f2d28acbe38 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -1578,9 +1578,17 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d - case VSIR_OP_HTAN: - msl_intrinsic(gen, ins, "tanh"); - break; -+ case VSIR_OP_IDIV: -+ case VSIR_OP_UDIV_SIMPLE: -+ msl_binop(gen, ins, "/"); -+ break; - case VSIR_OP_IF: - msl_if(gen, ins); - break; -+ case VSIR_OP_IREM: -+ case VSIR_OP_UREM: -+ msl_binop(gen, ins, "%"); -+ break; - case VSIR_OP_ISHL: - msl_binop(gen, ins, "<<"); - break; -@@ -1663,6 +1671,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d - case VSIR_OP_RSQ: - msl_intrinsic(gen, ins, "rsqrt"); - break; -+ case VSIR_OP_SATURATE: -+ msl_intrinsic(gen, ins, "saturate"); -+ break; - case VSIR_OP_SIN: - msl_intrinsic(gen, ins, "sin"); - break; -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 31271660e4f..8ff46759fb6 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -2524,6 +2524,7 @@ static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, - - case VSIR_DATA_I32: - case VSIR_DATA_U32: -+ case VSIR_DATA_MIXED: - type_id = vkd3d_spirv_get_op_type_int(builder, 32, data_type == VSIR_DATA_I32); - break; - -@@ -7627,6 +7628,18 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil - return VKD3D_OK; - } - -+static void spirv_compiler_emit_saturate(struct spirv_compiler *compiler, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ const struct vkd3d_shader_dst_param *dst = instruction->dst; -+ const struct vkd3d_shader_src_param *src = instruction->src; -+ uint32_t val_id; -+ -+ val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); -+ val_id = spirv_compiler_emit_sat(compiler, &dst->reg, dst->write_mask, val_id); -+ spirv_compiler_emit_store_dst(compiler, dst, val_id); -+} -+ - static void spirv_compiler_emit_isfinite(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) - { -@@ -10520,6 +10533,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - case VSIR_OP_ISFINITE: - spirv_compiler_emit_isfinite(compiler, instruction); - break; -+ case VSIR_OP_SATURATE: -+ spirv_compiler_emit_saturate(compiler, instruction); -+ break; - case VSIR_OP_ABS: - case VSIR_OP_ACOS: - case VSIR_OP_ASIN: -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index c70096f1f75..346c74ff698 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -542,6 +542,7 @@ enum vkd3d_shader_opcode - VSIR_OP_SAMPLE_LOD, - VSIR_OP_SAMPLE_LOD_S, - VSIR_OP_SAMPLE_POS, -+ VSIR_OP_SATURATE, - VSIR_OP_SETP, - VSIR_OP_SGE, - VSIR_OP_SGN, -@@ -1502,9 +1503,9 @@ static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterat - } - - /* When insertion takes place, argument `it' is updated to point to the same -- * instruction as before the insertion, and the optional argument `ins_it' is -- * initialized to point to the first inserted instruction. -- * A pointer to the first inserted instruction is returned. */ -+ * instruction as before the insertion, and argument `ins_it' is initialized -+ * to point to the first inserted instruction. A pointer to the first inserted -+ * instruction is returned. */ - static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before( - struct vsir_program_iterator *it, struct vsir_program_iterator *ins_it, size_t count) - { -diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index b6055a50a99..4bd97fd599f 100644 ---- a/libs/vkd3d/libs/vkd3d/state.c -+++ b/libs/vkd3d/libs/vkd3d/state.c -@@ -843,7 +843,7 @@ static struct vk_binding_array *d3d12_root_signature_vk_binding_array_for_type( - { - if (!context->static_samplers_descriptor_set) - { -- if (!context->push_descriptor && context->root_descriptor_set) -+ if (!root_signature->device->vk_info.KHR_push_descriptor && context->root_descriptor_set) - context->static_samplers_descriptor_set = context->root_descriptor_set; - else - /* The descriptor type is irrelevant here, it will never be used. */ --- -2.51.0 - diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-507990d3c5a7b61ad5df63a17bbd122d8dc.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-507990d3c5a7b61ad5df63a17bbd122d8dc.patch deleted file mode 100644 index 5497462b..00000000 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-507990d3c5a7b61ad5df63a17bbd122d8dc.patch +++ /dev/null @@ -1,1263 +0,0 @@ -From 653731fd7468dc26bc87777a24d8b4ae26a3d93e Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 16 Oct 2025 06:52:58 +1100 -Subject: [PATCH] Updated vkd3d to 507990d3c5a7b61ad5df63a17bbd122d8dc7e2e3. - ---- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 9 +- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 2 + - libs/vkd3d/libs/vkd3d-shader/ir.c | 22 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 364 ++++++++++++++------------- - 4 files changed, 199 insertions(+), 198 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index b2d4ec23c6e..87a7d48acca 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1597,6 +1597,9 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c - - program->has_descriptor_info = true; - -+ if (TRACE_ON()) -+ vsir_program_trace(program); -+ - if (ret >= 0 && sm1.p.status < 0) - ret = sm1.p.status; - -@@ -2171,11 +2174,11 @@ 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 ((version->type == VKD3D_SHADER_TYPE_PIXEL || output) && !vkd3d_shader_ver_ge(version, 3, 0)) - { -- if (reg.reg.idx[0].offset > SM1_RASTOUT_REGISTER_OFFSET) -+ 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) -+ else if (reg.reg.idx[0].offset >= SM1_COLOR_REGISTER_OFFSET) - reg.reg.idx[0].offset -= SM1_COLOR_REGISTER_OFFSET; - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index 91a96a5547e..ab45c4d1e73 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -514,6 +514,8 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g - "Internal compiler error: Unhandled destination register data type %#x.", data_type); - /* fall through */ - case VSIR_DATA_F32: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: - close = false; - break; - case VSIR_DATA_I32: -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index c013c9e61bd..82901c6fb34 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -1223,11 +1223,12 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra - 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; -+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; - - 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); -+ ins2->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - } - - for (k = 0; k < ins->src_count; ++k) -@@ -1392,7 +1393,7 @@ 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 vsir_program_iterator *it, unsigned int *tmp_idx) -+ struct vsir_program_iterator *it) - { - struct vkd3d_shader_instruction *mad, *mul_ins, *add_ins; - struct vkd3d_shader_dst_param *mul_dst; -@@ -1405,9 +1406,6 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro - if (!vsir_program_iterator_insert_after(it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- if (*tmp_idx == ~0u) -- *tmp_idx = program->temp_count++; -- - mul_ins = vsir_program_iterator_current(it); - add_ins = vsir_program_iterator_next(it); - -@@ -1422,14 +1420,9 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro - mul_dst = mul_ins->dst; - *add_ins->dst = *mul_dst; - -- mul_dst->modifiers = 0; -- vsir_register_init(&mul_dst->reg, VKD3DSPR_TEMP, mul_ins->src[0].reg.data_type, 1); -- mul_dst->reg.dimension = add_ins->dst->reg.dimension; -- mul_dst->reg.idx[0].offset = *tmp_idx; -+ dst_param_init_ssa(mul_dst, program->ssa_count, mul_ins->src[0].reg.data_type, VSIR_DIMENSION_VEC4); -+ src_param_init_ssa(&add_ins->src[0], program->ssa_count++, mul_ins->src[0].reg.data_type, VSIR_DIMENSION_VEC4); - -- add_ins->src[0].reg = mul_dst->reg; -- add_ins->src[0].swizzle = vsir_swizzle_from_writemask(mul_dst->write_mask); -- add_ins->src[0].modifiers = 0; - add_ins->src[1] = mul_ins->src[2]; - - return VKD3D_OK; -@@ -1736,7 +1729,7 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr - struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) - { - const struct vkd3d_shader_descriptor_info1 *sampler; -- unsigned int idx = ins->src[0].reg.idx[0].offset; -+ unsigned int idx = ins->dst[0].reg.idx[0].offset; - struct vkd3d_shader_src_param *srcs; - - /* texld DST, t# -> sample DST, t#, resource#, sampler# */ -@@ -2279,7 +2272,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_instruction *ins; -- unsigned int tmp_idx = ~0u; - enum vkd3d_result ret; - - for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -@@ -2287,7 +2279,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - switch (ins->opcode) - { - case VSIR_OP_MAD: -- if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) -+ if ((ret = vsir_program_lower_precise_mad(program, &it)) < 0) - return ret; - break; - -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 8ff46759fb6..a1572f69438 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -2491,70 +2491,6 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build - GLSLstd450NClamp, operands, ARRAY_SIZE(operands)); - } - --static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, -- enum vsir_data_type data_type, unsigned int component_count) --{ -- uint32_t scalar_id, type_id; -- -- VKD3D_ASSERT(data_type < VSIR_DATA_TYPE_COUNT); -- if (!component_count || component_count > VKD3D_VEC4_SIZE) -- { -- ERR("Invalid component count %u.\n", component_count); -- return 0; -- } -- -- if ((type_id = builder->numeric_type_ids[data_type][component_count - 1])) -- return type_id; -- -- if (component_count == 1) -- { -- switch (data_type) -- { -- case VSIR_DATA_BOOL: -- type_id = vkd3d_spirv_get_op_type_bool(builder); -- break; -- -- case VSIR_DATA_F32: -- type_id = vkd3d_spirv_get_op_type_float(builder, 32); -- break; -- -- case VSIR_DATA_F64: -- type_id = vkd3d_spirv_get_op_type_float(builder, 64); -- break; -- -- case VSIR_DATA_I32: -- case VSIR_DATA_U32: -- case VSIR_DATA_MIXED: -- type_id = vkd3d_spirv_get_op_type_int(builder, 32, data_type == VSIR_DATA_I32); -- break; -- -- case VSIR_DATA_I64: -- case VSIR_DATA_U64: -- type_id = vkd3d_spirv_get_op_type_int(builder, 64, data_type == VSIR_DATA_I64); -- break; -- -- case VSIR_DATA_UNUSED: -- type_id = vkd3d_spirv_get_op_type_void(builder); -- break; -- -- default: -- FIXME("Unhandled data type \"%s\" (%#x).\n", -- vsir_data_type_get_name(data_type, ""), data_type); -- return 0; -- } -- } -- else -- { -- VKD3D_ASSERT(data_type != VSIR_DATA_UNUSED); -- scalar_id = spirv_get_type_id(builder, data_type, 1); -- type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); -- } -- -- builder->numeric_type_ids[data_type][component_count - 1] = type_id; -- -- return type_id; --} -- - static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, - const char *entry_point, const char *source_name) - { -@@ -3471,6 +3407,74 @@ static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spi - return buffer; - } - -+static uint32_t spirv_get_type_id(struct spirv_compiler *compiler, -+ enum vsir_data_type data_type, unsigned int component_count) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ uint32_t scalar_id, type_id; -+ -+ VKD3D_ASSERT(data_type < VSIR_DATA_TYPE_COUNT); -+ if (!component_count || component_count > VKD3D_VEC4_SIZE) -+ { -+ ERR("Invalid component count %u.\n", component_count); -+ return 0; -+ } -+ -+ if ((type_id = builder->numeric_type_ids[data_type][component_count - 1])) -+ return type_id; -+ -+ if (component_count == 1) -+ { -+ switch (data_type) -+ { -+ case VSIR_DATA_BOOL: -+ type_id = vkd3d_spirv_get_op_type_bool(builder); -+ break; -+ -+ case VSIR_DATA_F32: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: -+ type_id = vkd3d_spirv_get_op_type_float(builder, 32); -+ break; -+ -+ case VSIR_DATA_F64: -+ type_id = vkd3d_spirv_get_op_type_float(builder, 64); -+ break; -+ -+ case VSIR_DATA_I32: -+ case VSIR_DATA_U32: -+ case VSIR_DATA_MIXED: -+ type_id = vkd3d_spirv_get_op_type_int(builder, 32, data_type == VSIR_DATA_I32); -+ break; -+ -+ case VSIR_DATA_I64: -+ case VSIR_DATA_U64: -+ type_id = vkd3d_spirv_get_op_type_int(builder, 64, data_type == VSIR_DATA_I64); -+ break; -+ -+ case VSIR_DATA_UNUSED: -+ type_id = vkd3d_spirv_get_op_type_void(builder); -+ break; -+ -+ default: -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled data type \"%s\" (%#x).", -+ vsir_data_type_get_name(data_type, ""), data_type); -+ return 0; -+ } -+ } -+ else -+ { -+ VKD3D_ASSERT(data_type != VSIR_DATA_UNUSED); -+ scalar_id = spirv_get_type_id(compiler, data_type, 1); -+ type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); -+ } -+ -+ builder->numeric_type_ids[data_type][component_count - 1] = type_id; -+ -+ return type_id; -+} -+ - static uint32_t spirv_compiler_get_label_id(struct spirv_compiler *compiler, unsigned int block_id) - { - --block_id; -@@ -3636,7 +3640,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, - unsigned int i; - - VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_VEC4_SIZE); -- type_id = spirv_get_type_id(builder, data_type, component_count); -+ type_id = spirv_get_type_id(compiler, data_type, component_count); - - switch (data_type) - { -@@ -3666,7 +3670,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, - if (component_count == 1) - return vkd3d_spirv_get_op_constant(builder, type_id, *values); - -- scalar_type_id = spirv_get_type_id(builder, data_type, 1); -+ scalar_type_id = spirv_get_type_id(compiler, data_type, 1); - for (i = 0; i < component_count; ++i) - { - component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, values[i]); -@@ -3683,7 +3687,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, - unsigned int i; - - VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_DVEC2_SIZE); -- type_id = spirv_get_type_id(builder, data_type, component_count); -+ type_id = spirv_get_type_id(compiler, data_type, component_count); - - if (data_type != VSIR_DATA_F64 && data_type != VSIR_DATA_I64 && data_type != VSIR_DATA_U64) - { -@@ -3696,7 +3700,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, - if (component_count == 1) - return vkd3d_spirv_get_op_constant64(builder, type_id, *values); - -- scalar_type_id = spirv_get_type_id(builder, data_type, 1); -+ scalar_type_id = spirv_get_type_id(compiler, data_type, 1); - for (i = 0; i < component_count; ++i) - { - component_ids[i] = vkd3d_spirv_get_op_constant64(builder, scalar_type_id, values[i]); -@@ -3756,9 +3760,7 @@ static uint32_t spirv_compiler_get_constant_uint64_vector(struct spirv_compiler - static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, uint32_t write_mask) - { -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- -- return spirv_get_type_id(builder, reg->data_type, vsir_write_mask_component_count(write_mask)); -+ return spirv_get_type_id(compiler, reg->data_type, vsir_write_mask_component_count(write_mask)); - } - - static uint32_t spirv_compiler_get_type_id_for_dst(struct spirv_compiler *compiler, -@@ -3884,7 +3886,7 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil - uint32_t type_id, length_id, ptr_type_id; - unsigned int i; - -- type_id = spirv_get_type_id(builder, data_type, component_count); -+ type_id = spirv_get_type_id(compiler, data_type, component_count); - for (i = 0; i < length_count; ++i) - { - if (!array_lengths[i]) -@@ -3982,8 +3984,8 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile - info = get_spec_constant_info(name); - default_value = info ? info->default_value.u : 0; - -- scalar_type_id = spirv_get_type_id(builder, type, 1); -- vector_type_id = spirv_get_type_id(builder, type, component_count); -+ scalar_type_id = spirv_get_type_id(compiler, type, 1); -+ vector_type_id = spirv_get_type_id(compiler, type, component_count); - - for (unsigned int i = 0; i < component_count; ++i) - { -@@ -4032,7 +4034,7 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi - unsigned int index = parameter - compiler->program->parameters; - uint32_t type_id, ptr_id, ptr_type_id; - -- type_id = spirv_get_type_id(builder, type, component_count); -+ type_id = spirv_get_type_id(compiler, type, component_count); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, - compiler->spirv_parameter_info[index].buffer_id, -@@ -4096,7 +4098,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp - - VKD3D_ASSERT(val_component_idx < val_component_count); - -- type_id = spirv_get_type_id(builder, data_type, component_count); -+ type_id = spirv_get_type_id(compiler, data_type, component_count); - if (val_component_count == 1) - { - for (i = 0; i < component_count; ++i) -@@ -4129,7 +4131,7 @@ static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *c - addr_id = spirv_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); - if (reg_index->offset) - { -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, addr_id, - spirv_compiler_get_constant_uint(compiler, reg_index->offset)); - } -@@ -4279,7 +4281,7 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, ptr_type_id, ptr_id, offset_id, index_ids[2]; - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - if (!(offset_id = compiler->descriptor_offset_ids[push_constant_index])) - { - index_ids[0] = compiler->descriptor_offsets_member_id; -@@ -4352,7 +4354,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp - if (index_count) - { - component_count = vsir_write_mask_component_count(register_info->write_mask); -- type_id = spirv_get_type_id(builder, register_info->data_type, component_count); -+ type_id = spirv_get_type_id(compiler, register_info->data_type, component_count); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id); - register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, - register_info->id, indexes, index_count); -@@ -4410,7 +4412,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, uin - && (component_count == 1 || vkd3d_swizzle_is_equal(val_write_mask, swizzle, write_mask))) - return val_id; - -- type_id = spirv_get_type_id(builder, data_type, component_count); -+ type_id = spirv_get_type_id(compiler, data_type, component_count); - - if (component_count == 1) - { -@@ -4461,7 +4463,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil - else - components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle, i); - } -- type_id = spirv_get_type_id(builder, data_type, component_count); -+ type_id = spirv_get_type_id(compiler, data_type, component_count); - - return vkd3d_spirv_build_op_vector_shuffle(builder, type_id, - vector1_id, vector2_id, components, component_count); -@@ -4477,7 +4479,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - - VKD3D_ASSERT(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_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, -@@ -4494,7 +4496,7 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, - - true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); - false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, component_count); - - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } -@@ -4508,7 +4510,7 @@ static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compile - true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, - component_count); - false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); -- type_id = spirv_get_type_id(builder, VSIR_DATA_U64, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U64, component_count); - - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } -@@ -4521,7 +4523,7 @@ static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compile - - true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); - false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, component_count); - - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } -@@ -4534,7 +4536,7 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil - - true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); - false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); -- type_id = spirv_get_type_id(builder, VSIR_DATA_F64, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F64, component_count); - - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } -@@ -4600,7 +4602,7 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, - - VKD3D_ASSERT(reg->type == VKD3DSPR_UNDEF); - -- type_id = spirv_get_type_id(builder, reg->data_type, component_count); -+ type_id = spirv_get_type_id(compiler, reg->data_type, component_count); - - return vkd3d_spirv_get_op_undef(builder, type_id); - } -@@ -4631,7 +4633,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, - component_idx, reg->type, reg->idx[0].offset, reg_info->write_mask); - } - -- type_id = spirv_get_type_id(builder, reg_info->data_type, 1); -+ type_id = spirv_get_type_id(compiler, reg_info->data_type, 1); - reg_id = reg_info->id; - if (reg_component_count != 1) - { -@@ -4646,13 +4648,13 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, - - if (reg->data_type != VSIR_DATA_BOOL) - { -- type_id = spirv_get_type_id(builder, reg->data_type, 1); -+ type_id = spirv_get_type_id(compiler, reg->data_type, 1); - return vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - - if (reg_info->data_type != VSIR_DATA_U32) - { -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - -@@ -4669,7 +4671,7 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil - element_count = icb->element_count; - - component_count = icb->component_count; -- elem_type_id = spirv_get_type_id(builder, icb->data_type, component_count); -+ elem_type_id = spirv_get_type_id(compiler, icb->data_type, component_count); - length_id = spirv_compiler_get_constant_uint(compiler, element_count); - type_id = vkd3d_spirv_get_op_type_array(builder, elem_type_id, length_id); - -@@ -4757,7 +4759,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - - if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) - { -- type_id = spirv_get_type_id(builder, reg->data_type, component_count); -+ type_id = spirv_get_type_id(compiler, reg->data_type, component_count); - return vkd3d_spirv_get_op_undef(builder, type_id); - } - spirv_compiler_emit_dereference_register(compiler, reg, ®_info); -@@ -4776,7 +4778,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - } - else - { -- type_id = spirv_get_type_id(builder, reg_info.data_type, -+ type_id = spirv_get_type_id(compiler, reg_info.data_type, - vsir_write_mask_component_count(reg_info.write_mask)); - val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone); - swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle; -@@ -4789,13 +4791,13 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - - if (reg->data_type != VSIR_DATA_BOOL) - { -- type_id = spirv_get_type_id(builder, reg->data_type, component_count); -+ type_id = spirv_get_type_id(compiler, reg->data_type, component_count); - return vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - - if (reg_info.data_type != VSIR_DATA_U32) - { -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, component_count); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - -@@ -4848,7 +4850,7 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, - - if (vsir_write_mask_component_count(dst_write_mask) > 1) - { -- type_id = spirv_get_type_id(builder, data_type, 1); -+ type_id = spirv_get_type_id(compiler, data_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); - component_idx = vsir_write_mask_get_component_idx(write_mask); - component_idx -= vsir_write_mask_get_component_idx(dst_write_mask); -@@ -4875,7 +4877,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, uint32_t - - if (dst_component_count == 1 && component_count != 1) - { -- type_id = spirv_get_type_id(builder, data_type, 1); -+ type_id = spirv_get_type_id(compiler, data_type, 1); - val_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, - vsir_write_mask_get_component_idx(dst_write_mask)); - write_mask &= dst_write_mask; -@@ -4888,7 +4890,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, uint32_t - - if (dst_component_count != component_count) - { -- type_id = spirv_get_type_id(builder, data_type, dst_component_count); -+ type_id = spirv_get_type_id(compiler, data_type, dst_component_count); - dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); - - VKD3D_ASSERT(component_count <= ARRAY_SIZE(components)); -@@ -4940,7 +4942,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, - if (data_type == VSIR_DATA_BOOL) - val_id = spirv_compiler_emit_bool_to_int(compiler, - vsir_write_mask_component_count(src_write_mask), val_id, false); -- type_id = spirv_get_type_id(builder, reg_info.data_type, -+ type_id = spirv_get_type_id(compiler, reg_info.data_type, - vsir_write_mask_component_count(src_write_mask)); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - data_type = reg_info.data_type; -@@ -5021,13 +5023,13 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, dst_type_id, val_id; - -- type_id = spirv_get_type_id(builder, data_type, component_count); -+ type_id = spirv_get_type_id(compiler, data_type, component_count); - if (component_count > 1) - val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, component_ids, component_count); - else - val_id = *component_ids; - -- dst_type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); -+ dst_type_id = spirv_get_type_id(compiler, dst->reg.data_type, component_count); - if (dst_type_id != type_id) - val_id = vkd3d_spirv_build_op_bitcast(builder, dst_type_id, val_id); - -@@ -5195,7 +5197,7 @@ static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler * - vkd3d_spirv_add_iface_variable(builder, base_var_id); - spirv_compiler_decorate_builtin(compiler, base_var_id, base); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_I32, 1); - base_id = vkd3d_spirv_build_op_load(builder, type_id, base_var_id, SpvMemoryAccessMaskNone); - - return vkd3d_spirv_build_op_isub(builder, type_id, index_id, base_id); -@@ -5229,10 +5231,10 @@ static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, uint32_t frag_ - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, w_id; - -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 1); - w_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, frag_coord_id, 3); - w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, spirv_compiler_get_constant_float(compiler, 1.0f), w_id); -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, VKD3D_VEC4_SIZE); - - return vkd3d_spirv_build_op_composite_insert1(builder, type_id, w_id, frag_coord_id, 3); - } -@@ -5439,7 +5441,7 @@ static uint32_t spirv_compiler_emit_load_invocation_id(struct spirv_compiler *co - uint32_t type_id, id; - - id = spirv_compiler_get_invocation_id(compiler); -- type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_I32, 1); - - return vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); - } -@@ -5778,7 +5780,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - vsir_register_init(&dst_reg, reg_type, VSIR_DATA_F32, 1); - dst_reg.idx[0].offset = element_idx; - -- type_id = spirv_get_type_id(builder, data_type, input_component_count); -+ type_id = spirv_get_type_id(compiler, data_type, input_component_count); - - val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone); - -@@ -5787,7 +5789,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - - if (data_type != VSIR_DATA_F32) - { -- float_type_id = spirv_get_type_id(builder, VSIR_DATA_F32, input_component_count); -+ float_type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, input_component_count); - val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id); - } - -@@ -6139,7 +6141,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - - if (data_type != VSIR_DATA_F32) - { -- type_id = spirv_get_type_id(builder, data_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, data_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - -@@ -6162,7 +6164,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - output_id = output_info->id; - if (output_index_id) - { -- type_id = spirv_get_type_id(builder, data_type, vsir_write_mask_component_count(dst_write_mask)); -+ type_id = spirv_get_type_id(compiler, data_type, vsir_write_mask_component_count(dst_write_mask)); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); - output_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, output_id, output_index_id); - } -@@ -6174,7 +6176,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - return; - } - -- type_id = spirv_get_type_id(builder, data_type, 1); -+ type_id = spirv_get_type_id(compiler, data_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); - mask = output_info->array_element_mask; - array_idx = spirv_compiler_get_output_array_index(compiler, output); -@@ -6216,7 +6218,7 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler * - function_id = compiler->epilogue_function_id; - - void_id = vkd3d_spirv_get_op_type_void(builder); -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 4); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 4); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); - for (i = 0, count = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i) - { -@@ -6445,7 +6447,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil - function_location = spirv_compiler_get_current_function_location(compiler); - vkd3d_spirv_begin_function_stream_insertion(builder, function_location); - -- type_id = spirv_get_type_id(builder, temp->data_type, temp->component_count); -+ type_id = spirv_get_type_id(compiler, temp->data_type, temp->component_count); - length_id = spirv_compiler_get_constant_uint(compiler, temp->register_size); - type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); -@@ -6486,7 +6488,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com - if (!(member_ids = vkd3d_calloc(count, sizeof(*member_ids)))) - return; - -- vec4_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); -+ vec4_id = spirv_get_type_id(compiler, VSIR_DATA_F32, VKD3D_VEC4_SIZE); - - for (i = 0, j = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) - { -@@ -6503,7 +6505,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com - - if (compiler->offset_info.descriptor_table_count) - { -- uint32_t type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ uint32_t type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - length_id = spirv_compiler_get_constant_uint(compiler, compiler->offset_info.descriptor_table_count); - member_ids[j] = vkd3d_spirv_build_op_type_array(builder, type_id, length_id); - vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 4); -@@ -6696,7 +6698,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, - return; - } - -- vec4_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); -+ vec4_id = spirv_get_type_id(compiler, VSIR_DATA_F32, VKD3D_VEC4_SIZE); - length_id = spirv_compiler_get_constant_uint(compiler, size); - array_type_id = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); - vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 16); -@@ -6797,6 +6799,8 @@ static SpvImageFormat image_format_for_image_read(enum vsir_data_type data_type) - switch (data_type) - { - case VSIR_DATA_F32: -+ case VSIR_DATA_SNORM: -+ case VSIR_DATA_UNORM: - return SpvImageFormatR32f; - case VSIR_DATA_I32: - return SpvImageFormatR32i; -@@ -6831,7 +6835,7 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler - vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat); - } - -- sampled_type_id = spirv_get_type_id(builder, data_type, 1); -+ sampled_type_id = spirv_get_type_id(compiler, data_type, 1); - - return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, 2, - resource_type_info->arrayed, resource_type_info->ms, reg->type == VKD3DSPR_UAV ? 2 : 1, format); -@@ -6957,7 +6961,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - { - uint32_t array_type_id, struct_id; - -- type_id = spirv_get_type_id(builder, sampled_type, 1); -+ type_id = spirv_get_type_id(compiler, sampled_type, 1); - - array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id); - vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4); -@@ -6998,7 +7002,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - { - VKD3D_ASSERT(structure_stride); /* counters are valid only for structured buffers */ - -- counter_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ counter_type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - if (spirv_compiler_is_opengl_target(compiler)) - { - vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage); -@@ -7062,7 +7066,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler - if (alignment) - TRACE("Ignoring alignment %u.\n", alignment); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - length_id = spirv_compiler_get_constant_uint(compiler, size); - array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - -@@ -7761,7 +7765,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp - component_count = vsir_write_mask_component_count(dst->write_mask); - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT32_MAX, component_count); - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpIEqual, -- spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count), val_id, uint_max_id); -+ spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count), val_id, uint_max_id); - rev_val_id = vkd3d_spirv_build_op_isub(builder, type_id, - spirv_compiler_get_constant_uint_vector(compiler, 31, component_count), val_id); - val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, rev_val_id); -@@ -7811,7 +7815,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, - dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); - src_id = spirv_compiler_get_register_id(compiler, &src->reg); - -- type_id = spirv_get_type_id(builder, dst_reg_info.data_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, dst_reg_info.data_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone); - dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); - -@@ -7840,7 +7844,7 @@ general_implementation: - val_id = spirv_compiler_emit_load_src(compiler, src, write_mask); - if (dst->reg.data_type != src->reg.data_type) - { -- val_id = vkd3d_spirv_build_op_bitcast(builder, spirv_get_type_id(builder, -+ val_id = vkd3d_spirv_build_op_bitcast(builder, spirv_get_type_id(compiler, - dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)), val_id); - } - spirv_compiler_emit_store_dst(compiler, dst, val_id); -@@ -7866,7 +7870,7 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, - { - if (instruction->opcode == VSIR_OP_CMP) - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, -- spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count), condition_id, -+ spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count), condition_id, - spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); - else - condition_id = spirv_compiler_emit_int_to_bool(compiler, -@@ -7893,7 +7897,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, - src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); - - component_count = vsir_write_mask_component_count(dst->write_mask); -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, component_count); - - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); -@@ -7929,7 +7933,7 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, - for (i = 0; i < ARRAY_SIZE(src_ids); ++i) - src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], write_mask); - -- type_id = spirv_get_type_id(builder, data_type, 1); -+ type_id = spirv_get_type_id(compiler, data_type, 1); - - val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - SpvOpDot, type_id, src_ids[0], src_ids[1]); -@@ -7972,7 +7976,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, - unsigned int i, component_count; - - component_count = vsir_write_mask_component_count(dst->write_mask); -- type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); -+ type_id = spirv_get_type_id(compiler, dst->reg.data_type, component_count); - - for (i = 0; i < ARRAY_SIZE(src_ids); ++i) - src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); -@@ -8024,7 +8028,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, - /* VSIR allows the destination of a signed conversion to be unsigned. */ - - int_max_id = spirv_compiler_get_constant_vector(compiler, dst->reg.data_type, component_count, INT_MAX); -- condition_type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); -+ condition_type_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count); - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); - -@@ -8077,7 +8081,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id); - - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); -- condition_type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); -+ condition_type_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count); - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); - -@@ -8102,7 +8106,7 @@ static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler, - - src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, component_count); - val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id); - if (instruction->flags & VKD3DSI_PRECISE_XYZW) - vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); -@@ -8126,7 +8130,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids)); - - data_type = dst->reg.data_type; -- type_id = spirv_get_type_id(builder, data_type, 1); -+ type_id = spirv_get_type_id(compiler, data_type, 1); - size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20; - mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); - size_id = spirv_compiler_get_constant_uint(compiler, size); -@@ -8183,8 +8187,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, - unsigned int i, j; - - instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); -- scalar_type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 2); -+ scalar_type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 1); - - /* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */ - VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); -@@ -8215,8 +8219,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, - unsigned int i, j; - - instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); -- scalar_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 2); -+ scalar_type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - zero_id = spirv_compiler_get_constant_float(compiler, 0.0f); - - /* FIXME: Consider a single PackHalf2x16 instruction per 2 components. */ -@@ -8294,7 +8298,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], write_mask); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count); - result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - op, type_id, src0_id, src1_id); - -@@ -8346,7 +8350,7 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, component_count); - result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id); - - result_id = spirv_compiler_emit_bool_to_float(compiler, component_count, result_id, false); -@@ -8873,7 +8877,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, - - spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); - -- type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); - if (image.resource_type_info->resource_type != VKD3D_SHADER_RESOURCE_BUFFER && !multisample) -@@ -8918,7 +8922,7 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, - spirv_compiler_prepare_image(compiler, &image, - &resource->reg, &sampler->reg, VKD3D_IMAGE_FLAG_SAMPLED); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 2); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); - val_id = vkd3d_spirv_build_op_image_query_lod(builder, - type_id, image.sampled_image_id, coordinate_id); -@@ -8987,7 +8991,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, - instruction, image.resource_type_info); - } - -- sampled_type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ sampled_type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); - VKD3D_ASSERT(image_operand_count <= ARRAY_SIZE(image_operands)); - val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, -@@ -9031,7 +9035,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, - instruction, image.resource_type_info); - } - -- sampled_type_id = spirv_get_type_id(builder, image.sampled_type, 1); -+ sampled_type_id = spirv_get_type_id(compiler, image.sampled_type, 1); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); - dref_id = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); - val_id = vkd3d_spirv_build_op_image_sample_dref(builder, op, sampled_type_id, -@@ -9089,7 +9093,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, - instruction, image.resource_type_info); - } - -- sampled_type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ sampled_type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = spirv_compiler_emit_load_src(compiler, addr, coordinate_mask); - if (image_flags & VKD3D_IMAGE_FLAG_DEPTH) -@@ -9169,10 +9173,10 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler - - if (storage_buffer_uav) - { -- texel_type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ texel_type_id = spirv_get_type_id(compiler, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, resource_symbol->info.resource.structure_stride, - &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9204,11 +9208,11 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler - - spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); - -- texel_type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ texel_type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); - VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); - for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) - { -@@ -9247,7 +9251,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, - if (!spirv_compiler_get_register_info(compiler, &resource->reg, ®_info)) - return; - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9306,10 +9310,10 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * - - if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) - { -- type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id(compiler, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, resource_symbol->info.resource.structure_stride, - &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9337,7 +9341,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * - } - else - { -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9380,7 +9384,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, - if (!spirv_compiler_get_register_info(compiler, &dst->reg, ®_info)) - return; - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9438,7 +9442,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, - - if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) - { -- type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id(compiler, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - indices[0] = spirv_compiler_get_constant_uint(compiler, 0); -@@ -9453,7 +9457,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, - else - { - spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); -- type_id = spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); - -@@ -9480,7 +9484,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, - - if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) - { -- type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id(compiler, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - indices[0] = spirv_compiler_get_constant_uint(compiler, 0); -@@ -9525,7 +9529,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c - counter_id = resource_symbol->info.resource.uav_counter_id; - VKD3D_ASSERT(counter_id); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - - if (resource_symbol->info.resource.uav_counter_array) - { -@@ -9686,7 +9690,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - } - } - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - if (structure_stride || raw) - { - VKD3D_ASSERT(!raw != !structure_stride); -@@ -9711,7 +9715,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) - { - data_type = resource_symbol->info.resource.sampled_type; -- type_id = spirv_get_type_id(builder, data_type, 1); -+ type_id = spirv_get_type_id(compiler, data_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - operands[0] = spirv_compiler_get_constant_uint(compiler, 0); - operands[1] = coordinate_id; -@@ -9720,7 +9724,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - else - { - data_type = image.sampled_type; -- type_id = spirv_get_type_id(builder, data_type, 1); -+ type_id = spirv_get_type_id(compiler, data_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id); - sample_id = spirv_compiler_get_constant_uint(compiler, 0); - pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, -@@ -9769,7 +9773,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, - { - resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - val_id = vkd3d_spirv_build_op_array_length(builder, type_id, resource_symbol->id, 0); - write_mask = VKD3DSP_WRITEMASK_0; - } -@@ -9779,7 +9783,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, - - spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id); - write_mask = VKD3DSP_WRITEMASK_0; - } -@@ -9789,7 +9793,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, - stride_id = spirv_compiler_get_constant_uint(compiler, image.structure_stride); - constituents[0] = vkd3d_spirv_build_op_udiv(builder, type_id, val_id, stride_id); - constituents[1] = stride_id; -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, ARRAY_SIZE(constituents)); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, ARRAY_SIZE(constituents)); - val_id = vkd3d_spirv_build_op_composite_construct(builder, - type_id, constituents, ARRAY_SIZE(constituents)); - write_mask |= VKD3DSP_WRITEMASK_1; -@@ -9828,14 +9832,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - size_component_count = image.resource_type_info->coordinate_component_count; - if (image.resource_type_info->dim == SpvDimCube) - --size_component_count; -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, size_component_count); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, size_component_count); - - supports_mipmaps = src[1].reg.type != VKD3DSPR_UAV && !image.resource_type_info->ms; - if (supports_mipmaps) - { - lod_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - val_id = vkd3d_spirv_build_op_image_query_size_lod(builder, type_id, image.image_id, lod_id); -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - miplevel_count_id = vkd3d_spirv_build_op_image_query_levels(builder, type_id, image.image_id); - } - else -@@ -9849,13 +9853,13 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - for (i = 0; i < 3 - size_component_count; ++i) - constituents[i + 1] = spirv_compiler_get_constant_uint(compiler, 0); - constituents[i + 1] = miplevel_count_id; -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, i + 2); - - if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) - { - data_type = VSIR_DATA_F32; -- type_id = spirv_get_type_id(builder, data_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, data_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); -@@ -9883,7 +9887,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co - vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); - - spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - val_id = vkd3d_spirv_build_op_image_query_samples(builder, type_id, image.image_id); - } - -@@ -9912,13 +9916,13 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, - { - constituents[i] = spirv_compiler_get_constant_uint(compiler, 0); - } -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE); - - if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) - { - data_type = VSIR_DATA_F32; -- type_id = spirv_get_type_id(builder, data_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, data_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); -@@ -9984,12 +9988,12 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, - sample_count_id = spirv_compiler_emit_query_sample_count(compiler, &instruction->src[0]); - sample_index_id = spirv_compiler_emit_load_src(compiler, &instruction->src[1], VKD3DSP_WRITEMASK_0); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - index_id = vkd3d_spirv_build_op_iadd(builder, type_id, sample_count_id, sample_index_id); - index_id = vkd3d_spirv_build_op_isub(builder, type_id, index_id, spirv_compiler_get_constant_uint(compiler, 1)); - - /* Validate sample index. */ -- bool_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, 1); -+ bool_id = spirv_get_type_id(compiler, VSIR_DATA_BOOL, 1); - id = vkd3d_spirv_build_op_logical_and(builder, bool_id, - vkd3d_spirv_build_op_uless_than(builder, bool_id, sample_index_id, sample_count_id), - vkd3d_spirv_build_op_uless_than_equal(builder, -@@ -9997,7 +10001,7 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, - index_id = vkd3d_spirv_build_op_select(builder, type_id, - id, index_id, spirv_compiler_get_constant_uint(compiler, 0)); - -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, 2); - if (!(id = compiler->sample_positions_id)) - { - length_id = spirv_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions)); -@@ -10061,7 +10065,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, - src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); - } - -- type_id = spirv_get_type_id(builder, VSIR_DATA_F32, -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_F32, - vsir_write_mask_component_count(register_info.write_mask)); - - instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); -@@ -10196,8 +10200,8 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, direction_type_id, direction_id, val_id; - -- type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -- direction_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -+ direction_type_id = spirv_get_type_id(compiler, 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); -@@ -10221,7 +10225,7 @@ static void spirv_compiler_emit_quad_read_lane_at(struct spirv_compiler *compile - return; - } - -- type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); - val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); - val_id = vkd3d_spirv_build_op_group_nonuniform_quad_broadcast(builder, type_id, val_id, lane_id); -@@ -10270,7 +10274,7 @@ static uint32_t spirv_compiler_emit_group_nonuniform_ballot(struct spirv_compile - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, val_id; - -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, VKD3D_VEC4_SIZE); - val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); - val_id = vkd3d_spirv_build_op_group_nonuniform_ballot(builder, type_id, val_id); - -@@ -10329,7 +10333,7 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, - - op = map_wave_alu_op(instruction->opcode, data_type_is_floating_point(src->reg.data_type)); - -- type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); - val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - - vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformArithmetic); -@@ -10353,7 +10357,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, - : SpvGroupOperationReduce; - - val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); -- type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(compiler, VSIR_DATA_U32, 1); - val_id = vkd3d_spirv_build_op_group_nonuniform_ballot_bit_count(builder, type_id, group_op, val_id); - - spirv_compiler_emit_store_dst(compiler, dst, val_id); -@@ -10378,7 +10382,7 @@ static void spirv_compiler_emit_wave_read_lane_at(struct spirv_compiler *compile - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, lane_id, val_id; - -- type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); - val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); - -@@ -10405,7 +10409,7 @@ static void spirv_compiler_emit_wave_read_lane_first(struct spirv_compiler *comp - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, val_id; - -- type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(compiler, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); - val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); - val_id = vkd3d_spirv_build_op_group_nonuniform_broadcast_first(builder, type_id, val_id); - -@@ -10941,7 +10945,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - { - uint32_t type_id, struct_id, ptr_type_id, var_id; - -- type_id = spirv_get_type_id(builder, parameter_data_type_map[parameter->data_type].type, -+ type_id = spirv_get_type_id(compiler, parameter_data_type_map[parameter->data_type].type, - parameter_data_type_map[parameter->data_type].component_count); - - struct_id = vkd3d_spirv_build_op_type_struct(builder, &type_id, 1); --- -2.51.0 - diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-86b8f2de3546603c67e1f2828a68b1cd0aa.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-86b8f2de3546603c67e1f2828a68b1cd0aa.patch deleted file mode 100644 index 70c64c28..00000000 --- a/patches/vkd3d-latest/0006-Updated-vkd3d-to-86b8f2de3546603c67e1f2828a68b1cd0aa.patch +++ /dev/null @@ -1,370 +0,0 @@ -From f6ccbf9518ca22514548ca078947750430f8ada7 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Sat, 18 Oct 2025 15:15:36 +1100 -Subject: [PATCH] Updated vkd3d to 86b8f2de3546603c67e1f2828a68b1cd0aa049df. - ---- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 31 ++------------------ - libs/vkd3d/libs/vkd3d-shader/ir.c | 44 ++++++++++++++++++++++++---- - libs/vkd3d/libs/vkd3d-shader/msl.c | 34 ++------------------- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 27 +++-------------- - 4 files changed, 49 insertions(+), 87 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index ab45c4d1e73..073282db129 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -392,7 +392,7 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd - 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; -+ struct vkd3d_string_buffer *register_name; - enum vsir_data_type src_data_type; - unsigned int size; - -@@ -409,25 +409,11 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd - - shader_glsl_print_register_name(register_name, gen, reg); - -- if (!vsir_src->modifiers) -- str = buffer; -- else -- str = vkd3d_string_buffer_get(&gen->string_buffers); -- - size = reg->dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; -- shader_glsl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, size); -+ shader_glsl_print_bitcast(buffer, gen, register_name->buffer, data_type, src_data_type, size); - if (reg->dimension == VSIR_DIMENSION_VEC4) -- shader_glsl_print_swizzle(str, vsir_src->swizzle, mask); -+ shader_glsl_print_swizzle(buffer, vsir_src->swizzle, mask); - -- if (vsir_src->modifiers) -- { -- vkd3d_string_buffer_printf(buffer, "(%s)", vsir_src->modifiers, str->buffer); -- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); -- } -- -- if (str != buffer) -- vkd3d_string_buffer_release(&gen->string_buffers, str); - vkd3d_string_buffer_release(&gen->string_buffers, register_name); - } - -@@ -489,23 +475,14 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g - 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); -- if (modifiers & ~VKD3DSPDM_SATURATE) -- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled destination modifier(s) %#x.", modifiers); - - shader_glsl_print_indent(buffer, gen->indent); - vkd3d_string_buffer_printf(buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer); -- if (modifiers & VKD3DSPDM_SATURATE) -- vkd3d_string_buffer_printf(buffer, "clamp("); - - switch (data_type) - { -@@ -530,8 +507,6 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g - - if (close) - vkd3d_string_buffer_printf(buffer, ")"); -- if (modifiers & VKD3DSPDM_SATURATE) -- vkd3d_string_buffer_printf(buffer, ", 0.0, 1.0)"); - vkd3d_string_buffer_printf(buffer, ";\n"); - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 82901c6fb34..000c78aeed3 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -2173,6 +2173,7 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr - { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), new_it; - struct vkd3d_shader_instruction *ins, *new_ins; -+ enum vkd3d_result ret = VKD3D_OK; - unsigned int i, j; - - for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) -@@ -2182,9 +2183,11 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr - enum vkd3d_shader_opcode new_opcodes[2] = {VSIR_OP_NOP, VSIR_OP_NOP}; - struct vkd3d_shader_src_param *src = &ins->src[i]; - -- /* TODO: support other modifiers, including destination modifiers. */ - switch (src->modifiers) - { -+ case VKD3DSPSM_NONE: -+ continue; -+ - case VKD3DSPSM_ABS: - new_opcodes[0] = VSIR_OP_ABS; - break; -@@ -2199,6 +2202,9 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr - break; - - default: -+ vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ "Aborting due to unimplemented feature: Source modifier %#x.", src->modifiers); -+ ret = VKD3D_ERROR_NOT_IMPLEMENTED; - continue; - } - -@@ -2234,12 +2240,23 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr - { - struct vkd3d_shader_dst_param *dst = &ins->dst[i]; - -+ /* It is always legitimate to ignore _pp. */ -+ dst->modifiers &= ~VKD3DSPDM_PARTIALPRECISION; -+ -+ if (dst->modifiers & ~VKD3DSPDM_SATURATE) -+ { -+ vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ "Aborting due to unimplemented feature: Destination modifier %#x.", dst->modifiers); -+ ret = VKD3D_ERROR_NOT_IMPLEMENTED; -+ continue; -+ } -+ - if (dst->modifiers & VKD3DSPDM_SATURATE) - { - if (!vsir_program_iterator_insert_after(&it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_current(&it); - new_ins = vsir_program_iterator_next(&it); -+ ins = vsir_program_iterator_prev(&it); - - if (!vsir_instruction_init_with_params(program, new_ins, &ins->location, VSIR_OP_SATURATE, 1, 1)) - { -@@ -2248,7 +2265,7 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr - } - - new_ins->dst[0] = *dst; -- new_ins->dst[0].modifiers &= ~VKD3DSPDM_NONE; -+ new_ins->dst[0].modifiers &= ~VKD3DSPDM_SATURATE; - - dst_param_init_ssa(dst, program->ssa_count, dst->reg.data_type, dst->reg.dimension); - src_param_init_ssa(&new_ins->src[0], program->ssa_count, dst->reg.data_type, dst->reg.dimension); -@@ -2264,7 +2281,7 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr - } - } - -- return VKD3D_OK; -+ return ret; - } - - static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, -@@ -5064,6 +5081,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( - for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) - { - struct vkd3d_shader_instruction *mov_ins; -+ struct vkd3d_shader_location loc; - bool finish = false; - size_t j; - -@@ -5083,6 +5101,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( - case VSIR_OP_SWITCH_MONOLITHIC: - info = &block_info[current_label - 1]; - -+ loc = ins->location; - if (!(mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count))) - goto fail; - VKD3D_ASSERT(mov_ins); -@@ -5091,7 +5110,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( - { - struct phi_incoming_to_temp *incoming = &info->incomings[j]; - -- if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VSIR_OP_MOV, 1, 0)) -+ if (!vsir_instruction_init_with_params(program, mov_ins, &loc, VSIR_OP_MOV, 1, 0)) - { - vkd3d_shader_instruction_make_nop(mov_ins); - goto fail; -@@ -9311,6 +9330,7 @@ struct temp_allocator - enum vkd3d_shader_register_type type; - unsigned int idx; - bool force_first; -+ bool fixed_mask; - } *ssa_regs, *temp_regs; - size_t ssa_count, temp_count; - unsigned int new_temp_count; -@@ -9339,6 +9359,9 @@ static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3 - src->reg.type = VKD3DSPR_TEMP; - src->reg.dimension = VSIR_DIMENSION_VEC4; - src->reg.idx[0].offset = reg->temp_id; -+ -+ if (reg->fixed_mask) -+ return; - src->swizzle = vsir_combine_swizzles(vsir_swizzle_from_writemask(reg->allocated_mask), src->swizzle); - } - -@@ -9430,7 +9453,16 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, - dst->reg.type = VKD3DSPR_TEMP; - dst->reg.dimension = VSIR_DIMENSION_VEC4; - dst->reg.idx[0].offset = reg->temp_id; -+ -+ if (reg->fixed_mask) -+ { -+ VKD3D_ASSERT((reg->allocated_mask & dst->write_mask) == dst->write_mask); -+ return; -+ } -+ - remapped_mask = vsir_combine_write_masks(reg->allocated_mask, dst->write_mask); -+ VKD3D_ASSERT(vkd3d_popcount(remapped_mask) == vkd3d_popcount(dst->write_mask)); -+ - if (dst->write_mask != remapped_mask) - { - dst->write_mask = remapped_mask; -@@ -9508,6 +9540,7 @@ static void temp_allocator_open_register(struct temp_allocator *allocator, struc - { - reg->temp_id = i; - reg->allocated_mask = liveness_reg->mask; -+ reg->fixed_mask = true; - current_allocation[i] |= reg->allocated_mask; - allocator->new_temp_count = max(allocator->new_temp_count, i + 1); - TRACE("Allocated r%u%s for %s (liveness %u-%u).\n", -@@ -9534,6 +9567,7 @@ static void temp_allocator_open_register(struct temp_allocator *allocator, struc - - reg->temp_id = i; - reg->allocated_mask = vsir_combine_write_masks(available_mask, mask); -+ reg->fixed_mask = false; - current_allocation[i] |= reg->allocated_mask; - allocator->new_temp_count = max(allocator->new_temp_count, i + 1); - TRACE("Allocated r%u%s for %s (liveness %u-%u).\n", -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index f2d28acbe38..3e7bf831e48 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -583,7 +583,7 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m - 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; -+ struct vkd3d_string_buffer *register_name; - enum msl_data_type src_data_type; - - register_name = vkd3d_string_buffer_get(&gen->string_buffers); -@@ -592,25 +592,10 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled 'non-uniform' modifier."); - -- if (!vsir_src->modifiers) -- str = buffer; -- else -- str = vkd3d_string_buffer_get(&gen->string_buffers); -- - src_data_type = msl_print_register_name(register_name, gen, reg); -- msl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, reg->dimension); -+ msl_print_bitcast(buffer, gen, register_name->buffer, data_type, src_data_type, reg->dimension); - if (reg->dimension == VSIR_DIMENSION_VEC4) -- msl_print_swizzle(str, vsir_src->swizzle, mask); -- -- if (vsir_src->modifiers) -- { -- vkd3d_string_buffer_printf(buffer, "(%s)", vsir_src->modifiers, str->buffer); -- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); -- } -- -- if (str != buffer) -- vkd3d_string_buffer_release(&gen->string_buffers, str); -+ msl_print_swizzle(buffer, vsir_src->swizzle, mask); - } - - static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, -@@ -674,32 +659,19 @@ static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_g - 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); -- if (modifiers & ~VKD3DSPDM_SATURATE) -- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled destination modifier(s) %#x.", modifiers); - - msl_print_indent(gen->buffer, gen->indent); - vkd3d_string_buffer_printf(gen->buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer); - -- if (modifiers & VKD3DSPDM_SATURATE) -- vkd3d_string_buffer_printf(gen->buffer, "saturate("); -- - va_start(args, format); - vkd3d_string_buffer_vprintf(gen->buffer, format, args); - va_end(args); - -- if (modifiers & VKD3DSPDM_SATURATE) -- vkd3d_string_buffer_printf(gen->buffer, ")"); -- - vkd3d_string_buffer_printf(gen->buffer, ";\n"); - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index a1572f69438..0f5df228121 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -4823,10 +4823,6 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler, - static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, - const struct vkd3d_shader_src_param *src, uint32_t write_mask) - { -- if (src->modifiers) -- spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -- "Unhandled source modifier(s) %#x.", src->modifiers); -- - return spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); - } - -@@ -4981,25 +4977,6 @@ static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, - static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler, - const struct vkd3d_shader_dst_param *dst, uint32_t val_id) - { -- uint32_t modifiers = dst->modifiers; -- -- /* It is always legitimate to ignore _pp. */ -- modifiers &= ~VKD3DSPDM_PARTIALPRECISION; -- -- if (modifiers & VKD3DSPDM_SATURATE) -- { -- val_id = spirv_compiler_emit_sat(compiler, &dst->reg, dst->write_mask, val_id); -- modifiers &= ~VKD3DSPDM_SATURATE; -- } -- -- if (dst->modifiers & VKD3DSPDM_MSAMPCENTROID) -- { -- FIXME("Ignoring _centroid modifier.\n"); -- modifiers &= ~VKD3DSPDM_MSAMPCENTROID; -- } -- -- VKD3D_ASSERT(!modifiers); -- - spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, val_id); - } - -@@ -11052,7 +11029,11 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - } - - if (compiler->failed) -+ { -+ vkd3d_shader_free_shader_code(spirv); -+ - return VKD3D_ERROR_INVALID_SHADER; -+ } - - if (compile_info->target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT) - { --- -2.51.0 - diff --git a/patches/vkd3d-latest/0007-Updated-vkd3d-to-d3f658d410c42d739bdb3513bfdbd3f4e78.patch b/patches/vkd3d-latest/0007-Updated-vkd3d-to-d3f658d410c42d739bdb3513bfdbd3f4e78.patch deleted file mode 100644 index 0e405e50..00000000 --- a/patches/vkd3d-latest/0007-Updated-vkd3d-to-d3f658d410c42d739bdb3513bfdbd3f4e78.patch +++ /dev/null @@ -1,1527 +0,0 @@ -From 65b2564bc2e373169e5de6198d42600dd8a44273 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 30 Oct 2025 06:55:00 +1100 -Subject: [PATCH] Updated vkd3d to d3f658d410c42d739bdb3513bfdbd3f4e787c528. - ---- - libs/vkd3d/include/vkd3d_shader.h | 77 ++++++ - libs/vkd3d/libs/vkd3d-shader/glsl.c | 1 + - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 6 + - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 11 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 25 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 172 ++++---------- - .../libs/vkd3d-shader/hlsl_constant_ops.c | 66 ++---- - libs/vkd3d/libs/vkd3d-shader/ir.c | 223 ++++++++++++++++-- - libs/vkd3d/libs/vkd3d-shader/msl.c | 216 ++++++----------- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 9 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 2 - - .../libs/vkd3d-shader/vkd3d_shader_private.h | 1 + - 12 files changed, 451 insertions(+), 358 deletions(-) - -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index df1f5d5250d..50bcf6b292b 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -961,6 +961,83 @@ enum vkd3d_shader_parameter_name - * \since 1.15 - */ - VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE, -+ /** -+ * Bump-mapping matrix. This parameter is used in the evaluation of the -+ * Shader Model 1.x instructions BEM, TEXBEM, and TEXBEML. -+ * -+ * This parameter specifies a 2x2 matrix, packed into a vector in the order -+ * [00, 01, 10, 11], where "01" specifies the component at column 0 and row -+ * 1. These coordinates correspond to the Direct3D notation. -+ * -+ * To use this parameter to implement Direct3D bump mapping, pass the values -+ * of the texture stage states D3DTSS_BUMPENVMAT00, D3DTSS_BUMPENVMAT01, -+ * D3DTSS_BUMPENVMAT10, and D3DTSS_BUMPENVMAT11, in that order. -+ * -+ * These enum values are contiguous and arithmetic may safely be performed -+ * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_[n] is -+ * VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 plus n. -+ * -+ * The data type for each parameter must be -+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4. -+ * -+ * The default value for each parameter is the zero matrix [0, 0; 0, 0]. -+ * -+ * \since 1.18 -+ */ -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_1, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_2, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_3, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_4, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_5, -+ /** -+ * Bump-mapping luminance scale factor. This parameter is used in the -+ * evaluation of the Shader Model 1.x instruction TEXBEML. -+ * -+ * To use this parameter to implement Direct3D bump mapping, pass the value -+ * of the texture stage state D3DTSS_BUMPENVLSCALE. -+ * -+ * These enum values are contiguous and arithmetic may safely be performed -+ * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_[n] is -+ * VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0 plus n. -+ * -+ * The data type for each parameter must be -+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32. -+ * -+ * The default value for each parameter is 0.0. -+ * -+ * \since 1.18 -+ */ -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_1, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_2, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_3, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_4, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_5, -+ /** -+ * Bump-mapping luminance offset. This parameter is used in the -+ * evaluation of the Shader Model 1.x instruction TEXBEML. -+ * -+ * To use this parameter to implement Direct3D bump mapping, pass the value -+ * of the texture stage state D3DTSS_BUMPENVLOFFSET. -+ * -+ * These enum values are contiguous and arithmetic may safely be performed -+ * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_[n] is -+ * VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0 plus n. -+ * -+ * The data type for each parameter must be -+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32. -+ * -+ * The default value for each parameter is 0.0. -+ * -+ * \since 1.18 -+ */ -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_1, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_2, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_3, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_4, -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME), - }; -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index 073282db129..4d7505d8740 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -2482,6 +2482,7 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, - - VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); - VKD3D_ASSERT(program->has_descriptor_info); -+ VKD3D_ASSERT(program->has_no_modifiers); - - vkd3d_glsl_generator_init(&generator, program, compile_info, - combined_sampler_info, message_context); -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 3b0a7acb52a..1de17e2b551 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -1737,6 +1737,12 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t - return &c->node; - } - -+struct hlsl_ir_node *hlsl_block_add_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, -+ struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc) -+{ -+ return append_new_instr(ctx, block, hlsl_new_constant(ctx, type, value, loc)); -+} -+ - struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc) - { - struct hlsl_constant_value value; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 829fcba0aab..75027f83e33 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -1579,6 +1579,8 @@ struct hlsl_ir_node *hlsl_block_add_binary_expr(struct hlsl_ctx *ctx, struct hls - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2); - struct hlsl_ir_node *hlsl_block_add_cast(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_node *arg, struct hlsl_type *type, const struct vkd3d_shader_location *loc); -+struct hlsl_ir_node *hlsl_block_add_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, -+ struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc); - struct hlsl_ir_node *hlsl_block_add_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], - struct hlsl_type *data_type, const struct vkd3d_shader_location *loc); -@@ -1833,10 +1835,13 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl - struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); - - bool hlsl_copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block); --bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); --bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); -+struct hlsl_ir_node *hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block); -+struct hlsl_ir_node *hlsl_fold_constant_identities(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block); - bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); --bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); -+struct hlsl_ir_node *hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block); - bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), - struct hlsl_block *block, void *context); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 759dadf8a58..8ec963c8656 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -3038,10 +3038,7 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, - if (!param->default_values[j].string) - { - value.u[0] = param->default_values[j].number; -- if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) -- return NULL; -- hlsl_block_add_instr(args->instrs, comp); -- -+ comp = hlsl_block_add_constant(ctx, args->instrs, type, &value, loc); - hlsl_block_add_store_component(ctx, args->instrs, ¶m_deref, j, comp); - } - } -@@ -3956,7 +3953,6 @@ static bool intrinsic_firstbithigh(struct hlsl_ctx *ctx, - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_type *type = params->args[0]->data_type; - struct hlsl_ir_node *c, *clz, *eq, *xor; -- struct hlsl_constant_value v; - - if (hlsl_version_lt(ctx, 4, 0)) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, -@@ -3978,20 +3974,14 @@ static bool intrinsic_firstbithigh(struct hlsl_ctx *ctx, - if (hlsl_version_lt(ctx, 5, 0)) - return add_expr(ctx, params->instrs, HLSL_OP1_FIND_MSB, operands, type, loc); - -- v.u[0].u = 0x1f; -- if (!(c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &v, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, c); -+ c = hlsl_block_add_uint_constant(ctx, params->instrs, 0x1f, loc); - - if (!(clz = add_expr(ctx, params->instrs, HLSL_OP1_CLZ, operands, type, loc))) - return false; - if (!(xor = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_BIT_XOR, c, clz, loc))) - return false; - -- v.u[0].i = -1; -- if (!(c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &v, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, c); -+ c = hlsl_block_add_uint_constant(ctx, params->instrs, ~0u, loc); - - if (!(eq = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_EQUAL, clz, c, loc))) - return false; -@@ -4043,9 +4033,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer - if (!(div = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, x, y, loc))) - return false; - -- if (!(zero = hlsl_new_constant(ctx, div->data_type, &zero_value, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, zero); -+ zero = hlsl_block_add_constant(ctx, params->instrs, div->data_type, &zero_value, loc); - - if (!(abs = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, div, loc))) - return false; -@@ -4641,9 +4629,8 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, - struct hlsl_type *int_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_INT, - arg->data_type->e.numeric.dimx, arg->data_type->e.numeric.dimy); - -- if (!(zero = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, arg->data_type->e.numeric.type), &zero_value, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, zero); -+ zero = hlsl_block_add_constant(ctx, params->instrs, -+ hlsl_get_scalar_type(ctx, arg->data_type->e.numeric.type), &zero_value, loc); - - /* Check if 0 < arg, cast bool to int */ - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 8f4e4cda73f..9048214923b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -4058,9 +4058,7 @@ static struct hlsl_ir_node *lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx - value.u[1].u = 1; - value.u[2].u = 2; - value.u[3].u = 3; -- if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, c); -+ c = hlsl_block_add_constant(ctx, block, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc); - - operands[0] = swizzle; - operands[1] = c; -@@ -4172,10 +4170,7 @@ static struct hlsl_ir_node *lower_nonconstant_array_loads(struct hlsl_ctx *ctx, - if (!(var = hlsl_new_synthetic_var(ctx, row_major ? "row_major-load" : "array-load", instr->data_type, &instr->loc))) - return NULL; - -- if (!(zero = hlsl_new_constant(ctx, instr->data_type, &zero_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, zero); -- -+ zero = hlsl_block_add_constant(ctx, block, instr->data_type, &zero_value, &instr->loc); - hlsl_block_add_simple_store(ctx, block, var, zero); - - TRACE("Lowering non-constant %s load on variable '%s'.\n", row_major ? "row_major" : "array", deref->var->name); -@@ -4540,17 +4535,13 @@ static struct hlsl_ir_node *lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_nod - struct hlsl_constant_value zero_value, one_value; - - memset(&zero_value, 0, sizeof(zero_value)); -- if (!(zero = hlsl_new_constant(ctx, arg->data_type, &zero_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, zero); -+ zero = hlsl_block_add_constant(ctx, block, arg->data_type, &zero_value, &instr->loc); - - one_value.u[0].f = 1.0; - one_value.u[1].f = 1.0; - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; -- if (!(one = hlsl_new_constant(ctx, arg->data_type, &one_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, one); -+ one = hlsl_block_add_constant(ctx, block, arg->data_type, &one_value, &instr->loc); - - fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); - neg_fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, fract, &instr->loc); -@@ -4745,9 +4736,7 @@ static struct hlsl_ir_node *lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_nod - component_count = hlsl_type_component_count(type); - for (i = 0; i < component_count; ++i) - half_value.u[i].f = 0.5f; -- if (!(half = hlsl_new_constant(ctx, type, &half_value, &expr->node.loc))) -- return NULL; -- hlsl_block_add_instr(block, half); -+ half = hlsl_block_add_constant(ctx, block, type, &half_value, &expr->node.loc); - - sum = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, half); - frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, sum, &instr->loc); -@@ -4828,15 +4817,10 @@ static struct hlsl_ir_node *lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node - neg_pi_value.u[i].f = -M_PI; - } - -- if (!(half = hlsl_new_constant(ctx, type, &half_value, &instr->loc)) -- || !(two_pi = hlsl_new_constant(ctx, type, &two_pi_value, &instr->loc)) -- || !(reciprocal_two_pi = hlsl_new_constant(ctx, type, &reciprocal_two_pi_value, &instr->loc)) -- || !(neg_pi = hlsl_new_constant(ctx, type, &neg_pi_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, half); -- hlsl_block_add_instr(block, two_pi); -- hlsl_block_add_instr(block, reciprocal_two_pi); -- hlsl_block_add_instr(block, neg_pi); -+ half = hlsl_block_add_constant(ctx, block, type, &half_value, &instr->loc); -+ two_pi = hlsl_block_add_constant(ctx, block, type, &two_pi_value, &instr->loc); -+ reciprocal_two_pi = hlsl_block_add_constant(ctx, block, type, &reciprocal_two_pi_value, &instr->loc); -+ neg_pi = hlsl_block_add_constant(ctx, block, type, &neg_pi_value, &instr->loc); - - if (!(mad = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, arg, reciprocal_two_pi, half))) - return NULL; -@@ -4905,10 +4889,7 @@ static struct hlsl_ir_node *lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir - one_value.u[1].f = 1.0; - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; -- if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, one); -- -+ one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); - sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg); - - memset(operands, 0, sizeof(operands)); -@@ -5069,10 +5050,7 @@ static struct hlsl_ir_node *lower_comparison_operators(struct hlsl_ctx *ctx, str - one_value.u[1].f = 1.0; - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; -- if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, one); -- -+ one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); - slt_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); - res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, slt_neg); - } -@@ -5119,17 +5097,13 @@ static struct hlsl_ir_node *lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node - sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg1_cast, neg); - - memset(&zero_value, 0, sizeof(zero_value)); -- if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, zero); -+ zero = hlsl_block_add_constant(ctx, block, float_type, &zero_value, &instr->loc); - - one_value.u[0].f = 1.0; - one_value.u[1].f = 1.0; - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; -- if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, one); -+ one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); - - if (!(cmp = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, sub, zero, one))) - return NULL; -@@ -5168,17 +5142,13 @@ static struct hlsl_ir_node *lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node - } - - memset(&zero_value, 0, sizeof(zero_value)); -- if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, zero); -+ zero = hlsl_block_add_constant(ctx, block, float_type, &zero_value, &instr->loc); - - one_value.u[0].f = 1.0; - one_value.u[1].f = 1.0; - one_value.u[2].f = 1.0; - one_value.u[3].f = 1.0; -- if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, one); -+ one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); - - slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, args_cast[0], zero); - mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[2], slt); -@@ -5210,11 +5180,7 @@ static struct hlsl_ir_node *lower_casts_to_bool(struct hlsl_ctx *ctx, - /* Narrowing casts should have already been lowered. */ - VKD3D_ASSERT(type->e.numeric.dimx == arg_type->e.numeric.dimx); - -- zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc); -- if (!zero) -- return NULL; -- hlsl_block_add_instr(block, zero); -- -+ zero = hlsl_block_add_constant(ctx, block, arg_type, &zero_value, &instr->loc); - neq = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_NEQUAL, expr->operands[0].node, zero); - neq->data_type = expr->node.data_type; - return neq; -@@ -5267,10 +5233,7 @@ static struct hlsl_ir_node *lower_int_division_sm4(struct hlsl_ctx *ctx, - - for (i = 0; i < type->e.numeric.dimx; ++i) - high_bit_value.u[i].u = 0x80000000; -- if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, high_bit); -- -+ high_bit = hlsl_block_add_constant(ctx, block, type, &high_bit_value, &instr->loc); - and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, xor, high_bit); - abs1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg1, &instr->loc); - cast1 = hlsl_block_add_cast(ctx, block, abs1, utype, &instr->loc); -@@ -5306,10 +5269,7 @@ static struct hlsl_ir_node *lower_int_modulus_sm4(struct hlsl_ctx *ctx, - - for (i = 0; i < type->e.numeric.dimx; ++i) - high_bit_value.u[i].u = 0x80000000; -- if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, high_bit); -- -+ high_bit = hlsl_block_add_constant(ctx, block, type, &high_bit_value, &instr->loc); - and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, arg1, high_bit); - abs1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg1, &instr->loc); - cast1 = hlsl_block_add_cast(ctx, block, abs1, utype, &instr->loc); -@@ -5418,10 +5378,7 @@ static struct hlsl_ir_node *lower_float_modulus(struct hlsl_ctx *ctx, - - for (i = 0; i < type->e.numeric.dimx; ++i) - one_value.u[i].f = 1.0f; -- if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) -- return NULL; -- hlsl_block_add_instr(block, one); -- -+ one = hlsl_block_add_constant(ctx, block, type, &one_value, &instr->loc); - div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond); - mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1); - frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc); -@@ -5447,9 +5404,7 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - hlsl_block_init(&block); - - arg_type = jump->condition.node->data_type; -- if (!(zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc))) -- return false; -- hlsl_block_add_instr(&block, zero); -+ zero = hlsl_block_add_constant(ctx, &block, arg_type, &zero_value, &instr->loc); - - operands[0] = jump->condition.node; - operands[1] = zero; -@@ -5457,9 +5412,8 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - arg_type->e.numeric.dimx, arg_type->e.numeric.dimy); - cmp = hlsl_block_add_expr(ctx, &block, HLSL_OP2_LESS, operands, cmp_type, &instr->loc); - -- if (!(bool_false = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc))) -- return false; -- hlsl_block_add_instr(&block, bool_false); -+ bool_false = hlsl_block_add_constant(ctx, &block, -+ hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc); - - or = bool_false; - -@@ -8417,22 +8371,21 @@ static struct hlsl_ir_node *evaluate_conditionals_recurse(struct hlsl_ctx *ctx, - return NULL; - } - --static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+static struct hlsl_ir_node *fold_conditional_identities(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_node *c, *x, *y, *res_x, *res_y; -- struct hlsl_ir_node *res = NULL; - struct hlsl_ir_expr *expr, *ec; -- struct hlsl_block block; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - - if (instr->data_type->class > HLSL_CLASS_VECTOR) -- return false; -+ return NULL; - - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP3_TERNARY) -- return false; -+ return NULL; - - c = expr->operands[0].node; - x = expr->operands[1].node; -@@ -8440,74 +8393,45 @@ static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_nod - - VKD3D_ASSERT(c->data_type->e.numeric.type == HLSL_TYPE_BOOL); - -+ /* c ? x : x -> x */ - if (nodes_are_equivalent(x, y)) -- { -- /* c ? x : x -> x */ -- hlsl_replace_node(instr, x); -- return true; -- } -+ return x; - - if (c->type == HLSL_IR_CONSTANT) - { -+ /* false ? x : y -> y */ - if (hlsl_constant_is_zero(hlsl_ir_constant(c))) -- { -- /* false ? x : y -> y */ -- hlsl_replace_node(instr, y); -- return true; -- } -+ return y; - -+ /* true ? x : y -> x */ - if (hlsl_constant_is_one(hlsl_ir_constant(c))) -- { -- /* true ? x : y -> x */ -- hlsl_replace_node(instr, x); -- return true; -- } -+ return x; - } - -- hlsl_block_init(&block); -- - if (x->type == HLSL_IR_CONSTANT && y->type == HLSL_IR_CONSTANT - && hlsl_types_are_equal(c->data_type, x->data_type) - && hlsl_types_are_equal(c->data_type, y->data_type)) - { -+ /* c ? true : false -> c */ - if (hlsl_constant_is_one(hlsl_ir_constant(x)) && hlsl_constant_is_zero(hlsl_ir_constant(y))) -- { -- /* c ? true : false -> c */ -- res = c; -- goto done; -- } -+ return c; - -+ /* c ? false : true -> !c */ - if (hlsl_constant_is_zero(hlsl_ir_constant(x)) && hlsl_constant_is_one(hlsl_ir_constant(y))) -- { -- /* c ? false : true -> !c */ -- res = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); -- goto done; -- } -+ return hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); - } - -+ /* !c ? x : y -> c ? y : x */ - ec = c->type == HLSL_IR_EXPR ? hlsl_ir_expr(c) : NULL; - if (ec && ec->op == HLSL_OP1_LOGIC_NOT) -- { -- /* !c ? x : y -> c ? y : x */ -- res = hlsl_add_conditional(ctx, &block, ec->operands[0].node, y, x); -- goto done; -- } -+ return hlsl_add_conditional(ctx, block, ec->operands[0].node, y, x); - -- res_x = evaluate_conditionals_recurse(ctx, &block, c, true, x, &instr->loc); -- res_y = evaluate_conditionals_recurse(ctx, &block, c, false, y, &instr->loc); -+ res_x = evaluate_conditionals_recurse(ctx, block, c, true, x, &instr->loc); -+ res_y = evaluate_conditionals_recurse(ctx, block, c, false, y, &instr->loc); - if (res_x || res_y) -- res = hlsl_add_conditional(ctx, &block, c, res_x ? res_x : x, res_y ? res_y : y); -+ return hlsl_add_conditional(ctx, block, c, res_x ? res_x : x, res_y ? res_y : y); - --done: -- if (res) -- { -- list_move_before(&instr->entry, &block.instrs); -- hlsl_replace_node(instr, res); -- return true; -- } -- -- hlsl_block_cleanup(&block); -- return false; -+ return NULL; - } - - static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) -@@ -8516,12 +8440,12 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) - - do - { -- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); -+ progress = replace_ir(ctx, hlsl_fold_constant_exprs, block); - progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL); - progress |= hlsl_transform_ir(ctx, fold_unary_identities, block, NULL); -- progress |= hlsl_transform_ir(ctx, fold_conditional_identities, block, NULL); -- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); -- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); -+ progress |= replace_ir(ctx, fold_conditional_identities, block); -+ progress |= replace_ir(ctx, hlsl_fold_constant_identities, block); -+ progress |= replace_ir(ctx, hlsl_fold_constant_swizzles, block); - - any_progress |= progress; - } while (progress); -@@ -14895,7 +14819,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v - replace_ir(ctx, lower_int_modulus_sm1, body); - replace_ir(ctx, lower_division, body); - /* Constants casted to float must be folded, and new casts to bool also need to be lowered. */ -- hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); -+ replace_ir(ctx, hlsl_fold_constant_exprs, body); - replace_ir(ctx, lower_casts_to_bool, body); - - replace_ir(ctx, lower_casts_to_int, body); -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -index 7b3b0470d5d..1c44e5fa37a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -@@ -1434,11 +1434,11 @@ static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c - return true; - } - --bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+struct hlsl_ir_node *hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL; - struct hlsl_constant_value res = {0}; -- struct hlsl_ir_node *res_node; - struct hlsl_ir_expr *expr; - unsigned int i; - bool success; -@@ -1638,36 +1638,32 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - } - - if (success) -- { -- if (!(res_node = hlsl_new_constant(ctx, instr->data_type, &res, &instr->loc))) -- return false; -- list_add_before(&expr->node.entry, &res_node->entry); -- hlsl_replace_node(&expr->node, res_node); -- } -- return success; -+ return hlsl_block_add_constant(ctx, block, instr->data_type, &res, &instr->loc); -+ -+ return NULL; - } - --bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+struct hlsl_ir_node *hlsl_fold_constant_identities(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - static const struct hlsl_constant_value zero; - struct hlsl_ir_constant *const_arg = NULL; - struct hlsl_ir_node *mut_arg = NULL; -- struct hlsl_ir_node *res_node; - struct hlsl_ir_expr *expr; - unsigned int i; - - if (instr->type != HLSL_IR_EXPR) -- return false; -+ return NULL; - expr = hlsl_ir_expr(instr); - - if (instr->data_type->class > HLSL_CLASS_VECTOR) -- return false; -+ return NULL; - - /* Verify that the expression has two operands. */ - for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) - { - if (!!expr->operands[i].node != (i < 2)) -- return false; -+ return NULL; - } - - if (expr->operands[0].node->type == HLSL_IR_CONSTANT) -@@ -1682,34 +1678,33 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - } - else - { -- return false; -+ return NULL; - } - -- res_node = NULL; - switch (expr->op) - { - case HLSL_OP2_ADD: - if (hlsl_constant_is_zero(const_arg)) -- res_node = mut_arg; -+ return mut_arg; - break; - - case HLSL_OP2_MUL: - if (hlsl_constant_is_one(const_arg)) -- res_node = mut_arg; -+ return mut_arg; - break; - - case HLSL_OP2_LOGIC_AND: - if (hlsl_constant_is_zero(const_arg)) -- res_node = &const_arg->node; -+ return &const_arg->node; - else if (hlsl_constant_is_one(const_arg)) -- res_node = mut_arg; -+ return mut_arg; - break; - - case HLSL_OP2_LOGIC_OR: - if (hlsl_constant_is_zero(const_arg)) -- res_node = mut_arg; -+ return mut_arg; - else if (hlsl_constant_is_one(const_arg)) -- res_node = &const_arg->node; -+ return &const_arg->node; - break; - - case HLSL_OP2_LESS: -@@ -1718,21 +1713,13 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - || expr->operands[1].node->type != HLSL_IR_CONSTANT - || !hlsl_constant_is_zero(hlsl_ir_constant(expr->operands[1].node))) - break; -- if (!(res_node = hlsl_new_constant(ctx, instr->data_type, &zero, &instr->loc))) -- break; -- list_add_before(&expr->node.entry, &res_node->entry); -- break; -+ return hlsl_block_add_constant(ctx, block, instr->data_type, &zero, &instr->loc); - - default: - break; - } - -- if (res_node) -- { -- hlsl_replace_node(&expr->node, res_node); -- return true; -- } -- return false; -+ return NULL; - } - - static bool is_op_associative(enum hlsl_ir_expr_op op, enum hlsl_base_type type) -@@ -1961,28 +1948,23 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst - return progress; - } - --bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+struct hlsl_ir_node *hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, -+ struct hlsl_ir_node *instr, struct hlsl_block *block) - { - struct hlsl_constant_value value; - struct hlsl_ir_swizzle *swizzle; - struct hlsl_ir_constant *src; -- struct hlsl_ir_node *dst; - unsigned int i; - - if (instr->type != HLSL_IR_SWIZZLE) -- return false; -+ return NULL; - swizzle = hlsl_ir_swizzle(instr); - if (swizzle->val.node->type != HLSL_IR_CONSTANT) -- return false; -+ return NULL; - src = hlsl_ir_constant(swizzle->val.node); - - for (i = 0; i < swizzle->node.data_type->e.numeric.dimx; ++i) - value.u[i] = src->value.u[hlsl_swizzle_get_component(swizzle->u.vector, i)]; - -- if (!(dst = hlsl_new_constant(ctx, instr->data_type, &value, &instr->loc))) -- return false; -- -- list_add_before(&swizzle->node.entry, &dst->entry); -- hlsl_replace_node(&swizzle->node, dst); -- return true; -+ return hlsl_block_add_constant(ctx, block, instr->data_type, &value, &instr->loc); - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 000c78aeed3..a566d65d8cd 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -1987,7 +1987,7 @@ static enum vkd3d_result vsir_program_lower_texcoord(struct vsir_program *progra - unsigned int idx = ins->dst[0].reg.idx[0].offset; - struct vkd3d_shader_src_param *srcs; - -- /* texcoord t# -> mov_sat t#, t# -+ /* texcoord t# -> saturate t#, t# - * Note that the t# destination will subsequently be turned into a temp. */ - - /* We run before I/O normalization. */ -@@ -2001,15 +2001,180 @@ static enum vkd3d_result vsir_program_lower_texcoord(struct vsir_program *progra - srcs[0].reg.dimension = VSIR_DIMENSION_VEC4; - srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - -- ins->dst[0].modifiers |= VKD3DSPDM_SATURATE; -- -- ins->opcode = VSIR_OP_MOV; -+ ins->opcode = VSIR_OP_SATURATE; - ins->src = srcs; - ins->src_count = 1; - - return VKD3D_OK; - } - -+static struct vkd3d_shader_instruction *generate_bump_coords(struct vsir_program *program, -+ struct vsir_program_iterator *it, uint32_t idx, const struct vkd3d_shader_src_param *coords, -+ const struct vkd3d_shader_src_param *perturbation, const struct vkd3d_shader_location *loc) -+{ -+ struct vkd3d_shader_instruction *ins; -+ uint32_t ssa_temp, ssa_coords; -+ -+ /* We generate the following code: -+ * -+ * mad srTMP.xy, PERTURBATION.xx, BUMP_MATRIX#.xy, COORDS.xy -+ * mad srCOORDS.xy, PERTURBATION.yy, BUMP_MATRIX#.zw, srTMP.xy -+ */ -+ -+ ssa_temp = program->ssa_count++; -+ ssa_coords = program->ssa_count++; -+ -+ ins = vsir_program_iterator_current(it); -+ if (!vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAD, 1, 3)) -+ return false; -+ dst_param_init_ssa_float4(&ins->dst[0], ssa_temp); -+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; -+ ins->src[0] = *perturbation; -+ ins->src[0].swizzle = vsir_combine_swizzles(perturbation->swizzle, VKD3D_SHADER_SWIZZLE(X, X, X, X)); -+ src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 + idx, VSIR_DATA_F32); -+ ins->src[2] = *coords; -+ -+ ins = vsir_program_iterator_next(it); -+ if (!vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAD, 1, 3)) -+ return false; -+ dst_param_init_ssa_float4(&ins->dst[0], ssa_coords); -+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; -+ ins->src[0] = *perturbation; -+ ins->src[0].swizzle = vsir_combine_swizzles(perturbation->swizzle, VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y)); -+ src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 + idx, VSIR_DATA_F32); -+ ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(Z, W, W, W); -+ src_param_init_ssa_float4(&ins->src[2], ssa_temp); -+ ins->src[2].swizzle = VKD3D_SHADER_SWIZZLE(X, Y, Y, Y); -+ -+ return ins; -+} -+ -+static enum vkd3d_result vsir_program_lower_bem(struct vsir_program *program, struct vsir_program_iterator *it) -+{ -+ struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); -+ const struct vkd3d_shader_location location = ins->location; -+ const struct vkd3d_shader_src_param *src = ins->src; -+ const struct vkd3d_shader_dst_param *dst = ins->dst; -+ -+ /* bem DST.xy, SRC0, SRC1 -+ * -> -+ * mad srTMP.xy, SRC1.xx, BUMP_MATRIX#.xy, SRC0.xy -+ * mad DST.xy, SRC1.yy, BUMP_MATRIX#.zw, srTMP.xy */ -+ -+ if (!vsir_program_iterator_insert_after(it, 1)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ if (!(ins = generate_bump_coords(program, it, dst[0].reg.idx[0].offset, &src[0], &src[1], &location))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ ins->dst[0] = dst[0]; -+ return VKD3D_OK; -+} -+ -+static enum vkd3d_result vsir_program_lower_texbem(struct vsir_program *program, -+ struct vsir_program_iterator *it, struct vkd3d_shader_message_context *message_context) -+{ -+ struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); -+ const struct vkd3d_shader_location location = ins->location; -+ const struct vkd3d_shader_descriptor_info1 *descriptor; -+ const struct vkd3d_shader_src_param *src = ins->src; -+ bool is_texbeml = (ins->opcode == VSIR_OP_TEXBEML); -+ unsigned int idx = ins->dst[0].reg.idx[0].offset; -+ uint32_t ssa_coords, ssa_luminance, ssa_sample; -+ struct vkd3d_shader_src_param orig_coords; -+ -+ /* texbem t#, SRC -+ * -> -+ * bem srCOORDS.xy, t#, SRC -+ * texld t#, srCOORDS -+ * -> -+ * mad srTMP.xy, SRC.xx, BUMP_MATRIX#.xy, t#.xy -+ * mad srCOORDS.xy, SRC.yy, BUMP_MATRIX#.zw, srTMP.xy -+ * sample t#, srCOORDS, resource#, sampler# -+ * -+ * Luminance then adds: -+ * -+ * mad srLUM.x, SRC.z, BUMP_LUMINANCE_SCALE#, BUMP_LUMINANCE_OFFSET# -+ * mul t#, t#, srLUM.xxxx -+ * -+ * Note that the t# destination will subsequently be turned into a temp. */ -+ -+ descriptor = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); -+ if (descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) -+ { -+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ "Unhandled TEXBEM(L) with a comparison sampler."); -+ return VKD3D_ERROR_NOT_IMPLEMENTED; -+ } -+ -+ descriptor = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, idx); -+ if (descriptor->resource_type != VKD3D_SHADER_RESOURCE_TEXTURE_2D) -+ { -+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ "Unhandled TEXBEM(L) with resource dimension %#x.", descriptor->resource_type); -+ return VKD3D_ERROR_NOT_IMPLEMENTED; -+ } -+ -+ if (!vsir_program_iterator_insert_after(it, is_texbeml ? 4 : 2)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ vsir_src_param_init(&orig_coords, VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); -+ orig_coords.reg.idx[0].offset = idx; -+ orig_coords.reg.dimension = VSIR_DIMENSION_VEC4; -+ orig_coords.swizzle = VKD3D_SHADER_NO_SWIZZLE; -+ -+ if (!(ins = generate_bump_coords(program, it, idx, &orig_coords, &src[0], &location))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ ssa_coords = ins->dst[0].reg.idx[0].offset; -+ -+ ins = vsir_program_iterator_next(it); -+ if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_SAMPLE, 1, 3)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); -+ ins->dst[0].reg.idx[0].offset = idx; -+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; -+ src_param_init_ssa_float4(&ins->src[0], ssa_coords); -+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, Y, Y, Y); -+ vsir_src_param_init_resource(&ins->src[1], idx, idx); -+ vsir_src_param_init_sampler(&ins->src[2], idx, idx); -+ -+ if (is_texbeml) -+ { -+ enum vkd3d_shader_swizzle_component z = vsir_swizzle_get_component(src[0].swizzle, 2); -+ -+ ssa_sample = program->ssa_count++; -+ ssa_luminance = program->ssa_count++; -+ -+ /* Replace t# destination of the SAMPLE instruction with an SSA value. */ -+ dst_param_init_ssa_float4(&ins->dst[0], ssa_sample); -+ -+ ins = vsir_program_iterator_next(it); -+ if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_MAD, 1, 3)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ dst_param_init_ssa_float4(&ins->dst[0], ssa_luminance); -+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; -+ ins->src[0] = src[0]; -+ ins->src[0].swizzle = vkd3d_shader_create_swizzle(z, z, z, z); -+ src_param_init_parameter(&ins->src[1], -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0 + idx, VSIR_DATA_F32); -+ src_param_init_parameter(&ins->src[2], -+ VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0 + idx, VSIR_DATA_F32); -+ -+ ins = vsir_program_iterator_next(it); -+ if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_MUL, 1, 2)) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); -+ ins->dst[0].reg.idx[0].offset = idx; -+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; -+ src_param_init_ssa_float4(&ins->src[0], ssa_sample); -+ src_param_init_ssa_float4(&ins->src[1], ssa_luminance); -+ ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ } -+ 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) - { -@@ -2094,6 +2259,10 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr - - switch (ins->opcode) - { -+ case VSIR_OP_BEM: -+ ret = vsir_program_lower_bem(program, &it); -+ break; -+ - case VSIR_OP_IFC: - ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context); - break; -@@ -2102,6 +2271,11 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr - ret = vsir_program_lower_sm1_sincos(program, &it); - break; - -+ case VSIR_OP_TEXBEM: -+ case VSIR_OP_TEXBEML: -+ ret = vsir_program_lower_texbem(program, &it, message_context); -+ break; -+ - case VSIR_OP_TEXCOORD: - if ((ret = vsir_program_lower_texcoord(program, ins)) < 0) - return ret; -@@ -2136,8 +2310,6 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr - ret = vsir_program_lower_texldl(program, ins); - break; - -- case VSIR_OP_TEXBEM: -- case VSIR_OP_TEXBEML: - case VSIR_OP_TEXDEPTH: - case VSIR_OP_TEXDP3: - case VSIR_OP_TEXDP3TEX: -@@ -2281,6 +2453,8 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr - } - } - -+ program->has_no_modifiers = true; -+ - return ret; - } - -@@ -2445,13 +2619,16 @@ static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program * - struct vkd3d_shader_instruction *ins; - struct vkd3d_shader_location loc; - -+ /* Note we run before I/O normalization. */ -+ VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM4); -+ - if (!(ins = vsir_program_iterator_tail(&it))) - return VKD3D_OK; - loc = ins->location; - - if (!(ins = vsir_program_append(program))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1)) -+ if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_SATURATE, 1, 1)) - { - vsir_instruction_init(ins, &loc, VSIR_OP_NOP); - return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -2459,12 +2636,10 @@ static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program * - - 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; - } -@@ -8344,9 +8519,9 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * - * neg sr0, vFOG.x - * add sr1, FOG_END, sr0 -- * mul_sat srFACTOR, sr1, FOG_SCALE -+ * mul srFACTOR, sr1, FOG_SCALE - */ -- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6))) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - ssa_temp = program->ssa_count++; -@@ -8368,7 +8543,6 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); -- ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp2); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); - ins = vsir_program_iterator_next(it); -@@ -8380,9 +8554,9 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * - * mul sr0, FOG_SCALE, vFOG.x - * neg sr1, sr0 -- * exp_sat srFACTOR, sr1 -+ * exp srFACTOR, sr1 - */ -- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6))) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - ssa_temp = program->ssa_count++; -@@ -8404,7 +8578,6 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); -- ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp2); - ins = vsir_program_iterator_next(it); - break; -@@ -8415,9 +8588,9 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * mul sr0, FOG_SCALE, vFOG.x - * mul sr1, sr0, sr0 - * neg sr2, sr1 -- * exp_sat srFACTOR, sr2 -+ * exp srFACTOR, sr2 - */ -- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 8))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - ssa_temp = program->ssa_count++; -@@ -8446,7 +8619,6 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - - 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_temp3); - ins = vsir_program_iterator_next(it); - break; -@@ -8459,10 +8631,12 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * - * neg sr0, FOG_COLOUR - * add sr1, FRAG_COLOUR, sr0 -- * mad oC0, sr1, srFACTOR, FOG_COLOUR -+ * saturate sr2, srFACTOR -+ * mad oC0, sr1, sr2, FOG_COLOUR - */ - ssa_temp = program->ssa_count++; - ssa_temp2 = program->ssa_count++; -+ ssa_temp3 = program->ssa_count++; - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); - dst_param_init_ssa_float4(&ins->dst[0], ssa_temp); -@@ -8475,11 +8649,16 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - src_param_init_ssa_float4(&ins->src[1], ssa_temp); - ins = vsir_program_iterator_next(it); - -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_SATURATE, 1, 1); -+ dst_param_init_ssa_float(&ins->dst[0], ssa_temp3); -+ src_param_init_ssa_float(&ins->src[0], ssa_factor); -+ ins = vsir_program_iterator_next(it); -+ - 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], ssa_temp2); -- src_param_init_ssa_float(&ins->src[1], ssa_factor); -+ src_param_init_ssa_float(&ins->src[1], ssa_temp3); - src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); - ins = vsir_program_iterator_next(it); - -@@ -10869,7 +11048,7 @@ static void vsir_validate_dst_param(struct validation_context *ctx, - break; - } - -- if (dst->modifiers & ~VKD3DSPDM_MASK) -+ if (dst->modifiers & ~VKD3DSPDM_MASK || (ctx->program->has_no_modifiers && dst->modifiers)) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.", - dst->modifiers); - -@@ -11050,7 +11229,7 @@ static void vsir_validate_src_param(struct validation_context *ctx, - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, - "Immediate constant source has invalid swizzle %#x.", src->swizzle); - -- if (src->modifiers >= VKD3DSPSM_COUNT) -+ if (src->modifiers >= VKD3DSPSM_COUNT || (ctx->program->has_no_modifiers && src->modifiers)) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.", - src->modifiers); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index 3e7bf831e48..7b4804e8036 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -209,20 +209,20 @@ static bool msl_check_shader_visibility(const struct msl_generator *gen, - } - } - --static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const struct msl_generator *gen, -- unsigned int register_space, unsigned int register_idx) -+static bool msl_get_binding(const struct msl_generator *gen, unsigned int register_space, unsigned int register_idx, -+ enum vkd3d_shader_descriptor_type type, enum vkd3d_shader_binding_flag flags, unsigned int *idx) - { - const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; - unsigned int i; - - if (!interface_info) -- return NULL; -+ return false; - - for (i = 0; i < interface_info->binding_count; ++i) - { - const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; - -- if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) -+ if (binding->type != type) - continue; - if (binding->register_space != register_space) - continue; -@@ -230,111 +230,43 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const s - continue; - if (!msl_check_shader_visibility(gen, binding->shader_visibility)) - continue; -- if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) -+ if ((binding->flags & flags) != flags) - continue; - -- return &binding->binding; -+ *idx = binding->binding.binding; -+ return true; - } - -- return NULL; -+ return false; - } - --static const struct vkd3d_shader_descriptor_binding *msl_get_sampler_binding(const struct msl_generator *gen, -- unsigned int register_space, unsigned int register_idx) -+static bool msl_get_cbv_binding(const struct msl_generator *gen, -+ unsigned int register_space, unsigned int register_idx, unsigned int *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; -+ return msl_get_binding(gen, register_space, register_idx, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, VKD3D_SHADER_BINDING_FLAG_BUFFER, idx); - } - --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) -+static bool msl_get_sampler_binding(const struct msl_generator *gen, -+ unsigned int register_space, unsigned int register_idx, unsigned int *idx) - { -- const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; -- 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) -- { -- const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; -- -- if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV) -- 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; -+ return msl_get_binding(gen, register_space, register_idx, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, 0, idx); - } - --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) -+static bool msl_get_srv_binding(const struct msl_generator *gen, unsigned int register_space, -+ unsigned int register_idx, enum vkd3d_shader_resource_type resource_type, unsigned int *idx) - { -- 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 msl_get_binding(gen, register_space, register_idx, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_type == VKD3D_SHADER_RESOURCE_BUFFER -+ ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE, idx); -+} - -- return NULL; -+static bool msl_get_uav_binding(const struct msl_generator *gen, unsigned int register_space, -+ unsigned int register_idx, enum vkd3d_shader_resource_type resource_type, unsigned int *idx) -+{ -+ return msl_get_binding(gen, register_space, register_idx, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, resource_type == VKD3D_SHADER_RESOURCE_BUFFER -+ ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE, idx); - } - - static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding) -@@ -370,6 +302,9 @@ static void msl_print_uav_name(struct vkd3d_string_buffer *buffer, struct msl_ge - static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer, - struct msl_generator *gen, const struct vkd3d_shader_register *reg) - { -+ const struct vkd3d_shader_descriptor_info1 *descriptor; -+ unsigned int binding, cbv_id, cbv_idx; -+ - switch (reg->type) - { - case VKD3DSPR_TEMP: -@@ -441,38 +376,47 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu - } - - case VKD3DSPR_CONSTBUFFER: -+ if (reg->idx_count != 3) - { -- const struct vkd3d_shader_descriptor_binding *binding; -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled constant buffer register index count %u.", -+ reg->idx_count); -+ vkd3d_string_buffer_printf(buffer, "", reg->type); -+ return MSL_DATA_UNION; -+ } - -- if (reg->idx_count != 3) -- { -- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled constant buffer register index count %u.", -- reg->idx_count); -- vkd3d_string_buffer_printf(buffer, "", reg->type); -- return MSL_DATA_UNION; -- } -- 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, -- "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); -- msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); -+ 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; -+ } -+ -+ cbv_id = reg->idx[0].offset; -+ cbv_idx = reg->idx[1].offset; -+ -+ if (!(descriptor = vkd3d_shader_find_descriptor(&gen->program->descriptors, -+ VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cbv_id))) -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Undeclared CBV descriptor %u.", cbv_id); -+ vkd3d_string_buffer_printf(buffer, "", reg->type); - return MSL_DATA_UNION; - } - -+ if (!msl_get_cbv_binding(gen, descriptor->register_space, cbv_idx, &binding)) -+ { -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, -+ "No descriptor binding specified for CBV %u.", cbv_id); -+ vkd3d_string_buffer_printf(buffer, "", reg->type); -+ return MSL_DATA_UNION; -+ } -+ -+ msl_print_cbv_name(buffer, binding); -+ 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); -@@ -923,7 +867,6 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - unsigned int resource_id, resource_idx, resource_space, sample_count; - const struct msl_resource_type_info *resource_type_info; - 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; -@@ -985,11 +928,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - } - 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 -+ if (!msl_get_srv_binding(gen, resource_space, resource_idx, resource_type, &srv_binding)) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "No descriptor binding specified for SRV %u (index %u, space %u).", -@@ -1042,7 +981,6 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - 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; -@@ -1114,11 +1052,7 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - } - 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 -+ if (!msl_get_srv_binding(gen, resource_space, resource_idx, resource_type, &srv_binding)) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "No descriptor binding specified for SRV %u (index %u, space %u).", -@@ -1154,11 +1088,7 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - sampler_space = 0; - } - -- if ((binding = msl_get_sampler_binding(gen, sampler_space, sampler_idx))) -- { -- sampler_binding = binding->binding; -- } -- else -+ if (!msl_get_sampler_binding(gen, sampler_space, sampler_idx, &sampler_binding)) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "No descriptor binding specified for sampler %u (index %u, space %u).", -@@ -1256,7 +1186,6 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - 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; -@@ -1300,11 +1229,7 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - } - 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 -+ if (!msl_get_uav_binding(gen, uav_space, uav_idx, resource_type, &uav_binding)) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "No descriptor binding specified for UAV %u (index %u, space %u).", -@@ -2334,6 +2259,7 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, - - VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); - VKD3D_ASSERT(program->has_descriptor_info); -+ VKD3D_ASSERT(program->has_no_modifiers); - - if ((ret = msl_generator_init(&generator, program, compile_info, message_context)) < 0) - return ret; -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 0f5df228121..aae5f6b5534 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -4752,8 +4752,14 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - else if (reg->type == VKD3DSPR_UNDEF) - return spirv_compiler_emit_load_undef(compiler, reg, write_mask); - else if (reg->type == VKD3DSPR_PARAMETER) -- return spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset, -+ { -+ val_id = spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset, - reg->data_type, reg->dimension == VSIR_DIMENSION_VEC4 ? 4 : 1); -+ if (reg->dimension != VSIR_DIMENSION_VEC4) -+ return val_id; -+ return spirv_compiler_emit_swizzle(compiler, val_id, -+ VKD3DSP_WRITEMASK_ALL, reg->data_type, swizzle, write_mask); -+ } - - component_count = vsir_write_mask_component_count(write_mask); - -@@ -11060,6 +11066,7 @@ int spirv_compile(struct vsir_program *program, uint64_t config_flags, - - VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); - VKD3D_ASSERT(program->has_descriptor_info); -+ VKD3D_ASSERT(program->has_no_modifiers); - - if (!(spirv_compiler = spirv_compiler_create(program, compile_info, - message_context, config_flags))) -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 821c639ee16..c0faa30f14a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -1503,8 +1503,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - if (context->cf_info_count) - context->cf_info[context->cf_info_count - 1].inside_block = false; - break; -- case VSIR_OP_TEXBEM: -- case VSIR_OP_TEXBEML: - case VSIR_OP_TEXDP3TEX: - case VSIR_OP_TEXM3x2TEX: - case VSIR_OP_TEXM3x3SPEC: -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 346c74ff698..404e7cec6ea 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1610,6 +1610,7 @@ struct vsir_program - uint8_t diffuse_written_mask; - enum vsir_control_flow_type cf_type; - enum vsir_normalisation_level normalisation_level; -+ bool has_no_modifiers; - enum vkd3d_tessellator_domain tess_domain; - enum vkd3d_shader_tessellator_partitioning tess_partitioning; - enum vkd3d_shader_tessellator_output_primitive tess_output_primitive; --- -2.51.0 - diff --git a/patches/vkd3d-latest/0008-Updated-vkd3d-to-39391230d27d58f4e7e8786ba32a0ca133b.patch b/patches/vkd3d-latest/0008-Updated-vkd3d-to-39391230d27d58f4e7e8786ba32a0ca133b.patch deleted file mode 100644 index 6d9fef92..00000000 --- a/patches/vkd3d-latest/0008-Updated-vkd3d-to-39391230d27d58f4e7e8786ba32a0ca133b.patch +++ /dev/null @@ -1,743 +0,0 @@ -From 94dda6de862380f5d527ebd1690a3be3aac2fba8 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 30 Oct 2025 06:55:15 +1100 -Subject: [PATCH] Updated vkd3d to 39391230d27d58f4e7e8786ba32a0ca133b28fc0. - ---- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 264 ++++++++++++++------------- - libs/vkd3d/libs/vkd3d-shader/ir.c | 25 +++ - libs/vkd3d/libs/vkd3d-shader/msl.c | 61 +++---- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 65 +++---- - 4 files changed, 221 insertions(+), 194 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 7861efc16d2..8d803b91f7a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -647,13 +647,13 @@ enum sm6_value_type - { - VALUE_TYPE_INVALID, - VALUE_TYPE_FUNCTION, -- VALUE_TYPE_DATA, - VALUE_TYPE_HANDLE, - VALUE_TYPE_SSA, - VALUE_TYPE_ICB, - VALUE_TYPE_IDXTEMP, - VALUE_TYPE_GROUPSHAREDMEM, - VALUE_TYPE_CONSTANT, -+ VALUE_TYPE_CONSTANT_ARRAY, - VALUE_TYPE_UNDEFINED, - }; - -@@ -706,6 +706,12 @@ struct sm6_constant_data - union vsir_immediate_constant immconst; - }; - -+struct sm6_constant_array_data -+{ -+ const struct vkd3d_shader_immediate_constant_buffer *icb; -+ const uint64_t *elements; -+}; -+ - struct sm6_value - { - const struct sm6_type *type; -@@ -716,13 +722,13 @@ struct sm6_value - union - { - struct sm6_function_data function; -- const struct vkd3d_shader_immediate_constant_buffer *data; - struct sm6_handle_data handle; - struct sm6_ssa_data ssa; - struct sm6_icb_data icb; - struct sm6_idxtemp_data idxtemp; - struct sm6_groupsharedmem_data groupsharedmem; - struct sm6_constant_data constant; -+ struct sm6_constant_array_data constant_array; - } u; - }; - -@@ -2280,6 +2286,11 @@ static inline bool sm6_value_is_constant(const struct sm6_value *value) - return value->value_type == VALUE_TYPE_CONSTANT; - } - -+static bool sm6_value_is_constant_array(const struct sm6_value *value) -+{ -+ return value->value_type == VALUE_TYPE_CONSTANT_ARRAY; -+} -+ - static bool sm6_value_is_constant_zero(const struct sm6_value *value) - { - if (value->value_type != VALUE_TYPE_CONSTANT) -@@ -2323,11 +2334,6 @@ static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **value - return true; - } - --static bool sm6_value_is_data(const struct sm6_value *value) --{ -- return value->value_type == VALUE_TYPE_DATA; --} -- - static bool sm6_value_is_ssa(const struct sm6_value *value) - { - return value->value_type == VALUE_TYPE_SSA; -@@ -2662,7 +2668,7 @@ static void vsir_register_from_dxil_value(struct vkd3d_shader_register *reg, - - case VALUE_TYPE_FUNCTION: - case VALUE_TYPE_HANDLE: -- case VALUE_TYPE_DATA: -+ case VALUE_TYPE_CONSTANT_ARRAY: - vkd3d_unreachable(); - } - -@@ -3067,7 +3073,7 @@ static bool sm6_value_validate_is_i32(const struct sm6_value *value, struct sm6_ - return true; - } - --static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx) -+static struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx) - { - if (idx < sm6->value_count) - return &sm6->values[idx]; -@@ -3211,107 +3217,6 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) - return value << 63; - } - --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. */ -- if (elem_type->class != TYPE_CLASS_INTEGER && elem_type->class != TYPE_CLASS_FLOAT) -- { -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_NOT_IMPLEMENTED, -- "The element data type for an immediate constant buffer is not scalar integer or floating point."); -- return VKD3D_ERROR_INVALID_SHADER; -- } -- -- /* Arrays of bool are not used in DXIL. dxc will emit an array of int32 instead if necessary. */ -- if (!(size = elem_type->u.width / CHAR_BIT)) -- { -- WARN("Invalid data type width %u.\n", elem_type->u.width); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -- "An immediate constant buffer is declared with boolean elements."); -- return VKD3D_ERROR_INVALID_SHADER; -- } -- size = max(size, sizeof(icb->data[0])); -- count = operands ? type->u.array.count * size / sizeof(icb->data[0]) : 0; -- -- if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count])))) -- { -- ERR("Failed to allocate buffer, count %u.\n", count); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -- "Out of memory allocating an immediate constant buffer of count %u.", count); -- return VKD3D_ERROR_OUT_OF_MEMORY; -- } -- if (!vsir_program_add_icb(sm6->program, icb)) -- { -- ERR("Failed to store icb object.\n"); -- vkd3d_free(icb); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -- "Out of memory storing an immediate constant buffer object."); -- return VKD3D_ERROR_OUT_OF_MEMORY; -- } -- -- dst->value_type = VALUE_TYPE_DATA; -- dst->u.data = icb; -- -- icb->register_idx = sm6->icb_count++; -- icb->data_type = vsir_data_type_from_dxil(elem_type, 0, sm6); -- icb->element_count = type->u.array.count; -- icb->component_count = 1; -- icb->is_null = !operands; -- -- if (!operands) -- return VKD3D_OK; -- -- count = type->u.array.count; -- switch (icb->data_type) -- { -- 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_I16: -- for (i = 0; i < count; ++i) -- icb->data[i] = (int16_t)operands[i]; -- icb->data_type = VSIR_DATA_I32; -- 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_I32: -- case VSIR_DATA_U32: -- for (i = 0; i < count; ++i) -- icb->data[i] = operands[i]; -- break; -- -- case VSIR_DATA_F64: -- case VSIR_DATA_I64: -- 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) -@@ -3498,8 +3403,8 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const - case CST_CODE_NULL: - if (sm6_type_is_array(type)) - { -- if ((ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) -- return ret; -+ dst->value_type = VALUE_TYPE_CONSTANT_ARRAY; -+ dst->u.constant_array.elements = NULL; - } - else - { -@@ -3559,8 +3464,8 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const - if (!dxil_record_validate_operand_count(record, type->u.array.count, type->u.array.count, sm6)) - return VKD3D_ERROR_INVALID_SHADER; - -- if ((ret = value_allocate_constant_array(dst, type, record->operands, sm6)) < 0) -- return ret; -+ dst->value_type = VALUE_TYPE_CONSTANT_ARRAY; -+ dst->u.constant_array.elements = record->operands; - - break; - -@@ -3943,20 +3848,129 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ - static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_initialiser( - size_t index, struct sm6_parser *sm6) - { -- const struct sm6_value *value; -+ struct sm6_value *value; - - VKD3D_ASSERT(index); - --index; -- if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_data(value) && !sm6_value_is_undef(value))) -+ if (!(value = sm6_parser_get_value_safe(sm6, index)) -+ || (!sm6_value_is_constant_array(value) && !sm6_value_is_undef(value))) - { - WARN("Invalid initialiser index %zu.\n", index); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Global variable initialiser value index %zu is invalid.", index); - return NULL; - } -- else if (sm6_value_is_data(value)) -+ else if (sm6_value_is_constant_array(value)) - { -- return value->u.data; -+ const uint64_t *elements = value->u.constant_array.elements; -+ struct vkd3d_shader_immediate_constant_buffer *icb; -+ const struct sm6_array_info *array; -+ const struct sm6_type *elem_type; -+ unsigned int i, size, count; -+ uint64_t *data64; -+ -+ if (value->u.constant_array.icb) -+ return value->u.constant_array.icb; -+ -+ array = &value->type->u.array; -+ elem_type = array->elem_type; -+ /* Multidimensional arrays are emitted in flattened form. */ -+ if (elem_type->class != TYPE_CLASS_INTEGER && elem_type->class != TYPE_CLASS_FLOAT) -+ { -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_NOT_IMPLEMENTED, -+ "The element data type for an immediate constant buffer is not scalar integer or floating point."); -+ return NULL; -+ } -+ -+ /* Arrays of bool are not used in DXIL. dxc will emit an array of int32 instead if necessary. */ -+ if (!(size = elem_type->u.width / CHAR_BIT)) -+ { -+ WARN("Invalid data type width %u.\n", elem_type->u.width); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "An immediate constant buffer is declared with boolean elements."); -+ return NULL; -+ } -+ size = max(size, sizeof(icb->data[0])); -+ count = elements ? array->count * size / sizeof(icb->data[0]) : 0; -+ -+ if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count])))) -+ { -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -+ "Out of memory allocating an immediate constant buffer of count %u.", count); -+ return NULL; -+ } -+ -+ if (!vsir_program_add_icb(sm6->program, icb)) -+ { -+ vkd3d_free(icb); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -+ "Out of memory storing an immediate constant buffer object."); -+ return NULL; -+ } -+ -+ count = array->count; -+ icb->register_idx = sm6->icb_count++; -+ icb->data_type = vsir_data_type_from_dxil(elem_type, 0, sm6); -+ icb->element_count = count; -+ icb->component_count = 1; -+ icb->is_null = !elements; -+ value->u.constant_array.icb = icb; -+ -+ if (!elements) -+ return icb; -+ -+ switch (icb->data_type) -+ { -+ case VSIR_DATA_F16: -+ icb->data_type = VSIR_DATA_F32; -+ for (i = 0; i < count; ++i) -+ { -+ icb->data[i] = half_to_float(elements[i]); -+ } -+ break; -+ -+ case VSIR_DATA_I16: -+ icb->data_type = VSIR_DATA_I32; -+ for (i = 0; i < count; ++i) -+ { -+ icb->data[i] = (int16_t)elements[i]; -+ } -+ break; -+ -+ case VSIR_DATA_U16: -+ icb->data_type = VSIR_DATA_U32; -+ for (i = 0; i < count; ++i) -+ { -+ icb->data[i] = (int16_t)elements[i]; -+ } -+ break; -+ -+ case VSIR_DATA_F32: -+ case VSIR_DATA_I32: -+ case VSIR_DATA_U32: -+ for (i = 0; i < count; ++i) -+ { -+ icb->data[i] = elements[i]; -+ } -+ break; -+ -+ case VSIR_DATA_F64: -+ case VSIR_DATA_I64: -+ case VSIR_DATA_U64: -+ data64 = (uint64_t *)icb->data; -+ for (i = 0; i < count; ++i) -+ { -+ data64[i] = elements[i]; -+ } -+ break; -+ -+ default: -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Invalid array of type %u.", icb->data_type); -+ return NULL; -+ } -+ -+ return icb; - } - /* In VSIR, initialisation with undefined values of objects is implied, not explicit. */ - return NULL; -@@ -3970,15 +3984,16 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm - return false; - - --index; -- if (!(value = sm6_parser_get_value_safe(sm6, index)) -- || (!sm6_value_is_data(value) && !sm6_value_is_constant(value) && !sm6_value_is_undef(value))) -+ if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_constant_array(value) -+ && !sm6_value_is_constant(value) && !sm6_value_is_undef(value))) - { - WARN("Invalid initialiser index %zu.\n", index); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "TGSM initialiser value index %zu is invalid.", index); - return false; - } -- else if ((sm6_value_is_data(value) && value->u.data->is_null) || sm6_value_is_constant_zero(value)) -+ else if ((sm6_value_is_constant_array(value) && !value->u.constant_array.elements) -+ || sm6_value_is_constant_zero(value)) - { - return true; - } -@@ -6299,8 +6314,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr - return; - } - e = &signature->elements[row_index]; -- if (!e->sysval_semantic) -- column_index += vsir_write_mask_get_component_idx(e->mask); -+ column_index += vsir_write_mask_get_component_idx(e->mask); - - if (column_index >= VKD3D_VEC4_SIZE) - { -@@ -8911,8 +8925,8 @@ static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const - if (!(value = sm6_parser_get_value_safe(sm6, value_idx))) - return VKD3D_ERROR_INVALID_SHADER; - -- if (!sm6_value_is_constant(value) && !sm6_value_is_undef(value) && !sm6_value_is_data(value) -- && !sm6_value_is_function_dcl(value)) -+ if (!sm6_value_is_constant(value) && !sm6_value_is_undef(value) -+ && !sm6_value_is_constant_array(value) && !sm6_value_is_function_dcl(value)) - { - WARN("Value at index %u is not a constant or a function declaration.\n", value_idx); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA, -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index a566d65d8cd..5b1d0449a64 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -2477,6 +2477,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - case VSIR_OP_DCL: - case VSIR_OP_DCL_CONSTANT_BUFFER: - case VSIR_OP_DCL_GLOBAL_FLAGS: -+ case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: - case VSIR_OP_DCL_INPUT_PRIMITIVE: - case VSIR_OP_DCL_OUTPUT_TOPOLOGY: - case VSIR_OP_DCL_SAMPLER: -@@ -11011,10 +11012,34 @@ static void vsir_validate_io_dst_param(struct validation_context *ctx, - const struct vkd3d_shader_dst_param *dst) - { - struct vsir_io_register_data io_reg_data; -+ const struct signature_element *e; -+ unsigned int idx; - - if (!vsir_get_io_register_data(ctx, dst->reg.type, &io_reg_data) || !(io_reg_data.flags & OUTPUT_BIT)) -+ { - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, - "Invalid register type %#x used as destination parameter.", dst->reg.type); -+ return; -+ } -+ -+ if (ctx->program->normalisation_level >= VSIR_NORMALISED_SM6) -+ { -+ if (!dst->reg.idx_count) -+ { -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, -+ "Invalid index count %u for a register of type %#x.", -+ dst->reg.idx_count, dst->reg.type); -+ return; -+ } -+ -+ idx = dst->reg.idx[dst->reg.idx_count - 1].offset; -+ e = &io_reg_data.signature->elements[idx]; -+ -+ if (dst->write_mask & ~e->mask) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, -+ "Invalid destination write mask %#x for signature element with mask %#x.", -+ dst->write_mask, e->mask); -+ } - } - - static void vsir_validate_dst_param(struct validation_context *ctx, -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index 7b4804e8036..c974c9e532b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -209,8 +209,8 @@ static bool msl_check_shader_visibility(const struct msl_generator *gen, - } - } - --static bool msl_get_binding(const struct msl_generator *gen, unsigned int register_space, unsigned int register_idx, -- enum vkd3d_shader_descriptor_type type, enum vkd3d_shader_binding_flag flags, unsigned int *idx) -+static bool msl_get_binding(const struct msl_generator *gen, const struct vkd3d_shader_descriptor_info1 *descriptor, -+ unsigned int register_idx, enum vkd3d_shader_binding_flag flags, unsigned int *idx) - { - const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; - unsigned int i; -@@ -222,9 +222,9 @@ static bool msl_get_binding(const struct msl_generator *gen, unsigned int regist - { - const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; - -- if (binding->type != type) -+ if (binding->type != descriptor->type) - continue; -- if (binding->register_space != register_space) -+ if (binding->register_space != descriptor->register_space) - continue; - if (binding->register_index != register_idx) - continue; -@@ -241,31 +241,30 @@ static bool msl_get_binding(const struct msl_generator *gen, unsigned int regist - } - - static bool msl_get_cbv_binding(const struct msl_generator *gen, -- unsigned int register_space, unsigned int register_idx, unsigned int *idx) -+ const struct vkd3d_shader_descriptor_info1 *descriptor, unsigned int register_idx, unsigned int *idx) - { -- return msl_get_binding(gen, register_space, register_idx, -- VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, VKD3D_SHADER_BINDING_FLAG_BUFFER, idx); -+ return msl_get_binding(gen, descriptor, register_idx, VKD3D_SHADER_BINDING_FLAG_BUFFER, idx); - } - - static bool msl_get_sampler_binding(const struct msl_generator *gen, -- unsigned int register_space, unsigned int register_idx, unsigned int *idx) -+ const struct vkd3d_shader_descriptor_info1 *descriptor, unsigned int register_idx, unsigned int *idx) - { -- return msl_get_binding(gen, register_space, register_idx, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, 0, idx); -+ return msl_get_binding(gen, descriptor, register_idx, 0, idx); - } - --static bool msl_get_srv_binding(const struct msl_generator *gen, unsigned int register_space, -- unsigned int register_idx, enum vkd3d_shader_resource_type resource_type, unsigned int *idx) -+static bool msl_get_srv_binding(const struct msl_generator *gen, -+ const struct vkd3d_shader_descriptor_info1 *descriptor, unsigned int register_idx, unsigned int *idx) - { -- return msl_get_binding(gen, register_space, register_idx, -- VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_type == VKD3D_SHADER_RESOURCE_BUFFER -+ return msl_get_binding(gen, descriptor, register_idx, -+ descriptor->resource_type == VKD3D_SHADER_RESOURCE_BUFFER - ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE, idx); - } - --static bool msl_get_uav_binding(const struct msl_generator *gen, unsigned int register_space, -- unsigned int register_idx, enum vkd3d_shader_resource_type resource_type, unsigned int *idx) -+static bool msl_get_uav_binding(const struct msl_generator *gen, -+ const struct vkd3d_shader_descriptor_info1 *descriptor, unsigned int register_idx, unsigned int *idx) - { -- return msl_get_binding(gen, register_space, register_idx, -- VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, resource_type == VKD3D_SHADER_RESOURCE_BUFFER -+ return msl_get_binding(gen, descriptor, register_idx, -+ descriptor->resource_type == VKD3D_SHADER_RESOURCE_BUFFER - ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE, idx); - } - -@@ -405,7 +404,7 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu - return MSL_DATA_UNION; - } - -- if (!msl_get_cbv_binding(gen, descriptor->register_space, cbv_idx, &binding)) -+ if (!msl_get_cbv_binding(gen, descriptor, cbv_idx, &binding)) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "No descriptor binding specified for CBV %u.", cbv_id); -@@ -871,7 +870,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - uint32_t coord_mask, write_mask_size; - struct vkd3d_string_buffer *read; - enum vsir_data_type data_type; -- unsigned int srv_binding; -+ unsigned int srv_binding = 0; - struct msl_dst dst; - - if (vkd3d_shader_instruction_has_texel_offset(ins)) -@@ -928,13 +927,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - } - coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); - -- if (!msl_get_srv_binding(gen, resource_space, resource_idx, resource_type, &srv_binding)) -- { -+ if (descriptor && !msl_get_srv_binding(gen, descriptor, resource_idx, &srv_binding)) - 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; -- } - - msl_dst_init(&dst, gen, ins, &ins->dst[0]); - read = vkd3d_string_buffer_get(&gen->string_buffers); -@@ -982,9 +978,9 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - const struct vkd3d_shader_src_param *resource, *sampler; - unsigned int resource_id, resource_idx, resource_space; - unsigned int sampler_id, sampler_idx, sampler_space; -+ unsigned int srv_binding = 0, sampler_binding = 0; - 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; -@@ -1052,13 +1048,10 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - } - coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); - -- if (!msl_get_srv_binding(gen, resource_space, resource_idx, resource_type, &srv_binding)) -- { -+ if (d && !msl_get_srv_binding(gen, d, resource_idx, &srv_binding)) - 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; -@@ -1088,13 +1081,10 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst - sampler_space = 0; - } - -- if (!msl_get_sampler_binding(gen, sampler_space, sampler_idx, &sampler_binding)) -- { -+ if (d && !msl_get_sampler_binding(gen, d, sampler_idx, &sampler_binding)) - 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); -@@ -1191,7 +1181,7 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - unsigned int uav_id, uav_idx, uav_space; - struct vkd3d_string_buffer *image_data; - enum vsir_data_type data_type; -- unsigned int uav_binding; -+ unsigned int uav_binding = 0; - uint32_t coord_mask; - - if (ins->dst[0].reg.idx[0].rel_addr || ins->dst[0].reg.idx[1].rel_addr) -@@ -1229,13 +1219,10 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - } - coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); - -- if (!msl_get_uav_binding(gen, uav_space, uav_idx, resource_type, &uav_binding)) -- { -+ if (d && !msl_get_uav_binding(gen, d, uav_idx, &uav_binding)) - 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); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index aae5f6b5534..3950021a2ef 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -5813,7 +5813,7 @@ static void calculate_clip_or_cull_distance_mask(const struct signature_element - return; - } - -- write_mask = e->mask >> vsir_write_mask_get_component_idx(e->mask); -+ write_mask = e->mask; - *mask |= (write_mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); - } - -@@ -6060,7 +6060,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - if (use_private_variable) - { - compiler->private_output_variable[element_idx] = var_id; -- compiler->private_output_variable_write_mask[element_idx] |= write_mask >> component_idx; -+ compiler->private_output_variable_write_mask[element_idx] |= write_mask; - if (!compiler->epilogue_function_id) - compiler->epilogue_function_id = vkd3d_spirv_alloc_id(builder); - } -@@ -6112,9 +6112,6 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - use_mask |= element->used_mask; - } - } -- index = vsir_write_mask_get_component_idx(output->mask); -- dst_write_mask >>= index; -- use_mask >>= index; - write_mask &= dst_write_mask; - - if (!write_mask) -@@ -6701,30 +6698,6 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, - spirv_compiler_put_symbol(compiler, ®_symbol); - } - --static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) --{ -- const struct vkd3d_shader_immediate_constant_buffer *icb = instruction->declaration.icb; -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- uint32_t type_id, const_id, ptr_type_id, icb_id; -- struct vkd3d_shader_register reg; -- struct vkd3d_symbol reg_symbol; -- -- const_id = spirv_compiler_emit_constant_array(compiler, icb, &type_id); -- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); -- icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, -- ptr_type_id, SpvStorageClassPrivate, const_id); -- 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, 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, -- icb->data_type, vkd3d_write_mask_from_component_count(icb->component_count)); -- spirv_compiler_put_symbol(compiler, ®_symbol); --} -- - static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compiler, - const struct vkd3d_shader_register_range *range, const struct vkd3d_shader_descriptor_info1 *descriptor) - { -@@ -10436,9 +10409,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - case VSIR_OP_DCL_INDEXABLE_TEMP: - spirv_compiler_emit_dcl_indexable_temp(compiler, instruction); - break; -- case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: -- spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction); -- break; - case VSIR_OP_DCL_TGSM_RAW: - spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction); - break; -@@ -10885,6 +10855,36 @@ static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *c - } - } - -+static void spirv_compiler_emit_immediate_constant_buffers(struct spirv_compiler *compiler) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ const struct vkd3d_shader_immediate_constant_buffer *icb; -+ const struct vsir_program *program = compiler->program; -+ uint32_t type_id, const_id, ptr_type_id, icb_id; -+ struct vkd3d_shader_register reg; -+ struct vkd3d_symbol reg_symbol; -+ size_t i; -+ -+ for (i = 0; i < program->icb_count; ++i) -+ { -+ icb = program->icbs[i]; -+ -+ const_id = spirv_compiler_emit_constant_array(compiler, icb, &type_id); -+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); -+ icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, -+ ptr_type_id, SpvStorageClassPrivate, const_id); -+ vkd3d_spirv_build_op_name(builder, icb_id, "icb%zu", icb->register_idx); -+ -+ /* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */ -+ 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, -+ icb->data_type, vkd3d_write_mask_from_component_count(icb->component_count)); -+ spirv_compiler_put_symbol(compiler, ®_symbol); -+ } -+} -+ - static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv) - { -@@ -10918,6 +10918,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - spirv_compiler_emit_global_flags(compiler, program->global_flags); - - spirv_compiler_emit_descriptor_declarations(compiler); -+ spirv_compiler_emit_immediate_constant_buffers(compiler); - - compiler->spirv_parameter_info = vkd3d_calloc(program->parameter_count, sizeof(*compiler->spirv_parameter_info)); - for (i = 0; i < program->parameter_count; ++i) --- -2.51.0 -