From 4de57fff29a3b39c16bd3f378a3b1ad20b47ee66 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 13 Jun 2025 08:26:56 +1000 Subject: [PATCH] Updated vkd3d-latest patchset --- ...-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch | 2 +- ...-87ec2d98973432531d7d9d08dfc837376f9.patch | 2 +- ...-2b257caea94fce2a5ef58dd303de9d73563.patch | 2 +- ...-f1b36edc076117970b5a6d05a924b6c4248.patch | 2 +- ...-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch | 2 +- ...-8da518f2cd4021ef8d642bbb8050881d7ff.patch | 2 +- ...-14477b1066cfd4d12ce044f98fea09507f3.patch | 2 +- ...-a8ca1f95c50561a16de5769646dcda0c045.patch | 1006 +++++++++++++++++ 8 files changed, 1013 insertions(+), 7 deletions(-) create mode 100644 patches/vkd3d-latest/0008-Updated-vkd3d-to-a8ca1f95c50561a16de5769646dcda0c045.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch index df7a5792..d9e75091 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch @@ -1,4 +1,4 @@ -From 38ded2c6b1b3b587e3a23cd2190230e6acd86120 Mon Sep 17 00:00:00 2001 +From 352ffa600188ae9a71129323febe30d5905e794c Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 26 May 2025 07:03:34 +1000 Subject: [PATCH] Updated vkd3d to c4c7f10d99daa5d3efc036d74d5e09b6f1342407. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch index 809bf762..2a16621d 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch @@ -1,4 +1,4 @@ -From ba99d7169b0bea213655531ac66e714ca60a81f6 Mon Sep 17 00:00:00 2001 +From 96b79c613055cef6f2da2015081adf61bd88becd Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 28 May 2025 07:14:59 +1000 Subject: [PATCH] Updated vkd3d to 87ec2d98973432531d7d9d08dfc837376f91844c. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch index dc4d17fd..b1dac027 100644 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch @@ -1,4 +1,4 @@ -From 5b1f9a771641044d8cc5ed6ab8560f220ebd5b9e Mon Sep 17 00:00:00 2001 +From 1bb8646ffba747c1dd8fe298e6b9e98595d28198 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 3 Jun 2025 07:40:14 +1000 Subject: [PATCH] Updated vkd3d to 2b257caea94fce2a5ef58dd303de9d73563b9126. diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch index cb90e02f..953eb340 100644 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch @@ -1,4 +1,4 @@ -From 27ace4a398f2f56c420c3889f5874f17c6381790 Mon Sep 17 00:00:00 2001 +From e30c5257409bcdeb321524dc3459cb9e64165a91 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 5 Jun 2025 07:25:40 +1000 Subject: [PATCH] Updated vkd3d to f1b36edc076117970b5a6d05a924b6c4248e082f. diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch index 50ff8a80..310b7f9a 100644 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch @@ -1,4 +1,4 @@ -From 18df694d072cb411ab6187218cdc6d3e2c21d44b Mon Sep 17 00:00:00 2001 +From e26c2e6860b1d6d6fe8573d9b4654e4405407757 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 6 Jun 2025 07:10:30 +1000 Subject: [PATCH] Updated vkd3d to d65be3d0c5698a1b0df7c39ec0eaa485a8bd35de. diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-8da518f2cd4021ef8d642bbb8050881d7ff.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-8da518f2cd4021ef8d642bbb8050881d7ff.patch index e38d53ef..e9eb4522 100644 --- a/patches/vkd3d-latest/0006-Updated-vkd3d-to-8da518f2cd4021ef8d642bbb8050881d7ff.patch +++ b/patches/vkd3d-latest/0006-Updated-vkd3d-to-8da518f2cd4021ef8d642bbb8050881d7ff.patch @@ -1,4 +1,4 @@ -From 60ca99ec5f6b94c4128614cfdcae8cc4a0b9a9ee Mon Sep 17 00:00:00 2001 +From ec08bb5bfc8d67b975516a5a2dc34e9eaf7306ae Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 10 Jun 2025 07:48:09 +1000 Subject: [PATCH] Updated vkd3d to 8da518f2cd4021ef8d642bbb8050881d7ff490c1. diff --git a/patches/vkd3d-latest/0007-Updated-vkd3d-to-14477b1066cfd4d12ce044f98fea09507f3.patch b/patches/vkd3d-latest/0007-Updated-vkd3d-to-14477b1066cfd4d12ce044f98fea09507f3.patch index b6a3ebbb..e0e62a66 100644 --- a/patches/vkd3d-latest/0007-Updated-vkd3d-to-14477b1066cfd4d12ce044f98fea09507f3.patch +++ b/patches/vkd3d-latest/0007-Updated-vkd3d-to-14477b1066cfd4d12ce044f98fea09507f3.patch @@ -1,4 +1,4 @@ -From 36be363d5d83d8854499d09d523a19952e422e29 Mon Sep 17 00:00:00 2001 +From bc2380830ccf29787be590fd59ef4acae4bfd243 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 11 Jun 2025 07:52:20 +1000 Subject: [PATCH] Updated vkd3d to 14477b1066cfd4d12ce044f98fea09507f320251. diff --git a/patches/vkd3d-latest/0008-Updated-vkd3d-to-a8ca1f95c50561a16de5769646dcda0c045.patch b/patches/vkd3d-latest/0008-Updated-vkd3d-to-a8ca1f95c50561a16de5769646dcda0c045.patch new file mode 100644 index 00000000..aaf96e9a --- /dev/null +++ b/patches/vkd3d-latest/0008-Updated-vkd3d-to-a8ca1f95c50561a16de5769646dcda0c045.patch @@ -0,0 +1,1006 @@ +From 0806cca6d0c3d59da09a8b7a429165261710a047 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Fri, 13 Jun 2025 07:50:21 +1000 +Subject: [PATCH] Updated vkd3d to a8ca1f95c50561a16de5769646dcda0c045b7a46. + +--- + libs/vkd3d/include/private/vkd3d_common.h | 1 + + libs/vkd3d/include/private/vkd3d_version.h | 2 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 117 +++++++- + libs/vkd3d/libs/vkd3d-shader/fx.c | 328 +++++++++++++++------ + libs/vkd3d/libs/vkd3d-shader/ir.c | 40 +-- + libs/vkd3d/libs/vkd3d-shader/msl.c | 28 +- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 92 +----- + 7 files changed, 397 insertions(+), 211 deletions(-) + +diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h +index 93c8a0bec7c..0501e6a06c2 100644 +--- a/libs/vkd3d/include/private/vkd3d_common.h ++++ b/libs/vkd3d/include/private/vkd3d_common.h +@@ -66,6 +66,7 @@ + + #define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') + #define TAG_CLI4 VKD3D_MAKE_TAG('C', 'L', 'I', '4') ++#define TAG_CLIT VKD3D_MAKE_TAG('C', 'L', 'I', 'T') + #define TAG_CTAB VKD3D_MAKE_TAG('C', 'T', 'A', 'B') + #define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C') + #define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') +diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h +index ae34ff97e25..687751d6a5f 100644 +--- a/libs/vkd3d/include/private/vkd3d_version.h ++++ b/libs/vkd3d/include/private/vkd3d_version.h +@@ -1 +1 @@ +-#define VKD3D_VCS_ID " (git 379b297d)" ++#define VKD3D_VCS_ID " (git a8ca1f95)" +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 1cbef387260..53578ce7141 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -2499,6 +2499,79 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type + return VKD3D_DATA_UINT; + } + ++/* Based on the implementation in the OpenGL Mathematics library. */ ++static uint32_t half_to_float(uint16_t value) ++{ ++ uint32_t s = (value & 0x8000u) << 16; ++ uint32_t e = (value >> 10) & 0x1fu; ++ uint32_t m = value & 0x3ffu; ++ ++ if (!e) ++ { ++ if (!m) ++ { ++ /* Plus or minus zero */ ++ return s; ++ } ++ else ++ { ++ /* Denormalized number -- renormalize it */ ++ while (!(m & 0x400u)) ++ { ++ m <<= 1; ++ --e; ++ } ++ ++ ++e; ++ m &= ~0x400u; ++ } ++ } ++ else if (e == 31u) ++ { ++ /* Positive or negative infinity for zero 'm'. ++ * Nan for non-zero 'm' -- preserve sign and significand bits */ ++ return s | 0x7f800000u | (m << 13); ++ } ++ ++ /* Normalized number */ ++ e += 127u - 15u; ++ m <<= 13; ++ ++ /* Assemble s, e and m. */ ++ return s | (e << 23) | m; ++} ++ ++static void register_convert_to_minimum_precision(struct vkd3d_shader_register *reg) ++{ ++ unsigned int i; ++ ++ switch (reg->data_type) ++ { ++ case VKD3D_DATA_HALF: ++ reg->data_type = VKD3D_DATA_FLOAT; ++ reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16; ++ if (reg->type == VKD3DSPR_IMMCONST) ++ { ++ for (i = 0; i < VSIR_DIMENSION_VEC4; ++i) ++ reg->u.immconst_u32[i] = half_to_float(reg->u.immconst_u32[i]); ++ } ++ break; ++ ++ case VKD3D_DATA_UINT16: ++ reg->data_type = VKD3D_DATA_UINT; ++ reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16; ++ if (reg->type == VKD3DSPR_IMMCONST) ++ { ++ for (i = 0; i < VSIR_DIMENSION_VEC4; ++i) ++ reg->u.immconst_u32[i] = (int16_t)reg->u.immconst_u32[i]; ++ } ++ break; ++ ++ default: ++ break; ++ } ++} ++ + static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, + struct sm6_parser *sm6); + +@@ -2516,6 +2589,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + case VALUE_TYPE_SSA: + register_init_with_id(reg, VKD3DSPR_SSA, data_type, value->u.ssa.id); + reg->dimension = sm6_type_is_scalar(value->type) ? VSIR_DIMENSION_SCALAR : VSIR_DIMENSION_VEC4; ++ register_convert_to_minimum_precision(reg); + break; + + case VALUE_TYPE_ICB: +@@ -2523,6 +2597,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + reg->idx[0].offset = value->u.icb.id; + register_index_address_init(®->idx[1], value->u.icb.index.index, sm6); + reg->idx[1].is_in_bounds = value->u.icb.index.is_in_bounds; ++ register_convert_to_minimum_precision(reg); + break; + + case VALUE_TYPE_IDXTEMP: +@@ -2530,6 +2605,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + reg->idx[0].offset = value->u.idxtemp.id; + register_index_address_init(®->idx[1], value->u.idxtemp.index.index, sm6); + reg->idx[1].is_in_bounds = value->u.idxtemp.index.is_in_bounds; ++ register_convert_to_minimum_precision(reg); + break; + + case VALUE_TYPE_GROUPSHAREDMEM: +@@ -2543,6 +2619,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + vsir_register_init(reg, scalar_type->u.width == 64 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST, + data_type, 0); + reg->u = value->u.constant.immconst; ++ register_convert_to_minimum_precision(reg); + break; + + case VALUE_TYPE_UNDEFINED: +@@ -3105,6 +3182,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co + 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. */ +@@ -3156,16 +3234,37 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co + return VKD3D_OK; + + count = type->u.array.count; +- if (size > sizeof(icb->data[0])) +- { +- uint64_t *data = (uint64_t *)icb->data; +- for (i = 0; i < count; ++i) +- data[i] = operands[i]; +- } +- else ++ switch (icb->data_type) + { +- for (i = 0; i < count; ++i) +- icb->data[i] = operands[i]; ++ case VKD3D_DATA_HALF: ++ for (i = 0; i < count; ++i) ++ icb->data[i] = half_to_float(operands[i]); ++ icb->data_type = VKD3D_DATA_FLOAT; ++ break; ++ ++ case VKD3D_DATA_UINT16: ++ for (i = 0; i < count; ++i) ++ icb->data[i] = (int16_t)operands[i]; ++ icb->data_type = VKD3D_DATA_UINT; ++ break; ++ ++ case VKD3D_DATA_FLOAT: ++ case VKD3D_DATA_UINT: ++ for (i = 0; i < count; ++i) ++ icb->data[i] = operands[i]; ++ break; ++ ++ case VKD3D_DATA_DOUBLE: ++ case VKD3D_DATA_UINT64: ++ 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; +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index 9efaa0bc1fa..f7b2e3d7d13 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -54,6 +54,19 @@ enum state_property_component_type + FX_COMPONENT_TYPE_COUNT, + }; + ++enum fxlvm_constants ++{ ++ FX_FXLC_COMP_COUNT_MASK = 0xffff, ++ FX_FXLC_OPCODE_MASK = 0x7ff, ++ FX_FXLC_OPCODE_SHIFT = 20, ++ FX_FXLC_IS_SCALAR_MASK = 0x80000000, ++ ++ FX_FXLC_REG_LITERAL = 1, ++ FX_FXLC_REG_CB = 2, ++ FX_FXLC_REG_OUTPUT = 4, ++ FX_FXLC_REG_TEMP = 7, ++}; ++ + struct rhs_named_value + { + const char *name; +@@ -1079,17 +1092,6 @@ enum fx_4_type_constants + FX_4_ASSIGNMENT_VALUE_EXPRESSION = 0x6, + FX_4_ASSIGNMENT_INLINE_SHADER = 0x7, + FX_5_ASSIGNMENT_INLINE_SHADER = 0x8, +- +- /* FXLVM constants */ +- FX_4_FXLC_COMP_COUNT_MASK = 0xffff, +- FX_4_FXLC_OPCODE_MASK = 0x7ff, +- FX_4_FXLC_OPCODE_SHIFT = 20, +- FX_4_FXLC_IS_SCALAR_MASK = 0x80000000, +- +- FX_4_FXLC_REG_LITERAL = 1, +- FX_4_FXLC_REG_CB = 2, +- FX_4_FXLC_REG_OUTPUT = 4, +- FX_4_FXLC_REG_TEMP = 7, + }; + + static const uint32_t fx_4_numeric_base_types[] = +@@ -4268,6 +4270,8 @@ static void fx_dump_blob(struct fx_parser *parser, const void *blob, uint32_t si + } + } + ++static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size); ++ + static void fx_parse_fx_2_array_selector(struct fx_parser *parser) + { + uint32_t size, blob_size = 0; +@@ -4295,7 +4299,7 @@ static void fx_parse_fx_2_array_selector(struct fx_parser *parser) + { + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "selector blob size %u\n", blob_size); +- fx_dump_blob(parser, blob, blob_size); ++ fx_2_parse_fxlvm_expression(parser, blob, blob_size); + } + } + +@@ -4718,7 +4722,7 @@ static const struct + uint32_t opcode; + const char *name; + } +-fx_4_fxlc_opcodes[] = ++fxlc_opcodes[] = + { + { 0x100, "mov" }, + { 0x101, "neg" }, +@@ -4773,14 +4777,14 @@ fx_4_fxlc_opcodes[] = + { 0x70e, "d3ds_dotswiz" }, + }; + +-static const char *fx_4_get_fxlc_opcode_name(uint32_t opcode) ++static const char *get_fxlc_opcode_name(uint32_t opcode) + { + size_t i; + +- for (i = 0; i < ARRAY_SIZE(fx_4_fxlc_opcodes); ++i) ++ for (i = 0; i < ARRAY_SIZE(fxlc_opcodes); ++i) + { +- if (fx_4_fxlc_opcodes[i].opcode == opcode) +- return fx_4_fxlc_opcodes[i].name; ++ if (fxlc_opcodes[i].opcode == opcode) ++ return fxlc_opcodes[i].name; + } + + return ""; +@@ -4804,10 +4808,29 @@ struct fx_4_ctab_entry + uint32_t default_value; + }; + ++struct fxlc_arg ++{ ++ uint32_t reg_type; ++ uint32_t address; ++ bool indexed; ++ struct ++ { ++ uint32_t reg_type; ++ uint32_t address; ++ } index; ++}; ++ + struct fxlvm_code + { +- const float *cli4; +- uint32_t cli4_count; ++ const uint32_t *ptr, *end; ++ bool failed; ++ ++ union ++ { ++ const float *_4; ++ const double *_8; ++ } cli; ++ uint32_t cli_count; + + const struct fx_4_ctab_entry *constants; + uint32_t ctab_offset; +@@ -4818,7 +4841,45 @@ struct fxlvm_code + bool scalar; + }; + +-static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr) ++static uint32_t fxlvm_read_u32(struct fxlvm_code *code) ++{ ++ if (code->end == code->ptr) ++ { ++ code->failed = true; ++ return 0; ++ } ++ ++ return *code->ptr++; ++} ++ ++static const uint32_t *find_d3dbc_section(const uint32_t *ptr, uint32_t count, uint32_t tag, uint32_t *size) ++{ ++ if (!count) ++ return NULL; ++ ++ /* Skip version tag */ ++ ptr++; ++ count--; ++ ++ while (count > 2 && (*ptr & 0xffff) == 0xfffe) ++ { ++ unsigned int section_size; ++ ++ section_size = (*ptr >> 16); ++ if (!section_size || section_size + 1 > count) ++ break; ++ if (*(ptr + 1) == tag) ++ { ++ *size = section_size; ++ return ptr + 2; ++ } ++ count -= section_size + 1; ++ ptr += section_size + 1; ++ } ++ return NULL; ++} ++ ++static void fx_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr) + { + unsigned int comp_count = code->scalar ? 1 : code->comp_count; + static const char comp[] = "xyzw"; +@@ -4827,44 +4888,76 @@ static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlv + vkd3d_string_buffer_printf(&parser->buffer, ".%.*s", comp_count, &comp[addr % 4]); + } + +-static void fx_4_parse_fxlc_constant_argument(struct fx_parser *parser, +- const struct fx_4_fxlc_argument *arg, const struct fxlvm_code *code) ++static void fx_parse_fxlc_constant_argument(struct fx_parser *parser, ++ const struct fxlc_arg *arg, const struct fxlvm_code *code) + { +- uint32_t i, offset, register_index = arg->address / 4; /* Address counts in components. */ ++ uint32_t register_index = arg->address / 4; /* Address counts in components. */ + +- for (i = 0; i < code->ctab_count; ++i) ++ if (code->ctab_count) + { +- const struct fx_4_ctab_entry *c = &code->constants[i]; ++ uint32_t i, offset; + +- if (register_index < c->register_index || register_index - c->register_index >= c->register_count) +- continue; ++ for (i = 0; i < code->ctab_count; ++i) ++ { ++ const struct fx_4_ctab_entry *c = &code->constants[i]; + +- vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); ++ if (register_index < c->register_index || register_index - c->register_index >= c->register_count) ++ continue; + +- /* Register offset within variable */ +- offset = arg->address - c->register_index * 4; ++ vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); + +- if (offset / 4) +- vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4); +- fx_4_parse_print_swizzle(parser, code, offset); +- return; ++ /* Register offset within variable */ ++ offset = arg->address - c->register_index * 4; ++ ++ if (offset / 4) ++ vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4); ++ fx_parse_print_swizzle(parser, code, offset); ++ return; ++ } ++ ++ vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)"); ++ } ++ else ++ { ++ vkd3d_string_buffer_printf(&parser->buffer, "c%u", register_index); ++ fx_parse_print_swizzle(parser, code, arg->address); ++ } ++} ++ ++static void fx_parse_fxlc_argument(struct fx_parser *parser, struct fxlc_arg *arg, struct fxlvm_code *code) ++{ ++ uint32_t flags; ++ ++ memset(arg, 0, sizeof(*arg)); ++ ++ flags = fxlvm_read_u32(code); ++ if (flags) ++ { ++ arg->indexed = true; ++ arg->index.reg_type = fxlvm_read_u32(code); ++ arg->index.address = fxlvm_read_u32(code); + } ++ arg->reg_type = fxlvm_read_u32(code); ++ arg->address = fxlvm_read_u32(code); ++} + +- vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)"); ++static void fx_print_fxlc_literal(struct fx_parser *parser, uint32_t address, struct fxlvm_code *code) ++{ ++ if (parser->version.major >= 4) ++ vkd3d_string_buffer_print_f32(&parser->buffer, code->cli._4[address]); ++ else ++ vkd3d_string_buffer_print_f64(&parser->buffer, code->cli._8[address]); + } + +-static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, const struct fxlvm_code *code) ++static void fx_print_fxlc_argument(struct fx_parser *parser, const struct fxlc_arg *arg, struct fxlvm_code *code) + { +- struct fx_4_fxlc_argument arg; + uint32_t count; + +- fx_parser_read_unstructured(parser, &arg, offset, sizeof(arg)); +- +- switch (arg.reg_type) ++ switch (arg->reg_type) + { +- case FX_4_FXLC_REG_LITERAL: ++ case FX_FXLC_REG_LITERAL: + count = code->scalar ? 1 : code->comp_count; +- if (arg.address >= code->cli4_count || count > code->cli4_count - arg.address) ++ if (arg->address >= code->cli_count || count > code->cli_count - arg->address) + { + vkd3d_string_buffer_printf(&parser->buffer, "()"); + parser->failed = true; +@@ -4872,42 +4965,120 @@ static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, + } + + vkd3d_string_buffer_printf(&parser->buffer, "("); +- vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address]); ++ fx_print_fxlc_literal(parser, arg->address, code); + for (unsigned int i = 1; i < code->comp_count; ++i) + { + vkd3d_string_buffer_printf(&parser->buffer, ", "); +- vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address + (code->scalar ? 0 : i)]); ++ fx_print_fxlc_literal(parser, arg->address + (code->scalar ? 0 : i), code); + } + vkd3d_string_buffer_printf(&parser->buffer, ")"); + break; + +- case FX_4_FXLC_REG_CB: +- fx_4_parse_fxlc_constant_argument(parser, &arg, code); ++ case FX_FXLC_REG_CB: ++ fx_parse_fxlc_constant_argument(parser, arg, code); + break; + +- case FX_4_FXLC_REG_OUTPUT: +- case FX_4_FXLC_REG_TEMP: +- if (arg.reg_type == FX_4_FXLC_REG_OUTPUT) ++ case FX_FXLC_REG_OUTPUT: ++ case FX_FXLC_REG_TEMP: ++ if (arg->reg_type == FX_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); ++ vkd3d_string_buffer_printf(&parser->buffer, "r%u", arg->address / 4); ++ fx_parse_print_swizzle(parser, code, arg->address); + break; + + default: +- vkd3d_string_buffer_printf(&parser->buffer, "", arg.reg_type); ++ vkd3d_string_buffer_printf(&parser->buffer, "", arg->reg_type); ++ break; ++ } ++} ++ ++static void fx_parse_fxlvm_expression(struct fx_parser *parser, struct fxlvm_code *code) ++{ ++ struct fxlc_arg args[9]; ++ uint32_t ins_count; ++ size_t i, j; ++ ++ ins_count = fxlvm_read_u32(code); ++ ++ parse_fx_start_indent(parser); ++ ++ for (i = 0; i < ins_count; ++i) ++ { ++ uint32_t instr, opcode, src_count; ++ ++ instr = fxlvm_read_u32(code); ++ src_count = fxlvm_read_u32(code); ++ ++ if (src_count >= ARRAY_SIZE(args)) ++ { ++ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, ++ "Unexpected instruction source count %u.", src_count); + break; ++ } ++ ++ /* Sources entries are followed by the destination, first read them all. ++ Output format is "opcode dst, src[0]...src[n]". */ ++ for (j = 0; j < src_count; ++j) ++ fx_parse_fxlc_argument(parser, &args[j], code); ++ fx_parse_fxlc_argument(parser, &args[src_count], code); ++ ++ opcode = (instr >> FX_FXLC_OPCODE_SHIFT) & FX_FXLC_OPCODE_MASK; ++ code->comp_count = instr & FX_FXLC_COMP_COUNT_MASK; ++ ++ parse_fx_print_indent(parser); ++ vkd3d_string_buffer_printf(&parser->buffer, "%s ", get_fxlc_opcode_name(opcode)); ++ ++ code->scalar = false; ++ fx_print_fxlc_argument(parser, &args[src_count], code); ++ vkd3d_string_buffer_printf(&parser->buffer, ", "); ++ ++ for (j = 0; j < src_count; ++j) ++ { ++ /* Scalar modifier applies only to the first source. */ ++ code->scalar = j == 0 && !!(instr & FX_FXLC_IS_SCALAR_MASK); ++ fx_print_fxlc_argument(parser, &args[j], code); ++ if (j < src_count - 1) ++ vkd3d_string_buffer_printf(&parser->buffer, ", "); ++ } ++ ++ vkd3d_string_buffer_printf(&parser->buffer, "\n"); + } ++ ++ parse_fx_end_indent(parser); ++} ++ ++static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size) ++{ ++ uint32_t count = size / sizeof(uint32_t); ++ struct fxlvm_code code = { 0 }; ++ uint32_t section_size; ++ const uint32_t *data; ++ ++ /* Literal constants, using 64-bit floats. */ ++ if ((data = find_d3dbc_section(blob, count, TAG_CLIT, §ion_size))) ++ { ++ code.cli_count = *data++; ++ code.cli._8 = (const double *)data; ++ } ++ ++ /* CTAB does not contain variable names */ ++ ++ /* Code blob */ ++ code.ptr = find_d3dbc_section(blob, count, TAG_FXLC, &count); ++ code.end = code.ptr + count; ++ ++ fx_parse_fxlvm_expression(parser, &code); + } + + static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offset) + { + struct vkd3d_shader_dxbc_section_desc *section, fxlc, cli4, ctab; + struct vkd3d_shader_dxbc_desc dxbc_desc; ++ struct fxlvm_code code = { 0 }; + struct vkd3d_shader_code dxbc; +- uint32_t size, ins_count; +- struct fxlvm_code code; +- size_t i, j; ++ uint32_t size; ++ size_t i; + + offset = fx_parser_read_unstructured(parser, &size, offset, sizeof(size)); + +@@ -4943,8 +5114,8 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse + { + uint32_t cli4_offset = offset + (size_t)cli4.data.code - (size_t)dxbc.code; + +- fx_parser_read_unstructured(parser, &code.cli4_count, cli4_offset, sizeof(code.cli4_count)); +- code.cli4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli4_count * sizeof(float)); ++ fx_parser_read_unstructured(parser, &code.cli_count, cli4_offset, sizeof(code.cli_count)); ++ code.cli._4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli_count * sizeof(float)); + } + + if (ctab.data.code) +@@ -4960,47 +5131,10 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse + ctab_offset + consts_offset, code.ctab_count * sizeof(*code.constants)); + } + +- offset += (size_t)fxlc.data.code - (size_t)dxbc.code; +- offset = fx_parser_read_unstructured(parser, &ins_count, offset, sizeof(ins_count)); +- +- parse_fx_start_indent(parser); +- +- 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)); ++ code.ptr = fxlc.data.code; ++ code.end = (uint32_t *)((uint8_t *)fxlc.data.code + fxlc.data.size); + +- opcode = (instr >> FX_4_FXLC_OPCODE_SHIFT) & FX_4_FXLC_OPCODE_MASK; +- code.comp_count = instr & FX_4_FXLC_COMP_COUNT_MASK; +- code.scalar = false; +- +- parse_fx_print_indent(parser); +- vkd3d_string_buffer_printf(&parser->buffer, "%s ", fx_4_get_fxlc_opcode_name(opcode)); +- +- /* Destination first. */ +- fx_4_parse_fxlc_argument(parser, offset + sizeof(arg) * src_count, &code); +- +- for (j = 0; j < src_count; ++j) +- { +- vkd3d_string_buffer_printf(&parser->buffer, ", "); +- +- /* Scalar modifier applies only to first source. */ +- code.scalar = j == 0 && !!(instr & FX_4_FXLC_IS_SCALAR_MASK); +- fx_4_parse_fxlc_argument(parser, offset, &code); +- +- offset += sizeof(arg); +- } +- +- /* Destination */ +- offset += sizeof(arg); +- +- vkd3d_string_buffer_printf(&parser->buffer, "\n"); +- } +- +- parse_fx_end_indent(parser); ++ fx_parse_fxlvm_expression(parser, &code); + } + + static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32_t count, +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 1925e20c685..0aebfea2add 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -8727,8 +8727,9 @@ static void vsir_validate_dst_count(struct validation_context *ctx, + { + if (instruction->dst_count != count) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, +- "Invalid destination count %u for an instruction of type %#x, expected %u.", +- instruction->dst_count, instruction->opcode, count); ++ "Invalid destination parameter count %u for instruction \"%s\" (%#x); expected %u.", ++ instruction->dst_count, vsir_opcode_get_name(instruction->opcode, ""), ++ instruction->opcode, count); + } + + static void vsir_validate_src_count(struct validation_context *ctx, +@@ -8736,8 +8737,9 @@ static void vsir_validate_src_count(struct validation_context *ctx, + { + if (instruction->src_count != count) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, +- "Invalid source count %u for an instruction of type %#x, expected %u.", +- instruction->src_count, instruction->opcode, count); ++ "Invalid source parameter count %u for instruction \"%s\" (%#x); expected %u.", ++ instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), ++ instruction->opcode, count); + } + + static bool vsir_validate_src_min_count(struct validation_context *ctx, +@@ -8746,8 +8748,9 @@ static bool vsir_validate_src_min_count(struct validation_context *ctx, + if (instruction->src_count < count) + { + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, +- "Invalid source count %u for an instruction of type %#x, expected at least %u.", +- instruction->src_count, instruction->opcode, count); ++ "Invalid source parameter count %u for instruction \"%s\" (%#x); expected at least %u.", ++ instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), ++ instruction->opcode, count); + return false; + } + +@@ -8760,8 +8763,9 @@ static bool vsir_validate_src_max_count(struct validation_context *ctx, + if (instruction->src_count > count) + { + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, +- "Invalid source count %u for an instruction of type %#x, expected at most %u.", +- instruction->src_count, instruction->opcode, count); ++ "Invalid source parameter count %u for instruction \"%s\" (%#x); expected at most %u.", ++ instruction->src_count, vsir_opcode_get_name(instruction->opcode, ""), ++ instruction->opcode, count); + return false; + } + +@@ -9249,7 +9253,9 @@ static void vsir_validate_cf_type(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction, enum vsir_control_flow_type expected_type) + { + if (ctx->program->cf_type != expected_type) +- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "Invalid instruction %#x in %s shader.", ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, ++ "Invalid instruction \"%s\" (%#x) in %s shader.", ++ vsir_opcode_get_name(instruction->opcode, ""), + instruction->opcode, name_from_cf_type(ctx->program->cf_type)); + } + +@@ -9268,12 +9274,12 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, + { + if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, +- "Phase instruction %#x is only valid in a hull shader.", +- instruction->opcode); ++ "Phase instruction \"%s\" (%#x) is only valid in a hull shader.", ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + if (ctx->depth != 0) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, +- "Phase instruction %#x must appear to top level.", +- instruction->opcode); ++ "Phase instruction \"%s\" (%#x) must appear at the top level.", ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + ctx->phase = instruction->opcode; + ctx->dcl_temps_found = false; + } +@@ -10038,8 +10044,8 @@ static void vsir_validate_instruction(struct validation_context *ctx) + default: + if (!vsir_instruction_is_dcl(instruction)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, +- "Instruction %#x appear before any phase instruction in a hull shader.", +- instruction->opcode); ++ "Instruction \"%s\" (%#x) appears before any phase instruction in a hull shader.", ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + break; + } + } +@@ -10059,8 +10065,8 @@ static void vsir_validate_instruction(struct validation_context *ctx) + default: + if (!vsir_instruction_is_dcl(instruction)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, +- "Invalid instruction %#x outside any block.", +- instruction->opcode); ++ "Invalid instruction \"%s\" (%#x) outside any block.", ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + break; + } + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index 47ea6ce1f4b..08519787b0a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -612,10 +612,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment( + + static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) + { ++ const char *name = vsir_opcode_get_name(ins->opcode, ""); ++ + msl_print_indent(gen->buffer, gen->indent); +- vkd3d_string_buffer_printf(gen->buffer, "/* */\n", ins->opcode); ++ vkd3d_string_buffer_printf(gen->buffer, "/* */\n", name, ins->opcode); + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled instruction %#x.", ins->opcode); ++ "Internal compiler error: Unhandled instruction \"%s\" (%#x).", name, ins->opcode); + } + + static void msl_binop(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) +@@ -861,10 +863,11 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + data_type = VKD3D_DATA_FLOAT; + } + +- if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS +- || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBE +- || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY +- || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY) ++ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBE ++ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY ++ || (ins->opcode != VKD3DSIH_LD2DMS ++ && (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS ++ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY))) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Texel fetches from resource type %#x are not supported.", resource_type); + +@@ -903,7 +906,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) + { + vkd3d_string_buffer_printf(read, ", "); +- msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); ++ if (ins->opcode != VKD3DSIH_LD2DMS) ++ msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); ++ else ++ msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VKD3D_DATA_UINT); + } + vkd3d_string_buffer_printf(read, "))"); + msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask); +@@ -1096,6 +1102,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + break; + case VKD3DSIH_ILT: + case VKD3DSIH_LTO: ++ case VKD3DSIH_ULT: + msl_relop(gen, ins, "<"); + break; + case VKD3DSIH_MAD: +@@ -1114,11 +1121,15 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_NEU: + msl_relop(gen, ins, "!="); + break; ++ case VKD3DSIH_INEG: ++ msl_unary_op(gen, ins, "-"); ++ break; + case VKD3DSIH_ITOF: + case VKD3DSIH_UTOF: + msl_cast(gen, ins, "float"); + break; + case VKD3DSIH_LD: ++ case VKD3DSIH_LD2DMS: + msl_ld(gen, ins); + break; + case VKD3DSIH_LOG: +@@ -1166,6 +1177,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_SWITCH: + msl_switch(gen, ins); + break; ++ case VKD3DSIH_XOR: ++ msl_binop(gen, ins, "^"); ++ break; + default: + msl_unhandled(gen, ins); + break; +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 3e58718afa1..13ebde5cfd5 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -4527,70 +4527,6 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); + } + +-/* Based on the implementation in the OpenGL Mathematics library. */ +-static uint32_t half_to_float(uint16_t value) +-{ +- uint32_t s = (value & 0x8000u) << 16; +- uint32_t e = (value >> 10) & 0x1fu; +- uint32_t m = value & 0x3ffu; +- +- if (!e) +- { +- if (!m) +- { +- /* Plus or minus zero */ +- return s; +- } +- else +- { +- /* Denormalized number -- renormalize it */ +- +- while (!(m & 0x400u)) +- { +- m <<= 1; +- --e; +- } +- +- ++e; +- m &= ~0x400u; +- } +- } +- else if (e == 31u) +- { +- /* Positive or negative infinity for zero 'm'. +- * Nan for non-zero 'm' -- preserve sign and significand bits */ +- return s | 0x7f800000u | (m << 13); +- } +- +- /* Normalized number */ +- e += 127u - 15u; +- m <<= 13; +- +- /* Assemble s, e and m. */ +- return s | (e << 23) | m; +-} +- +-static uint32_t convert_raw_constant32(enum vkd3d_data_type data_type, unsigned int uint_value) +-{ +- int16_t i; +- +- /* TODO: native 16-bit support. */ +- if (data_type != VKD3D_DATA_UINT16 && data_type != VKD3D_DATA_HALF) +- return uint_value; +- +- if (data_type == VKD3D_DATA_HALF) +- return half_to_float(uint_value); +- +- /* Values in DXIL have no signedness, so it is ambiguous whether 16-bit constants should or +- * should not be sign-extended when 16-bit execution is not supported. The AMD RX 580 Windows +- * driver has no 16-bit support, and sign-extends all 16-bit constant ints to 32 bits. These +- * results differ from SM 5. The RX 6750 XT supports 16-bit execution, so constants are not +- * extended, and results match SM 5. It seems best to replicate the sign-extension, and if +- * execution is 16-bit, the values will be truncated. */ +- i = uint_value; +- return (int32_t)i; +-} +- + static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler, + const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask) + { +@@ -4603,15 +4539,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile + if (reg->dimension == VSIR_DIMENSION_SCALAR) + { + for (i = 0; i < component_count; ++i) +- values[i] = convert_raw_constant32(reg->data_type, reg->u.immconst_u32[0]); ++ values[i] = reg->u.immconst_u32[0]; + } + else + { + for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) + { + if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) +- values[j++] = convert_raw_constant32(reg->data_type, +- reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)]); ++ values[j++] = reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)]; + } + } + +@@ -4755,13 +4690,6 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil + + switch (icb->data_type) + { +- case VKD3D_DATA_HALF: +- case VKD3D_DATA_UINT16: +- /* Scalar only. */ +- for (i = 0; i < element_count; ++i) +- elements[i] = vkd3d_spirv_get_op_constant(builder, elem_type_id, +- convert_raw_constant32(icb->data_type, icb->data[i])); +- break; + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_INT: + case VKD3D_DATA_UINT: +@@ -9203,7 +9131,9 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, + &src[3], VKD3DSP_WRITEMASK_0); + break; + default: +- ERR("Unexpected instruction %#x.\n", instruction->opcode); ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, ++ "Unhandled instruction \"%s\" (%#x).", ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + return; + } + +@@ -9884,7 +9814,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil + op = spirv_compiler_map_atomic_instruction(instruction); + if (op == SpvOpMax) + { +- ERR("Unexpected instruction %#x.\n", instruction->opcode); ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, ++ "Unhandled instruction \"%s\" (%#x).", ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + return; + } + +@@ -9963,9 +9895,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil + + if (instruction->flags & VKD3DARF_VOLATILE) + { +- WARN("Ignoring 'volatile' attribute.\n"); + spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_IGNORING_FLAG, +- "Ignoring the 'volatile' attribute flag for atomic instruction %#x.", instruction->opcode); ++ "Ignoring the 'volatile' attribute flag for atomic instruction \"%s\" (%#x).", ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + } + + memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) +@@ -11040,9 +10972,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + /* nothing to do */ + break; + default: +- FIXME("Unhandled instruction %#x.\n", instruction->opcode); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER, +- "Encountered invalid/unhandled instruction handler %#x.", instruction->opcode); ++ "Unhandled instruction \"%s\" (%#x).", ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + break; + } + +-- +2.47.2 +