From 35465516857e3ad7c058364b66d520f2651e4c7e Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 25 Feb 2025 12:01:15 +1100 Subject: [PATCH] Updated vkd3d-latest patchset --- ...-2feb3a3bbade41b8d7374e0ced625342b35.patch | 2 +- ...-e746a4c12ff1bb2e443a0b32e08778070b1.patch | 2232 +++++++++++++++++ 2 files changed, 2233 insertions(+), 1 deletion(-) create mode 100644 patches/vkd3d-latest/0002-Updated-vkd3d-to-e746a4c12ff1bb2e443a0b32e08778070b1.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-2feb3a3bbade41b8d7374e0ced625342b35.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-2feb3a3bbade41b8d7374e0ced625342b35.patch index 03bbf3e2..6a297aa5 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-2feb3a3bbade41b8d7374e0ced625342b35.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-2feb3a3bbade41b8d7374e0ced625342b35.patch @@ -1,4 +1,4 @@ -From aab38ae6e569226fcdc34cd048c9f0cc55031669 Mon Sep 17 00:00:00 2001 +From 05cf5fe0eb241db9e3c9a9ad0495e482ddafe178 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 21 Feb 2025 09:15:01 +1100 Subject: [PATCH] Updated vkd3d to 2feb3a3bbade41b8d7374e0ced625342b35cd50b. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-e746a4c12ff1bb2e443a0b32e08778070b1.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-e746a4c12ff1bb2e443a0b32e08778070b1.patch new file mode 100644 index 00000000..9d17c410 --- /dev/null +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-e746a4c12ff1bb2e443a0b32e08778070b1.patch @@ -0,0 +1,2232 @@ +From 77a6f575a77627f53458e9f5f88bf5e6bacd62c4 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Tue, 25 Feb 2025 11:54:17 +1100 +Subject: [PATCH] Updated vkd3d to e746a4c12ff1bb2e443a0b32e08778070b134cb2. + +--- + libs/vkd3d/include/private/vkd3d_common.h | 3 + + .../include/private/vkd3d_shader_utils.h | 4 - + libs/vkd3d/include/vkd3d_shader.h | 8 + + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 23 +- + libs/vkd3d/libs/vkd3d-shader/dxbc.c | 28 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 27 +- + libs/vkd3d/libs/vkd3d-shader/fx.c | 344 ++++++++++- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 50 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 12 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 98 +--- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 534 ++++-------------- + .../libs/vkd3d-shader/hlsl_constant_ops.c | 33 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 3 + + libs/vkd3d/libs/vkd3d-shader/spirv.c | 3 +- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 6 - + .../libs/vkd3d-shader/vkd3d_shader_private.h | 4 +- + libs/vkd3d/libs/vkd3d/device.c | 4 - + 17 files changed, 609 insertions(+), 575 deletions(-) + +diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h +index fd62730f948..93c8a0bec7c 100644 +--- a/libs/vkd3d/include/private/vkd3d_common.h ++++ b/libs/vkd3d/include/private/vkd3d_common.h +@@ -65,9 +65,12 @@ + #define vkd3d_clamp(value, lower, upper) max(min(value, upper), lower) + + #define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') ++#define TAG_CLI4 VKD3D_MAKE_TAG('C', 'L', 'I', '4') ++#define TAG_CTAB VKD3D_MAKE_TAG('C', 'T', 'A', 'B') + #define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C') + #define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') + #define TAG_FX10 VKD3D_MAKE_TAG('F', 'X', '1', '0') ++#define TAG_FXLC VKD3D_MAKE_TAG('F', 'X', 'L', 'C') + #define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1') + #define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N') + #define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1') +diff --git a/libs/vkd3d/include/private/vkd3d_shader_utils.h b/libs/vkd3d/include/private/vkd3d_shader_utils.h +index c9f8001e590..00052a89988 100644 +--- a/libs/vkd3d/include/private/vkd3d_shader_utils.h ++++ b/libs/vkd3d/include/private/vkd3d_shader_utils.h +@@ -43,16 +43,12 @@ static inline enum vkd3d_result vkd3d_shader_parse_dxbc_source_type(const struct + if (tag == TAG_SHDR || tag == TAG_SHEX) + { + *type = VKD3D_SHADER_SOURCE_DXBC_TPF; +-#ifndef VKD3D_SHADER_UNSUPPORTED_DXIL +- break; +-#else + } + else if (tag == TAG_DXIL) + { + *type = VKD3D_SHADER_SOURCE_DXBC_DXIL; + /* Default to DXIL if both are present. */ + break; +-#endif + } + } + +diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h +index 7a5d4eecbe5..7e51bdd5179 100644 +--- a/libs/vkd3d/include/vkd3d_shader.h ++++ b/libs/vkd3d/include/vkd3d_shader.h +@@ -2286,6 +2286,14 @@ enum vkd3d_shader_component_type + VKD3D_SHADER_COMPONENT_DOUBLE = 0x5, + /** 64-bit unsigned integer. \since 1.11 */ + VKD3D_SHADER_COMPONENT_UINT64 = 0x6, ++ /** 64-bit signed integer. \since 1.16 */ ++ VKD3D_SHADER_COMPONENT_INT64 = 0x7, ++ /** 16-bit IEEE floating-point. \since 1.16 */ ++ VKD3D_SHADER_COMPONENT_FLOAT16 = 0x8, ++ /** 16-bit unsigned integer. \since 1.16 */ ++ VKD3D_SHADER_COMPONENT_UINT16 = 0x9, ++ /** 16-bit signed integer. \since 1.16 */ ++ VKD3D_SHADER_COMPONENT_INT16 = 0xa, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE), + }; +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index 0639da83aa6..7b69535a445 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -2069,15 +2069,22 @@ static const char *get_component_type_name(enum vkd3d_shader_component_type type + { + switch (type) + { +- case VKD3D_SHADER_COMPONENT_VOID: return "void"; +- case VKD3D_SHADER_COMPONENT_UINT: return "uint"; +- case VKD3D_SHADER_COMPONENT_INT: return "int"; +- case VKD3D_SHADER_COMPONENT_FLOAT: return "float"; +- case VKD3D_SHADER_COMPONENT_BOOL: return "bool"; +- case VKD3D_SHADER_COMPONENT_DOUBLE: return "double"; +- case VKD3D_SHADER_COMPONENT_UINT64: return "uint64"; +- default: return "??"; ++ case VKD3D_SHADER_COMPONENT_VOID: return "void"; ++ case VKD3D_SHADER_COMPONENT_UINT: return "uint"; ++ case VKD3D_SHADER_COMPONENT_INT: return "int"; ++ case VKD3D_SHADER_COMPONENT_FLOAT: return "float"; ++ case VKD3D_SHADER_COMPONENT_BOOL: return "bool"; ++ case VKD3D_SHADER_COMPONENT_DOUBLE: return "double"; ++ case VKD3D_SHADER_COMPONENT_UINT64: return "uint64"; ++ case VKD3D_SHADER_COMPONENT_INT64: return "int64"; ++ case VKD3D_SHADER_COMPONENT_FLOAT16: return "float16"; ++ case VKD3D_SHADER_COMPONENT_UINT16: return "uint16"; ++ case VKD3D_SHADER_COMPONENT_INT16: return "int16"; ++ case VKD3D_SHADER_COMPONENT_TYPE_FORCE_32BIT: ++ break; + } ++ ++ return "??"; + } + + static const char *get_minimum_precision_name(enum vkd3d_shader_minimum_precision prec) +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c +index 270d607bc0e..9e3a57132a1 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c +@@ -381,7 +381,8 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s + uint32_t count, header_size; + struct signature_element *e; + const char *ptr = data; +- unsigned int i, j; ++ bool fail = false; ++ unsigned int i; + + if (!require_space(0, 2, sizeof(uint32_t), section->data.size)) + { +@@ -436,17 +437,19 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s + if (!(name = shader_get_string(data, section->data.size, name_offset)) + || !(e[i].semantic_name = vkd3d_strdup(name))) + { +- WARN("Invalid name offset %#zx (data size %#zx).\n", name_offset, section->data.size); +- for (j = 0; j < i; ++j) +- { +- vkd3d_free((void *)e[j].semantic_name); +- } +- vkd3d_free(e); +- return VKD3D_ERROR_INVALID_ARGUMENT; ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_STRING_REFERENCE, ++ "Element %u has invalid semantic name reference %#zx (data size %#zx).\n", ++ i, name_offset, section->data.size); ++ fail = true; + } + e[i].semantic_index = read_u32(&ptr); + e[i].sysval_semantic = read_u32(&ptr); +- e[i].component_type = read_u32(&ptr); ++ if ((e[i].component_type = read_u32(&ptr)) > VKD3D_SHADER_COMPONENT_FLOAT) ++ { ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_COMPONENT_TYPE, ++ "Element %u has invalid component type %#x.\n", i, e[i].component_type); ++ fail = true; ++ } + e[i].register_index = read_u32(&ptr); + e[i].target_location = e[i].register_index; + e[i].register_count = 1; +@@ -477,8 +480,15 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s + } + + s->elements = e; ++ s->elements_capacity = count; + s->element_count = count; + ++ if (fail) ++ { ++ shader_signature_cleanup(s); ++ return VKD3D_ERROR_INVALID_ARGUMENT; ++ } ++ + return VKD3D_OK; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index d13c2791fa6..29e714ee2ac 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -8578,19 +8578,29 @@ static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const + return VKD3D_OK; + } + +-static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component_type(enum dxil_component_type type) ++static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component_type( ++ enum dxil_component_type type, bool native_16bit) + { + switch (type) + { + case COMPONENT_TYPE_I1: + return VKD3D_SHADER_COMPONENT_BOOL; + case COMPONENT_TYPE_I16: ++ if (native_16bit) ++ return VKD3D_SHADER_COMPONENT_INT16; ++ return VKD3D_SHADER_COMPONENT_INT; + case COMPONENT_TYPE_I32: + return VKD3D_SHADER_COMPONENT_INT; + case COMPONENT_TYPE_U16: ++ if (native_16bit) ++ return VKD3D_SHADER_COMPONENT_UINT16; ++ return VKD3D_SHADER_COMPONENT_UINT; + case COMPONENT_TYPE_U32: + return VKD3D_SHADER_COMPONENT_UINT; + case COMPONENT_TYPE_F16: ++ if (native_16bit) ++ return VKD3D_SHADER_COMPONENT_FLOAT16; ++ return VKD3D_SHADER_COMPONENT_FLOAT; + case COMPONENT_TYPE_F32: + case COMPONENT_TYPE_SNORMF32: + case COMPONENT_TYPE_UNORMF32: +@@ -8605,8 +8615,12 @@ static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component + } + } + +-static enum vkd3d_shader_minimum_precision minimum_precision_from_dxil_component_type(enum dxil_component_type type) ++static enum vkd3d_shader_minimum_precision minimum_precision_from_dxil_component_type( ++ enum dxil_component_type type, bool native_16bit) + { ++ if (native_16bit) ++ return VKD3D_SHADER_MINIMUM_PRECISION_NONE; ++ + switch (type) + { + case COMPONENT_TYPE_F16: +@@ -9432,8 +9446,10 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const + { + unsigned int i, j, column_count, operand_count, index; + const struct sm6_metadata_node *node, *element_node; ++ struct vsir_program *program = sm6->p.program; + struct signature_element *elements, *e; + unsigned int values[10]; ++ bool native_16bit; + bool is_register; + + if (!m) +@@ -9458,6 +9474,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const + return VKD3D_ERROR_OUT_OF_MEMORY; + } + ++ native_16bit = program->global_flags & VKD3DSGF_FORCE_NATIVE_LOW_PRECISION; + for (i = 0; i < operand_count; ++i) + { + m = node->operands[i]; +@@ -9518,8 +9535,8 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const + } + e->semantic_name = element_node->operands[1]->u.string_value; + +- e->component_type = vkd3d_component_type_from_dxil_component_type(values[2]); +- e->min_precision = minimum_precision_from_dxil_component_type(values[2]); ++ e->component_type = vkd3d_component_type_from_dxil_component_type(values[2], native_16bit); ++ e->min_precision = minimum_precision_from_dxil_component_type(values[2], native_16bit); + + j = values[3]; + e->sysval_semantic = sysval_semantic_from_dxil_semantic_kind(j, tessellator_domain); +@@ -10683,8 +10700,6 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co + uint32_t *byte_code = NULL; + int ret; + +- MESSAGE("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n"); +- + dxbc_desc.is_dxil = true; + if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name, + &dxbc_desc)) < 0) +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index bd7e7b420db..45bb8d18df9 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -560,8 +560,21 @@ enum fx_4_type_constants + FX_4_ASSIGNMENT_VARIABLE = 0x2, + FX_4_ASSIGNMENT_ARRAY_CONSTANT_INDEX = 0x3, + FX_4_ASSIGNMENT_ARRAY_VARIABLE_INDEX = 0x4, ++ FX_4_ASSIGNMENT_INDEX_EXPRESSION = 0x5, ++ FX_4_ASSIGNMENT_VALUE_EXPRESSION = 0x6, + FX_4_ASSIGNMENT_INLINE_SHADER = 0x7, + FX_5_ASSIGNMENT_INLINE_SHADER = 0x8, ++ ++ /* FXLVM constants */ ++ FX_4_FXLC_COMP_COUNT_MASK = 0xffff, ++ FX_4_FXLC_OPCODE_MASK = 0x7ff, ++ FX_4_FXLC_OPCODE_SHIFT = 20, ++ FX_4_FXLC_IS_SCALAR_MASK = 0x80000000, ++ ++ FX_4_FXLC_REG_LITERAL = 1, ++ FX_4_FXLC_REG_CB = 2, ++ FX_4_FXLC_REG_OUTPUT = 4, ++ FX_4_FXLC_REG_TEMP = 7, + }; + + static const uint32_t fx_4_numeric_base_types[] = +@@ -2986,15 +2999,16 @@ static const void *fx_parser_get_unstructured_ptr(struct fx_parser *parser, uint + return &ptr[offset]; + } + +-static void fx_parser_read_unstructured(struct fx_parser *parser, void *dst, uint32_t offset, size_t size) ++static uint32_t fx_parser_read_unstructured(struct fx_parser *parser, void *dst, uint32_t offset, size_t size) + { + const uint8_t *ptr; + + memset(dst, 0, size); + if (!(ptr = fx_parser_get_unstructured_ptr(parser, offset, size))) +- return; ++ return offset; + + memcpy(dst, ptr, size); ++ return offset + size; + } + + static const char *fx_4_get_string(struct fx_parser *parser, uint32_t offset) +@@ -3053,7 +3067,7 @@ static void parse_fx_4_numeric_value(struct fx_parser *parser, uint32_t offset, + fx_parser_read_unstructured(parser, &value, offset, sizeof(uint32_t)); + + if (base_type == FX_4_NUMERIC_TYPE_FLOAT) +- vkd3d_string_buffer_printf(&parser->buffer, "%f", value.f); ++ vkd3d_string_buffer_print_f32(&parser->buffer, value.f); + else if (base_type == FX_4_NUMERIC_TYPE_INT) + vkd3d_string_buffer_printf(&parser->buffer, "%d", value.i); + else if (base_type == FX_4_NUMERIC_TYPE_UINT) +@@ -3240,6 +3254,13 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_15}, + }; + ++ if (!shader->offset) ++ { ++ parse_fx_print_indent(parser); ++ vkd3d_string_buffer_printf(&parser->buffer, "NULL"); ++ return; ++ } ++ + fx_parser_read_unstructured(parser, &data_size, shader->offset, sizeof(data_size)); + if (data_size) + data = fx_parser_get_unstructured_ptr(parser, shader->offset + 4, data_size); +@@ -3366,6 +3387,294 @@ static int fx_4_state_id_compare(const void *a, const void *b) + return id - state->id; + } + ++static const struct ++{ ++ uint32_t opcode; ++ const char *name; ++} ++fx_4_fxlc_opcodes[] = ++{ ++ { 0x100, "mov" }, ++ { 0x101, "neg" }, ++ { 0x103, "rcp" }, ++ { 0x104, "frc" }, ++ { 0x105, "exp" }, ++ { 0x106, "log" }, ++ { 0x107, "rsq" }, ++ { 0x108, "sin" }, ++ { 0x109, "cos" }, ++ { 0x10a, "asin" }, ++ { 0x10b, "acos" }, ++ { 0x10c, "atan" }, ++ { 0x112, "sqrt" }, ++ { 0x120, "ineg" }, ++ { 0x121, "not" }, ++ { 0x130, "itof" }, ++ { 0x131, "utof" }, ++ { 0x133, "ftou" }, ++ { 0x137, "ftob" }, ++ { 0x139, "floor" }, ++ { 0x13a, "ceil" }, ++ { 0x200, "min" }, ++ { 0x201, "max" }, ++ { 0x204, "add" }, ++ { 0x205, "mul" }, ++ { 0x206, "atan2" }, ++ { 0x208, "div" }, ++ { 0x210, "bilt" }, ++ { 0x211, "bige" }, ++ { 0x212, "bieq" }, ++ { 0x213, "bine" }, ++ { 0x214, "buge" }, ++ { 0x215, "bult" }, ++ { 0x216, "iadd" }, ++ { 0x219, "imul" }, ++ { 0x21a, "udiv" }, ++ { 0x21d, "imin" }, ++ { 0x21e, "imax" }, ++ { 0x21f, "umin" }, ++ { 0x220, "umax" }, ++ { 0x230, "and" }, ++ { 0x231, "or" }, ++ { 0x233, "xor" }, ++ { 0x234, "ishl" }, ++ { 0x235, "ishr" }, ++ { 0x236, "ushr" }, ++ { 0x301, "movc" }, ++ { 0x500, "dot" }, ++ { 0x70e, "d3ds_dotswiz" }, ++}; ++ ++static const char *fx_4_get_fxlc_opcode_name(uint32_t opcode) ++{ ++ size_t i; ++ ++ for (i = 0; i < ARRAY_SIZE(fx_4_fxlc_opcodes); ++i) ++ { ++ if (fx_4_fxlc_opcodes[i].opcode == opcode) ++ return fx_4_fxlc_opcodes[i].name; ++ } ++ ++ return ""; ++} ++ ++struct fx_4_fxlc_argument ++{ ++ uint32_t flags; ++ uint32_t reg_type; ++ uint32_t address; ++}; ++ ++struct fx_4_ctab_entry ++{ ++ uint32_t name; ++ uint16_t register_set; ++ uint16_t register_index; ++ uint16_t register_count; ++ uint16_t reserved; ++ uint32_t typeinfo; ++ uint32_t default_value; ++}; ++ ++struct fxlvm_code ++{ ++ const float *cli4; ++ uint32_t cli4_count; ++ ++ const struct fx_4_ctab_entry *constants; ++ uint32_t ctab_offset; ++ uint32_t ctab_count; ++ const char *ctab; ++ ++ unsigned int comp_count; ++ bool scalar; ++}; ++ ++static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr) ++{ ++ unsigned int comp_count = code->scalar ? 1 : code->comp_count; ++ static const char comp[] = "xyzw"; ++ ++ if (comp_count < 4) ++ vkd3d_string_buffer_printf(&parser->buffer, ".%.*s", comp_count, &comp[addr % 4]); ++} ++ ++static void fx_4_parse_fxlc_constant_argument(struct fx_parser *parser, ++ const struct fx_4_fxlc_argument *arg, const struct fxlvm_code *code) ++{ ++ uint32_t i, offset, register_index = arg->address / 4; /* Address counts in components. */ ++ ++ for (i = 0; i < code->ctab_count; ++i) ++ { ++ const struct fx_4_ctab_entry *c = &code->constants[i]; ++ ++ if (register_index < c->register_index || register_index - c->register_index >= c->register_count) ++ continue; ++ ++ vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); ++ ++ /* Register offset within variable */ ++ offset = arg->address - c->register_index * 4; ++ ++ if (offset / 4) ++ vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4); ++ fx_4_parse_print_swizzle(parser, code, offset); ++ return; ++ } ++ ++ vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)"); ++} ++ ++static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, const struct fxlvm_code *code) ++{ ++ struct fx_4_fxlc_argument arg; ++ uint32_t count; ++ ++ fx_parser_read_unstructured(parser, &arg, offset, sizeof(arg)); ++ ++ switch (arg.reg_type) ++ { ++ case FX_4_FXLC_REG_LITERAL: ++ count = code->scalar ? 1 : code->comp_count; ++ if (arg.address >= code->cli4_count || count > code->cli4_count - arg.address) ++ { ++ vkd3d_string_buffer_printf(&parser->buffer, "()"); ++ parser->failed = true; ++ break; ++ } ++ ++ vkd3d_string_buffer_printf(&parser->buffer, "("); ++ vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address]); ++ for (unsigned int i = 1; i < code->comp_count; ++i) ++ { ++ vkd3d_string_buffer_printf(&parser->buffer, ", "); ++ vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address + code->scalar ? 0 : i]); ++ } ++ vkd3d_string_buffer_printf(&parser->buffer, ")"); ++ break; ++ ++ case FX_4_FXLC_REG_CB: ++ fx_4_parse_fxlc_constant_argument(parser, &arg, code); ++ break; ++ ++ case FX_4_FXLC_REG_OUTPUT: ++ case FX_4_FXLC_REG_TEMP: ++ if (arg.reg_type == FX_4_FXLC_REG_OUTPUT) ++ vkd3d_string_buffer_printf(&parser->buffer, "expr"); ++ else ++ vkd3d_string_buffer_printf(&parser->buffer, "r%u", arg.address / 4); ++ fx_4_parse_print_swizzle(parser, code, arg.address); ++ break; ++ ++ default: ++ vkd3d_string_buffer_printf(&parser->buffer, "", arg.reg_type); ++ break; ++ } ++} ++ ++static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offset) ++{ ++ struct vkd3d_shader_dxbc_section_desc *section, fxlc, cli4, ctab; ++ struct vkd3d_shader_dxbc_desc dxbc_desc; ++ struct vkd3d_shader_code dxbc; ++ uint32_t size, ins_count; ++ struct fxlvm_code code; ++ size_t i, j; ++ ++ offset = fx_parser_read_unstructured(parser, &size, offset, sizeof(size)); ++ ++ dxbc.size = size; ++ dxbc.code = fx_parser_get_unstructured_ptr(parser, offset, size); ++ if (!dxbc.code) ++ return; ++ ++ if (vkd3d_shader_parse_dxbc(&dxbc, 0, &dxbc_desc, NULL) < 0) ++ { ++ parser->failed = true; ++ return; ++ } ++ ++ memset(&fxlc, 0, sizeof(fxlc)); ++ memset(&cli4, 0, sizeof(cli4)); ++ memset(&ctab, 0, sizeof(ctab)); ++ for (i = 0; i < dxbc_desc.section_count; ++i) ++ { ++ section = &dxbc_desc.sections[i]; ++ ++ if (section->tag == TAG_FXLC) ++ fxlc = *section; ++ else if (section->tag == TAG_CLI4) ++ cli4 = *section; ++ else if (section->tag == TAG_CTAB) ++ ctab = *section; ++ } ++ ++ vkd3d_shader_free_dxbc(&dxbc_desc); ++ ++ if (cli4.data.code) ++ { ++ uint32_t cli4_offset = offset + (size_t)cli4.data.code - (size_t)dxbc.code; ++ ++ fx_parser_read_unstructured(parser, &code.cli4_count, cli4_offset, sizeof(code.cli4_count)); ++ code.cli4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli4_count * sizeof(float)); ++ } ++ ++ if (ctab.data.code) ++ { ++ uint32_t ctab_offset = offset + (size_t)ctab.data.code - (size_t)dxbc.code; ++ uint32_t consts_offset; ++ ++ fx_parser_read_unstructured(parser, &code.ctab_count, ctab_offset + 12, sizeof(code.ctab_count)); ++ fx_parser_read_unstructured(parser, &consts_offset, ctab_offset + 16, sizeof(consts_offset)); ++ ++ code.ctab = ctab.data.code; ++ code.constants = fx_parser_get_unstructured_ptr(parser, ++ ctab_offset + consts_offset, code.ctab_count * sizeof(*code.constants)); ++ } ++ ++ offset += (size_t)fxlc.data.code - (size_t)dxbc.code; ++ offset = fx_parser_read_unstructured(parser, &ins_count, offset, sizeof(ins_count)); ++ ++ parse_fx_start_indent(parser); ++ ++ for (i = 0; i < ins_count; ++i) ++ { ++ uint32_t instr, opcode, src_count; ++ struct fx_4_fxlc_argument arg; ++ ++ offset = fx_parser_read_unstructured(parser, &instr, offset, sizeof(instr)); ++ offset = fx_parser_read_unstructured(parser, &src_count, offset, sizeof(src_count)); ++ ++ opcode = (instr >> FX_4_FXLC_OPCODE_SHIFT) & FX_4_FXLC_OPCODE_MASK; ++ code.comp_count = instr & FX_4_FXLC_COMP_COUNT_MASK; ++ code.scalar = false; ++ ++ parse_fx_print_indent(parser); ++ vkd3d_string_buffer_printf(&parser->buffer, "%s ", fx_4_get_fxlc_opcode_name(opcode)); ++ ++ /* Destination first. */ ++ fx_4_parse_fxlc_argument(parser, offset + sizeof(arg) * src_count, &code); ++ ++ for (j = 0; j < src_count; ++j) ++ { ++ vkd3d_string_buffer_printf(&parser->buffer, ", "); ++ ++ /* Scalar modifier applies only to first source. */ ++ code.scalar = j == 0 && !!(instr & FX_4_FXLC_IS_SCALAR_MASK); ++ fx_4_parse_fxlc_argument(parser, offset, &code); ++ ++ offset += sizeof(arg); ++ } ++ ++ /* Destination */ ++ offset += sizeof(arg); ++ ++ vkd3d_string_buffer_printf(&parser->buffer, "\n"); ++ } ++ ++ parse_fx_end_indent(parser); ++} ++ + static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32_t count, + enum hlsl_type_class type_class) + { +@@ -3496,6 +3805,19 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 + vkd3d_string_buffer_printf(&parser->buffer, "%s[%s]", fx_4_get_string(parser, index.name), + fx_4_get_string(parser, index.index)); + break; ++ case FX_4_ASSIGNMENT_INDEX_EXPRESSION: ++ fx_parser_read_unstructured(parser, &index, entry.value, sizeof(index)); ++ vkd3d_string_buffer_printf(&parser->buffer, "%s[eval(\n", fx_4_get_string(parser, index.name)); ++ fx_4_parse_fxlvm_expression(parser, index.index); ++ parse_fx_print_indent(parser); ++ vkd3d_string_buffer_printf(&parser->buffer, ")]"); ++ break; ++ case FX_4_ASSIGNMENT_VALUE_EXPRESSION: ++ vkd3d_string_buffer_printf(&parser->buffer, "eval(\n"); ++ fx_4_parse_fxlvm_expression(parser, entry.value); ++ parse_fx_print_indent(parser); ++ vkd3d_string_buffer_printf(&parser->buffer, ")"); ++ break; + case FX_4_ASSIGNMENT_INLINE_SHADER: + case FX_5_ASSIGNMENT_INLINE_SHADER: + { +@@ -3544,12 +3866,14 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct + }; + unsigned int i, element_count, count; + uint32_t value; ++ bool is_array; + + if (!fx_4_object_has_initializer(type)) + return; + + vkd3d_string_buffer_printf(&parser->buffer, " = {\n"); + element_count = max(type->element_count, 1); ++ is_array = element_count > 1; + for (i = 0; i < element_count; ++i) + { + switch (type->typeinfo) +@@ -3565,9 +3889,21 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct + case FX_4_OBJECT_TYPE_SAMPLER_STATE: + count = fx_parser_read_u32(parser); + ++ if (is_array) ++ { ++ parse_fx_start_indent(parser); ++ parse_fx_print_indent(parser); ++ vkd3d_string_buffer_printf(&parser->buffer, "{\n"); ++ } + parse_fx_start_indent(parser); + fx_4_parse_state_object_initializer(parser, count, type_classes[type->typeinfo]); + parse_fx_end_indent(parser); ++ if (is_array) ++ { ++ parse_fx_print_indent(parser); ++ vkd3d_string_buffer_printf(&parser->buffer, "}"); ++ parse_fx_end_indent(parser); ++ } + break; + case FX_4_OBJECT_TYPE_PIXEL_SHADER: + case FX_4_OBJECT_TYPE_VERTEX_SHADER: +@@ -3586,7 +3922,7 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct + "Parsing object type %u is not implemented.", type->typeinfo); + return; + } +- vkd3d_string_buffer_printf(&parser->buffer, ",\n"); ++ vkd3d_string_buffer_printf(&parser->buffer, is_array ? ",\n" : "\n"); + } + vkd3d_string_buffer_printf(&parser->buffer, "}"); + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index db216b5df30..b2f42f69492 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -1330,17 +1330,6 @@ static struct hlsl_ir_node *append_new_instr(struct hlsl_ctx *ctx, struct hlsl_b + return instr; + } + +-struct hlsl_ir_node *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type, +- const struct vkd3d_shader_location *loc) +-{ +- struct hlsl_ir_node *cast; +- +- cast = hlsl_new_unary_expr(ctx, HLSL_OP1_CAST, node, loc); +- if (cast) +- cast->data_type = type; +- return cast; +-} +- + struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node) + { + /* Use a cast to the same type as a makeshift identity expression. */ +@@ -1581,7 +1570,7 @@ struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const + return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &value, loc); + } + +-struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, ++static struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, + const struct vkd3d_shader_location *loc) + { + struct hlsl_constant_value value; +@@ -1590,6 +1579,12 @@ struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, + return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), &value, 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) ++{ ++ return append_new_instr(ctx, block, hlsl_new_float_constant(ctx, f, loc)); ++} ++ + static struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, + const struct vkd3d_shader_location *loc) + { +@@ -1660,7 +1655,7 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op + return &expr->node; + } + +-struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, ++static struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg}; +@@ -1668,6 +1663,12 @@ struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr + return hlsl_new_expr(ctx, op, operands, arg->data_type, loc); + } + ++struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) ++{ ++ return append_new_instr(ctx, block, hlsl_new_unary_expr(ctx, op, arg, loc)); ++} ++ + struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) + { +@@ -1676,6 +1677,12 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp + return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); + } + ++struct hlsl_ir_node *hlsl_block_add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) ++{ ++ return append_new_instr(ctx, block, hlsl_new_binary_expr(ctx, op, arg1, arg2)); ++} ++ + 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) + { +@@ -1684,6 +1691,23 @@ struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_ex + return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); + } + ++struct hlsl_ir_node *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type, ++ const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *cast; ++ ++ cast = hlsl_new_unary_expr(ctx, HLSL_OP1_CAST, node, loc); ++ if (cast) ++ cast->data_type = type; ++ return cast; ++} ++ ++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) ++{ ++ return append_new_instr(ctx, block, hlsl_new_cast(ctx, arg, type, loc)); ++} ++ + static struct hlsl_ir_node *hlsl_new_error_expr(struct hlsl_ctx *ctx) + { + static const struct vkd3d_shader_location loc = {.source_name = ""}; +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index 49e8b0460fb..8a2c2cfb488 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -1505,10 +1505,18 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc + void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl); + void hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl); + ++struct hlsl_ir_node *hlsl_block_add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ 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_float_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ float f, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_int_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + int32_t n, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_uint_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + unsigned int n, const struct vkd3d_shader_location *loc); ++struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc); + void hlsl_block_cleanup(struct hlsl_block *block); + bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block); + +@@ -1583,8 +1591,6 @@ struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *no + 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); +-struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, +- float f, const struct vkd3d_shader_location *loc); + 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); +@@ -1659,8 +1665,6 @@ struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *forma + struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, + const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc); +-struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, +- const struct vkd3d_shader_location *loc); + struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, + const struct vkd3d_shader_location *loc, const struct hlsl_semantic *semantic, uint32_t modifiers, + const struct hlsl_reg_reservation *reg_reservation); +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index cc09eecffad..889a7bcce39 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -351,7 +351,6 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl + struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) + { + struct hlsl_type *src_type = node->data_type; +- struct hlsl_ir_node *cast; + + if (hlsl_types_are_equal(src_type, dst_type)) + return node; +@@ -359,11 +358,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl + if (src_type->class == HLSL_CLASS_NULL) + return node; + +- if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) +- return NULL; +- hlsl_block_add_instr(block, cast); +- +- return cast; ++ return hlsl_block_add_cast(ctx, block, node, dst_type, loc); + } + + static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -474,9 +469,7 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co + if (!(cast = add_cast(ctx, cond_block, condition, bool_type, &condition->loc))) + return false; + +- if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, cast, &condition->loc))) +- return false; +- hlsl_block_add_instr(cond_block, not); ++ not = hlsl_block_add_unary_expr(ctx, cond_block, HLSL_OP1_LOGIC_NOT, cast, &condition->loc); + + hlsl_block_init(&then_block); + +@@ -942,7 +935,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str + struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) + { + const struct hlsl_type *expr_type = array->data_type, *index_type = index->data_type; +- struct hlsl_ir_node *return_index, *cast; ++ struct hlsl_ir_node *return_index; + + if (array->data_type->class == HLSL_CLASS_ERROR || index->data_type->class == HLSL_CLASS_ERROR) + { +@@ -983,10 +976,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str + return false; + } + +- if (!(cast = hlsl_new_cast(ctx, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc))) +- return false; +- hlsl_block_add_instr(block, cast); +- index = cast; ++ index = hlsl_block_add_cast(ctx, block, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc); + + if (expr_type->class != HLSL_CLASS_ARRAY && expr_type->class != HLSL_CLASS_VECTOR && expr_type->class != HLSL_CLASS_MATRIX) + { +@@ -3443,9 +3433,7 @@ static bool add_combine_components(struct hlsl_ctx *ctx, const struct parse_init + if (!(load = hlsl_add_load_component(ctx, params->instrs, arg, i, loc))) + return false; + +- if (!(res = hlsl_new_binary_expr(ctx, op, res, load))) +- return NULL; +- hlsl_block_add_instr(params->instrs, res); ++ res = hlsl_block_add_binary_expr(ctx, params->instrs, op, res, load); + } + + return true; +@@ -3793,9 +3781,7 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, + if (!(mul1 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl1, arg2_swzl1, loc))) + return false; + +- if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, mul1_neg); ++ mul1_neg = hlsl_block_add_unary_expr(ctx, params->instrs, HLSL_OP1_NEG, mul1, loc); + + if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc))) + return false; +@@ -3875,10 +3861,7 @@ static bool intrinsic_degrees(struct hlsl_ctx *ctx, + return false; + + /* 1 rad = 180/pi degree = 57.2957795 degree */ +- if (!(deg = hlsl_new_float_constant(ctx, 57.2957795f, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, deg); +- ++ deg = hlsl_block_add_float_constant(ctx, params->instrs, 57.2957795f, loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, deg, loc); + } + +@@ -4062,9 +4045,7 @@ static bool intrinsic_exp(struct hlsl_ctx *ctx, + return false; + + /* 1/ln(2) */ +- if (!(coeff = hlsl_new_float_constant(ctx, 1.442695f, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, coeff); ++ coeff = hlsl_block_add_float_constant(ctx, params->instrs, 1.442695f, loc); + + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, coeff, arg, loc))) + return false; +@@ -4303,21 +4284,6 @@ static bool intrinsic_lerp(struct hlsl_ctx *ctx, + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, params->args[0], mul, loc); + } + +-static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx, +- struct hlsl_block *instrs, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, +- const struct vkd3d_shader_location *loc) +-{ +- struct hlsl_ir_node *log, *mul; +- +- if (!(log = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_LOG2, arg1, loc))) +- return NULL; +- +- if (!(mul = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_MUL, arg2, log, loc))) +- return NULL; +- +- return add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_EXP2, mul, loc); +-} +- + static bool intrinsic_lit(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -4359,10 +4325,7 @@ static bool intrinsic_log(struct hlsl_ctx *ctx, + return false; + + /* ln(2) */ +- if (!(coeff = hlsl_new_float_constant(ctx, 0.69314718055f, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, coeff); +- ++ coeff = hlsl_block_add_float_constant(ctx, params->instrs, 0.69314718055f, loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, log, coeff, loc); + } + +@@ -4378,10 +4341,7 @@ static bool intrinsic_log10(struct hlsl_ctx *ctx, + return false; + + /* 1 / log2(10) */ +- if (!(coeff = hlsl_new_float_constant(ctx, 0.301029996f, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, coeff); +- ++ coeff = hlsl_block_add_float_constant(ctx, params->instrs, 0.301029996f, loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, log, coeff, loc); + } + +@@ -4586,10 +4546,18 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, + static bool intrinsic_pow(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { ++ struct hlsl_ir_node *log, *mul; ++ + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + +- return !!add_pow_expr(ctx, params->instrs, params->args[0], params->args[1], loc); ++ if (!(log = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, params->args[0], loc))) ++ return NULL; ++ ++ if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[1], log, loc))) ++ return NULL; ++ ++ return add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, mul, loc); + } + + static bool intrinsic_radians(struct hlsl_ctx *ctx, +@@ -4601,10 +4569,7 @@ static bool intrinsic_radians(struct hlsl_ctx *ctx, + return false; + + /* 1 degree = pi/180 rad = 0.0174532925f rad */ +- if (!(rad = hlsl_new_float_constant(ctx, 0.0174532925f, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, rad); +- ++ rad = hlsl_block_add_float_constant(ctx, params->instrs, 0.0174532925f, loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, rad, loc); + } + +@@ -5042,7 +5007,6 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * + if (dim == HLSL_SAMPLER_DIM_1D) + { + struct hlsl_ir_load *load; +- struct hlsl_ir_node *half; + struct hlsl_ir_var *var; + unsigned int idx = 0; + +@@ -5051,15 +5015,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * + + initialize_var_components(ctx, params->instrs, var, &idx, coords, false); + if (hlsl_version_ge(ctx, 4, 0)) +- { +- if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc))) +- return false; +- hlsl_block_add_instr(params->instrs, half); +- +- initialize_var_components(ctx, params->instrs, var, &idx, half, false); +- } +- else +- initialize_var_components(ctx, params->instrs, var, &idx, coords, false); ++ coords = hlsl_block_add_float_constant(ctx, params->instrs, 0.5f, loc); ++ initialize_var_components(ctx, params->instrs, var, &idx, coords, false); + + if (!(load = hlsl_new_var_load(ctx, var, loc))) + return false; +@@ -5252,9 +5209,7 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, + if (!(arg = intrinsic_float_convert_arg(ctx, params, arg, loc))) + return false; + +- if (!(c = hlsl_new_float_constant(ctx, 255.0f + (0.5f / 256.0f), loc))) +- return false; +- hlsl_block_add_instr(params->instrs, c); ++ c = hlsl_block_add_float_constant(ctx, params->instrs, 255.0f + (0.5f / 256.0f), loc); + + if (arg_type->class == HLSL_CLASS_VECTOR) + { +@@ -9365,12 +9320,9 @@ func_arguments: + primary_expr: + C_FLOAT + { +- struct hlsl_ir_node *c; +- +- if (!(c = hlsl_new_float_constant(ctx, $1, &@1))) +- YYABORT; +- if (!($$ = make_block(ctx, c))) ++ if (!($$ = make_empty_block(ctx))) + YYABORT; ++ hlsl_block_add_float_constant(ctx, $$, $1, &@1); + } + | C_INTEGER + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index d5e53c58618..dea6b740a7e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -64,10 +64,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str + + c = hlsl_block_add_uint_constant(ctx, block, size, loc); + +- if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, c, idx))) +- return NULL; +- hlsl_block_add_instr(block, idx_offset); +- ++ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); + break; + } + +@@ -93,12 +90,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str + } + + if (idx_offset) +- { +- if (!(base_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, base_offset, idx_offset))) +- return NULL; +- hlsl_block_add_instr(block, base_offset); +- } +- ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, base_offset, idx_offset); + return base_offset; + } + +@@ -125,16 +117,9 @@ static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, st + struct hlsl_block idx_block; + + hlsl_block_init(&idx_block); +- +- if (!(offset = new_offset_from_path_index(ctx, &idx_block, type, offset, deref->path[i].node, +- regset, offset_component, loc))) +- { +- hlsl_block_cleanup(&idx_block); +- return NULL; +- } +- ++ offset = new_offset_from_path_index(ctx, &idx_block, type, offset, ++ deref->path[i].node, regset, offset_component, loc); + hlsl_block_add_block(block, &idx_block); +- + type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); + } + +@@ -165,8 +150,7 @@ static bool replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der + + deref->data_type = type; + +- if (!(offset = new_offset_instr_from_deref(ctx, &block, deref, &offset_component, &instr->loc))) +- return false; ++ offset = new_offset_instr_from_deref(ctx, &block, deref, &offset_component, &instr->loc); + list_move_before(&instr->entry, &block.instrs); + + hlsl_cleanup_deref(deref); +@@ -456,9 +440,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + hlsl_block_add_instr(block, &load->node); + } + +- if (!(cast = hlsl_new_cast(ctx, &load->node, vector_type_dst, &var->loc))) +- return; +- hlsl_block_add_instr(block, cast); ++ cast = hlsl_block_add_cast(ctx, block, &load->node, vector_type_dst, &var->loc); + + if (type->class == HLSL_CLASS_MATRIX) + { +@@ -1051,9 +1033,7 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun + return false; + hlsl_block_add_instr(block, &load->node); + +- if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, &load->node, &cf_instr->loc))) +- return false; +- hlsl_block_add_instr(block, not); ++ not = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_LOGIC_NOT, &load->node, &cf_instr->loc); + + if (!(iff = hlsl_new_if(ctx, not, &then_block, NULL, &cf_instr->loc))) + return false; +@@ -1189,9 +1169,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + if (!(component_load = hlsl_add_load_component(ctx, block, arg, src_idx, &arg->loc))) + return false; + +- if (!(cast = hlsl_new_cast(ctx, component_load, dst_comp_type, &arg->loc))) +- return false; +- hlsl_block_add_instr(block, cast); ++ cast = hlsl_block_add_cast(ctx, block, component_load, dst_comp_type, &arg->loc); + + if (!hlsl_new_store_component(ctx, &store_block, &var_deref, dst_idx, cast)) + return false; +@@ -1370,9 +1348,7 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s + dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->e.numeric.type); + /* We need to preserve the cast since it might be doing more than just + * turning the scalar into a vector. */ +- if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_scalar_type, &cast->node.loc))) +- return false; +- hlsl_block_add_instr(block, new_cast); ++ 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) + { +@@ -2584,9 +2560,7 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + dst_vector_type = hlsl_get_vector_type(ctx, dst_type->e.numeric.type, src_type->e.numeric.dimx); + /* We need to preserve the cast since it might be doing more than just + * narrowing the vector. */ +- if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_vector_type, &cast->node.loc))) +- return false; +- hlsl_block_add_instr(block, new_cast); ++ new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc); + + if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), + dst_type->e.numeric.dimx, new_cast, &cast->node.loc))) +@@ -2832,9 +2806,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir + return false; + hlsl_block_add_instr(block, eq); + +- if (!(eq = hlsl_new_cast(ctx, eq, type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, eq); ++ eq = hlsl_block_add_cast(ctx, block, eq, type, &instr->loc); + + op = HLSL_OP2_DOT; + if (width == 1) +@@ -3321,13 +3293,8 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return false; + hlsl_block_add_instr(block, one); + +- if (!(fract = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, arg, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, fract); +- +- if (!(neg_fract = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, fract, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg_fract); ++ 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; +@@ -3337,41 +3304,19 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return false; + hlsl_block_add_instr(block, extra); + +- if (!(floor = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, neg_fract))) +- return false; +- hlsl_block_add_instr(block, floor); +- +- if (!(res = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, floor, extra))) +- return false; +- hlsl_block_add_instr(block, res); ++ 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); + } + else + { + struct hlsl_ir_node *neg_arg, *is_neg, *fract, *neg_fract, *has_fract, *floor; + +- if (!(neg_arg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg_arg); +- +- if (!(is_neg = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, arg, neg_arg))) +- return false; +- hlsl_block_add_instr(block, is_neg); +- +- if (!(fract = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, arg, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, fract); +- +- if (!(neg_fract = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, fract, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg_fract); +- +- if (!(has_fract = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, neg_fract, fract))) +- return false; +- hlsl_block_add_instr(block, has_fract); +- +- if (!(floor = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, neg_fract))) +- return false; +- hlsl_block_add_instr(block, floor); ++ neg_arg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); ++ is_neg = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, arg, neg_arg); ++ 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); ++ has_fract = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, neg_fract, fract); ++ 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; +@@ -3390,8 +3335,8 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + /* Lower DIV to RCP + MUL. */ + static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { +- struct hlsl_ir_node *rcp, *mul; + struct hlsl_ir_expr *expr; ++ struct hlsl_ir_node *rcp; + + if (instr->type != HLSL_IR_EXPR) + return false; +@@ -3399,22 +3344,16 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str + if (expr->op != HLSL_OP2_DIV) + return false; + +- if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, expr->operands[1].node, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, rcp); +- +- if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, expr->operands[0].node, rcp))) +- return false; +- hlsl_block_add_instr(block, mul); +- ++ rcp = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, expr->operands[1].node, &instr->loc); ++ hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, expr->operands[0].node, rcp); + return true; + } + + /* Lower SQRT to RSQ + RCP. */ + static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { +- struct hlsl_ir_node *rsq, *rcp; + struct hlsl_ir_expr *expr; ++ struct hlsl_ir_node *rsq; + + if (instr->type != HLSL_IR_EXPR) + return false; +@@ -3422,20 +3361,15 @@ static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + if (expr->op != HLSL_OP1_SQRT) + return false; + +- if (!(rsq = hlsl_new_unary_expr(ctx, HLSL_OP1_RSQ, expr->operands[0].node, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, rsq); +- +- if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, rsq, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, rcp); ++ 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; + } + + /* Lower DP2 to MUL + ADD */ + static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { +- struct hlsl_ir_node *arg1, *arg2, *mul, *replacement, *zero, *add_x, *add_y; ++ struct hlsl_ir_node *arg1, *arg2, *mul, *replacement, *add_x, *add_y; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +@@ -3452,22 +3386,17 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + { + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; + +- if (!(zero = hlsl_new_float_constant(ctx, 0.0f, &expr->node.loc))) +- return false; +- hlsl_block_add_instr(block, zero); +- + operands[0] = arg1; + operands[1] = arg2; +- operands[2] = zero; ++ operands[2] = hlsl_block_add_float_constant(ctx, block, 0.0f, &expr->node.loc); + + if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc))) + return false; ++ hlsl_block_add_instr(block, replacement); + } + else + { +- if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node))) +- return false; +- hlsl_block_add_instr(block, mul); ++ mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node); + + if (!(add_x = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), + instr->data_type->e.numeric.dimx, mul, &expr->node.loc))) +@@ -3479,10 +3408,8 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + return false; + hlsl_block_add_instr(block, add_y); + +- if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, add_x, add_y))) +- return false; ++ hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); + } +- hlsl_block_add_instr(block, replacement); + + return true; + } +@@ -3490,7 +3417,7 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + /* Lower ABS to MAX */ + static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { +- struct hlsl_ir_node *arg, *neg, *replacement; ++ struct hlsl_ir_node *arg, *neg; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +@@ -3500,21 +3427,15 @@ static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + if (expr->op != HLSL_OP1_ABS) + return false; + +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- +- if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_MAX, neg, arg))) +- return false; +- hlsl_block_add_instr(block, replacement); +- ++ 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; + } + + /* 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) + { +- struct hlsl_ir_node *arg, *neg, *sum, *frc, *half, *replacement; ++ struct hlsl_ir_node *arg, *neg, *sum, *frc, *half; + struct hlsl_type *type = instr->data_type; + struct hlsl_constant_value half_value; + unsigned int i, component_count; +@@ -3535,29 +3456,17 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + return false; + hlsl_block_add_instr(block, half); + +- if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, half))) +- return false; +- hlsl_block_add_instr(block, sum); +- +- if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, sum, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, frc); +- +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, frc, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- +- if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, sum, neg))) +- return false; +- hlsl_block_add_instr(block, replacement); +- ++ 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; + } + + /* Lower CEIL to FRC */ + static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { +- struct hlsl_ir_node *arg, *neg, *sum, *frc; ++ struct hlsl_ir_node *arg, *neg, *frc; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +@@ -3568,25 +3477,16 @@ static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + if (expr->op != HLSL_OP1_CEIL) + return false; + +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- +- if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, neg, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, frc); +- +- if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, frc, arg))) +- return false; +- hlsl_block_add_instr(block, sum); +- ++ 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; + } + + /* Lower FLOOR to FRC */ + static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { +- struct hlsl_ir_node *arg, *neg, *sum, *frc; ++ struct hlsl_ir_node *arg, *neg, *frc; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +@@ -3597,18 +3497,9 @@ static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + if (expr->op != HLSL_OP1_FLOOR) + return false; + +- if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, arg, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, frc); +- +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, frc, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- +- if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, neg, arg))) +- return false; +- hlsl_block_add_instr(block, sum); +- ++ 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; + } + +@@ -3660,18 +3551,14 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + if (!(mad = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, arg, reciprocal_two_pi, half))) + return false; + hlsl_block_add_instr(block, mad); +- if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, mad, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, frc); ++ 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; + hlsl_block_add_instr(block, reduced); + + if (type->e.numeric.dimx == 1) + { +- if (!(sincos = hlsl_new_unary_expr(ctx, op, reduced, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, sincos); ++ sincos = hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc); + } + else + { +@@ -3697,9 +3584,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct + { + struct hlsl_block store_block; + +- if (!(sincos = hlsl_new_unary_expr(ctx, op, comps[i], &instr->loc))) +- return false; +- hlsl_block_add_instr(block, sincos); ++ sincos = hlsl_block_add_unary_expr(ctx, block, op, comps[i], &instr->loc); + + if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, sincos)) + return false; +@@ -3734,13 +3619,9 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st + /* If this is happens, it means we failed to cast the argument to boolean somewhere. */ + VKD3D_ASSERT(arg->data_type->e.numeric.type == HLSL_TYPE_BOOL); + +- if (!(arg_cast = hlsl_new_cast(ctx, arg, float_type, &arg->loc))) +- return false; +- hlsl_block_add_instr(block, arg_cast); ++ arg_cast = hlsl_block_add_cast(ctx, block, arg, float_type, &arg->loc); + +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg_cast, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); ++ neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg_cast, &instr->loc); + + one_value.u[0].f = 1.0; + one_value.u[1].f = 1.0; +@@ -3750,9 +3631,7 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st + return false; + hlsl_block_add_instr(block, one); + +- if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, one, neg))) +- return false; +- hlsl_block_add_instr(block, sub); ++ sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg); + + memset(operands, 0, sizeof(operands)); + operands[0] = sub; +@@ -3792,14 +3671,8 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + + type = hlsl_get_numeric_type(ctx, instr->data_type->class, HLSL_TYPE_FLOAT, + instr->data_type->e.numeric.dimx, instr->data_type->e.numeric.dimy); +- +- if (!(float_cond = hlsl_new_cast(ctx, cond, type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, float_cond); +- +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, float_cond, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); ++ float_cond = hlsl_block_add_cast(ctx, block, cond, type, &instr->loc); ++ neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, float_cond, &instr->loc); + + memset(operands, 0, sizeof(operands)); + operands[0] = neg; +@@ -3877,13 +3750,8 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + arg2 = expr->operands[1].node; + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); + +- if (!(arg1_cast = hlsl_new_cast(ctx, arg1, float_type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, arg1_cast); +- +- if (!(arg2_cast = hlsl_new_cast(ctx, arg2, float_type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, arg2_cast); ++ arg1_cast = hlsl_block_add_cast(ctx, block, arg1, float_type, &instr->loc); ++ arg2_cast = hlsl_block_add_cast(ctx, block, arg2, float_type, &instr->loc); + + switch (expr->op) + { +@@ -3892,36 +3760,21 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + { + struct hlsl_ir_node *neg, *sub, *abs, *abs_neg; + +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2_cast, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- +- if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg1_cast, neg))) +- return false; +- hlsl_block_add_instr(block, sub); ++ neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg2_cast, &instr->loc); ++ sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg1_cast, neg); + + if (ctx->profile->major_version >= 3) + { +- if (!(abs = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, sub, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, abs); ++ abs = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, sub, &instr->loc); + } + else + { + /* Use MUL as a precarious ABS. */ +- if (!(abs = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, sub, sub))) +- return false; +- hlsl_block_add_instr(block, abs); ++ abs = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, sub, sub); + } + +- if (!(abs_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, abs, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, abs_neg); +- +- if (!(slt = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, abs_neg, abs))) +- return false; +- hlsl_block_add_instr(block, slt); +- ++ abs_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, abs, &instr->loc); ++ slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, abs_neg, abs); + negate = (expr->op == HLSL_OP2_EQUAL); + break; + } +@@ -3929,10 +3782,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + case HLSL_OP2_GEQUAL: + case HLSL_OP2_LESS: + { +- if (!(slt = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, arg1_cast, arg2_cast))) +- return false; +- hlsl_block_add_instr(block, slt); +- ++ slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, arg1_cast, arg2_cast); + negate = (expr->op == HLSL_OP2_GEQUAL); + break; + } +@@ -3954,13 +3804,8 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + return false; + hlsl_block_add_instr(block, one); + +- if (!(slt_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, slt, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, slt_neg); +- +- if (!(res = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, one, slt_neg))) +- return false; +- hlsl_block_add_instr(block, res); ++ 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); + } + else + { +@@ -4003,21 +3848,10 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + arg2 = expr->operands[1].node; + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); + +- if (!(arg1_cast = hlsl_new_cast(ctx, arg1, float_type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, arg1_cast); +- +- if (!(arg2_cast = hlsl_new_cast(ctx, arg2, float_type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, arg2_cast); +- +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2_cast, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- +- if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg1_cast, neg))) +- return false; +- hlsl_block_add_instr(block, sub); ++ arg1_cast = hlsl_block_add_cast(ctx, block, arg1, float_type, &instr->loc); ++ arg2_cast = hlsl_block_add_cast(ctx, block, arg2, float_type, &instr->loc); ++ neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg2_cast, &instr->loc); ++ 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))) +@@ -4049,7 +3883,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + */ + static bool 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, *add; ++ 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; + struct hlsl_type *float_type; + struct hlsl_ir_expr *expr; +@@ -4066,10 +3900,7 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + for (i = 0; i < 3; ++i) + { + args[i] = expr->operands[i].node; +- +- if (!(args_cast[i] = hlsl_new_cast(ctx, args[i], float_type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, args_cast[i]); ++ args_cast[i] = hlsl_block_add_cast(ctx, block, args[i], float_type, &instr->loc); + } + + memset(&zero_value, 0, sizeof(zero_value)); +@@ -4085,30 +3916,12 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h + return false; + hlsl_block_add_instr(block, one); + +- if (!(slt = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, args_cast[0], zero))) +- return false; +- hlsl_block_add_instr(block, slt); +- +- if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, args_cast[2], slt))) +- return false; +- hlsl_block_add_instr(block, mul1); +- +- if (!(neg_slt = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, slt, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg_slt); +- +- if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, one, neg_slt))) +- return false; +- hlsl_block_add_instr(block, sub); +- +- if (!(mul2 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, args_cast[1], sub))) +- return false; +- hlsl_block_add_instr(block, mul2); +- +- if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, mul1, mul2))) +- return false; +- hlsl_block_add_instr(block, add); +- ++ 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; + } + +@@ -4138,10 +3951,8 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return false; + hlsl_block_add_instr(block, zero); + +- if (!(neq = hlsl_new_binary_expr(ctx, HLSL_OP2_NEQUAL, expr->operands[0].node, zero))) +- return false; ++ neq = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_NEQUAL, expr->operands[0].node, zero); + neq->data_type = expr->node.data_type; +- hlsl_block_add_instr(block, neq); + + return true; + } +@@ -4159,10 +3970,7 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc + { + cond_type = hlsl_get_numeric_type(ctx, cond_type->class, HLSL_TYPE_BOOL, + cond_type->e.numeric.dimx, cond_type->e.numeric.dimy); +- +- if (!(condition = hlsl_new_cast(ctx, condition, cond_type, &condition->loc))) +- return NULL; +- hlsl_block_add_instr(instrs, condition); ++ condition = hlsl_block_add_cast(ctx, instrs, condition, cond_type, &condition->loc); + } + + operands[0] = condition; +@@ -4196,9 +4004,7 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return false; + utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); + +- if (!(xor = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_XOR, arg1, arg2))) +- return false; +- hlsl_block_add_instr(block, xor); ++ 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; +@@ -4206,38 +4012,14 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return false; + hlsl_block_add_instr(block, high_bit); + +- if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, high_bit))) +- return false; +- hlsl_block_add_instr(block, and); +- +- if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, abs1); +- +- if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, cast1); +- +- if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, abs2); +- +- if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, cast2); +- +- if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, cast1, cast2))) +- return false; +- hlsl_block_add_instr(block, div); +- +- if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, cast3); +- +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- ++ 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); ++ abs2 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg2, &instr->loc); ++ cast2 = hlsl_block_add_cast(ctx, block, abs2, utype, &instr->loc); ++ div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, cast1, cast2); ++ cast3 = hlsl_block_add_cast(ctx, block, div, type, &instr->loc); ++ neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, cast3, &instr->loc); + return hlsl_add_conditional(ctx, block, and, neg, cast3); + } + +@@ -4268,45 +4050,21 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return false; + hlsl_block_add_instr(block, high_bit); + +- if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, high_bit))) +- return false; +- hlsl_block_add_instr(block, and); +- +- if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, abs1); +- +- if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, cast1); +- +- if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, abs2); +- +- if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, cast2); +- +- if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_MOD, cast1, cast2))) +- return false; +- hlsl_block_add_instr(block, div); +- +- if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, cast3); +- +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- ++ 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); ++ abs2 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg2, &instr->loc); ++ cast2 = hlsl_block_add_cast(ctx, block, abs2, utype, &instr->loc); ++ div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MOD, cast1, cast2); ++ cast3 = hlsl_block_add_cast(ctx, block, div, type, &instr->loc); ++ neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, cast3, &instr->loc); + 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) + { + struct hlsl_type *type = instr->data_type; +- struct hlsl_ir_node *arg, *neg, *max; ++ struct hlsl_ir_node *arg, *neg; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) +@@ -4322,14 +4080,8 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + + arg = expr->operands[0].node; + +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg); +- +- if (!(max = hlsl_new_binary_expr(ctx, HLSL_OP2_MAX, arg, neg))) +- return false; +- hlsl_block_add_instr(block, max); +- ++ 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; + } + +@@ -4357,9 +4109,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + dimx = arg1->data_type->e.numeric.dimx; + is_bool = type->e.numeric.type == HLSL_TYPE_BOOL; + +- if (!(mult = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL, arg1, arg2))) +- return false; +- hlsl_block_add_instr(block, mult); ++ mult = hlsl_block_add_binary_expr(ctx, block, is_bool ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL, arg1, arg2); + + for (i = 0; i < dimx; ++i) + { +@@ -4372,11 +4122,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + + res = comps[0]; + for (i = 1; i < dimx; ++i) +- { +- if (!(res = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]))) +- return false; +- hlsl_block_add_instr(block, res); +- } ++ res = hlsl_block_add_binary_expr(ctx, block, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]); + + return true; + } +@@ -4386,7 +4132,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + + static bool 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, *mul3; ++ struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one; + struct hlsl_type *type = instr->data_type, *btype; + struct hlsl_constant_value one_value; + struct hlsl_ir_expr *expr; +@@ -4405,22 +4151,13 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return false; + btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); + +- if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, arg2, arg1))) +- return false; +- hlsl_block_add_instr(block, mul1); +- +- if (!(neg1 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg1); ++ mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, arg2, arg1); ++ neg1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul1, &instr->loc); + +- if (!(ge = hlsl_new_binary_expr(ctx, HLSL_OP2_GEQUAL, mul1, neg1))) +- return false; ++ ge = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_GEQUAL, mul1, neg1); + ge->data_type = btype; +- hlsl_block_add_instr(block, ge); + +- if (!(neg2 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, neg2); ++ neg2 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg2, &instr->loc); + + if (!(cond = hlsl_add_conditional(ctx, block, ge, arg2, neg2))) + return false; +@@ -4431,22 +4168,10 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return false; + hlsl_block_add_instr(block, one); + +- if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, one, cond))) +- return false; +- hlsl_block_add_instr(block, div); +- +- if (!(mul2 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, div, arg1))) +- return false; +- hlsl_block_add_instr(block, mul2); +- +- if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, mul2, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, frc); +- +- if (!(mul3 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, frc, cond))) +- return false; +- hlsl_block_add_instr(block, mul3); +- ++ 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; + } + +@@ -4473,7 +4198,7 @@ static bool lower_nonfloat_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + case HLSL_OP2_MUL: + { + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; +- struct hlsl_ir_node *arg, *arg_cast, *float_expr, *ret; ++ struct hlsl_ir_node *arg, *float_expr; + struct hlsl_type *float_type; + unsigned int i; + +@@ -4484,11 +4209,7 @@ static bool lower_nonfloat_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + continue; + + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->e.numeric.dimx); +- if (!(arg_cast = hlsl_new_cast(ctx, arg, float_type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, arg_cast); +- +- operands[i] = arg_cast; ++ operands[i] = hlsl_block_add_cast(ctx, block, arg, float_type, &instr->loc); + } + + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); +@@ -4496,10 +4217,7 @@ static bool lower_nonfloat_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + return false; + hlsl_block_add_instr(block, float_expr); + +- if (!(ret = hlsl_new_cast(ctx, float_expr, instr->data_type, &instr->loc))) +- return false; +- hlsl_block_add_instr(block, ret); +- ++ hlsl_block_add_cast(ctx, block, float_expr, instr->data_type, &instr->loc); + return true; + } + default: +@@ -4550,9 +4268,7 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + if (!(load = hlsl_add_load_component(ctx, &block, cmp, i, &instr->loc))) + return false; + +- if (!(or = hlsl_new_binary_expr(ctx, HLSL_OP2_LOGIC_OR, or, load))) +- return NULL; +- hlsl_block_add_instr(&block, or); ++ or = hlsl_block_add_binary_expr(ctx, &block, HLSL_OP2_LOGIC_OR, or, load); + } + + list_move_tail(&instr->entry, &block.instrs); +@@ -4581,17 +4297,9 @@ static bool lower_discard_nz(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v + + hlsl_block_init(&block); + +- if (!(cond_cast = hlsl_new_cast(ctx, cond, float_type, &instr->loc))) +- return false; +- hlsl_block_add_instr(&block, cond_cast); +- +- if (!(abs = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, cond_cast, &instr->loc))) +- return false; +- hlsl_block_add_instr(&block, abs); +- +- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, abs, &instr->loc))) +- return false; +- hlsl_block_add_instr(&block, neg); ++ cond_cast = hlsl_block_add_cast(ctx, &block, cond, float_type, &instr->loc); ++ abs = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_ABS, cond_cast, &instr->loc); ++ neg = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_NEG, abs, &instr->loc); + + list_move_tail(&instr->entry, &block.instrs); + hlsl_src_remove(&jump->condition); +@@ -11768,9 +11476,7 @@ static struct hlsl_ir_if *loop_unrolling_generate_var_check(struct hlsl_ctx *ctx + return NULL; + hlsl_block_add_instr(dst, &load->node); + +- if (!(cond = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, &load->node, loc))) +- return NULL; +- hlsl_block_add_instr(dst, cond); ++ cond = hlsl_block_add_unary_expr(ctx, dst, HLSL_OP1_LOGIC_NOT, &load->node, loc); + + if (!(iff = hlsl_new_if(ctx, cond, &then_block, NULL, loc))) + return NULL; +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +index 538f0f46854..09c7cf5771d 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +@@ -1593,9 +1593,9 @@ static struct hlsl_ir_node *collect_exprs(struct hlsl_ctx *ctx, struct hlsl_bloc + { + enum hlsl_base_type type = instr->data_type->e.numeric.type; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; +- struct hlsl_ir_node *ab, *res; + struct hlsl_ir_expr *e1, *e2; + enum hlsl_ir_expr_op opl; ++ struct hlsl_ir_node *res; + + if (!node1 || !node2 || node1->type != HLSL_IR_EXPR || node2->type != HLSL_IR_EXPR) + return NULL; +@@ -1610,13 +1610,8 @@ static struct hlsl_ir_node *collect_exprs(struct hlsl_ctx *ctx, struct hlsl_bloc + if (e1->operands[1].node->type != HLSL_IR_CONSTANT || e2->operands[1].node->type != HLSL_IR_CONSTANT) + return NULL; + +- if (!(ab = hlsl_new_binary_expr(ctx, opr, e1->operands[1].node, e2->operands[1].node))) +- return NULL; +- hlsl_block_add_instr(block, ab); +- + operands[0] = e1->operands[0].node; +- operands[1] = ab; +- ++ operands[1] = hlsl_block_add_binary_expr(ctx, block, opr, e1->operands[1].node, e2->operands[1].node); + if (!(res = hlsl_new_expr(ctx, opl, operands, instr->data_type, &instr->loc))) + return NULL; + hlsl_block_add_instr(block, res); +@@ -1677,26 +1672,14 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + if (arg2->type == HLSL_IR_CONSTANT) + { + /* (x OP a) OP b -> x OP (a OP b) */ +- struct hlsl_ir_node *ab; +- +- if (!(ab = hlsl_new_binary_expr(ctx, op, e1->operands[1].node, arg2))) +- goto fail; +- hlsl_block_add_instr(&block, ab); +- + arg1 = e1->operands[0].node; +- arg2 = ab; ++ arg2 = hlsl_block_add_binary_expr(ctx, &block, op, e1->operands[1].node, arg2); + progress = true; + } + else if (is_op_commutative(op)) + { + /* (x OP a) OP y -> (x OP y) OP a */ +- struct hlsl_ir_node *xy; +- +- if (!(xy = hlsl_new_binary_expr(ctx, op, e1->operands[0].node, arg2))) +- goto fail; +- hlsl_block_add_instr(&block, xy); +- +- arg1 = xy; ++ arg1 = hlsl_block_add_binary_expr(ctx, &block, op, e1->operands[0].node, arg2); + arg2 = e1->operands[1].node; + progress = true; + } +@@ -1706,13 +1689,7 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + && e2->operands[0].node->type != HLSL_IR_CONSTANT && e2->operands[1].node->type == HLSL_IR_CONSTANT) + { + /* x OP (y OP a) -> (x OP y) OP a */ +- struct hlsl_ir_node *xy; +- +- if (!(xy = hlsl_new_binary_expr(ctx, op, arg1, e2->operands[0].node))) +- goto fail; +- hlsl_block_add_instr(&block, xy); +- +- arg1 = xy; ++ arg1 = hlsl_block_add_binary_expr(ctx, &block, op, arg1, e2->operands[0].node); + arg2 = e2->operands[1].node; + progress = true; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index d145617ec36..41aa99fbc09 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -8520,10 +8520,13 @@ static void vsir_validate_signature_element(struct validation_context *ctx, + { + case VKD3D_SHADER_COMPONENT_INT: + case VKD3D_SHADER_COMPONENT_UINT: ++ case VKD3D_SHADER_COMPONENT_INT16: ++ case VKD3D_SHADER_COMPONENT_UINT16: + integer_type = true; + break; + + case VKD3D_SHADER_COMPONENT_FLOAT: ++ case VKD3D_SHADER_COMPONENT_FLOAT16: + break; + + default: +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index db7ebab742d..b65082e35a7 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -3375,7 +3375,8 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, + "Vectors of bool type are not supported."); + return vkd3d_spirv_get_op_undef(builder, type_id); + default: +- FIXME("Unhandled component_type %#x.\n", component_type); ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE, ++ "Unhandled component_type %#x.", component_type); + return vkd3d_spirv_get_op_undef(builder, type_id); + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index d3e4d9cea5a..c990b496545 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -1978,9 +1978,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns + VKD3D_SHADER_SOURCE_DXBC_TPF, + VKD3D_SHADER_SOURCE_HLSL, + VKD3D_SHADER_SOURCE_D3D_BYTECODE, +-#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL + VKD3D_SHADER_SOURCE_DXBC_DXIL, +-#endif + VKD3D_SHADER_SOURCE_FX, + }; + +@@ -2029,7 +2027,6 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( + VKD3D_SHADER_TARGET_D3D_ASM, + }; + +-#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL + static const enum vkd3d_shader_target_type dxbc_dxil_types[] = + { + VKD3D_SHADER_TARGET_SPIRV_BINARY, +@@ -2038,7 +2035,6 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( + # endif + VKD3D_SHADER_TARGET_D3D_ASM, + }; +-#endif + + static const enum vkd3d_shader_target_type fx_types[] = + { +@@ -2061,11 +2057,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( + *count = ARRAY_SIZE(d3dbc_types); + return d3dbc_types; + +-#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL + case VKD3D_SHADER_SOURCE_DXBC_DXIL: + *count = ARRAY_SIZE(dxbc_dxil_types); + return dxbc_dxil_types; +-#endif + + case VKD3D_SHADER_SOURCE_FX: + *count = ARRAY_SIZE(fx_types); +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 03643acff3c..aaa446d73ad 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -59,7 +59,7 @@ + #define VKD3D_VEC4_SIZE 4 + #define VKD3D_DVEC2_SIZE 2 + +-#define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_UINT64 + 1) ++#define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_INT16 + 1) + #define VKD3D_SHADER_MINIMUM_PRECISION_COUNT (VKD3D_SHADER_MINIMUM_PRECISION_UINT_16 + 1) + + #define VKD3D_MAX_STREAM_COUNT 4 +@@ -74,6 +74,8 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6, + VKD3D_SHADER_ERROR_DXBC_OUT_OF_MEMORY = 7, + VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE = 8, ++ VKD3D_SHADER_ERROR_DXBC_INVALID_STRING_REFERENCE = 9, ++ VKD3D_SHADER_ERROR_DXBC_INVALID_COMPONENT_TYPE = 10, + + VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000, + VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_RANGE = 1001, +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index 0575b492d64..67bc4493855 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -3610,11 +3610,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device9 + + TRACE("Request shader model %#x.\n", data->HighestShaderModel); + +-#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL + data->HighestShaderModel = min(data->HighestShaderModel, D3D_SHADER_MODEL_6_0); +-#else +- data->HighestShaderModel = min(data->HighestShaderModel, D3D_SHADER_MODEL_5_1); +-#endif + + TRACE("Shader model %#x.\n", data->HighestShaderModel); + return S_OK; +-- +2.47.2 +