diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch index 52696a9f..608645f9 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch @@ -1,7 +1,8 @@ -From 42ae9179305a3517e179134598edc612d496791f Mon Sep 17 00:00:00 2001 +From ceefa7472488abad8434bb1ad515b09ab74f5a71 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 8 Dec 2023 13:21:19 +1100 -Subject: [PATCH] Updated vkd3d to fd7d23f64bc8c33fe3b59431219e14c0865be37a. +Subject: [PATCH 1/5] Updated vkd3d to + fd7d23f64bc8c33fe3b59431219e14c0865be37a. --- libs/vkd3d/Makefile.in | 1 + diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch index 27a5592f..12713e18 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch @@ -1,7 +1,8 @@ -From 68e2bce0d09d84419126651774b5a08b22b30c48 Mon Sep 17 00:00:00 2001 +From 512ffa3af40d1fab9d76cfff8b26d6b60c4481ac Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 1 Feb 2024 12:20:04 +1100 -Subject: [PATCH] Updated vkd3d to 6dea3d08b1e9453bfc51dfec827cf1a25c2729df. +Subject: [PATCH 2/5] Updated vkd3d to + 6dea3d08b1e9453bfc51dfec827cf1a25c2729df. --- libs/vkd3d/include/private/vkd3d_debug.h | 4 + diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch index 89a1463c..18b34a0b 100644 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch @@ -1,7 +1,8 @@ -From f8499236adae63a576482e7754c05c5859f086ea Mon Sep 17 00:00:00 2001 +From 29082a5f01e6e1fb631668d6f29b2615300e481e Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 7 Feb 2024 13:39:16 +1100 -Subject: [PATCH] Updated vkd3d to 06ddb10c4008adde7d81e1ece4fdce7a2b267870. +Subject: [PATCH 3/5] Updated vkd3d to + 06ddb10c4008adde7d81e1ece4fdce7a2b267870. --- libs/vkd3d/include/private/vkd3d_common.h | 2 +- diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch new file mode 100644 index 00000000..0e5167d0 --- /dev/null +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch @@ -0,0 +1,1667 @@ +From a7881d22b7765f148af5eb1c9ebbf4eaace98f86 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 8 Feb 2024 12:06:22 +1100 +Subject: [PATCH 4/5] Updated vkd3d to + 5c917552c927835c6f446dbecf1aa6ff2cc30cbe. + +--- + libs/vkd3d/include/private/vkd3d_common.h | 12 - + libs/vkd3d/include/private/vkd3d_test.h | 40 +- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 6 + + libs/vkd3d/libs/vkd3d-shader/dxil.c | 232 ++++++++--- + libs/vkd3d/libs/vkd3d-shader/ir.c | 384 +++++++++++++++++- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 185 +++++---- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 6 + + libs/vkd3d/libs/vkd3d/command.c | 28 +- + libs/vkd3d/libs/vkd3d/device.c | 96 ++++- + libs/vkd3d/libs/vkd3d/resource.c | 10 +- + libs/vkd3d/libs/vkd3d/utils.c | 5 + + libs/vkd3d/libs/vkd3d/vkd3d_main.c | 8 +- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 29 +- + 13 files changed, 831 insertions(+), 210 deletions(-) + +diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h +index 666bb80faf9..b5a8240d28e 100644 +--- a/libs/vkd3d/include/private/vkd3d_common.h ++++ b/libs/vkd3d/include/private/vkd3d_common.h +@@ -304,18 +304,6 @@ static inline uint32_t vkd3d_atomic_increment_u32(uint32_t volatile *x) + return vkd3d_atomic_add_fetch_u32(x, 1); + } + +-#ifndef _WIN32 +-static inline LONG InterlockedIncrement(LONG volatile *x) +-{ +- return vkd3d_atomic_increment_u32((uint32_t *)x); +-} +- +-static inline LONG InterlockedDecrement(LONG volatile *x) +-{ +- return vkd3d_atomic_decrement_u32((uint32_t *)x); +-} +-#endif /* _WIN32 */ +- + static inline void vkd3d_parse_version(const char *version, int *major, int *minor) + { + *major = atoi(version); +diff --git a/libs/vkd3d/include/private/vkd3d_test.h b/libs/vkd3d/include/private/vkd3d_test.h +index 081443c4fa6..a337ac07269 100644 +--- a/libs/vkd3d/include/private/vkd3d_test.h ++++ b/libs/vkd3d/include/private/vkd3d_test.h +@@ -101,12 +101,12 @@ static void vkd3d_test_end_todo(void); + + struct vkd3d_test_state + { +- LONG success_count; +- LONG failure_count; +- LONG skip_count; +- LONG todo_count; +- LONG todo_success_count; +- LONG bug_count; ++ unsigned int success_count; ++ unsigned int failure_count; ++ unsigned int skip_count; ++ unsigned int todo_count; ++ unsigned int todo_success_count; ++ unsigned int bug_count; + + unsigned int debug_level; + +@@ -150,13 +150,13 @@ vkd3d_test_check_assert_that(unsigned int line, bool result, const char *fmt, va + { + if (result) + { +- InterlockedIncrement(&vkd3d_test_state.success_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.success_count); + if (vkd3d_test_state.debug_level > 1) + vkd3d_test_printf(line, "Test succeeded.\n"); + } + else + { +- InterlockedIncrement(&vkd3d_test_state.failure_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.failure_count); + vkd3d_test_printf(line, "Test failed: "); + vprintf(fmt, args); + } +@@ -180,7 +180,7 @@ vkd3d_test_check_ok(unsigned int line, bool result, const char *fmt, va_list arg + + if (is_bug && vkd3d_test_state.bug_enabled) + { +- InterlockedIncrement(&vkd3d_test_state.bug_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.bug_count); + if (is_todo) + result = !result; + if (result) +@@ -193,12 +193,12 @@ vkd3d_test_check_ok(unsigned int line, bool result, const char *fmt, va_list arg + { + if (result) + { +- InterlockedIncrement(&vkd3d_test_state.todo_success_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.todo_success_count); + vkd3d_test_printf(line, "Todo succeeded: "); + } + else + { +- InterlockedIncrement(&vkd3d_test_state.todo_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.todo_count); + vkd3d_test_printf(line, "Todo: "); + } + vprintf(fmt, args); +@@ -227,7 +227,7 @@ vkd3d_test_skip(unsigned int line, const char *fmt, ...) + vkd3d_test_printf(line, "Test skipped: "); + vprintf(fmt, args); + va_end(args); +- InterlockedIncrement(&vkd3d_test_state.skip_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.skip_count); + } + + static void VKD3D_PRINTF_FUNC(2, 3) VKD3D_UNUSED +@@ -293,16 +293,14 @@ int main(int argc, char **argv) + + vkd3d_test_main(argc, argv); + +- printf("%s: %lu tests executed (%lu failures, %lu skipped, %lu todo, %lu bugs).\n", ++ printf("%s: %u tests executed (%u failures, %u skipped, %u todo, %u bugs).\n", + vkd3d_test_name, +- (unsigned long)(vkd3d_test_state.success_count +- + vkd3d_test_state.failure_count + vkd3d_test_state.todo_count +- + vkd3d_test_state.todo_success_count), +- (unsigned long)(vkd3d_test_state.failure_count +- + vkd3d_test_state.todo_success_count), +- (unsigned long)vkd3d_test_state.skip_count, +- (unsigned long)vkd3d_test_state.todo_count, +- (unsigned long)vkd3d_test_state.bug_count); ++ vkd3d_test_state.success_count + vkd3d_test_state.failure_count ++ + vkd3d_test_state.todo_count + vkd3d_test_state.todo_success_count, ++ vkd3d_test_state.failure_count + vkd3d_test_state.todo_success_count, ++ vkd3d_test_state.skip_count, ++ vkd3d_test_state.todo_count, ++ vkd3d_test_state.bug_count); + + if (test_platform) + free(test_platform); +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index dd96b7fa50b..3f86bd45960 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -30,8 +30,11 @@ + static const char * const shader_opcode_names[] = + { + [VKD3DSIH_ABS ] = "abs", ++ [VKD3DSIH_ACOS ] = "acos", + [VKD3DSIH_ADD ] = "add", + [VKD3DSIH_AND ] = "and", ++ [VKD3DSIH_ASIN ] = "asin", ++ [VKD3DSIH_ATAN ] = "atan", + [VKD3DSIH_ATOMIC_AND ] = "atomic_and", + [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", + [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", +@@ -168,10 +171,13 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_GATHER4_S ] = "gather4_s", + [VKD3DSIH_GEO ] = "ge", + [VKD3DSIH_GEU ] = "ge_unord", ++ [VKD3DSIH_HCOS ] = "hcos", + [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", + [VKD3DSIH_HS_DECLS ] = "hs_decls", + [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", + [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", ++ [VKD3DSIH_HSIN ] = "hsin", ++ [VKD3DSIH_HTAN ] = "htan", + [VKD3DSIH_IADD ] = "iadd", + [VKD3DSIH_IBFE ] = "ibfe", + [VKD3DSIH_IDIV ] = "idiv", +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index ba951a6e51b..a001f6f0642 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -339,6 +339,12 @@ enum dx_intrinsic_opcode + DX_COS = 12, + DX_SIN = 13, + DX_TAN = 14, ++ DX_ACOS = 15, ++ DX_ASIN = 16, ++ DX_ATAN = 17, ++ DX_HCOS = 18, ++ DX_HSIN = 19, ++ DX_HTAN = 20, + DX_EXP = 21, + DX_FRC = 22, + DX_LOG = 23, +@@ -364,6 +370,7 @@ enum dx_intrinsic_opcode + DX_CREATE_HANDLE = 57, + DX_CBUFFER_LOAD_LEGACY = 59, + DX_TEXTURE_LOAD = 66, ++ DX_TEXTURE_STORE = 67, + DX_BUFFER_LOAD = 68, + DX_DERIV_COARSEX = 83, + DX_DERIV_COARSEY = 84, +@@ -2176,21 +2183,29 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type + } + + static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type, +- unsigned int component_count, struct sm6_parser *sm6) ++ unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6) + { + enum vkd3d_data_type data_type; + unsigned int id; + +- id = sm6_parser_alloc_ssa_id(sm6); ++ if (value && register_is_ssa(&value->u.reg) && value->u.reg.idx[0].offset) ++ { ++ id = value->u.reg.idx[0].offset; ++ TRACE("Using forward-allocated id %u.\n", id); ++ } ++ else ++ { ++ id = sm6_parser_alloc_ssa_id(sm6); ++ } + data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0)); + register_init_with_id(reg, VKD3DSPR_SSA, data_type, id); + reg->dimension = component_count > 1 ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; + } + + static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type, +- struct sm6_parser *sm6) ++ struct sm6_value *value, struct sm6_parser *sm6) + { +- register_init_ssa_vector(reg, type, 1, sm6); ++ register_init_ssa_vector(reg, sm6_type_get_scalar_type(type, 0), 1, value, sm6); + } + + static void dst_param_init(struct vkd3d_shader_dst_param *param) +@@ -2200,6 +2215,13 @@ static void dst_param_init(struct vkd3d_shader_dst_param *param) + param->shift = 0; + } + ++static void dst_param_init_with_mask(struct vkd3d_shader_dst_param *param, unsigned int mask) ++{ ++ param->write_mask = mask; ++ param->modifiers = 0; ++ param->shift = 0; ++} ++ + static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, unsigned int component_idx) + { + param->write_mask = 1u << component_idx; +@@ -2215,10 +2237,10 @@ static void dst_param_init_vector(struct vkd3d_shader_dst_param *param, unsigned + } + + static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type, +- struct sm6_parser *sm6) ++ struct sm6_value *value, struct sm6_parser *sm6) + { + dst_param_init(param); +- register_init_ssa_scalar(¶m->reg, type, sm6); ++ register_init_ssa_scalar(¶m->reg, type, value, sm6); + } + + static inline void src_param_init(struct vkd3d_shader_src_param *param) +@@ -2275,7 +2297,7 @@ static void instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio + struct vkd3d_shader_dst_param *param = instruction_dst_params_alloc(ins, 1, sm6); + struct sm6_value *dst = sm6_parser_get_current_value(sm6); + +- dst_param_init_ssa_scalar(param, dst->type, sm6); ++ dst_param_init_ssa_scalar(param, dst->type, dst, sm6); + param->write_mask = VKD3DSP_WRITEMASK_0; + dst->u.reg = param->reg; + } +@@ -2287,7 +2309,7 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio + struct sm6_value *dst = sm6_parser_get_current_value(sm6); + + dst_param_init_vector(param, component_count); +- register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, sm6); ++ register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, dst, sm6); + dst->u.reg = param->reg; + } + +@@ -2450,6 +2472,7 @@ static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, + static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const struct dxil_record *record, + const struct sm6_type *fwd_type, unsigned int *rec_idx) + { ++ struct sm6_value *value; + unsigned int idx; + uint64_t val_ref; + size_t operand; +@@ -2463,23 +2486,39 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru + if (operand == SIZE_MAX) + return SIZE_MAX; + +- if (operand >= sm6->value_count) ++ if (operand >= sm6->value_count && !fwd_type) + { +- if (!fwd_type) ++ /* Forward references are followed by a type id unless an earlier operand set the type, ++ * or it is contained in a function declaration. */ ++ if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6)) ++ return SIZE_MAX; ++ if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++]))) ++ return SIZE_MAX; ++ } ++ *rec_idx = idx; ++ ++ if (fwd_type) ++ { ++ value = &sm6->values[operand]; ++ if (value->type) + { +- /* Forward references are followed by a type id unless an earlier operand set the type, +- * or it is contained in a function declaration. */ +- if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6)) +- return SIZE_MAX; +- if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++]))) +- return SIZE_MAX; ++ if (value->type != fwd_type) ++ { ++ WARN("Value already has a mismatching type.\n"); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, ++ "The type of a source value does not match the predefined type."); ++ } ++ } ++ else ++ { ++ value->type = fwd_type; ++ value->value_type = VALUE_TYPE_REG; ++ register_init_with_id(&value->u.reg, VKD3DSPR_SSA, vkd3d_data_type_from_sm6_type( ++ sm6_type_get_scalar_type(fwd_type, 0)), sm6_parser_alloc_ssa_id(sm6)); ++ value->u.reg.dimension = sm6_type_is_scalar(fwd_type) ? VSIR_DIMENSION_SCALAR ++ : VSIR_DIMENSION_VEC4; + } +- FIXME("Forward value references are not supported yet.\n"); +- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +- "Unsupported value forward reference."); +- return SIZE_MAX; + } +- *rec_idx = idx; + + return operand; + } +@@ -3476,7 +3515,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + + dst_param_init(&dst_params[0]); + dst_param_init(&dst_params[1]); +- register_init_ssa_scalar(&dst_params[index].reg, a->type, sm6); ++ register_init_ssa_scalar(&dst_params[index].reg, a->type, dst, sm6); + vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + dst->u.reg = dst_params[index].reg; + } +@@ -3547,47 +3586,36 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record + ins->handler_idx = VKD3DSIH_NOP; + } + +-static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, +- const struct sm6_value *z_operand, struct function_emission_state *state, +- struct vkd3d_shader_register *reg) ++static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs, ++ unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) + { +- const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_params; + struct vkd3d_shader_dst_param *dst_param; +- const unsigned int max_operands = 3; +- unsigned int i, component_count; + bool all_constant = true; +- +- for (component_count = 0; component_count < max_operands; ++component_count) +- { +- if (!z_operand && operands[component_count]->is_undefined) +- break; +- operand_regs[component_count] = &operands[component_count]->u.reg; +- all_constant &= register_is_constant_or_undef(operand_regs[component_count]); +- } +- if (z_operand) +- { +- all_constant &= register_is_constant(&z_operand->u.reg); +- operand_regs[component_count++] = &z_operand->u.reg; +- } ++ unsigned int i; + + if (component_count == 1) + { +- *reg = operands[0]->u.reg; ++ *reg = *operand_regs[0]; + return true; + } + ++ for (i = 0; i < component_count; ++i) ++ all_constant &= register_is_constant(operand_regs[i]); ++ + if (all_constant) + { + vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0]->data_type, 0); + reg->dimension = VSIR_DIMENSION_VEC4; + for (i = 0; i < component_count; ++i) + reg->u.immconst_u32[i] = operand_regs[i]->u.immconst_u32[0]; ++ for (; i < VKD3D_VEC4_SIZE; ++i) ++ reg->u.immconst_u32[i] = 0; + return true; + } + +- register_init_with_id(reg, VKD3DSPR_TEMP, operands[0]->u.reg.data_type, state->temp_idx++); ++ register_init_with_id(reg, VKD3DSPR_TEMP, operand_regs[0]->data_type, state->temp_idx++); + reg->dimension = VSIR_DIMENSION_VEC4; + + for (i = 0; i < component_count; ++i, ++ins) +@@ -3613,6 +3641,40 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s + return true; + } + ++static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const struct sm6_value **operands, ++ unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) ++{ ++ const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; ++ unsigned int i; ++ ++ for (i = 0; i < component_count; ++i) ++ operand_regs[i] = &operands[i]->u.reg; ++ ++ return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); ++} ++ ++static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, ++ const struct sm6_value *z_operand, struct function_emission_state *state, ++ struct vkd3d_shader_register *reg) ++{ ++ const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; ++ const unsigned int max_operands = 3; ++ unsigned int component_count; ++ ++ for (component_count = 0; component_count < max_operands; ++component_count) ++ { ++ if (!z_operand && operands[component_count]->is_undefined) ++ break; ++ operand_regs[component_count] = &operands[component_count]->u.reg; ++ } ++ if (z_operand) ++ { ++ operand_regs[component_count++] = &z_operand->u.reg; ++ } ++ ++ return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); ++} ++ + static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) + { + switch (op) +@@ -3625,6 +3687,18 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) + return VKD3DSIH_ISFINITE; + case DX_TAN: + return VKD3DSIH_TAN; ++ case DX_ACOS: ++ return VKD3DSIH_ACOS; ++ case DX_ASIN: ++ return VKD3DSIH_ASIN; ++ case DX_ATAN: ++ return VKD3DSIH_ATAN; ++ case DX_HCOS: ++ return VKD3DSIH_HCOS; ++ case DX_HSIN: ++ return VKD3DSIH_HSIN; ++ case DX_HTAN: ++ return VKD3DSIH_HTAN; + case DX_EXP: + return VKD3DSIH_EXP; + case DX_FRC: +@@ -3983,7 +4057,7 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ + dst_params = instruction_dst_params_alloc(ins, 2, sm6); + dst_param_init(&dst_params[0]); + dst_param_init(&dst_params[1]); +- register_init_ssa_scalar(&dst_params[index].reg, dst->type, sm6); ++ register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6); + vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + dst->u.reg = dst_params[index].reg; + } +@@ -4099,6 +4173,56 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); + } + ++static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) ++{ ++ struct vkd3d_shader_register coord, texel; ++ struct vkd3d_shader_src_param *src_params; ++ struct vkd3d_shader_dst_param *dst_param; ++ unsigned int write_mask, component_count; ++ struct vkd3d_shader_instruction *ins; ++ const struct sm6_value *resource; ++ ++ resource = operands[0]; ++ if (!sm6_value_validate_is_texture_handle(resource, op, sm6)) ++ return; ++ ++ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], NULL, state, &coord)) ++ return; ++ ++ write_mask = sm6_value_get_constant_uint(operands[8]); ++ if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) ++ { ++ WARN("Invalid write mask %#x.\n", write_mask); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Write mask %#x for a texture store operation is invalid.", write_mask); ++ return; ++ } ++ else if (write_mask & (write_mask + 1)) ++ { ++ /* In this case, it is unclear which source operands will be defined unless we encounter it in a shader. */ ++ FIXME("Unhandled write mask %#x.\n", write_mask); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Write mask %#x for a texture store operation is unhandled.", write_mask); ++ } ++ component_count = vsir_write_mask_component_count(write_mask); ++ ++ if (!sm6_parser_emit_composite_construct(sm6, &operands[4], component_count, state, &texel)) ++ return; ++ ++ ins = state->ins; ++ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED); ++ ++ if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) ++ return; ++ src_param_init_vector_from_reg(&src_params[0], &coord); ++ src_param_init_vector_from_reg(&src_params[1], &texel); ++ ++ dst_param = instruction_dst_params_alloc(ins, 1, sm6); ++ dst_param->reg = resource->u.handle.reg; ++ dst_param_init_with_mask(dst_param, write_mask); ++} ++ + struct sm6_dx_opcode_info + { + const char *ret_type; +@@ -4127,6 +4251,9 @@ struct sm6_dx_opcode_info + */ + static const struct sm6_dx_opcode_info sm6_dx_op_table[] = + { ++ [DX_ACOS ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_ASIN ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_ATAN ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_BFREV ] = {"m", "R", sm6_parser_emit_dx_unary}, + [DX_BUFFER_LOAD ] = {"o", "Hii", sm6_parser_emit_dx_buffer_load}, + [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load}, +@@ -4145,6 +4272,9 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = + [DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary}, + [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_IBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, ++ [DX_HCOS ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_HSIN ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_HTAN ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, + [DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, + [DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary}, +@@ -4166,6 +4296,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = + [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, + [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_TEXTURE_LOAD ] = {"o", "HiiiiCCC", sm6_parser_emit_dx_texture_load}, ++ [DX_TEXTURE_STORE ] = {"v", "Hiiiooooc", sm6_parser_emit_dx_texture_store}, + [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, + [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, + [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, +@@ -4725,8 +4856,8 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + + src_param = instruction_src_params_alloc(ins, 1, sm6); +- src_param_init_scalar(src_param, elem_idx); + src_param->reg = src->u.reg; ++ src_param_init_scalar(src_param, elem_idx); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -4919,7 +5050,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record + } + + dst->type = type; +- register_init_ssa_scalar(&dst->u.reg, type, sm6); ++ register_init_ssa_scalar(&dst->u.reg, type, dst, sm6); + + if (!(phi = sm6_block_phi_require_space(code_block, sm6))) + return; +@@ -5492,6 +5623,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const + struct vkd3d_shader_instruction *ins; + size_t i, block_idx, block_count; + const struct dxil_record *record; ++ const struct sm6_type *fwd_type; + bool ret_found, is_terminator; + struct sm6_block *code_block; + struct sm6_value *dst; +@@ -5568,6 +5700,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const + ins->handler_idx = VKD3DSIH_INVALID; + + dst = sm6_parser_get_current_value(sm6); ++ fwd_type = dst->type; + dst->type = NULL; + dst->value_type = VALUE_TYPE_REG; + is_terminator = false; +@@ -5647,6 +5780,13 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const + else + assert(ins->handler_idx == VKD3DSIH_NOP); + ++ if (dst->type && fwd_type && dst->type != fwd_type) ++ { ++ WARN("Type mismatch.\n"); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, ++ "The type of a result value does not match the type defined by a forward reference."); ++ } ++ + sm6->value_count += !!dst->type; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index a0d6212cbf5..88634487482 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -470,6 +470,25 @@ static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned + dst->reg.idx[0].offset = idx; + } + ++static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx) ++{ ++ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ dst->reg.idx[0].offset = idx; ++ dst->write_mask = VKD3DSP_WRITEMASK_0; ++} ++ ++static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx) ++{ ++ vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ src->reg.idx[0].offset = idx; ++} ++ ++static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value) ++{ ++ vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); ++ src->reg.u.immconst_u32[0] = value; ++} ++ + void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, + enum vkd3d_shader_opcode handler_idx) + { +@@ -2637,6 +2656,359 @@ fail: + return VKD3D_ERROR_OUT_OF_MEMORY; + } + ++static void materialize_ssas_to_temps_process_src_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_src_param *src); ++ ++/* This is idempotent: it can be safely applied more than once on the ++ * same register. */ ++static void materialize_ssas_to_temps_process_reg(struct vkd3d_shader_parser *parser, struct vkd3d_shader_register *reg) ++{ ++ unsigned int i; ++ ++ if (reg->type == VKD3DSPR_SSA) ++ { ++ reg->type = VKD3DSPR_TEMP; ++ reg->idx[0].offset += parser->program.temp_count; ++ } ++ ++ for (i = 0; i < reg->idx_count; ++i) ++ if (reg->idx[i].rel_addr) ++ materialize_ssas_to_temps_process_src_param(parser, reg->idx[i].rel_addr); ++} ++ ++static void materialize_ssas_to_temps_process_dst_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_dst_param *dst) ++{ ++ materialize_ssas_to_temps_process_reg(parser, &dst->reg); ++} ++ ++static void materialize_ssas_to_temps_process_src_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_src_param *src) ++{ ++ materialize_ssas_to_temps_process_reg(parser, &src->reg); ++} ++ ++static const struct vkd3d_shader_src_param *materialize_ssas_to_temps_compute_source(struct vkd3d_shader_instruction *ins, ++ unsigned int label) ++{ ++ unsigned int i; ++ ++ assert(ins->handler_idx == VKD3DSIH_PHI); ++ ++ for (i = 0; i < ins->src_count; i += 2) ++ { ++ if (label_from_src_param(&ins->src[i + 1]) == label) ++ return &ins->src[i]; ++ } ++ ++ vkd3d_unreachable(); ++} ++ ++static bool materialize_ssas_to_temps_synthesize_mov(struct vkd3d_shader_parser *parser, ++ struct vkd3d_shader_instruction *instruction, const struct vkd3d_shader_location *loc, ++ const struct vkd3d_shader_dst_param *dest, const struct vkd3d_shader_src_param *cond, ++ const struct vkd3d_shader_src_param *source, bool invert) ++{ ++ struct vkd3d_shader_src_param *src; ++ struct vkd3d_shader_dst_param *dst; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, instruction, loc, ++ cond ? VKD3DSIH_MOVC : VKD3DSIH_MOV, 1, cond ? 3 : 1)) ++ return false; ++ ++ dst = instruction->dst; ++ src = instruction->src; ++ ++ dst[0] = *dest; ++ materialize_ssas_to_temps_process_dst_param(parser, &dst[0]); ++ ++ assert(dst[0].write_mask == VKD3DSP_WRITEMASK_0); ++ assert(dst[0].modifiers == 0); ++ assert(dst[0].shift == 0); ++ ++ if (cond) ++ { ++ src[0] = *cond; ++ src[1 + invert] = *source; ++ memset(&src[2 - invert], 0, sizeof(src[2 - invert])); ++ src[2 - invert].reg = dst[0].reg; ++ materialize_ssas_to_temps_process_src_param(parser, &src[1]); ++ materialize_ssas_to_temps_process_src_param(parser, &src[2]); ++ } ++ else ++ { ++ src[0] = *source; ++ materialize_ssas_to_temps_process_src_param(parser, &src[0]); ++ } ++ ++ return true; ++} ++ ++static enum vkd3d_result materialize_ssas_to_temps(struct vkd3d_shader_parser *parser) ++{ ++ struct vkd3d_shader_instruction *instructions = NULL; ++ struct materialize_ssas_to_temps_block_data ++ { ++ size_t phi_begin; ++ size_t phi_count; ++ } *block_index = NULL; ++ size_t ins_capacity = 0, ins_count = 0, i; ++ unsigned int current_label = 0; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, parser->program.instructions.count)) ++ goto fail; ++ ++ if (!(block_index = vkd3d_calloc(parser->program.block_count, sizeof(*block_index)))) ++ { ++ ERR("Failed to allocate block index.\n"); ++ goto fail; ++ } ++ ++ for (i = 0; i < parser->program.instructions.count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_LABEL: ++ current_label = label_from_src_param(&ins->src[0]); ++ break; ++ ++ case VKD3DSIH_PHI: ++ assert(current_label != 0); ++ assert(i != 0); ++ if (block_index[current_label - 1].phi_begin == 0) ++ block_index[current_label - 1].phi_begin = i; ++ block_index[current_label - 1].phi_count += 1; ++ break; ++ ++ default: ++ current_label = 0; ++ break; ++ } ++ } ++ ++ for (i = 0; i < parser->program.instructions.count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; ++ size_t j; ++ ++ for (j = 0; j < ins->dst_count; ++j) ++ materialize_ssas_to_temps_process_dst_param(parser, &ins->dst[j]); ++ ++ for (j = 0; j < ins->src_count; ++j) ++ materialize_ssas_to_temps_process_src_param(parser, &ins->src[j]); ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_LABEL: ++ current_label = label_from_src_param(&ins->src[0]); ++ break; ++ ++ case VKD3DSIH_BRANCH: ++ { ++ if (vsir_register_is_label(&ins->src[0].reg)) ++ { ++ const struct materialize_ssas_to_temps_block_data *data = &block_index[label_from_src_param(&ins->src[0]) - 1]; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + data->phi_count)) ++ goto fail; ++ ++ for (j = data->phi_begin; j < data->phi_begin + data->phi_count; ++j) ++ { ++ const struct vkd3d_shader_src_param *source; ++ ++ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); ++ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, ++ &parser->program.instructions.elements[j].dst[0], NULL, source, false)) ++ goto fail; ++ ++ ++ins_count; ++ } ++ } ++ else ++ { ++ struct materialize_ssas_to_temps_block_data *data_true = &block_index[label_from_src_param(&ins->src[1]) - 1], ++ *data_false = &block_index[label_from_src_param(&ins->src[2]) - 1]; ++ const struct vkd3d_shader_src_param *cond = &ins->src[0]; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ++ ins_count + data_true->phi_count + data_false->phi_count)) ++ goto fail; ++ ++ for (j = data_true->phi_begin; j < data_true->phi_begin + data_true->phi_count; ++j) ++ { ++ const struct vkd3d_shader_src_param *source; ++ ++ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); ++ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, ++ &parser->program.instructions.elements[j].dst[0], cond, source, false)) ++ goto fail; ++ ++ ++ins_count; ++ } ++ ++ for (j = data_false->phi_begin; j < data_false->phi_begin + data_false->phi_count; ++j) ++ { ++ const struct vkd3d_shader_src_param *source; ++ ++ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); ++ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, ++ &parser->program.instructions.elements[j].dst[0], cond, source, true)) ++ goto fail; ++ ++ ++ins_count; ++ } ++ } ++ break; ++ } ++ ++ case VKD3DSIH_PHI: ++ continue; ++ ++ default: ++ break; ++ } ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) ++ goto fail; ++ ++ instructions[ins_count++] = *ins; ++ } ++ ++ vkd3d_free(parser->program.instructions.elements); ++ vkd3d_free(block_index); ++ parser->program.instructions.elements = instructions; ++ parser->program.instructions.capacity = ins_capacity; ++ parser->program.instructions.count = ins_count; ++ parser->program.temp_count += parser->program.ssa_count; ++ parser->program.ssa_count = 0; ++ ++ return VKD3D_OK; ++ ++fail: ++ vkd3d_free(instructions); ++ vkd3d_free(block_index); ++ ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++} ++ ++static enum vkd3d_result simple_structurizer_run(struct vkd3d_shader_parser *parser) ++{ ++ const unsigned int block_temp_idx = parser->program.temp_count; ++ struct vkd3d_shader_instruction *instructions = NULL; ++ const struct vkd3d_shader_location no_loc = {0}; ++ size_t ins_capacity = 0, ins_count = 0, i; ++ bool first_label_found = false; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, parser->program.instructions.count)) ++ goto fail; ++ ++ for (i = 0; i < parser->program.instructions.count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_PHI: ++ case VKD3DSIH_SWITCH_MONOLITHIC: ++ vkd3d_unreachable(); ++ ++ case VKD3DSIH_LABEL: ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 4)) ++ goto fail; ++ ++ if (!first_label_found) ++ { ++ first_label_found = true; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOV, 1, 1)) ++ goto fail; ++ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); ++ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); ++ ins_count++; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_LOOP, 0, 0)) ++ goto fail; ++ ins_count++; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_SWITCH, 0, 1)) ++ goto fail; ++ src_param_init_temp_uint(&instructions[ins_count].src[0], block_temp_idx); ++ ins_count++; ++ } ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_CASE, 0, 1)) ++ goto fail; ++ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); ++ ins_count++; ++ break; ++ ++ case VKD3DSIH_BRANCH: ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 2)) ++ goto fail; ++ ++ if (vsir_register_is_label(&ins->src[0].reg)) ++ { ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOV, 1, 1)) ++ goto fail; ++ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); ++ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); ++ ins_count++; ++ } ++ else ++ { ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOVC, 1, 3)) ++ goto fail; ++ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); ++ instructions[ins_count].src[0] = ins->src[0]; ++ src_param_init_const_uint(&instructions[ins_count].src[1], label_from_src_param(&ins->src[1])); ++ src_param_init_const_uint(&instructions[ins_count].src[2], label_from_src_param(&ins->src[2])); ++ ins_count++; ++ } ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_BREAK, 0, 0)) ++ goto fail; ++ ins_count++; ++ break; ++ ++ case VKD3DSIH_RET: ++ default: ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) ++ goto fail; ++ ++ instructions[ins_count++] = *ins; ++ break; ++ } ++ } ++ ++ assert(first_label_found); ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3)) ++ goto fail; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_ENDSWITCH, 0, 0)) ++ goto fail; ++ ins_count++; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_ENDLOOP, 0, 0)) ++ goto fail; ++ ins_count++; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_RET, 0, 0)) ++ goto fail; ++ ins_count++; ++ ++ vkd3d_free(parser->program.instructions.elements); ++ parser->program.instructions.elements = instructions; ++ parser->program.instructions.capacity = ins_capacity; ++ parser->program.instructions.count = ins_count; ++ parser->program.temp_count += 1; ++ ++ return VKD3D_OK; ++ ++fail: ++ vkd3d_free(instructions); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++} ++ + enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, + const struct vkd3d_shader_compile_info *compile_info) + { +@@ -2652,6 +3024,12 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, + { + if ((result = lower_switch_to_if_ladder(&parser->program)) < 0) + return result; ++ ++ if ((result = materialize_ssas_to_temps(parser)) < 0) ++ return result; ++ ++ if ((result = simple_structurizer_run(parser)) < 0) ++ return result; + } + else + { +@@ -2679,13 +3057,13 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, + + remove_dead_code(&parser->program); + +- if ((result = flatten_control_flow_constructs(parser)) < 0) +- return result; +- + if ((result = normalise_combined_samplers(parser)) < 0) + return result; + } + ++ if ((result = flatten_control_flow_constructs(parser)) < 0) ++ return result; ++ + if (TRACE_ON()) + vkd3d_shader_trace(&parser->program); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 9b6ce742976..6c92b03b216 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -3669,6 +3669,73 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil + type_id, vector1_id, vector2_id, components, component_count); + } + ++static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, ++ enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, ++ unsigned int component_count, uint32_t val_id) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id; ++ SpvOp op; ++ ++ assert(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); ++ ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; ++ return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, ++ data_type == VKD3D_DATA_UINT64 ++ ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) ++ : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); ++} ++ ++static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, ++ unsigned int component_count, uint32_t val_id, bool signedness) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id, true_id, false_id; ++ ++ true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); ++ false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); ++ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++} ++ ++static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compiler, ++ unsigned int component_count, uint32_t val_id, bool signedness) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id, true_id, false_id; ++ ++ true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, ++ component_count); ++ false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); ++ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++} ++ ++static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, ++ unsigned int component_count, uint32_t val_id, bool signedness) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id, true_id, false_id; ++ ++ true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); ++ false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); ++ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++} ++ ++static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compiler, ++ unsigned int component_count, uint32_t val_id, bool signedness) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id, true_id, false_id; ++ ++ true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); ++ false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); ++ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++} ++ + 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) + { +@@ -3777,8 +3844,21 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, + + if (component_type != reg_info->component_type) + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); +- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) ++ { ++ if (reg_info->component_type != VKD3D_SHADER_COMPONENT_UINT) ++ { ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } ++ val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, ++ VKD3D_DATA_UINT, 1, val_id); ++ } ++ else ++ { ++ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } + } + + return val_id; +@@ -3965,8 +4045,21 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, + + if (component_type != reg_info.component_type) + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); +- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) ++ { ++ if (reg_info.component_type != VKD3D_SHADER_COMPONENT_UINT) ++ { ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } ++ val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, ++ VKD3D_DATA_UINT, component_count, val_id); ++ } ++ else ++ { ++ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } + } + + return val_id; +@@ -4160,6 +4253,9 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, + { + if (data_type_is_64_bit(reg->data_type)) + src_write_mask = vsir_write_mask_32_from_64(write_mask); ++ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) ++ val_id = spirv_compiler_emit_bool_to_int(compiler, ++ vsir_write_mask_component_count(src_write_mask), val_id, false); + type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, + vsir_write_mask_component_count(src_write_mask)); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); +@@ -4383,73 +4479,6 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler + } + } + +-static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, +- enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, +- unsigned int component_count, uint32_t val_id) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id; +- SpvOp op; +- +- assert(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); +- +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); +- op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; +- return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, +- data_type == VKD3D_DATA_UINT64 +- ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) +- : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); +-} +- +-static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, +- unsigned int component_count, uint32_t val_id, bool signedness) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id, true_id, false_id; +- +- true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); +- false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); +- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +-} +- +-static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compiler, +- unsigned int component_count, uint32_t val_id, bool signedness) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id, true_id, false_id; +- +- true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, +- component_count); +- false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); +- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +-} +- +-static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, +- unsigned int component_count, uint32_t val_id, bool signedness) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id, true_id, false_id; +- +- true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); +- false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); +- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +-} +- +-static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compiler, +- unsigned int component_count, uint32_t val_id, bool signedness) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id, true_id, false_id; +- +- true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); +- false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); +- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +-} +- + typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct spirv_compiler *compiler, + uint32_t val_id); + +@@ -6968,6 +6997,9 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( + } + glsl_insts[] = + { ++ {VKD3DSIH_ACOS, GLSLstd450Acos}, ++ {VKD3DSIH_ASIN, GLSLstd450Asin}, ++ {VKD3DSIH_ATAN, GLSLstd450Atan}, + {VKD3DSIH_DFMA, GLSLstd450Fma}, + {VKD3DSIH_DMAX, GLSLstd450NMax}, + {VKD3DSIH_DMIN, GLSLstd450NMin}, +@@ -6976,6 +7008,9 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( + {VKD3DSIH_FIRSTBIT_LO, GLSLstd450FindILsb}, + {VKD3DSIH_FIRSTBIT_SHI, GLSLstd450FindSMsb}, + {VKD3DSIH_FRC, GLSLstd450Fract}, ++ {VKD3DSIH_HCOS, GLSLstd450Cosh}, ++ {VKD3DSIH_HSIN, GLSLstd450Sinh}, ++ {VKD3DSIH_HTAN, GLSLstd450Tanh}, + {VKD3DSIH_IMAX, GLSLstd450SMax}, + {VKD3DSIH_IMIN, GLSLstd450SMin}, + {VKD3DSIH_LOG, GLSLstd450Log2}, +@@ -7082,7 +7117,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, + } + + write_mask32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_write_mask_32_from_64(dst->write_mask) : dst->write_mask; +- swizzle32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_swizzle_32_from_64(src->swizzle) : src->swizzle; ++ swizzle32 = data_type_is_64_bit(src->reg.data_type) ? vsir_swizzle_32_from_64(src->swizzle) : src->swizzle; + component_count = vsir_write_mask_component_count(write_mask32); + if (component_count != 1 && component_count != VKD3D_VEC4_SIZE + && dst_reg_info.write_mask == VKD3DSP_WRITEMASK_ALL) +@@ -9552,6 +9587,12 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VKD3DSIH_ISFINITE: + spirv_compiler_emit_isfinite(compiler, instruction); + break; ++ case VKD3DSIH_ACOS: ++ case VKD3DSIH_ASIN: ++ case VKD3DSIH_ATAN: ++ case VKD3DSIH_HCOS: ++ case VKD3DSIH_HSIN: ++ case VKD3DSIH_HTAN: + case VKD3DSIH_DFMA: + case VKD3DSIH_DMAX: + case VKD3DSIH_DMIN: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index a709121f1a1..acfd39b7643 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -225,8 +225,11 @@ enum vkd3d_shader_error + enum vkd3d_shader_opcode + { + VKD3DSIH_ABS, ++ VKD3DSIH_ACOS, + VKD3DSIH_ADD, + VKD3DSIH_AND, ++ VKD3DSIH_ASIN, ++ VKD3DSIH_ATAN, + VKD3DSIH_ATOMIC_AND, + VKD3DSIH_ATOMIC_CMP_STORE, + VKD3DSIH_ATOMIC_IADD, +@@ -363,10 +366,13 @@ enum vkd3d_shader_opcode + VKD3DSIH_GATHER4_S, + VKD3DSIH_GEO, + VKD3DSIH_GEU, ++ VKD3DSIH_HCOS, + VKD3DSIH_HS_CONTROL_POINT_PHASE, + VKD3DSIH_HS_DECLS, + VKD3DSIH_HS_FORK_PHASE, + VKD3DSIH_HS_JOIN_PHASE, ++ VKD3DSIH_HSIN, ++ VKD3DSIH_HTAN, + VKD3DSIH_IADD, + VKD3DSIH_IBFE, + VKD3DSIH_IDIV, +diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c +index f9940b3d383..8a47dc494f7 100644 +--- a/libs/vkd3d/libs/vkd3d/command.c ++++ b/libs/vkd3d/libs/vkd3d/command.c +@@ -1921,12 +1921,12 @@ HRESULT d3d12_command_allocator_create(struct d3d12_device *device, + + static void d3d12_command_signature_incref(struct d3d12_command_signature *signature) + { +- vkd3d_atomic_increment(&signature->internal_refcount); ++ vkd3d_atomic_increment_u32(&signature->internal_refcount); + } + + static void d3d12_command_signature_decref(struct d3d12_command_signature *signature) + { +- unsigned int refcount = vkd3d_atomic_decrement(&signature->internal_refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&signature->internal_refcount); + + if (!refcount) + { +@@ -4499,8 +4499,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I + { + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + +- TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", +- iface, root_parameter_index, base_descriptor.ptr); ++ TRACE("iface %p, root_parameter_index %u, base_descriptor %s.\n", ++ iface, root_parameter_index, debug_gpu_handle(base_descriptor)); + + d3d12_command_list_set_descriptor_table(list, VKD3D_PIPELINE_BIND_POINT_COMPUTE, + root_parameter_index, base_descriptor); +@@ -4511,8 +4511,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable( + { + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + +- TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", +- iface, root_parameter_index, base_descriptor.ptr); ++ TRACE("iface %p, root_parameter_index %u, base_descriptor %s.\n", ++ iface, root_parameter_index, debug_gpu_handle(base_descriptor)); + + d3d12_command_list_set_descriptor_table(list, VKD3D_PIPELINE_BIND_POINT_GRAPHICS, + root_parameter_index, base_descriptor); +@@ -5432,8 +5432,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID + struct d3d12_resource *resource_impl; + VkClearColorValue colour; + +- TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", +- iface, gpu_handle.ptr, debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); ++ TRACE("iface %p, gpu_handle %s, cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", ++ iface, debug_gpu_handle(gpu_handle), debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); + + resource_impl = unsafe_impl_from_ID3D12Resource(resource); + if (!(descriptor = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view)) +@@ -5496,8 +5496,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I + VkClearColorValue colour; + struct vkd3d_view *view; + +- TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", +- iface, gpu_handle.ptr, debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); ++ TRACE("iface %p, gpu_handle %s, cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", ++ iface, debug_gpu_handle(gpu_handle), debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); + + resource_impl = unsafe_impl_from_ID3D12Resource(resource); + if (!(view = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view)) +@@ -5963,15 +5963,15 @@ static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCom + static void STDMETHODCALLTYPE d3d12_command_list_InitializeMetaCommand(ID3D12GraphicsCommandList5 *iface, + ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) + { +- FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, +- meta_command, parameters_data, data_size_in_bytes); ++ FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %"PRIuPTR" stub!\n", iface, ++ meta_command, parameters_data, (uintptr_t)data_size_in_bytes); + } + + static void STDMETHODCALLTYPE d3d12_command_list_ExecuteMetaCommand(ID3D12GraphicsCommandList5 *iface, + ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) + { +- FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, +- meta_command, parameters_data, data_size_in_bytes); ++ FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %"PRIuPTR" stub!\n", iface, ++ meta_command, parameters_data, (uintptr_t)data_size_in_bytes); + } + + static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface, +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index cf8b506fdf5..90272818b3d 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -3348,6 +3348,91 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device7 + return S_OK; + } + ++ case D3D12_FEATURE_D3D12_OPTIONS6: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS6 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->AdditionalShadingRatesSupported = FALSE; ++ data->PerPrimitiveShadingRateSupportedWithViewportIndexing = FALSE; ++ data->VariableShadingRateTier = D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED; ++ data->ShadingRateImageTileSize = 0; ++ data->BackgroundProcessingSupported = FALSE; ++ ++ TRACE("Additional shading rates support %#x.\n", data->AdditionalShadingRatesSupported); ++ TRACE("Per-primitive shading rates with viewport indexing %#x.\n", ++ data->PerPrimitiveShadingRateSupportedWithViewportIndexing); ++ TRACE("Variable shading rate tier %#x.\n", data->VariableShadingRateTier); ++ TRACE("Shading rate image tile size %#x.\n", data->ShadingRateImageTileSize); ++ TRACE("Background processing support %#x.\n", data->BackgroundProcessingSupported); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS7: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS7 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->MeshShaderTier = D3D12_MESH_SHADER_TIER_NOT_SUPPORTED; ++ data->SamplerFeedbackTier = D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED; ++ ++ TRACE("Mesh shading tier %#x.\n", data->MeshShaderTier); ++ TRACE("Sampler feedback tier %#x.\n", data->SamplerFeedbackTier); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS8: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS8 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->UnalignedBlockTexturesSupported = FALSE; ++ ++ TRACE("Unaligned block texture support %#x.\n", data->UnalignedBlockTexturesSupported); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS9: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS9 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->MeshShaderPipelineStatsSupported = FALSE; ++ data->MeshShaderSupportsFullRangeRenderTargetArrayIndex = FALSE; ++ data->AtomicInt64OnTypedResourceSupported = FALSE; ++ data->AtomicInt64OnGroupSharedSupported = FALSE; ++ data->DerivativesInMeshAndAmplificationShadersSupported = FALSE; ++ data->WaveMMATier = D3D12_WAVE_MMA_TIER_NOT_SUPPORTED; ++ ++ TRACE("Mesh shader pipeline stats support %#x.\n", data->MeshShaderPipelineStatsSupported); ++ TRACE("Mesh shader RT array index full range %#x.\n", data->MeshShaderSupportsFullRangeRenderTargetArrayIndex); ++ TRACE("Atomic int64 on typed resource %#x.\n", data->AtomicInt64OnTypedResourceSupported); ++ TRACE("Atomic int64 on group shared mem %#x.\n", data->AtomicInt64OnGroupSharedSupported); ++ TRACE("Derivatives in mesh and amp shaders %#x.\n", data->DerivativesInMeshAndAmplificationShadersSupported); ++ TRACE("Wave MMA tier %#x.\n", data->WaveMMATier); ++ return S_OK; ++ } ++ + default: + FIXME("Unhandled feature %#x.\n", feature); + return E_NOTIMPL; +@@ -3402,8 +3487,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device7 + struct d3d12_root_signature *object; + HRESULT hr; + +- TRACE("iface %p, node_mask 0x%08x, bytecode %p, bytecode_length %lu, riid %s, root_signature %p.\n", +- iface, node_mask, bytecode, bytecode_length, debugstr_guid(riid), root_signature); ++ TRACE("iface %p, node_mask 0x%08x, bytecode %p, bytecode_length %"PRIuPTR", riid %s, root_signature %p.\n", ++ iface, node_mask, bytecode, (uintptr_t)bytecode_length, debugstr_guid(riid), root_signature); + + debug_ignored_node_mask(node_mask); + +@@ -4040,7 +4125,8 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device7 *iface + static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device7 *iface, + const void *blob, SIZE_T blob_size, REFIID iid, void **lib) + { +- FIXME("iface %p, blob %p, blob_size %lu, iid %s, lib %p stub!\n", iface, blob, blob_size, debugstr_guid(iid), lib); ++ FIXME("iface %p, blob %p, blob_size %"PRIuPTR", iid %s, lib %p stub!\n", ++ iface, blob, (uintptr_t)blob_size, debugstr_guid(iid), lib); + + return DXGI_ERROR_UNSUPPORTED; + } +@@ -4237,9 +4323,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device7 *i + SIZE_T data_size_in_bytes, REFIID iid, void **meta_command) + { + FIXME("iface %p, command_id %s, node_mask %#x, parameters_data %p, " +- "data_size_in_bytes %lu, iid %s, meta_command %p stub!\n", iface, ++ "data_size_in_bytes %"PRIuPTR", iid %s, meta_command %p stub!\n", iface, + debugstr_guid(command_id), node_mask, parameters_data, +- data_size_in_bytes, debugstr_guid(iid), meta_command); ++ (uintptr_t)data_size_in_bytes, debugstr_guid(iid), meta_command); + + return E_NOTIMPL; + } +diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c +index c04f48702a0..8f4d18358d2 100644 +--- a/libs/vkd3d/libs/vkd3d/resource.c ++++ b/libs/vkd3d/libs/vkd3d/resource.c +@@ -2314,14 +2314,14 @@ static void *vkd3d_desc_object_cache_get(struct vkd3d_desc_object_cache *cache) + + STATIC_ASSERT(!(ARRAY_SIZE(cache->heads) & HEAD_INDEX_MASK)); + +- i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK; ++ i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK; + for (;;) + { + if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) + { + if ((u.object = cache->heads[i].head)) + { +- vkd3d_atomic_decrement(&cache->free_count); ++ vkd3d_atomic_decrement_u32(&cache->free_count); + cache->heads[i].head = u.header->next; + vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); + return u.object; +@@ -2345,7 +2345,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache, + + /* Using the same index as above may result in a somewhat uneven distribution, + * but the main objective is to avoid costly spinlock contention. */ +- i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK; ++ i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK; + for (;;) + { + if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) +@@ -2357,7 +2357,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache, + u.header->next = head; + cache->heads[i].head = u.object; + vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); +- vkd3d_atomic_increment(&cache->free_count); ++ vkd3d_atomic_increment_u32(&cache->free_count); + } + + #undef HEAD_INDEX_MASK +@@ -2429,7 +2429,7 @@ void vkd3d_view_decref(void *view, struct d3d12_device *device) + { + union d3d12_desc_object u = {view}; + +- if (vkd3d_atomic_decrement(&u.header->refcount)) ++ if (vkd3d_atomic_decrement_u32(&u.header->refcount)) + return; + + if (u.header->magic != VKD3D_DESCRIPTOR_MAGIC_CBV) +diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c +index 28913a83e8c..ac79ae5ddff 100644 +--- a/libs/vkd3d/libs/vkd3d/utils.c ++++ b/libs/vkd3d/libs/vkd3d/utils.c +@@ -678,6 +678,11 @@ const char *debug_d3d12_shader_component_mapping(unsigned int mapping) + debug_d3d12_shader_component(D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(3, mapping))); + } + ++const char *debug_gpu_handle(D3D12_GPU_DESCRIPTOR_HANDLE handle) ++{ ++ return vkd3d_dbg_sprintf("{%#"PRIx64"}", handle.ptr); ++} ++ + const char *debug_vk_extent_3d(VkExtent3D extent) + { + return vkd3d_dbg_sprintf("(%u, %u, %u)", +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c +index f71b370137f..7919b7d8760 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c +@@ -222,8 +222,8 @@ HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_s + struct d3d12_root_signature_deserializer *object; + HRESULT hr; + +- TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", +- data, data_size, debugstr_guid(iid), deserializer); ++ TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n", ++ data, (uintptr_t)data_size, debugstr_guid(iid), deserializer); + + if (!(object = vkd3d_malloc(sizeof(*object)))) + return E_OUTOFMEMORY; +@@ -406,8 +406,8 @@ HRESULT vkd3d_create_versioned_root_signature_deserializer(const void *data, SIZ + struct vkd3d_shader_code dxbc = {data, data_size}; + HRESULT hr; + +- TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", +- data, data_size, debugstr_guid(iid), deserializer); ++ TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n", ++ data, (uintptr_t)data_size, debugstr_guid(iid), deserializer); + + if (!(object = vkd3d_malloc(sizeof(*object)))) + return E_OUTOFMEMORY; +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +index 8ecf6764ab6..78f4f3514e2 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +@@ -257,16 +257,6 @@ static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) + { + } + +-static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x) +-{ +- return InterlockedIncrement((LONG volatile *)x); +-} +- +-static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x) +-{ +- return InterlockedDecrement((LONG volatile *)x); +-} +- + static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg) + { + return InterlockedCompareExchange((LONG volatile *)x, xchg, cmp) == cmp; +@@ -389,24 +379,6 @@ static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) + ERR("Could not destroy the condition variable, error %d.\n", ret); + } + +-# if HAVE_SYNC_SUB_AND_FETCH +-static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x) +-{ +- return __sync_sub_and_fetch(x, 1); +-} +-# else +-# error "vkd3d_atomic_decrement() not implemented for this platform" +-# endif /* HAVE_SYNC_SUB_AND_FETCH */ +- +-# if HAVE_SYNC_ADD_AND_FETCH +-static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x) +-{ +- return __sync_add_and_fetch(x, 1); +-} +-# else +-# error "vkd3d_atomic_increment() not implemented for this platform" +-# endif /* HAVE_SYNC_ADD_AND_FETCH */ +- + # if HAVE_SYNC_BOOL_COMPARE_AND_SWAP + static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg) + { +@@ -1963,6 +1935,7 @@ HRESULT return_interface(void *iface, REFIID iface_iid, REFIID requested_iid, vo + const char *debug_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle); + const char *debug_d3d12_box(const D3D12_BOX *box); + const char *debug_d3d12_shader_component_mapping(unsigned int mapping); ++const char *debug_gpu_handle(D3D12_GPU_DESCRIPTOR_HANDLE handle); + const char *debug_vk_extent_3d(VkExtent3D extent); + const char *debug_vk_memory_heap_flags(VkMemoryHeapFlags flags); + const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags); +-- +2.43.0 + diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-5eba031fa1c7f606ffacf3cb7310615728d.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-5eba031fa1c7f606ffacf3cb7310615728d.patch new file mode 100644 index 00000000..fa9314b1 --- /dev/null +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-5eba031fa1c7f606ffacf3cb7310615728d.patch @@ -0,0 +1,113 @@ +From ed09b9ae4c28d9a6b6d3a47cfe2de6bf6791db8f Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 10 Feb 2024 18:23:30 +1100 +Subject: [PATCH 5/5] Updated vkd3d to + 5eba031fa1c7f606ffacf3cb7310615728d150f0. + +--- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 18 ++++++++++++++++-- + libs/vkd3d/libs/vkd3d/device.c | 4 ++-- + 2 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 8dc353e11c0..5f6334a4d19 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -5572,11 +5572,11 @@ attribute: + $$->name = $2; + hlsl_block_init(&$$->instrs); + hlsl_block_add_block(&$$->instrs, $4.instrs); +- vkd3d_free($4.instrs); + $$->loc = @$; + $$->args_count = $4.args_count; + for (i = 0; i < $4.args_count; ++i) + hlsl_src_from_node(&$$->args[i], $4.args[i]); ++ free_parse_initializer(&$4); + } + + attribute_list: +@@ -5807,7 +5807,11 @@ func_prototype: + } + else + { +- free($1.attrs); ++ unsigned int i; ++ ++ for (i = 0; i < $1.count; ++i) ++ hlsl_free_attribute((void *)$1.attrs[i]); ++ vkd3d_free($1.attrs); + } + $$ = $2; + } +@@ -6992,8 +6996,10 @@ primary_expr: + if (!(var = hlsl_get_var(ctx->cur_scope, $1))) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable \"%s\" is not defined.", $1); ++ vkd3d_free($1); + YYABORT; + } ++ vkd3d_free($1); + if (!(load = hlsl_new_var_load(ctx, var, &@1))) + YYABORT; + if (!($$ = make_block(ctx, &load->node))) +@@ -7067,12 +7073,17 @@ postfix_expr: + if (!(field = get_struct_field(type->e.record.fields, type->e.record.field_count, $3))) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", $3); ++ vkd3d_free($3); + YYABORT; + } + + field_idx = field - type->e.record.fields; + if (!add_record_access(ctx, $1, node, field_idx, &@2)) ++ { ++ vkd3d_free($3); + YYABORT; ++ } ++ vkd3d_free($3); + $$ = $1; + } + else if (hlsl_is_numeric_type(node->data_type)) +@@ -7082,14 +7093,17 @@ postfix_expr: + if (!(swizzle = get_swizzle(ctx, node, $3, &@3))) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle \"%s\".", $3); ++ vkd3d_free($3); + YYABORT; + } + hlsl_block_add_instr($1, swizzle); ++ vkd3d_free($3); + $$ = $1; + } + else + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript \"%s\".", $3); ++ vkd3d_free($3); + YYABORT; + } + } +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index 90272818b3d..1e094690f42 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -3888,7 +3888,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device7 * + struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + FIXME("iface %p, object %p, attributes %p, access %#x, name %s, handle %p stub!\n", +- iface, object, attributes, access, debugstr_w(name, device->wchar_size), handle); ++ iface, object, attributes, (uint32_t)access, debugstr_w(name, device->wchar_size), handle); + + return E_NOTIMPL; + } +@@ -3908,7 +3908,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic + struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + FIXME("iface %p, name %s, access %#x, handle %p stub!\n", +- iface, debugstr_w(name, device->wchar_size), access, handle); ++ iface, debugstr_w(name, device->wchar_size), (uint32_t)access, handle); + + return E_NOTIMPL; + } +-- +2.43.0 +