From 1b2e959b75d5a622c2fb23436b974c2cb9e5dc45 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 28 May 2025 07:36:25 +1000 Subject: [PATCH] Updated vkd3d-latest patchset --- ...-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch | 1416 +++++++++++++++++ ...-87ec2d98973432531d7d9d08dfc837376f9.patch | 308 ++++ 2 files changed, 1724 insertions(+) create mode 100644 patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch create mode 100644 patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch new file mode 100644 index 00000000..83f41ce5 --- /dev/null +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch @@ -0,0 +1,1416 @@ +From c54c3405e484d6893c44e0d185256acdb4b39f6f 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. + +--- + libs/vkd3d/include/private/vkd3d_common.h | 2 +- + libs/vkd3d/include/private/vkd3d_version.h | 2 +- + libs/vkd3d/libs/vkd3d-common/blob.c | 1 + + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 + + libs/vkd3d/libs/vkd3d-shader/dxil.c | 257 ++++++++++-------- + libs/vkd3d/libs/vkd3d-shader/fx.c | 49 ++-- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 26 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 40 +-- + libs/vkd3d/libs/vkd3d-shader/preproc.l | 1 + + libs/vkd3d/libs/vkd3d-shader/tpf.c | 10 + + .../libs/vkd3d-shader/vkd3d_shader_main.c | 57 ++-- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 2 + + .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 2 + + 13 files changed, 281 insertions(+), 170 deletions(-) + +diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h +index beb23257fb7..93c8a0bec7c 100644 +--- a/libs/vkd3d/include/private/vkd3d_common.h ++++ b/libs/vkd3d/include/private/vkd3d_common.h +@@ -278,7 +278,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) + { + #ifdef _MSC_VER + return __popcnt(v); +-#elif defined(__MINGW32__) ++#elif defined(HAVE_BUILTIN_POPCOUNT) + return __builtin_popcount(v); + #else + v -= (v >> 1) & 0x55555555; +diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h +index 0edc4428022..ae34ff97e25 100644 +--- a/libs/vkd3d/include/private/vkd3d_version.h ++++ b/libs/vkd3d/include/private/vkd3d_version.h +@@ -1 +1 @@ +-#define VKD3D_VCS_ID " (Wine bundled)" ++#define VKD3D_VCS_ID " (git 379b297d)" +diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c +index f60ef7db769..c2c6ad67804 100644 +--- a/libs/vkd3d/libs/vkd3d-common/blob.c ++++ b/libs/vkd3d/libs/vkd3d-common/blob.c +@@ -20,6 +20,7 @@ + #define WIDL_C_INLINE_WRAPPERS + #endif + #define COBJMACROS ++ + #define CONST_VTABLE + #include "vkd3d.h" + #include "vkd3d_blob.h" +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index 4521bfabd8e..dc1678795e8 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -88,6 +88,7 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface", + [VKD3DSIH_DCL_OUTPUT ] = "dcl_output", + [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", ++ [VKD3DSIH_DCL_OUTPUT_SGV ] = "dcl_output_sgv", + [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv", + [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", + [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw", +@@ -1865,6 +1866,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, + case VKD3DSIH_DCL_INPUT_PS_SGV: + case VKD3DSIH_DCL_INPUT_SGV: + case VKD3DSIH_DCL_INPUT_SIV: ++ case VKD3DSIH_DCL_OUTPUT_SGV: + case VKD3DSIH_DCL_OUTPUT_SIV: + shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, ""); + shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, ""); +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index ca79939a39b..c9e99c6a9ba 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -655,6 +655,12 @@ enum sm6_value_type + VALUE_TYPE_INVALID, + }; + ++struct sm6_index ++{ ++ const struct sm6_value *index; ++ bool is_in_bounds; ++}; ++ + struct sm6_function_data + { + const char *name; +@@ -678,16 +684,19 @@ struct sm6_icb_data + { + unsigned int data_id; + unsigned int id; ++ struct sm6_index index; + }; + + struct sm6_idxtemp_data + { + unsigned int id; ++ struct sm6_index index; + }; + + struct sm6_groupsharedmem_data + { + unsigned int id; ++ struct sm6_index index; + }; + + struct sm6_value +@@ -2433,7 +2442,11 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type + return VKD3D_DATA_UINT; + } + +-static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value) ++static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, ++ struct sm6_parser *sm6); ++ ++static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value, ++ struct sm6_parser *sm6) + { + enum vkd3d_data_type data_type; + +@@ -2451,15 +2464,24 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + break; + + case VALUE_TYPE_ICB: +- register_init_with_id(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, value->u.icb.id); ++ vsir_register_init(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, 2); ++ reg->idx[0].offset = value->u.icb.id; ++ register_index_address_init(®->idx[1], value->u.icb.index.index, sm6); ++ reg->idx[1].is_in_bounds = value->u.icb.index.is_in_bounds; + break; + + case VALUE_TYPE_IDXTEMP: +- register_init_with_id(reg, VKD3DSPR_IDXTEMP, data_type, value->u.idxtemp.id); ++ vsir_register_init(reg, VKD3DSPR_IDXTEMP, data_type, 2); ++ reg->idx[0].offset = value->u.idxtemp.id; ++ register_index_address_init(®->idx[1], value->u.idxtemp.index.index, sm6); ++ reg->idx[1].is_in_bounds = value->u.idxtemp.index.is_in_bounds; + break; + + case VALUE_TYPE_GROUPSHAREDMEM: +- register_init_with_id(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, value->u.groupsharedmem.id); ++ vsir_register_init(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, 2); ++ reg->idx[0].offset = value->u.groupsharedmem.id; ++ register_index_address_init(®->idx[1], value->u.groupsharedmem.index.index, sm6); ++ reg->idx[1].is_in_bounds = value->u.groupsharedmem.index.is_in_bounds; + break; + + case VALUE_TYPE_UNDEFINED: +@@ -2490,7 +2512,7 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value * + + value->value_type = VALUE_TYPE_SSA; + value->u.ssa.id = id; +- sm6_register_from_value(&value->reg, value); ++ sm6_register_from_value(&value->reg, value, sm6); + } + + static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value) +@@ -2547,10 +2569,11 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned + param->modifiers = VKD3DSPSM_NONE; + } + +-static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src) ++static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src, ++ struct sm6_parser *sm6) + { + src_param_init(param); +- sm6_register_from_value(¶m->reg, src); ++ sm6_register_from_value(¶m->reg, src, sm6); + } + + static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param, +@@ -2570,12 +2593,12 @@ static void src_param_make_constant_uint(struct vkd3d_shader_src_param *param, u + static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, + struct sm6_parser *sm6) + { +- if (sm6_value_is_constant(address)) ++ if (address && sm6_value_is_constant(address)) + { + idx->offset = sm6_value_get_constant_uint(address); + idx->rel_addr = NULL; + } +- else if (sm6_value_is_undef(address)) ++ else if (!address || sm6_value_is_undef(address)) + { + idx->offset = 0; + idx->rel_addr = NULL; +@@ -2584,7 +2607,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, + { + struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1); + if (rel_addr) +- src_param_init_from_value(rel_addr, address); ++ src_param_init_from_value(rel_addr, address, sm6); + idx->offset = 0; + idx->rel_addr = rel_addr; + } +@@ -2619,7 +2642,7 @@ static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio + + dst_param_init(param); + sm6_parser_init_ssa_value(sm6, dst); +- sm6_register_from_value(¶m->reg, dst); ++ sm6_register_from_value(¶m->reg, dst, sm6); + return true; + } + +@@ -2631,7 +2654,7 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio + + dst_param_init_vector(param, component_count); + sm6_parser_init_ssa_value(sm6, dst); +- sm6_register_from_value(¶m->reg, dst); ++ sm6_register_from_value(¶m->reg, dst, sm6); + } + + static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) +@@ -2928,7 +2951,7 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru + value->type = fwd_type; + value->value_type = VALUE_TYPE_SSA; + value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6); +- sm6_register_from_value(&value->reg, value); ++ sm6_register_from_value(&value->reg, value, sm6); + } + } + +@@ -3130,13 +3153,34 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co + return VKD3D_OK; + } + ++static struct sm6_index *sm6_get_value_index(struct sm6_parser *sm6, struct sm6_value *value) ++{ ++ switch (value->value_type) ++ { ++ case VALUE_TYPE_ICB: ++ return &value->u.icb.index; ++ ++ case VALUE_TYPE_IDXTEMP: ++ return &value->u.idxtemp.index; ++ ++ case VALUE_TYPE_GROUPSHAREDMEM: ++ return &value->u.groupsharedmem.index; ++ ++ default: ++ WARN("Cannot index into value of type %#x.\n", value->value_type); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Cannot index into value of type %#x.", value->value_type); ++ return NULL; ++ } ++} ++ + static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, const struct dxil_record *record, + struct sm6_value *dst) + { + const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type; +- struct vkd3d_shader_register reg; + struct sm6_value *operands[3]; + unsigned int i, j, offset; ++ struct sm6_index *index; + uint64_t value; + + i = 0; +@@ -3178,9 +3222,13 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + } + } + +- sm6_register_from_value(®, operands[0]); ++ *dst = *operands[0]; ++ index = sm6_get_value_index(sm6, dst); ++ ++ if (!index) ++ return VKD3D_ERROR_INVALID_SHADER; + +- if (reg.idx_count > 1) ++ if (index->index) + { + WARN("Unsupported stacked GEP.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -3203,8 +3251,6 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + return VKD3D_ERROR_INVALID_SHADER; + } + +- dst->structure_stride = operands[0]->structure_stride; +- + ptr_type = operands[0]->type; + if (!sm6_type_is_pointer(ptr_type)) + { +@@ -3241,10 +3287,11 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + "Module does not define a pointer type for a constexpr GEP result."); + return VKD3D_ERROR_INVALID_SHADER; + } +- dst->reg = reg; +- dst->reg.idx[1].offset = offset; +- dst->reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; +- dst->reg.idx_count = 2; ++ ++ index->index = operands[2]; ++ index->is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; ++ ++ sm6_register_from_value(&dst->reg, dst, sm6); + + return VKD3D_OK; + } +@@ -3422,7 +3469,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + case CST_CODE_UNDEF: + dxil_record_validate_operand_max_count(record, 0, sm6); + dst->value_type = VALUE_TYPE_UNDEFINED; +- sm6_register_from_value(&dst->reg, dst); ++ sm6_register_from_value(&dst->reg, dst, sm6); + break; + + default: +@@ -3430,7 +3477,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Constant code %u is unhandled.", record->code); + dst->value_type = VALUE_TYPE_INVALID; +- sm6_register_from_value(&dst->reg, dst); ++ sm6_register_from_value(&dst->reg, dst, sm6); + break; + } + +@@ -3537,7 +3584,7 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru + + dst->value_type = VALUE_TYPE_IDXTEMP; + dst->u.idxtemp.id = ins->declaration.indexable_temp.register_idx; +- sm6_register_from_value(&dst->reg, dst); ++ sm6_register_from_value(&dst->reg, dst, sm6); + } + + static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type, +@@ -3551,8 +3598,8 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 + dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; + dst->u.groupsharedmem.id = sm6->tgsm_count++; + dst->structure_stride = 0; +- sm6_register_from_value(&dst->reg, dst); +- sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst); ++ sm6_register_from_value(&dst->reg, dst, sm6); ++ sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst, sm6); + ins->declaration.tgsm_raw.alignment = alignment; + byte_count = elem_type->u.width / 8u; + if (byte_count != 4) +@@ -3576,8 +3623,8 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str + dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; + dst->u.groupsharedmem.id = sm6->tgsm_count++; + dst->structure_stride = elem_type->u.width / 8u; +- sm6_register_from_value(&dst->reg, dst); +- sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst); ++ sm6_register_from_value(&dst->reg, dst, sm6); ++ sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst, sm6); + if (dst->structure_stride != 4) + { + FIXME("Unsupported structure stride %u.\n", dst->structure_stride); +@@ -3891,7 +3938,7 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + value->u.icb.id = icb->register_idx; + else + value->u.icb.id = 0; +- sm6_register_from_value(&value->reg, value); ++ sm6_register_from_value(&value->reg, value, sm6); + } + + return VKD3D_OK; +@@ -3912,12 +3959,12 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, + } + + static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params, +- const struct sm6_value **operands, unsigned int count) ++ const struct sm6_value **operands, unsigned int count, struct sm6_parser *sm6) + { + unsigned int i; + + for (i = 0; i < count; ++i) +- src_param_init_from_value(&src_params[i], operands[i]); ++ src_param_init_from_value(&src_params[i], operands[i], sm6); + } + + static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( +@@ -4228,7 +4275,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ + || !sm6_value_validate_is_backward_ref(ptr, sm6)) + return; + +- sm6_register_from_value(®, ptr); ++ sm6_register_from_value(®, ptr, sm6); + + if (reg.type != VKD3DSPR_GROUPSHAREDMEM) + { +@@ -4284,12 +4331,12 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ + src_param_init_vector_from_reg(&src_params[0], &coord); + else + src_param_make_constant_uint(&src_params[0], 0); +- src_param_init_from_value(&src_params[1], src); ++ src_param_init_from_value(&src_params[1], src, sm6); + + sm6_parser_init_ssa_value(sm6, dst); + + dst_params = instruction_dst_params_alloc(ins, 2, sm6); +- sm6_register_from_value(&dst_params[0].reg, dst); ++ sm6_register_from_value(&dst_params[0].reg, dst, sm6); + dst_param_init(&dst_params[0]); + + dst_params[1].reg = reg; +@@ -4459,8 +4506,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +- src_param_init_from_value(&src_params[0], a); +- src_param_init_from_value(&src_params[1], b); ++ src_param_init_from_value(&src_params[0], a, sm6); ++ src_param_init_from_value(&src_params[1], b, sm6); + if (code == BINOP_SUB) + src_params[1].modifiers = VKD3DSPSM_NEG; + +@@ -4474,7 +4521,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]); + sm6_parser_init_ssa_value(sm6, dst); +- sm6_register_from_value(&dst_params[index].reg, dst); ++ sm6_register_from_value(&dst_params[index].reg, dst, sm6); + vsir_dst_param_init_null(&dst_params[index ^ 1]); + } + else +@@ -4536,7 +4583,7 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record + dxil_record_validate_operand_max_count(record, i, sm6); + + code_block->terminator.type = TERMINATOR_COND_BR; +- sm6_register_from_value(&code_block->terminator.conditional_reg, value); ++ sm6_register_from_value(&code_block->terminator.conditional_reg, value, sm6); + code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6); + code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6); + } +@@ -4607,7 +4654,7 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st + unsigned int i; + + for (i = 0; i < component_count; ++i) +- sm6_register_from_value(&operand_regs[i], operands[i]); ++ sm6_register_from_value(&operand_regs[i], operands[i], sm6); + + return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); + } +@@ -4623,11 +4670,11 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s + { + if (!z_operand && operands[component_count]->value_type == VALUE_TYPE_UNDEFINED) + break; +- sm6_register_from_value(&operand_regs[component_count], operands[component_count]); ++ sm6_register_from_value(&operand_regs[component_count], operands[component_count], sm6); + } + + if (z_operand) +- sm6_register_from_value(&operand_regs[component_count++], z_operand); ++ sm6_register_from_value(&operand_regs[component_count++], z_operand, sm6); + + return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); + } +@@ -4741,7 +4788,7 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o + vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op)); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -4780,8 +4827,8 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ + vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type)); + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +- src_param_init_from_value(&src_params[0], operands[0]); +- src_param_init_from_value(&src_params[1], operands[1]); ++ src_param_init_from_value(&src_params[0], operands[0], sm6); ++ src_param_init_from_value(&src_params[1], operands[1], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -4852,7 +4899,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr + } + else + { +- sm6_register_from_value(®, operands[coord_idx]); ++ sm6_register_from_value(®, operands[coord_idx], sm6); + } + + for (i = coord_idx + coord_count; i < coord_idx + 3; ++i) +@@ -4873,14 +4920,14 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr + return; + src_param_init_vector_from_reg(&src_params[0], ®); + if (is_cmp_xchg) +- src_param_init_from_value(&src_params[1], operands[4]); +- src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5]); ++ src_param_init_from_value(&src_params[1], operands[4], sm6); ++ src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5], sm6); + + sm6_parser_init_ssa_value(sm6, dst); + + dst_params = instruction_dst_params_alloc(ins, 2, sm6); + dst_param_init(&dst_params[0]); +- sm6_register_from_value(&dst_params[0].reg, dst); ++ sm6_register_from_value(&dst_params[0].reg, dst, sm6); + dst_param_init(&dst_params[1]); + sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); + } +@@ -5142,7 +5189,7 @@ static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DISCARD); + + if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + } + + static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -5256,7 +5303,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri + register_index_address_init(&src_params[0].reg.idx[0], operands[1], sm6); + + if (op == DX_EVAL_SAMPLE_INDEX) +- src_param_init_from_value(&src_params[1], operands[3]); ++ src_param_init_from_value(&src_params[1], operands[3], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -5270,7 +5317,7 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + src_param->modifiers = VKD3DSPSM_ABS; + + instruction_dst_param_init_ssa_scalar(ins, sm6); +@@ -5345,7 +5392,7 @@ static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opco + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) + return; + for (i = 0; i < 3; ++i) +- src_param_init_from_value(&src_params[i], operands[i]); ++ src_param_init_from_value(&src_params[i], operands[i], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -5375,7 +5422,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in + if (is_texture) + { + ins->flags = VKD3DSI_RESINFO_UINT; +- src_param_init_from_value(&src_params[0], operands[1]); ++ src_param_init_from_value(&src_params[0], operands[1], sm6); + component_count = VKD3D_VEC4_SIZE; + + if (resource_kind_is_multisampled(resource_kind)) +@@ -5448,7 +5495,7 @@ static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsi + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) + return; + for (i = 0; i < 3; ++i) +- src_param_init_from_value(&src_params[i], operands[i]); ++ src_param_init_from_value(&src_params[i], operands[i], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -5589,7 +5636,7 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -5631,7 +5678,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i + operand_count = 2 + !raw; + if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) + return; +- src_params_init_from_operands(src_params, &operands[1], operand_count - 1); ++ src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6); + src_param_init_vector_from_handle(sm6, &src_params[operand_count - 1], &resource->u.handle); + + instruction_dst_param_init_ssa_vector(ins, component_count, sm6); +@@ -5697,7 +5744,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ + + if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) + return; +- src_params_init_from_operands(src_params, &operands[1], operand_count - 1); ++ src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6); + data.data_type = VKD3D_DATA_UINT; + src_param_init_vector_from_reg(&src_params[operand_count - 1], &data); + +@@ -5736,7 +5783,7 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri + + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +- src_param_init_from_value(&src_params[0], operands[1]); ++ src_param_init_from_value(&src_params[0], operands[1], sm6); + if (!sm6_value_is_undef(operands[2])) + { + /* Constant zero would be ok, but is not worth checking for unless it shows up. */ +@@ -5801,7 +5848,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr + + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +- src_param_init_from_value(&src_params[0], operands[1]); ++ src_param_init_from_value(&src_params[0], operands[1], sm6); + if (!sm6_value_is_undef(operands[2])) + { + /* Constant zero would have no effect, but is not worth checking for unless it shows up. */ +@@ -5856,14 +5903,14 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in + if (op == DX_TEX2DMS_GET_SAMPLE_POS) + { + src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); +- src_param_init_from_value(&src_params[1], operands[1]); ++ src_param_init_from_value(&src_params[1], operands[1], sm6); + } + else + { + src_param_init_vector(&src_params[0], 2); + vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0); + src_params[0].reg.dimension = VSIR_DIMENSION_VEC4; +- src_param_init_from_value(&src_params[1], operands[0]); ++ src_param_init_from_value(&src_params[1], operands[0], sm6); + } + + instruction_dst_param_init_ssa_vector(ins, 2, sm6); +@@ -5925,7 +5972,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ + instruction_init_with_resource(ins, (op == DX_SAMPLE_B) ? VKD3DSIH_SAMPLE_B : VKD3DSIH_SAMPLE_LOD, + resource, sm6); + src_params = instruction_src_params_alloc(ins, 4, sm6); +- src_param_init_from_value(&src_params[3], operands[9]); ++ src_param_init_from_value(&src_params[3], operands[9], sm6); + break; + case DX_SAMPLE_C: + clamp_idx = 10; +@@ -5934,7 +5981,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ + instruction_init_with_resource(ins, (op == DX_SAMPLE_C_LZ) ? VKD3DSIH_SAMPLE_C_LZ : VKD3DSIH_SAMPLE_C, + resource, sm6); + src_params = instruction_src_params_alloc(ins, 4, sm6); +- src_param_init_from_value(&src_params[3], operands[9]); ++ src_param_init_from_value(&src_params[3], operands[9], sm6); + component_count = 1; + break; + case DX_SAMPLE_GRAD: +@@ -6003,7 +6050,7 @@ static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsi + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + + if (instruction_dst_param_init_ssa_scalar(ins, sm6)) + ins->dst->modifiers = VKD3DSPDM_SATURATE; +@@ -6021,7 +6068,7 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SINCOS); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + + sm6_parser_init_ssa_value(sm6, dst); + +@@ -6029,7 +6076,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]); +- sm6_register_from_value(&dst_params[index].reg, dst); ++ sm6_register_from_value(&dst_params[index].reg, dst, sm6); + vsir_dst_param_init_null(&dst_params[index ^ 1]); + } + +@@ -6042,7 +6089,7 @@ static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intr + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + + instruction_dst_param_init_ssa_vector(ins, 2, sm6); + } +@@ -6108,7 +6155,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr + } + + if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) +- src_param_init_from_value(src_param, value); ++ src_param_init_from_value(src_param, value, sm6); + } + + static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -6150,7 +6197,7 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in + instruction_init_with_resource(ins, extended_offset ? VKD3DSIH_GATHER4_PO_C : VKD3DSIH_GATHER4_C, resource, sm6); + if (!(src_params = instruction_src_params_alloc(ins, 4 + extended_offset, sm6))) + return; +- src_param_init_from_value(&src_params[3 + extended_offset], operands[9]); ++ src_param_init_from_value(&src_params[3 + extended_offset], operands[9], sm6); + } + + src_param_init_vector_from_reg(&src_params[0], &coord); +@@ -6213,7 +6260,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr + src_param_init_vector_from_reg(&src_params[0], &coord); + src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); + if (is_multisample) +- src_param_init_from_value(&src_params[2], mip_level_or_sample_count); ++ src_param_init_from_value(&src_params[2], mip_level_or_sample_count, sm6); + + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); + } +@@ -6277,7 +6324,7 @@ static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum d + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_WAVE_ACTIVE_BALLOT); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); + } +@@ -6317,7 +6364,7 @@ static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_i + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -6368,7 +6415,7 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, operands[0]); ++ src_param_init_from_value(src_param, operands[0], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -6645,7 +6692,7 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade + return; + + dst->value_type = VALUE_TYPE_INVALID; +- sm6_register_from_value(&dst->reg, dst); ++ sm6_register_from_value(&dst->reg, dst, sm6); + } + + static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -6896,7 +6943,7 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor + + if (handler_idx == VKD3DSIH_NOP) + { +- sm6_register_from_value(&dst->reg, value); ++ sm6_register_from_value(&dst->reg, value, sm6); + /* Set the result type for casts from 16-bit min precision. */ + if (type->u.width != 16) + dst->reg.data_type = vkd3d_data_type_from_sm6_type(type); +@@ -6905,7 +6952,7 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_from_value(src_param, value); ++ src_param_init_from_value(src_param, value, sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + +@@ -7051,8 +7098,8 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor + + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +- src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a); +- src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b); ++ src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a, sm6); ++ src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b, sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -7074,7 +7121,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re + || !sm6_value_validate_is_backward_ref(ptr, sm6)) + return; + +- sm6_register_from_value(®, ptr); ++ sm6_register_from_value(®, ptr, sm6); + + if (reg.type != VKD3DSPR_GROUPSHAREDMEM) + { +@@ -7129,14 +7176,14 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) + return; + src_param_make_constant_uint(&src_params[0], 0); +- src_param_init_from_value(&src_params[1], cmp); +- src_param_init_from_value(&src_params[2], new); ++ src_param_init_from_value(&src_params[1], cmp, sm6); ++ src_param_init_from_value(&src_params[2], new, sm6); + + sm6_parser_init_ssa_value(sm6, dst); + + if (!(dst_params = instruction_dst_params_alloc(ins, 2, sm6))) + return; +- sm6_register_from_value(&dst_params[0].reg, dst); ++ sm6_register_from_value(&dst_params[0].reg, dst, sm6); + dst_param_init(&dst_params[0]); + dst_params[1].reg = reg; + dst_param_init(&dst_params[1]); +@@ -7195,7 +7242,7 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- sm6_register_from_value(&src_param->reg, src); ++ sm6_register_from_value(&src_param->reg, src, sm6); + src_param_init_scalar(src_param, elem_idx); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +@@ -7208,9 +7255,8 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + unsigned int elem_idx, operand_idx = 2; + enum bitcode_address_space addr_space; + const struct sm6_value *elem_value; +- struct vkd3d_shader_register reg; + const struct sm6_value *src; +- bool is_in_bounds; ++ struct sm6_index *index; + + if (!dxil_record_validate_operand_min_count(record, 5, sm6) + || !(type = sm6_parser_get_type(sm6, record->operands[1])) +@@ -7222,9 +7268,13 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + return; + } + +- sm6_register_from_value(®, src); ++ *dst = *src; ++ index = sm6_get_value_index(sm6, dst); + +- if (reg.idx_count > 1) ++ if (!index) ++ return; ++ ++ if (index->index) + { + WARN("Unsupported stacked GEP.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -7232,8 +7282,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + return; + } + +- is_in_bounds = record->operands[0]; +- + if ((pointee_type = src->type->u.pointer.type) != type) + { + WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type->class, +@@ -7293,13 +7341,10 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + return; + } + +- reg.idx[1].offset = 0; +- register_index_address_init(®.idx[1], elem_value, sm6); +- reg.idx[1].is_in_bounds = is_in_bounds; +- reg.idx_count = 2; ++ index->index = elem_value; ++ index->is_in_bounds = record->operands[0]; + +- dst->reg = reg; +- dst->structure_stride = src->structure_stride; ++ sm6_register_from_value(&dst->reg, dst, sm6); + + ins->opcode = VKD3DSIH_NOP; + } +@@ -7348,7 +7393,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor + if (record->operands[i]) + WARN("Ignoring volatile modifier.\n"); + +- sm6_register_from_value(®, ptr); ++ sm6_register_from_value(®, ptr, sm6); + + if (ptr->structure_stride) + { +@@ -7363,7 +7408,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor + src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); + /* Struct offset is always zero as there is no struct, just an array. */ + src_param_make_constant_uint(&src_params[1], 0); +- src_param_init_from_value(&src_params[2], ptr); ++ src_param_init_from_value(&src_params[2], ptr, sm6); + src_params[2].reg.alignment = alignment; + /* The offset is already in src_params[0]. */ + src_params[2].reg.idx_count = 1; +@@ -7377,7 +7422,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor + return; + if (operand_count > 1) + src_param_make_constant_uint(&src_params[0], 0); +- src_param_init_from_value(&src_params[operand_count - 1], ptr); ++ src_param_init_from_value(&src_params[operand_count - 1], ptr, sm6); + src_params[operand_count - 1].reg.alignment = alignment; + } + +@@ -7425,7 +7470,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record + + if (!(phi = sm6_block_phi_require_space(code_block, sm6))) + return; +- sm6_register_from_value(&phi->reg, dst); ++ sm6_register_from_value(&phi->reg, dst, sm6); + phi->incoming_count = record->operand_count / 2u; + + if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count, +@@ -7536,7 +7581,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco + if (record->operands[i]) + WARN("Ignoring volatile modifier.\n"); + +- sm6_register_from_value(®, ptr); ++ sm6_register_from_value(®, ptr, sm6); + + if (ptr->structure_stride) + { +@@ -7551,7 +7596,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco + src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); + /* Struct offset is always zero as there is no struct, just an array. */ + src_param_make_constant_uint(&src_params[1], 0); +- src_param_init_from_value(&src_params[2], src); ++ src_param_init_from_value(&src_params[2], src, sm6); + } + else + { +@@ -7562,7 +7607,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco + return; + if (operand_count > 1) + src_param_make_constant_uint(&src_params[0], 0); +- src_param_init_from_value(&src_params[operand_count - 1], src); ++ src_param_init_from_value(&src_params[operand_count - 1], src, sm6); + } + + dst_param = instruction_dst_params_alloc(ins, 1, sm6); +@@ -7612,7 +7657,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec + return; + } + +- sm6_register_from_value(&terminator->conditional_reg, src); ++ sm6_register_from_value(&terminator->conditional_reg, src, sm6); + terminator->type = TERMINATOR_SWITCH; + + terminator->case_count = record->operand_count / 2u; +@@ -7688,7 +7733,7 @@ static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_re + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) + return; + for (i = 0; i < 3; ++i) +- src_param_init_from_value(&src_params[i], src[i]); ++ src_param_init_from_value(&src_params[i], src[i], sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -8029,7 +8074,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "The type of a phi incoming value does not match the result type."); + } +- sm6_register_from_value(&phi->incoming[j].reg, src); ++ sm6_register_from_value(&phi->incoming[j].reg, src, sm6); + } + } + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index a4f1a371299..c475a46da42 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -369,18 +369,23 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context + name = get_fx_4_type_name(element_type); + modifiers = element_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK; + +- LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry) ++ /* We don't try to reuse nameless types; they will get the same ++ * "" name, but are not available for the type cache. */ ++ if (name) + { +- if (strcmp(type_entry->name, name)) +- continue; ++ LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry) ++ { ++ if (strcmp(type_entry->name, name)) ++ continue; + +- if (type_entry->elements_count != elements_count) +- continue; ++ if (type_entry->elements_count != elements_count) ++ continue; + +- if (type_entry->modifiers != modifiers) +- continue; ++ if (type_entry->modifiers != modifiers) ++ continue; + +- return type_entry->offset; ++ return type_entry->offset; ++ } + } + + if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry)))) +@@ -391,7 +396,8 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context + type_entry->elements_count = elements_count; + type_entry->modifiers = modifiers; + +- list_add_tail(&fx->types, &type_entry->entry); ++ if (name) ++ list_add_tail(&fx->types, &type_entry->entry); + + return type_entry->offset; + } +@@ -1238,7 +1244,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co + + name = get_fx_4_type_name(element_type); + +- name_offset = write_string(name, fx); ++ name_offset = write_string(name ? name : "", fx); + if (element_type->class == HLSL_CLASS_STRUCT) + { + if (!(field_offsets = hlsl_calloc(ctx, element_type->e.record.field_count, sizeof(*field_offsets)))) +@@ -1623,6 +1629,15 @@ static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_contex + set_u32(buffer, pass_count_offset, count); + } + ++/* Effects represent bool values as 1/0, as opposed to ~0u/0 as used by ++ * Direct3D shader model 4+. */ ++static uint32_t get_fx_default_numeric_value(const struct hlsl_type *type, uint32_t value) ++{ ++ if (type->e.numeric.type == HLSL_TYPE_BOOL) ++ return !!value; ++ return value; ++} ++ + static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hlsl_default_value *value, + struct fx_write_context *fx) + { +@@ -1656,7 +1671,7 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl + + for (j = 0; j < comp_count; ++j) + { +- put_u32(buffer, value->number.u); ++ put_u32(buffer, get_fx_default_numeric_value(type, value->number.u)); + value++; + } + break; +@@ -1673,8 +1688,8 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl + + for (j = 0; j < type->e.record.field_count; ++j) + { +- write_fx_2_default_value(fields[i].type, value, fx); +- value += hlsl_type_component_count(fields[i].type); ++ write_fx_2_default_value(fields[j].type, value, fx); ++ value += hlsl_type_component_count(fields[j].type); + } + break; + } +@@ -2001,7 +2016,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl + + for (j = 0; j < comp_count; ++j) + { +- put_u32_unaligned(buffer, value->number.u); ++ put_u32_unaligned(buffer, get_fx_default_numeric_value(type, value->number.u)); + value++; + } + break; +@@ -2018,8 +2033,8 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl + + for (j = 0; j < type->e.record.field_count; ++j) + { +- write_fx_4_default_value(fields[i].type, value, fx); +- value += hlsl_type_component_count(fields[i].type); ++ write_fx_4_default_value(fields[j].type, value, fx); ++ value += hlsl_type_component_count(fields[j].type); + } + break; + } +@@ -3219,7 +3234,7 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx + continue; + + write_fx_4_numeric_variable(var, shared, fx); +- size += get_fx_4_type_size(var->data_type); ++ size = max(size, get_fx_4_type_size(var->data_type) + var->buffer_offset * 4); + ++count; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 38d5c55c26b..f8f5f65517b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -5754,7 +5754,7 @@ static const char *debug_register(char class, struct hlsl_reg reg, const struct + static const char writemask_offset[] = {'w','x','y','z'}; + unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; + +- if (reg_size > 4) ++ if (reg_size > 4 && !hlsl_type_is_patch_array(type)) + { + if (reg_size & 3) + return vkd3d_dbg_sprintf("%c%u-%c%u.%c", class, reg.id, class, reg.id + (reg_size / 4), +@@ -9983,6 +9983,9 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs + if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL + || (version->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)) + opcode = VKD3DSIH_DCL_OUTPUT; ++ else if ((semantic == VKD3D_SHADER_SV_PRIMITIVE_ID || semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) ++ && version->type == VKD3D_SHADER_TYPE_GEOMETRY) ++ opcode = VKD3DSIH_DCL_OUTPUT_SGV; + else + opcode = VKD3DSIH_DCL_OUTPUT_SIV; + } +@@ -13523,7 +13526,26 @@ static void process_entry_function(struct hlsl_ctx *ctx, + else + { + if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func) +- hlsl_fixme(ctx, &entry_func->loc, "Passthrough hull shader control point function."); ++ { ++ if (!ctx->input_control_point_type) ++ { ++ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INPUT_PATCH, ++ "Pass-through control point function \"%s\" is missing an InputPatch parameter.", ++ entry_func->func->name); ++ } ++ else if (ctx->output_control_point_count ++ && ctx->output_control_point_count != ctx->input_control_point_count) ++ { ++ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, ++ "Output control point count %u does not match the input control point count %u.", ++ ctx->output_control_point_count, ctx->input_control_point_count); ++ } ++ else ++ { ++ ctx->output_control_point_type = ctx->input_control_point_type; ++ ctx->output_control_point_count = ctx->input_control_point_count; ++ } ++ } + } + + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && ctx->input_primitive_type == VKD3D_PT_UNDEFINED) +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 7466f7a2da1..a6f17d4a834 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -1031,6 +1031,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + case VKD3DSIH_DCL_INPUT_PS: + case VKD3DSIH_DCL_INPUT_PS_SGV: + case VKD3DSIH_DCL_INPUT_PS_SIV: ++ case VKD3DSIH_DCL_OUTPUT_SGV: + case VKD3DSIH_DCL_OUTPUT_SIV: + vkd3d_shader_instruction_make_nop(ins); + break; +@@ -1142,15 +1143,15 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, + return VKD3D_OK; + } + +-static bool add_signature_element(struct shader_signature *signature, const char *semantic_name, +- uint32_t semantic_index, uint32_t mask, uint32_t register_index, ++static struct signature_element *add_signature_element(struct shader_signature *signature, ++ const char *semantic_name, uint32_t semantic_index, uint32_t mask, uint32_t register_index, + enum vkd3d_shader_interpolation_mode interpolation_mode) + { + struct signature_element *new_elements, *e; + + if (!(new_elements = vkd3d_realloc(signature->elements, + (signature->element_count + 1) * sizeof(*signature->elements)))) +- return false; ++ return NULL; + signature->elements = new_elements; + e = &signature->elements[signature->element_count++]; + memset(e, 0, sizeof(*e)); +@@ -1164,7 +1165,7 @@ static bool add_signature_element(struct shader_signature *signature, const char + e->register_index = register_index; + e->target_location = register_index; + e->interpolation_mode = interpolation_mode; +- return true; ++ return e; + } + + static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program, +@@ -6362,9 +6363,9 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + struct shader_signature *signature = &program->output_signature; + unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; + const struct vkd3d_shader_parameter1 *mask_parameter = NULL; +- struct signature_element *new_elements, *clip_element; + uint32_t position_signature_idx, position_temp, mask; + static const struct vkd3d_shader_location no_loc; ++ struct signature_element *clip_element; + struct vkd3d_shader_instruction *ins; + unsigned int plane_count; + size_t new_pos; +@@ -6422,33 +6423,20 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + + plane_count = vkd3d_popcount(mask); + +- if (!(new_elements = vkd3d_realloc(signature->elements, +- (signature->element_count + 2) * sizeof(*signature->elements)))) ++ /* Register mask is ignored since we operate after I/O normalisation. */ ++ if (!(clip_element = add_signature_element(signature, "SV_ClipDistance", 0, ++ vkd3d_write_mask_from_component_count(min(plane_count, 4)), 0, VKD3DSIM_NONE))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- signature->elements = new_elements; +- +- low_signature_idx = signature->element_count; +- clip_element = &signature->elements[signature->element_count++]; +- memset(clip_element, 0, sizeof(*clip_element)); ++ low_signature_idx = clip_element - signature->elements; + clip_element->sysval_semantic = VKD3D_SHADER_SV_CLIP_DISTANCE; +- clip_element->component_type = VKD3D_SHADER_COMPONENT_FLOAT; +- clip_element->register_count = 1; +- clip_element->mask = vkd3d_write_mask_from_component_count(min(plane_count, 4)); +- clip_element->used_mask = clip_element->mask; +- clip_element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE; + + if (plane_count > 4) + { +- high_signature_idx = signature->element_count; +- clip_element = &signature->elements[signature->element_count++]; +- memset(clip_element, 0, sizeof(*clip_element)); ++ if (!(clip_element = add_signature_element(signature, "SV_ClipDistance", 1, ++ vkd3d_write_mask_from_component_count(plane_count - 4), 0, VKD3DSIM_NONE))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ high_signature_idx = clip_element - signature->elements; + clip_element->sysval_semantic = VKD3D_SHADER_SV_CLIP_DISTANCE; +- clip_element->semantic_index = 1; +- clip_element->component_type = VKD3D_SHADER_COMPONENT_FLOAT; +- clip_element->register_count = 1; +- clip_element->mask = vkd3d_write_mask_from_component_count(plane_count - 4); +- clip_element->used_mask = clip_element->mask; +- clip_element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE; + } + + /* We're going to be reading from the output position, so we need to go +diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l +index 4a8d0fddae1..d167415c356 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/preproc.l ++++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l +@@ -20,6 +20,7 @@ + + %{ + ++#include "preproc.h" + #include "preproc.tab.h" + + #undef ERROR /* defined in wingdi.h */ +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index 29b03871e05..59dca87c57d 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -261,6 +261,7 @@ enum vkd3d_sm4_opcode + VKD3D_SM4_OP_DCL_INPUT_PS_SGV = 0x63, + VKD3D_SM4_OP_DCL_INPUT_PS_SIV = 0x64, + VKD3D_SM4_OP_DCL_OUTPUT = 0x65, ++ VKD3D_SM4_OP_DCL_OUTPUT_SGV = 0x66, + VKD3D_SM4_OP_DCL_OUTPUT_SIV = 0x67, + VKD3D_SM4_OP_DCL_TEMPS = 0x68, + VKD3D_SM4_OP_DCL_INDEXABLE_TEMP = 0x69, +@@ -1559,6 +1560,8 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) + shader_sm4_read_dcl_input_ps_siv}, + {VKD3D_SM4_OP_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT, "", "", + shader_sm4_read_declaration_dst}, ++ {VKD3D_SM4_OP_DCL_OUTPUT_SGV, VKD3DSIH_DCL_OUTPUT_SGV, "", "", ++ shader_sm4_read_declaration_register_semantic}, + {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VKD3DSIH_DCL_OUTPUT_SIV, "", "", + shader_sm4_read_declaration_register_semantic}, + {VKD3D_SM4_OP_DCL_TEMPS, VKD3DSIH_DCL_TEMPS, "", "", +@@ -3129,6 +3132,9 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s + {"position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, + {"sv_position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, + {"sv_primitiveid", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_PRIMITIVE_ID}, ++ {"sv_isfrontface", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_IS_FRONT_FACE}, ++ {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, ++ {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX}, + + {"sv_outputcontrolpointid", false, VKD3D_SHADER_TYPE_HULL, ~0u}, + {"sv_position", false, VKD3D_SHADER_TYPE_HULL, ~0u}, +@@ -4135,6 +4141,10 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT, &ins->declaration.dst, 0); + break; + ++ case VKD3DSIH_DCL_OUTPUT_SGV: ++ tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SGV, &ins->declaration.register_semantic, 0); ++ break; ++ + case VKD3DSIH_DCL_OUTPUT_SIV: + tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SIV, &ins->declaration.register_semantic, 0); + break; +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index f56608940db..4f625e3fae5 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -23,6 +23,8 @@ + #include + #include + ++/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */ ++ + static inline int char_to_int(char c) + { + if ('0' <= c && c <= '9') +@@ -336,7 +338,10 @@ bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_cont + void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, + enum vkd3d_shader_log_level level, const char *format, va_list args) + { +- if (context->log_level < level) ++ struct vkd3d_string_buffer *messages = &context->messages; ++ size_t pos = messages->content_size; ++ ++ if (!WARN_ON() && context->log_level < level) + return; + + if (location) +@@ -344,19 +349,26 @@ void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const stru + const char *source_name = location->source_name ? location->source_name : ""; + + if (location->line) +- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: ", ++ vkd3d_string_buffer_printf(messages, "%s:%u:%u: ", + source_name, location->line, location->column); + else +- vkd3d_string_buffer_printf(&context->messages, "%s: ", source_name); ++ vkd3d_string_buffer_printf(messages, "%s: ", source_name); + } +- vkd3d_string_buffer_vprintf(&context->messages, format, args); +- vkd3d_string_buffer_printf(&context->messages, "\n"); ++ vkd3d_string_buffer_vprintf(messages, format, args); ++ vkd3d_string_buffer_printf(messages, "\n"); ++ ++ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); ++ if (context->log_level < level) ++ messages->content_size = pos; + } + + void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, + enum vkd3d_shader_error error, const char *format, va_list args) + { +- if (context->log_level < VKD3D_SHADER_LOG_WARNING) ++ struct vkd3d_string_buffer *messages = &context->messages; ++ size_t pos = messages->content_size; ++ ++ if (!WARN_ON() && context->log_level < VKD3D_SHADER_LOG_WARNING) + return; + + if (location) +@@ -364,17 +376,21 @@ void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const s + const char *source_name = location->source_name ? location->source_name : ""; + + if (location->line) +- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: W%04u: ", ++ vkd3d_string_buffer_printf(messages, "%s:%u:%u: W%04u: ", + source_name, location->line, location->column, error); + else +- vkd3d_string_buffer_printf(&context->messages, "%s: W%04u: ", source_name, error); ++ vkd3d_string_buffer_printf(messages, "%s: W%04u: ", source_name, error); + } + else + { +- vkd3d_string_buffer_printf(&context->messages, "W%04u: ", error); ++ vkd3d_string_buffer_printf(messages, "W%04u: ", error); + } +- vkd3d_string_buffer_vprintf(&context->messages, format, args); +- vkd3d_string_buffer_printf(&context->messages, "\n"); ++ vkd3d_string_buffer_vprintf(messages, format, args); ++ vkd3d_string_buffer_printf(messages, "\n"); ++ ++ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); ++ if (context->log_level < VKD3D_SHADER_LOG_WARNING) ++ messages->content_size = pos; + } + + void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, +@@ -390,7 +406,10 @@ void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const st + void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, + enum vkd3d_shader_error error, const char *format, va_list args) + { +- if (context->log_level < VKD3D_SHADER_LOG_ERROR) ++ struct vkd3d_string_buffer *messages = &context->messages; ++ size_t pos = messages->content_size; ++ ++ if (!WARN_ON() && context->log_level < VKD3D_SHADER_LOG_ERROR) + return; + + if (location) +@@ -398,17 +417,21 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str + const char *source_name = location->source_name ? location->source_name : ""; + + if (location->line) +- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: E%04u: ", ++ vkd3d_string_buffer_printf(messages, "%s:%u:%u: E%04u: ", + source_name, location->line, location->column, error); + else +- vkd3d_string_buffer_printf(&context->messages, "%s: E%04u: ", source_name, error); ++ vkd3d_string_buffer_printf(messages, "%s: E%04u: ", source_name, error); + } + else + { +- vkd3d_string_buffer_printf(&context->messages, "E%04u: ", error); ++ vkd3d_string_buffer_printf(messages, "E%04u: ", error); + } +- vkd3d_string_buffer_vprintf(&context->messages, format, args); +- vkd3d_string_buffer_printf(&context->messages, "\n"); ++ vkd3d_string_buffer_vprintf(messages, format, args); ++ vkd3d_string_buffer_printf(messages, "\n"); ++ ++ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); ++ if (context->log_level < VKD3D_SHADER_LOG_ERROR) ++ messages->content_size = pos; + } + + void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 3b4fb626fcc..d4d76266df2 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -174,6 +174,7 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT = 5042, + VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE = 5043, + VKD3D_SHADER_ERROR_HLSL_MISPLACED_STREAM_OUTPUT = 5044, ++ VKD3D_SHADER_ERROR_HLSL_MISSING_INPUT_PATCH = 5045, + + VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, + VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, +@@ -337,6 +338,7 @@ enum vkd3d_shader_opcode + VKD3DSIH_DCL_INTERFACE, + VKD3DSIH_DCL_OUTPUT, + VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, ++ VKD3DSIH_DCL_OUTPUT_SGV, + VKD3DSIH_DCL_OUTPUT_SIV, + VKD3DSIH_DCL_OUTPUT_TOPOLOGY, + VKD3DSIH_DCL_RESOURCE_RAW, +diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +index f2b18b665f8..c41f8bae806 100644 +--- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c ++++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +@@ -19,6 +19,8 @@ + #include "vkd3d_utils_private.h" + #undef D3D12CreateDevice + ++/* VKD3D_DEBUG_ENV_NAME("VKD3D_DEBUG"); */ ++ + static const char *debug_d3d_blob_part(D3D_BLOB_PART part) + { + switch (part) +-- +2.47.2 + diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch new file mode 100644 index 00000000..a4c13357 --- /dev/null +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch @@ -0,0 +1,308 @@ +From 86947d34ad20c2245de3b035fe15f116f4e00949 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. + +--- + libs/vkd3d/libs/vkd3d-shader/dxbc.c | 10 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 8 +- + libs/vkd3d/libs/vkd3d-shader/fx.c | 106 ++++++++++++++++---- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 2 +- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 4 +- + 6 files changed, 100 insertions(+), 32 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c +index 9e3a57132a1..45a45c3ad4a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c +@@ -388,7 +388,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s + { + WARN("Invalid data size %#zx.\n", section->data.size); + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, +- "Section size %zu is smaller than the minimum signature header size.\n", section->data.size); ++ "Section size %zu is smaller than the minimum signature header size.", section->data.size); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + +@@ -402,7 +402,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s + { + WARN("Invalid header size %#x.\n", header_size); + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, +- "Signature header size %#x is invalid.\n", header_size); ++ "Signature header size %#x is invalid.", header_size); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + skip_dword_unknown(&ptr, i - 2); +@@ -438,7 +438,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s + || !(e[i].semantic_name = vkd3d_strdup(name))) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_STRING_REFERENCE, +- "Element %u has invalid semantic name reference %#zx (data size %#zx).\n", ++ "Element %u has invalid semantic name reference %#zx (data size %#zx).", + i, name_offset, section->data.size); + fail = true; + } +@@ -447,7 +447,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s + if ((e[i].component_type = read_u32(&ptr)) > VKD3D_SHADER_COMPONENT_FLOAT) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_COMPONENT_TYPE, +- "Element %u has invalid component type %#x.\n", i, e[i].component_type); ++ "Element %u has invalid component type %#x.", i, e[i].component_type); + fail = true; + } + e[i].register_index = read_u32(&ptr); +@@ -531,7 +531,7 @@ static int shdr_parse_features(const struct vkd3d_shader_dxbc_section_desc *sect + { + WARN("Invalid data size %#zx.\n", section->data.size); + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE, +- "SFI0 section size %zu is too small to contain flags.\n", section->data.size); ++ "SFI0 section size %zu is too small to contain flags.", section->data.size); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + flags = read_u64(&ptr); +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index c9e99c6a9ba..9a4d194586b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -6343,7 +6343,7 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_bit_op(enum dxil_wave_bit_op_kin + default: + FIXME("Unhandled wave bit op %u.\n", op); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, +- "Wave bit operation %u is unhandled.\n", op); ++ "Wave bit operation %u is unhandled.", op); + return VKD3DSIH_INVALID; + } + } +@@ -6389,7 +6389,7 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_op(enum dxil_wave_op_kind op, bo + default: + FIXME("Unhandled wave op %u.\n", op); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, +- "Wave operation %u is unhandled.\n", op); ++ "Wave operation %u is unhandled.", op); + return VKD3DSIH_INVALID; + } + } +@@ -6892,7 +6892,7 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ + default: + FIXME("Unhandled cast op %"PRIu64".\n", code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +- "Cast operation %"PRIu64" is unhandled.\n", code); ++ "Cast operation %"PRIu64" is unhandled.", code); + return VKD3DSIH_INVALID; + } + +@@ -6900,7 +6900,7 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ + { + FIXME("Invalid types %u and/or %u for op %"PRIu64".\n", from->class, to->class, code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +- "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.\n", ++ "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.", + code, from->class, from->u.width, to->class, to->u.width); + return VKD3DSIH_INVALID; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index c475a46da42..1d5f95fa988 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -1547,12 +1547,33 @@ static uint32_t get_fx_2_type_class(const struct hlsl_type *type) + return hlsl_sm1_class(type); + } + +-static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, +- const struct hlsl_semantic *semantic, bool is_combined_sampler, struct fx_write_context *fx) ++struct fx_2_write_type_context + { +- struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; +- uint32_t semantic_offset, offset, elements_count = 0, name_offset; +- size_t i; ++ uint32_t *names; ++ uint32_t *semantics; ++ uint32_t count; ++ ++ uint32_t offset; ++ ++ bool is_combined_sampler; ++ struct fx_write_context *fx; ++}; ++ ++static void count_type_iter(const struct hlsl_type *type, const char *name, ++ const struct hlsl_semantic *semantic, void *context) ++{ ++ struct fx_2_write_type_context *ctx = context; ++ ++ ++ctx->count; ++} ++ ++static void write_fx_2_type_iter(const struct hlsl_type *type, const char *name, ++ const struct hlsl_semantic *semantic, void *context) ++{ ++ struct fx_2_write_type_context *ctx = context; ++ struct fx_write_context *fx = ctx->fx; ++ struct vkd3d_bytecode_buffer *buffer; ++ uint32_t offset, elements_count = 0; + + /* Resolve arrays to element type and number of elements. */ + if (type->class == HLSL_CLASS_ARRAY) +@@ -1561,13 +1582,11 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n + type = hlsl_get_multiarray_element_type(type); + } + +- name_offset = write_string(name, fx); +- semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0; +- +- offset = put_u32(buffer, hlsl_sm1_base_type(type, is_combined_sampler)); ++ buffer = &fx->unstructured; ++ offset = put_u32(buffer, hlsl_sm1_base_type(type, ctx->is_combined_sampler)); + put_u32(buffer, get_fx_2_type_class(type)); +- put_u32(buffer, name_offset); +- put_u32(buffer, semantic_offset); ++ *ctx->names++ = put_u32(buffer, 0); ++ *ctx->semantics++ = put_u32(buffer, 0); + put_u32(buffer, elements_count); + + switch (type->class) +@@ -1592,19 +1611,68 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n + ; + } + ++ /* Save the offset of the top level type. */ ++ if (!ctx->offset) ++ ctx->offset = offset; ++} ++ ++static void write_fx_2_type_strings_iter(const struct hlsl_type *type, const char *name, ++ const struct hlsl_semantic *semantic, void *context) ++{ ++ struct fx_2_write_type_context *ctx = context; ++ struct fx_write_context *fx = ctx->fx; ++ struct vkd3d_bytecode_buffer *buffer; ++ ++ buffer = &fx->unstructured; ++ set_u32(buffer, *ctx->names++, write_string(name, fx)); ++ set_u32(buffer, *ctx->semantics++, semantic->raw_name ? write_string(semantic->raw_name, fx) : 0); ++} ++ ++static void foreach_type(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, ++ void (*iter_func)(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, void *context), ++ void *context) ++{ ++ iter_func(type, name, semantic, context); ++ ++ type = hlsl_get_multiarray_element_type(type); + if (type->class == HLSL_CLASS_STRUCT) + { +- for (i = 0; i < type->e.record.field_count; ++i) ++ for (size_t i = 0; i < type->e.record.field_count; ++i) + { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; +- +- /* Validated in check_invalid_object_fields(). */ +- VKD3D_ASSERT(hlsl_is_numeric_type(field->type)); +- write_fx_2_parameter(field->type, field->name, &field->semantic, false, fx); ++ foreach_type(field->type, field->name, &field->semantic, iter_func, context); + } + } ++} + +- return offset; ++static uint32_t write_fx_2_parameter(const struct hlsl_ir_var *var, struct fx_write_context *fx) ++{ ++ struct fx_2_write_type_context ctx = { .fx = fx, .is_combined_sampler = var->is_combined_sampler }; ++ uint32_t *offsets; ++ ++ /* Parameter type information has to be stored in a contiguous segment, so ++ * that any structure fields come right after each other. To achieve that ++ * the variable length string data is written after the type data. */ ++ ++ /* Calculate the number of string entries needed for this type. */ ++ foreach_type(var->data_type, var->name, &var->semantic, count_type_iter, &ctx); ++ ++ if (!(offsets = calloc(ctx.count, 2 * sizeof(*offsets)))) ++ return 0; ++ ++ /* Writing type information also sets string offsets. */ ++ ctx.names = offsets; ++ ctx.semantics = &offsets[ctx.count]; ++ foreach_type(var->data_type, var->name, &var->semantic, write_fx_2_type_iter, &ctx); ++ ++ /* Now the final pass to write the string data. */ ++ ctx.names = offsets; ++ ctx.semantics = &offsets[ctx.count]; ++ foreach_type(var->data_type, var->name, &var->semantic, write_fx_2_type_strings_iter, &ctx); ++ ++ free(offsets); ++ ++ return ctx.offset; + } + + static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_context *fx) +@@ -1876,7 +1944,7 @@ static void write_fx_2_parameters(struct fx_write_context *fx) + if (!is_type_supported_fx_2(ctx, var->data_type, &var->loc)) + continue; + +- desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx); ++ desc_offset = write_fx_2_parameter(var, fx); + value_offset = write_fx_2_initial_value(var, fx); + + flags = 0; +@@ -1899,7 +1967,7 @@ static void write_fx_2_annotation(struct hlsl_ir_var *var, struct fx_write_conte + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + uint32_t desc_offset, value_offset; + +- desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx); ++ desc_offset = write_fx_2_parameter(var, fx); + value_offset = write_fx_2_initial_value(var, fx); + + put_u32(buffer, desc_offset); +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index f8f5f65517b..e9d3d2ec8dd 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -3919,7 +3919,7 @@ static bool lower_separate_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + if (load->texel_offset.node) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, +- "Texel offsets are not supported on profiles lower than 4.0.\n"); ++ "Texel offsets are not supported on profiles lower than 4.0."); + return false; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 1f967c22406..a6f34703c2d 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -4239,7 +4239,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, + if (!(entry = rb_get(&compiler->symbol_table, ®_symbol))) + { + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE, +- "Unrecognized register (%s).\n", debug_vkd3d_symbol(®_symbol)); ++ "Unrecognized register (%s).", debug_vkd3d_symbol(®_symbol)); + memset(register_info, 0, sizeof(*register_info)); + return false; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index 59dca87c57d..6042a76c3c4 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -1169,7 +1169,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u + WARN("No matching signature element for input register %u with mask %#x.\n", + dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DCL, +- "No matching signature element for input register %u with mask %#x.\n", ++ "No matching signature element for input register %u with mask %#x.", + dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + } + else +@@ -1195,7 +1195,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in + WARN("No matching signature element for input register %u with mask %#x.\n", + dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DCL, +- "No matching signature element for input register %u with mask %#x.\n", ++ "No matching signature element for input register %u with mask %#x.", + dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + } + else +-- +2.47.2 +