diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch index 83f41ce5..05963cf1 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c4c7f10d99daa5d3efc036d74d5e09b6f13.patch @@ -1,4 +1,4 @@ -From c54c3405e484d6893c44e0d185256acdb4b39f6f Mon Sep 17 00:00:00 2001 +From 40128154c0cefe020a9f8a6cf5da908339df493b Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 26 May 2025 07:03:34 +1000 Subject: [PATCH] Updated vkd3d to c4c7f10d99daa5d3efc036d74d5e09b6f1342407. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch index a4c13357..85b64013 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-87ec2d98973432531d7d9d08dfc837376f9.patch @@ -1,4 +1,4 @@ -From 86947d34ad20c2245de3b035fe15f116f4e00949 Mon Sep 17 00:00:00 2001 +From 4b9f58f4f2577c30a1fa3b949217bcf5e525598f Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 28 May 2025 07:14:59 +1000 Subject: [PATCH] Updated vkd3d to 87ec2d98973432531d7d9d08dfc837376f91844c. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch new file mode 100644 index 00000000..3cf17d02 --- /dev/null +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-2b257caea94fce2a5ef58dd303de9d73563.patch @@ -0,0 +1,1454 @@ +From 5a866e3b406c57d7b78417110cb3685035fa4b15 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Tue, 3 Jun 2025 07:40:14 +1000 +Subject: [PATCH] Updated vkd3d to 2b257caea94fce2a5ef58dd303de9d73563b9126. + +--- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 8 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 8 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 227 +++++++++--------- + libs/vkd3d/libs/vkd3d-shader/fx.c | 139 +++++------ + libs/vkd3d/libs/vkd3d-shader/glsl.c | 8 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 1 + + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 180 +++++++++++--- + libs/vkd3d/libs/vkd3d-shader/ir.c | 9 +- + libs/vkd3d/libs/vkd3d-shader/msl.c | 10 +- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 51 ---- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 29 ++- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 3 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 12 +- + 13 files changed, 385 insertions(+), 300 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index dc1678795e8..db60883f2a3 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -298,14 +298,16 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch", + [VKD3DSIH_SYNC ] = "sync", + [VKD3DSIH_TAN ] = "tan", +- [VKD3DSIH_TEX ] = "texld", ++ [VKD3DSIH_TEX ] = "tex", + [VKD3DSIH_TEXBEM ] = "texbem", + [VKD3DSIH_TEXBEML ] = "texbeml", +- [VKD3DSIH_TEXCOORD ] = "texcrd", ++ [VKD3DSIH_TEXCOORD ] = "texcoord", ++ [VKD3DSIH_TEXCRD ] = "texcrd", + [VKD3DSIH_TEXDEPTH ] = "texdepth", + [VKD3DSIH_TEXDP3 ] = "texdp3", + [VKD3DSIH_TEXDP3TEX ] = "texdp3tex", + [VKD3DSIH_TEXKILL ] = "texkill", ++ [VKD3DSIH_TEXLD ] = "texld", + [VKD3DSIH_TEXLDD ] = "texldd", + [VKD3DSIH_TEXLDL ] = "texldl", + [VKD3DSIH_TEXM3x2DEPTH ] = "texm3x2depth", +@@ -1706,7 +1708,7 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile + shader_dump_sync_flags(compiler, ins->flags); + break; + +- case VKD3DSIH_TEX: ++ case VKD3DSIH_TEXLD: + if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0)) + { + if (ins->flags & VKD3DSI_TEXLD_PROJECT) +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index 57d874efe37..05f46e264b9 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -382,11 +382,11 @@ static const struct vkd3d_sm1_opcode_info ps_opcode_table[] = + {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 1}}, + /* Texture */ + {VKD3D_SM1_OP_TEXCOORD, 1, 0, VKD3DSIH_TEXCOORD, {0, 0}, {1, 3}}, +- {VKD3D_SM1_OP_TEXCOORD, 1, 1, VKD3DSIH_TEXCOORD, {1, 4}, {1, 4}}, ++ {VKD3D_SM1_OP_TEXCOORD, 1, 1, VKD3DSIH_TEXCRD, {1, 4}, {1, 4}}, + {VKD3D_SM1_OP_TEXKILL, 1, 0, VKD3DSIH_TEXKILL, {1, 0}}, + {VKD3D_SM1_OP_TEX, 1, 0, VKD3DSIH_TEX, {0, 0}, {1, 3}}, +- {VKD3D_SM1_OP_TEX, 1, 1, VKD3DSIH_TEX, {1, 4}, {1, 4}}, +- {VKD3D_SM1_OP_TEX, 1, 2, VKD3DSIH_TEX, {2, 0}}, ++ {VKD3D_SM1_OP_TEX, 1, 1, VKD3DSIH_TEXLD, {1, 4}, {1, 4}}, ++ {VKD3D_SM1_OP_TEX, 1, 2, VKD3DSIH_TEXLD, {2, 0}}, + {VKD3D_SM1_OP_TEXBEM, 1, 1, VKD3DSIH_TEXBEM, {0, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXBEML, 1, 1, VKD3DSIH_TEXBEML, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VKD3DSIH_TEXREG2AR, {1, 0}, {1, 3}}, +@@ -2014,7 +2014,7 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str + case VKD3DSIH_MUL: + case VKD3DSIH_SINCOS: + case VKD3DSIH_SLT: +- case VKD3DSIH_TEX: ++ case VKD3DSIH_TEXLD: + case VKD3DSIH_TEXLDD: + d3dbc_write_instruction(d3dbc, ins); + break; +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 9a4d194586b..c85b644df15 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -651,6 +651,7 @@ enum sm6_value_type + VALUE_TYPE_ICB, + VALUE_TYPE_IDXTEMP, + VALUE_TYPE_GROUPSHAREDMEM, ++ VALUE_TYPE_CONSTANT, + VALUE_TYPE_UNDEFINED, + VALUE_TYPE_INVALID, + }; +@@ -699,6 +700,11 @@ struct sm6_groupsharedmem_data + struct sm6_index index; + }; + ++struct sm6_constant_data ++{ ++ union vsir_immediate_constant immconst; ++}; ++ + struct sm6_value + { + const struct sm6_type *type; +@@ -714,6 +720,7 @@ struct sm6_value + struct sm6_icb_data icb; + struct sm6_idxtemp_data idxtemp; + struct sm6_groupsharedmem_data groupsharedmem; ++ struct sm6_constant_data constant; + } u; + struct vkd3d_shader_register reg; + }; +@@ -2019,11 +2026,6 @@ static inline bool sm6_type_is_handle(const struct sm6_type *type) + return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Handle"); + } + +-static inline const struct sm6_type *sm6_type_get_element_type(const struct sm6_type *type) +-{ +- return (type->class == TYPE_CLASS_ARRAY || type->class == TYPE_CLASS_VECTOR) ? type->u.array.elem_type : type; +-} +- + static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type *type, + enum bitcode_address_space addr_space, struct sm6_parser *sm6) + { +@@ -2278,6 +2280,7 @@ static inline bool sm6_value_is_register(const struct sm6_value *value) + case VALUE_TYPE_ICB: + case VALUE_TYPE_IDXTEMP: + case VALUE_TYPE_GROUPSHAREDMEM: ++ case VALUE_TYPE_CONSTANT: + case VALUE_TYPE_UNDEFINED: + case VALUE_TYPE_INVALID: + return true; +@@ -2329,7 +2332,16 @@ static bool sm6_value_is_ssa(const struct sm6_value *value) + + static bool sm6_value_is_numeric_array(const struct sm6_value *value) + { +- return sm6_value_is_register(value) && register_is_numeric_array(&value->reg); ++ switch (value->value_type) ++ { ++ case VALUE_TYPE_ICB: ++ case VALUE_TYPE_IDXTEMP: ++ case VALUE_TYPE_GROUPSHAREDMEM: ++ return true; ++ ++ default: ++ return false; ++ } + } + + static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) +@@ -2448,9 +2460,11 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, + static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value, + struct sm6_parser *sm6) + { ++ const struct sm6_type *scalar_type; + enum vkd3d_data_type data_type; + +- data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(value->type, 0)); ++ scalar_type = sm6_type_get_scalar_type(value->type, 0); ++ data_type = vkd3d_data_type_from_sm6_type(scalar_type); + + switch (value->value_type) + { +@@ -2484,6 +2498,12 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + reg->idx[1].is_in_bounds = value->u.groupsharedmem.index.is_in_bounds; + break; + ++ case VALUE_TYPE_CONSTANT: ++ vsir_register_init(reg, scalar_type->u.width == 64 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST, ++ data_type, 0); ++ reg->u = value->u.constant.immconst; ++ break; ++ + case VALUE_TYPE_UNDEFINED: + case VALUE_TYPE_INVALID: + vsir_register_init(reg, VKD3DSPR_UNDEF, data_type, 0); +@@ -2657,19 +2677,17 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio + 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) ++static bool instruction_dst_param_init_uint_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) + { +- struct sm6_value *dst = sm6_parser_get_current_value(sm6); + struct vkd3d_shader_dst_param *param; + + if (!(param = instruction_dst_params_alloc(ins, 1, sm6))) + return false; + +- vsir_dst_param_init(param, VKD3DSPR_TEMP, vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(dst->type, 0)), 1); ++ vsir_dst_param_init(param, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + param->write_mask = VKD3DSP_WRITEMASK_ALL; + param->reg.idx[0].offset = 0; + param->reg.dimension = VSIR_DIMENSION_VEC4; +- dst->reg = param->reg; + + return true; + } +@@ -3040,30 +3058,6 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) + return value << 63; + } + +-static float bitcast_uint_to_float(unsigned int value) +-{ +- union +- { +- uint32_t uint32_value; +- float float_value; +- } u; +- +- u.uint32_value = value; +- return u.float_value; +-} +- +-static inline double bitcast_uint64_to_double(uint64_t value) +-{ +- union +- { +- uint64_t uint64_value; +- double double_value; +- } u; +- +- u.uint64_value = value; +- return u.double_value; +-} +- + static float register_get_float_value(const struct vkd3d_shader_register *reg) + { + if (!register_is_constant(reg) || !data_type_is_floating_point(reg->data_type)) +@@ -3075,10 +3069,10 @@ static float register_get_float_value(const struct vkd3d_shader_register *reg) + if (reg->type == VKD3DSPR_IMMCONST64) + { + WARN("Truncating double to float.\n"); +- return bitcast_uint64_to_double(reg->u.immconst_u64[0]); ++ return reg->u.immconst_f64[0]; + } + +- return bitcast_uint_to_float(reg->u.immconst_u32[0]); ++ return reg->u.immconst_f32[0]; + } + + static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, +@@ -3298,10 +3292,8 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + + static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block) + { +- enum vkd3d_shader_register_type reg_type = VKD3DSPR_INVALID; +- const struct sm6_type *type, *elem_type, *ptr_type; ++ const struct sm6_type *type, *ptr_type; + size_t i, base_value_idx, value_idx; +- enum vkd3d_data_type reg_data_type; + const struct dxil_record *record; + const struct sm6_value *src; + enum vkd3d_result ret; +@@ -3322,18 +3314,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + if (!(type = sm6_parser_get_type(sm6, record->operands[0]))) + return VKD3D_ERROR_INVALID_SHADER; + +- elem_type = sm6_type_get_element_type(type); +- if (sm6_type_is_numeric(elem_type)) +- { +- reg_data_type = vkd3d_data_type_from_sm6_type(elem_type); +- reg_type = elem_type->u.width > 32 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST; +- } +- else +- { +- reg_data_type = VKD3D_DATA_UNUSED; +- reg_type = VKD3DSPR_INVALID; +- } +- + if (i == block->record_count - 1) + WARN("Unused SETTYPE record.\n"); + +@@ -3348,19 +3328,22 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + + dst = sm6_parser_get_current_value(sm6); + dst->type = type; +- dst->value_type = VALUE_TYPE_REG; + dst->is_back_ref = true; +- vsir_register_init(&dst->reg, reg_type, reg_data_type, 0); + + switch (record->code) + { + case CST_CODE_NULL: +- if (sm6_type_is_array(type) +- && (ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) ++ if (sm6_type_is_array(type)) + { +- return ret; ++ if ((ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) ++ return ret; ++ } ++ else ++ { ++ dst->value_type = VALUE_TYPE_CONSTANT; ++ memset(&dst->u.constant, 0, sizeof(dst->u.constant)); ++ sm6_register_from_value(&dst->reg, dst, sm6); + } +- /* For non-aggregates, register constant data is already zero-filled. */ + break; + + case CST_CODE_INTEGER: +@@ -3373,11 +3356,15 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + return VKD3D_ERROR_INVALID_SHADER; + } + ++ dst->value_type = VALUE_TYPE_CONSTANT; ++ + value = decode_rotated_signed_value(record->operands[0]); + if (type->u.width <= 32) +- dst->reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1); ++ dst->u.constant.immconst.immconst_u32[0] = value & ((1ull << type->u.width) - 1); + else +- dst->reg.u.immconst_u64[0] = value; ++ dst->u.constant.immconst.immconst_u64[0] = value; ++ ++ sm6_register_from_value(&dst->reg, dst, sm6); + + break; + +@@ -3391,14 +3378,15 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + return VKD3D_ERROR_INVALID_SHADER; + } + +- if (type->u.width == 16) +- dst->reg.u.immconst_u32[0] = record->operands[0]; +- else if (type->u.width == 32) +- dst->reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); +- else if (type->u.width == 64) +- dst->reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); ++ dst->value_type = VALUE_TYPE_CONSTANT; ++ ++ value = record->operands[0]; ++ if (type->u.width <= 32) ++ dst->u.constant.immconst.immconst_u32[0] = value & ((1ull << type->u.width) - 1); + else +- vkd3d_unreachable(); ++ dst->u.constant.immconst.immconst_u64[0] = value; ++ ++ sm6_register_from_value(&dst->reg, dst, sm6); + + break; + +@@ -3424,6 +3412,48 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + return ret; + break; + ++ case CST_CODE_CE_CAST: ++ /* Resolve later in case forward refs exist. */ ++ dst->type = type; ++ dst->value_type = VALUE_TYPE_INVALID; ++ break; ++ ++ 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); ++ break; ++ ++ default: ++ 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); ++ break; ++ } ++ ++ if (record->attachment) ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, ++ "Ignoring a metadata attachment for a constant."); ++ ++ ++sm6->value_count; ++ } ++ ++ value_idx = base_value_idx; ++ ++ for (i = 0; i < block->record_count; ++i) ++ { ++ sm6->p.location.column = i; ++ record = block->records[i]; ++ ++ switch (record->code) ++ { ++ case CST_CODE_SETTYPE: ++ continue; ++ ++ default: ++ break; ++ + case CST_CODE_CE_CAST: + if (!dxil_record_validate_operand_count(record, 3, 3, sm6)) + return VKD3D_ERROR_INVALID_SHADER; +@@ -3460,59 +3490,28 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + return VKD3D_ERROR_INVALID_SHADER; + } + +- /* Resolve later in case forward refs exist. */ +- dst->type = type; +- dst->reg.type = VKD3DSPR_COUNT; +- dst->reg.idx[0].offset = value; +- break; ++ dst = &sm6->values[value_idx]; ++ src = &sm6->values[value]; + +- 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); +- break; ++ if (!sm6_value_is_numeric_array(src)) ++ { ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Constexpr cast source value is not a global array element."); ++ return VKD3D_ERROR_INVALID_SHADER; ++ } ++ ++ type = dst->type; ++ *dst = *src; ++ dst->type = type; + +- default: +- FIXME("Unhandled constant code %u.\n", record->code); +- 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); + break; + } + +- if (record->attachment) +- { +- WARN("Ignoring metadata attachment.\n"); +- vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, +- "Ignoring a metadata attachment for a constant."); +- } +- +- ++sm6->value_count; ++ ++value_idx; + } + +- /* Resolve cast forward refs. */ +- for (i = base_value_idx; i < sm6->value_count; ++i) +- { +- dst = &sm6->values[i]; +- if (dst->reg.type != VKD3DSPR_COUNT) +- continue; +- +- type = dst->type; +- +- src = &sm6->values[dst->reg.idx[0].offset]; +- if (!sm6_value_is_numeric_array(src)) +- { +- WARN("Value is not an array.\n"); +- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +- "Constexpr cast source value is not a global array element."); +- return VKD3D_ERROR_INVALID_SHADER; +- } +- +- *dst = *src; +- dst->type = type; +- dst->reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type); +- } ++ VKD3D_ASSERT(value_idx == sm6->value_count); + + return VKD3D_OK; + } +@@ -5427,7 +5426,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in + + if (resource_kind_is_multisampled(resource_kind)) + { +- instruction_dst_param_init_temp_vector(ins++, sm6); ++ instruction_dst_param_init_uint_temp_vector(ins++, sm6); + state->temp_idx = 1; + + /* DXIL does not have an intrinsic for sample info, and resinfo is expected to return +@@ -5440,7 +5439,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in + src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); + src_params[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + +- if (!instruction_dst_param_init_temp_vector(ins, sm6)) ++ if (!instruction_dst_param_init_uint_temp_vector(ins, sm6)) + return; + dst = ins->dst; + dst->write_mask = VKD3DSP_WRITEMASK_3; +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index 1d5f95fa988..90da8048b8e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -873,7 +873,7 @@ fx_2_states[] = + { "AdaptiveTess_Y", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 84 }, + { "AdaptiveTess_Z", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 85 }, + { "AdaptiveTess_W", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 86 }, +- { "EnableAdaptiveTesselation", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 }, ++ { "EnableAdaptiveTessellation",HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 }, + { "TwoSidedStencilMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 88 }, + { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 89, fx_2_stencilcaps_values }, + { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 90, fx_2_stencilcaps_values }, +@@ -904,17 +904,17 @@ fx_2_states[] = + { "BumpEnvMat01", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 113 }, + { "BumpEnvMat10", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 114 }, + { "BumpEnvMat11", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 115 }, +- { "TextCoordIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 }, ++ { "TexCoordIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 }, + { "BumpEnvLScale", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 117 }, + { "BumpEnvLOffset", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 118 }, + { "TextureTransformFlags", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 119, fx_2_texturetransform_values }, + { "Constant", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 120 }, +- { "NPatchMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 }, ++ { "PatchSegments", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 }, + { "FVF", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 122 }, + + { "ProjectionTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 123 }, + { "ViewTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 124 }, +- { "WorldTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 125 }, ++ { "WorldTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 256, 125 }, + { "TextureTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 8, 126 }, + + { "MaterialAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 127 }, +@@ -923,55 +923,55 @@ fx_2_states[] = + { "MaterialEmissive", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 130 }, + { "MaterialPower", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 131 }, + +- { "LightType", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 132, fx_2_lighttype_values }, +- { "LightDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 133 }, +- { "LightSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 134 }, +- { "LightAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 135 }, +- { "LightPosition", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 136 }, +- { "LightDirection", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 137 }, +- { "LightRange", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 138 }, +- { "LightFalloff", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 139 }, +- { "LightAttenuation0", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 140 }, +- { "LightAttenuation1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 141 }, +- { "LightAttenuation2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 142 }, +- { "LightTheta", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 143 }, +- { "LightPhi", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 144 }, +- { "LightEnable", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 145 }, ++ { "LightType", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 132, fx_2_lighttype_values }, ++ { "LightDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 133 }, ++ { "LightSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 134 }, ++ { "LightAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 135 }, ++ { "LightPosition", HLSL_CLASS_VECTOR, FX_FLOAT, 3, ~0u, 136 }, ++ { "LightDirection", HLSL_CLASS_VECTOR, FX_FLOAT, 3, ~0u, 137 }, ++ { "LightRange", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 138 }, ++ { "LightFalloff", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 139 }, ++ { "LightAttenuation0", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 140 }, ++ { "LightAttenuation1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 141 }, ++ { "LightAttenuation2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 142 }, ++ { "LightTheta", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 143 }, ++ { "LightPhi", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 144 }, ++ { "LightEnable", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 145 }, + + { "VertexShader", HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 }, + { "PixelShader", HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 }, + +- { "VertexShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 148 }, +- { "VertexShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 149 }, +- { "VertexShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 150 }, +- { "VertexShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 151 }, +- { "VertexShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 152 }, +- { "VertexShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 153 }, +- { "VertexShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 154 }, +- { "VertexShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 155 }, +- +- { "PixelShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 156 }, +- { "PixelShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 157 }, +- { "PixelShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 158 }, +- { "PixelShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 159 }, +- { "PixelShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 160 }, +- { "PixelShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 161 }, +- { "PixelShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 162 }, +- { "PixelShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 163 }, +- +- { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 }, +- { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values }, +- { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values }, +- { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values }, +- { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 }, +- { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values }, +- { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values }, +- { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values }, +- { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 }, +- { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 }, +- { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 }, +- { "SRBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 }, +- { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 }, ++ { "VertexShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 148 }, ++ { "VertexShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u, 149 }, ++ { "VertexShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 150 }, ++ { "VertexShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 151 }, ++ { "VertexShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 152 }, ++ { "VertexShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 153 }, ++ { "VertexShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 154 }, ++ { "VertexShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 155 }, ++ ++ { "PixelShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 156 }, ++ { "PixelShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u, 157 }, ++ { "PixelShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 158 }, ++ { "PixelShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 159 }, ++ { "PixelShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 160 }, ++ { "PixelShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 161 }, ++ { "PixelShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 162 }, ++ { "PixelShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 163 }, ++ ++ { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 261, 164 }, ++ { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 165, fx_2_address_values }, ++ { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 166, fx_2_address_values }, ++ { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 167, fx_2_address_values }, ++ { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 168 }, ++ { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 169, fx_2_filter_values }, ++ { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 170, fx_2_filter_values }, ++ { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 171, fx_2_filter_values }, ++ { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 172 }, ++ { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 173 }, ++ { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 174 }, ++ { "SRGBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 175 }, ++ { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 176 }, + }; + + static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) +@@ -994,16 +994,6 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx + fx->shader_count++; + } + +-static uint32_t get_fx_4_type_size(const struct hlsl_type *type) +-{ +- uint32_t elements_count; +- +- elements_count = hlsl_get_multiarray_size(type); +- type = hlsl_get_multiarray_element_type(type); +- +- return type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float) * elements_count; +-} +- + enum fx_4_type_constants + { + /* Numeric types encoding */ +@@ -1021,6 +1011,9 @@ enum fx_4_type_constants + FX_4_NUMERIC_COLUMNS_SHIFT = 11, + FX_4_NUMERIC_COLUMN_MAJOR_MASK = 0x4000, + ++ /* Variable flags */ ++ FX_4_HAS_EXPLICIT_BIND_POINT = 0x4, ++ + /* Object types */ + FX_4_OBJECT_TYPE_STRING = 0x1, + FX_4_OBJECT_TYPE_BLEND_STATE = 0x2, +@@ -2140,13 +2133,9 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + uint32_t name_offset, type_offset, value_offset; + uint32_t semantic_offset, flags = 0; +- enum fx_4_numeric_variable_flags +- { +- HAS_EXPLICIT_BIND_POINT = 0x4, +- }; + + if (var->has_explicit_bind_point) +- flags |= HAS_EXPLICIT_BIND_POINT; ++ flags |= FX_4_HAS_EXPLICIT_BIND_POINT; + + type_offset = write_type(var->data_type, fx); + name_offset = write_string(var->name, fx); +@@ -3295,6 +3284,8 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx + size = 0; + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { ++ uint32_t unpacked_size; ++ + if (!is_numeric_fx_4_type(var->data_type)) + continue; + +@@ -3302,7 +3293,9 @@ 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 = max(size, get_fx_4_type_size(var->data_type) + var->buffer_offset * 4); ++ ++ unpacked_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float); ++ size = max(size, unpacked_size + var->buffer_offset * 4); + ++count; + } + +@@ -3969,7 +3962,7 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a + } + vkd3d_string_buffer_printf(&parser->buffer, " = "); + +- if (state && state->type == FX_UINT) ++ if (state && state->type == FX_UINT && state->values) + { + const struct rhs_named_value *ptr = state->values; + uint32_t value; +@@ -3993,13 +3986,14 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a + } + else if (state) + { +- if (state->type == FX_UINT || state->type == FX_FLOAT) ++ if (state->type == FX_UINT || state->type == FX_FLOAT || state->type == FX_BOOL) + { +- uint32_t offset = entry->type; ++ uint32_t offset = entry->type, base_type; + unsigned int size; + + size = fx_get_fx_2_type_size(parser, &offset); +- parse_fx_2_numeric_value(parser, entry->value, size, entry->type); ++ fx_parser_read_unstructured(parser, &base_type, entry->type, sizeof(base_type)); ++ parse_fx_2_numeric_value(parser, entry->value, size, base_type); + } + else if (state->type == FX_VERTEXSHADER || state->type == FX_PIXELSHADER) + { +@@ -4540,6 +4534,11 @@ static void fx_parse_fx_4_numeric_variables(struct fx_parser *parser, uint32_t c + semantic = fx_4_get_string(parser, var.semantic); + vkd3d_string_buffer_printf(&parser->buffer, " : %s", semantic); + } ++ if (var.flags & FX_4_HAS_EXPLICIT_BIND_POINT) ++ { ++ vkd3d_string_buffer_printf(&parser->buffer, " : packoffset(c%u.%c)", ++ var.offset / 16, "xyzw"[(var.offset % 16) / 4]); ++ } + fx_parse_fx_4_annotations(parser); + + if (var.value) +@@ -4575,6 +4574,8 @@ static void fx_parse_buffers(struct fx_parser *parser) + name = fx_4_get_string(parser, buffer.name); + + vkd3d_string_buffer_printf(&parser->buffer, "cbuffer %s", name); ++ if (buffer.bind_point != ~0u) ++ vkd3d_string_buffer_printf(&parser->buffer, " : register(b%u)", buffer.bind_point); + fx_parse_fx_4_annotations(parser); + + vkd3d_string_buffer_printf(&parser->buffer, "\n{\n"); +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index e4497b9ac5b..0a91024a8d1 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -421,6 +421,9 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd + case VKD3DSPSM_ABS: + vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); + break; ++ case VKD3DSPSM_ABSNEG: ++ vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); ++ break; + default: + vkd3d_string_buffer_printf(buffer, "(%s)", + vsir_src->modifiers, str->buffer); +@@ -495,6 +498,9 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g + uint32_t modifiers = dst->vsir->modifiers; + bool close = true; + ++ /* It is always legitimate to ignore _pp. */ ++ modifiers &= ~VKD3DSPDM_PARTIALPRECISION; ++ + if (dst->vsir->shift) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift); +@@ -2313,7 +2319,7 @@ static void shader_glsl_handle_global_flags(struct vkd3d_string_buffer *buffer, + flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; + } + +- if (flags) ++ if (flags & ~VKD3DSGF_REFACTORING_ALLOWED) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)flags); + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index 58f579cd9f9..63c9733ec7b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -245,6 +245,7 @@ struct hlsl_semantic + { + const char *name; + uint32_t index; ++ uint32_t stream_index; + + /* Name exactly as it appears in the sources. */ + const char *raw_name; +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index e9d3d2ec8dd..d4cd338f15a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -288,7 +288,8 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls + + static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, + struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, +- uint32_t index, bool output, bool force_align, bool create, const struct vkd3d_shader_location *loc) ++ uint32_t index, uint32_t stream_index, bool output, bool force_align, bool create, ++ const struct vkd3d_shader_location *loc) + { + struct hlsl_semantic new_semantic; + struct hlsl_ir_var *ext_var; +@@ -300,7 +301,12 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir + else + prefix = output ? "output" : "input"; + +- if (!(new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", prefix, semantic->name, index))) ++ if (stream_index) ++ new_name = hlsl_sprintf_alloc(ctx, "<%s-m%u:%s%u>", prefix, stream_index, semantic->name, index); ++ else ++ new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", prefix, semantic->name, index); ++ ++ if (!new_name) + return NULL; + + LIST_FOR_EACH_ENTRY(ext_var, &func->extern_vars, struct hlsl_ir_var, extern_entry) +@@ -353,6 +359,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir + return NULL; + } + new_semantic.index = index; ++ new_semantic.stream_index = stream_index; + if (!(ext_var = hlsl_new_var(ctx, new_name, type, loc, &new_semantic, modifiers, NULL))) + { + vkd3d_free(new_name); +@@ -435,7 +442,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + prim_type_src->modifiers = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK; + + if (!(input = add_semantic_var(ctx, func, var, prim_type_src, +- modifiers, semantic, semantic_index + i, false, force_align, true, loc))) ++ modifiers, semantic, semantic_index + i, 0, false, force_align, true, loc))) + return; + hlsl_init_simple_deref_from_var(&prim_deref, input); + +@@ -448,7 +455,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + else + { + if (!(input = add_semantic_var(ctx, func, var, vector_type_src, +- modifiers, semantic, semantic_index + i, false, force_align, true, loc))) ++ modifiers, semantic, semantic_index + i, 0, false, force_align, true, loc))) + return; + + if (!(load = hlsl_new_var_load(ctx, input, &var->loc))) +@@ -558,7 +565,7 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function + + static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, +- struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) ++ struct hlsl_semantic *semantic, uint32_t semantic_index, uint32_t stream_index, bool force_align, bool create) + { + struct hlsl_type *type = rhs->node.data_type, *vector_type; + struct vkd3d_shader_location *loc = &rhs->node.loc; +@@ -588,7 +595,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_node *load; + + if (!(output = add_semantic_var(ctx, func, var, vector_type, +- modifiers, semantic, semantic_index + i, true, force_align, create, loc))) ++ modifiers, semantic, semantic_index + i, stream_index, true, force_align, create, loc))) + return; + + if (type->class == HLSL_CLASS_MATRIX) +@@ -609,7 +616,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, + + static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, +- struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) ++ struct hlsl_semantic *semantic, uint32_t semantic_index, uint32_t stream_index, bool force_align, bool create) + { + struct vkd3d_shader_location *loc = &rhs->node.loc; + struct hlsl_ir_var *var = rhs->src.var; +@@ -654,12 +661,13 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * + hlsl_block_add_instr(block, &element_load->node); + + append_output_copy_recurse(ctx, block, func, element_type, element_load, element_modifiers, semantic, +- elem_semantic_index, force_align, create); ++ elem_semantic_index, stream_index, force_align, create); + } + } + else + { +- append_output_copy(ctx, block, func, rhs, modifiers, semantic, semantic_index, force_align, create); ++ append_output_copy(ctx, block, func, rhs, modifiers, semantic, ++ semantic_index, stream_index, force_align, create); + } + } + +@@ -676,7 +684,7 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function + hlsl_block_add_instr(&func->body, &load->node); + + append_output_copy_recurse(ctx, &func->body, func, var->data_type, load, var->storage_modifiers, +- &var->semantic, var->semantic.index, false, true); ++ &var->semantic, var->semantic.index, 0, false, true); + } + + bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), +@@ -3360,7 +3368,7 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + struct stream_append_ctx + { + struct hlsl_ir_function_decl *func; +- bool created; ++ bool created[VKD3D_MAX_STREAM_COUNT]; + }; + + static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -3371,6 +3379,7 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + const struct hlsl_type *type; + struct hlsl_ir_var *var; + struct hlsl_block block; ++ uint32_t stream_index; + + if (instr->type != HLSL_IR_RESOURCE_STORE) + return false; +@@ -3390,18 +3399,17 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + } + + VKD3D_ASSERT(var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); ++ stream_index = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; + +- if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) +- { +- hlsl_fixme(ctx, &instr->loc, "Append to an output stream with a nonzero stream index."); +- return false; +- } ++ VKD3D_ASSERT(stream_index < ARRAY_SIZE(append_ctx->created)); + + hlsl_block_init(&block); + +- append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), var->storage_modifiers, +- &var->semantic, var->semantic.index, false, !append_ctx->created); +- append_ctx->created = true; ++ append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), ++ var->storage_modifiers, &var->semantic, var->semantic.index, ++ var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, false, !append_ctx->created[stream_index]); ++ ++ append_ctx->created[stream_index] = true; + + list_move_before(&instr->entry, &block.instrs); + hlsl_src_remove(&store->value); +@@ -6456,6 +6464,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var + + if ((!output && !var->last_read) || (output && !var->first_write)) + return; ++ ++ optimize = false; + } + else + { +@@ -6518,8 +6528,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var + static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, + uint32_t *output_reg_count) + { ++ struct register_allocator input_allocator = {0}, output_allocators[VKD3D_MAX_STREAM_COUNT] = {{0}}; + struct register_allocator in_prim_allocator = {0}, patch_constant_out_patch_allocator = {0}; +- struct register_allocator input_allocator = {0}, output_allocator = {0}; + bool is_vertex_shader = ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX; + bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; + struct hlsl_ir_var *var; +@@ -6527,7 +6537,8 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + in_prim_allocator.prioritize_smaller_writemasks = true; + patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; + input_allocator.prioritize_smaller_writemasks = true; +- output_allocator.prioritize_smaller_writemasks = true; ++ for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) ++ output_allocators[i].prioritize_smaller_writemasks = true; + + LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) + { +@@ -6550,15 +6561,22 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + } + + if (var->is_output_semantic) +- allocate_semantic_register(ctx, var, &output_allocator, true, !is_pixel_shader); ++ { ++ VKD3D_ASSERT(var->semantic.stream_index < ARRAY_SIZE(output_allocators)); ++ allocate_semantic_register(ctx, var, &output_allocators[var->semantic.stream_index], ++ true, !is_pixel_shader); ++ } + } + +- *output_reg_count = output_allocator.reg_count; ++ *output_reg_count = output_allocators[0].reg_count; ++ for (unsigned int i = 1; i < ARRAY_SIZE(output_allocators); ++i) ++ *output_reg_count = max(*output_reg_count, output_allocators[i].reg_count); + + vkd3d_free(in_prim_allocator.allocations); + vkd3d_free(patch_constant_out_patch_allocator.allocations); + vkd3d_free(input_allocator.allocations); +- vkd3d_free(output_allocator.allocations); ++ for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) ++ vkd3d_free(output_allocators[i].allocations); + } + + static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, +@@ -8018,6 +8036,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + return; + } + element->semantic_index = var->semantic.index; ++ element->stream_index = var->semantic.stream_index; + element->sysval_semantic = sysval; + element->component_type = component_type; + element->register_index = register_index; +@@ -8485,6 +8504,14 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p + VKD3D_ASSERT(regset == HLSL_REGSET_SAMPLERS); + *writemask = VKD3DSP_WRITEMASK_ALL; + } ++ else if (regset == HLSL_REGSET_STREAM_OUTPUTS) ++ { ++ reg->type = VKD3DSPR_STREAM; ++ reg->dimension = VSIR_DIMENSION_NONE; ++ reg->idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; ++ reg->idx_count = 1; ++ *writemask = VKD3DSP_WRITEMASK_ALL; ++ } + else + { + unsigned int offset = deref->const_offset + var->buffer_offset; +@@ -9279,16 +9306,16 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, + switch (load->load_type) + { + case HLSL_RESOURCE_SAMPLE: +- opcode = VKD3DSIH_TEX; ++ opcode = VKD3DSIH_TEXLD; + break; + + case HLSL_RESOURCE_SAMPLE_PROJ: +- opcode = VKD3DSIH_TEX; ++ opcode = VKD3DSIH_TEXLD; + flags |= VKD3DSI_TEXLD_PROJECT; + break; + + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: +- opcode = VKD3DSIH_TEX; ++ opcode = VKD3DSIH_TEXLD; + flags |= VKD3DSI_TEXLD_BIAS; + break; + +@@ -9922,6 +9949,57 @@ static void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ct + ctab->size = buffer.size; + } + ++static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, ++ unsigned int index) ++{ ++ switch (sysval) ++ { ++ case VKD3D_SHADER_SV_COVERAGE: ++ case VKD3D_SHADER_SV_DEPTH: ++ case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: ++ case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: ++ case VKD3D_SHADER_SV_NONE: ++ case VKD3D_SHADER_SV_STENCIL_REF: ++ case VKD3D_SHADER_SV_TARGET: ++ return VKD3D_SIV_NONE; ++ case VKD3D_SHADER_SV_POSITION: ++ return VKD3D_SIV_POSITION; ++ case VKD3D_SHADER_SV_CLIP_DISTANCE: ++ return VKD3D_SIV_CLIP_DISTANCE; ++ case VKD3D_SHADER_SV_CULL_DISTANCE: ++ return VKD3D_SIV_CULL_DISTANCE; ++ case VKD3D_SHADER_SV_INSTANCE_ID: ++ return VKD3D_SIV_INSTANCE_ID; ++ case VKD3D_SHADER_SV_IS_FRONT_FACE: ++ return VKD3D_SIV_IS_FRONT_FACE; ++ case VKD3D_SHADER_SV_PRIMITIVE_ID: ++ return VKD3D_SIV_PRIMITIVE_ID; ++ case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX: ++ return VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX; ++ case VKD3D_SHADER_SV_SAMPLE_INDEX: ++ return VKD3D_SIV_SAMPLE_INDEX; ++ case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE: ++ return VKD3D_SIV_QUAD_U0_TESS_FACTOR + index; ++ case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT: ++ return VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR + index; ++ case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE: ++ return VKD3D_SIV_TRIANGLE_U_TESS_FACTOR + index; ++ case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT: ++ return VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR; ++ case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET: ++ return VKD3D_SIV_LINE_DETAIL_TESS_FACTOR; ++ case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN: ++ return VKD3D_SIV_LINE_DENSITY_TESS_FACTOR; ++ case VKD3D_SHADER_SV_VERTEX_ID: ++ return VKD3D_SIV_VERTEX_ID; ++ case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX: ++ return VKD3D_SIV_VIEWPORT_ARRAY_INDEX; ++ default: ++ FIXME("Unhandled sysval %#x, index %u.\n", sysval, index); ++ return VKD3D_SIV_NONE; ++ } ++} ++ + static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vsir_program *program, + const struct hlsl_ir_var *var, struct hlsl_block *block, const struct vkd3d_shader_location *loc) + { +@@ -10835,20 +10913,27 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, + + if (store->store_type != HLSL_RESOURCE_STORE) + { +- enum vkd3d_shader_opcode opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND +- ? VKD3DSIH_EMIT : VKD3DSIH_CUT; ++ enum vkd3d_shader_opcode opcode; + + VKD3D_ASSERT(!store->value.node && !store->coords.node); + VKD3D_ASSERT(store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); + +- if (store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) ++ if (hlsl_version_lt(ctx, 5, 0)) + { +- hlsl_fixme(ctx, &instr->loc, "Stream output operation with a nonzero stream index."); +- return false; ++ opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ? VKD3DSIH_EMIT : VKD3DSIH_CUT; ++ ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0); ++ return !!ins; + } + +- ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0); +- return !!ins; ++ opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ? VKD3DSIH_EMIT_STREAM : VKD3DSIH_CUT_STREAM; ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 1))) ++ return false; ++ ++ if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, &ins->src[0], ++ &store->resource, VKD3DSP_WRITEMASK_ALL, &instr->loc)) ++ return false; ++ ++ return true; + } + + if (!store->resource.var->is_uniform) +@@ -12130,6 +12215,22 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + } + } + ++static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, ++ struct vsir_program *program, const struct hlsl_ir_var *var) ++{ ++ struct vkd3d_shader_instruction *ins; ++ ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VKD3DSIH_DCL_STREAM, 0, 1))) ++ { ++ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; ++ return; ++ } ++ ++ vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VKD3D_DATA_OPAQUE, 1); ++ ins->src[0].reg.dimension = VSIR_DIMENSION_NONE; ++ ins->src[0].reg.idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; ++} ++ + /* OBJECTIVE: Translate all the information from ctx and entry_func to the + * vsir_program, so it can be used as input to tpf_compile() without relying + * on ctx and entry_func. */ +@@ -12204,6 +12305,17 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl + } + sm4_free_extern_resources(extern_resources, extern_resources_count); + ++ if (version.type == VKD3D_SHADER_TYPE_GEOMETRY && version.major >= 5) ++ { ++ const struct hlsl_ir_var *var; ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (var->bind_count[HLSL_REGSET_STREAM_OUTPUTS]) ++ sm4_generate_vsir_add_dcl_stream(ctx, program, var); ++ } ++ } ++ + if (version.type == VKD3D_SHADER_TYPE_HULL) + generate_vsir_add_program_instruction(ctx, program, + &ctx->patch_constant_func->loc, VKD3DSIH_HS_CONTROL_POINT_PHASE, 0, 0); +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index a6f17d4a834..4abf6a65dbb 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -823,7 +823,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, + div_ins->src[1] = tex->src[0]; + div_ins->src[1].swizzle = vkd3d_shader_create_swizzle(w_comp, w_comp, w_comp, w_comp); + +- if (!vsir_instruction_init_with_params(program, tex_ins, location, VKD3DSIH_TEX, 1, 2)) ++ if (!vsir_instruction_init_with_params(program, tex_ins, location, VKD3DSIH_TEXLD, 1, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + tex_ins->dst[0] = tex->dst[0]; +@@ -838,7 +838,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, + return VKD3D_OK; + } + +-static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, ++static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program, + struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context) + { + unsigned int idx = tex->src[1].reg.idx[0].offset; +@@ -1041,7 +1041,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + return ret; + break; + +- case VKD3DSIH_TEX: ++ case VKD3DSIH_TEXLD: + if (ins->flags == VKD3DSI_TEXLD_PROJECT) + { + if ((ret = vsir_program_lower_texldp(program, ins, &tmp_idx)) < 0) +@@ -1049,7 +1049,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + } + else + { +- if ((ret = vsir_program_lower_tex(program, ins, message_context)) < 0) ++ if ((ret = vsir_program_lower_texld(program, ins, message_context)) < 0) + return ret; + } + break; +@@ -1062,6 +1062,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + case VKD3DSIH_TEXBEM: + case VKD3DSIH_TEXBEML: + case VKD3DSIH_TEXCOORD: ++ case VKD3DSIH_TEXCRD: + case VKD3DSIH_TEXDEPTH: + case VKD3DSIH_TEXDP3: + case VKD3DSIH_TEXDP3TEX: +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index 4f37468af86..d354c7efcb1 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -488,6 +488,9 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m + case VKD3DSPSM_ABS: + vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); + break; ++ case VKD3DSPSM_ABSNEG: ++ vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); ++ break; + default: + vkd3d_string_buffer_printf(buffer, "(%s)", + vsir_src->modifiers, str->buffer); +@@ -545,6 +548,9 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment( + uint32_t modifiers = dst->vsir->modifiers; + va_list args; + ++ /* It is always legitimate to ignore _pp. */ ++ modifiers &= ~VKD3DSPDM_PARTIALPRECISION; ++ + if (dst->vsir->shift) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift); +@@ -1353,7 +1359,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + vkd3d_string_buffer_printf(gen->buffer, "#include \n\n"); + vkd3d_string_buffer_printf(gen->buffer, "using namespace metal;\n\n"); + +- if (gen->program->global_flags) ++ if (gen->program->global_flags & ~VKD3DSGF_REFACTORING_ALLOWED) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)gen->program->global_flags); + +@@ -1388,7 +1394,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + msl_generate_output_struct_declarations(gen); + + vkd3d_string_buffer_printf(gen->buffer, +- "void %s_main(thread vkd3d_vec4 *v, " ++ "static void %s_main(thread vkd3d_vec4 *v, " + "thread vkd3d_vec4 *o", + gen->prefix); + if (gen->write_depth) +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index a6f34703c2d..3e58718afa1 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -847,57 +847,6 @@ static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, enum vkd3d_s + vkd3d_shader_message_context_cleanup(&message_context); + } + +-enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, +- unsigned int index) +-{ +- switch (sysval) +- { +- case VKD3D_SHADER_SV_COVERAGE: +- case VKD3D_SHADER_SV_DEPTH: +- case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: +- case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: +- case VKD3D_SHADER_SV_NONE: +- case VKD3D_SHADER_SV_STENCIL_REF: +- case VKD3D_SHADER_SV_TARGET: +- return VKD3D_SIV_NONE; +- case VKD3D_SHADER_SV_POSITION: +- return VKD3D_SIV_POSITION; +- case VKD3D_SHADER_SV_CLIP_DISTANCE: +- return VKD3D_SIV_CLIP_DISTANCE; +- case VKD3D_SHADER_SV_CULL_DISTANCE: +- return VKD3D_SIV_CULL_DISTANCE; +- case VKD3D_SHADER_SV_INSTANCE_ID: +- return VKD3D_SIV_INSTANCE_ID; +- case VKD3D_SHADER_SV_IS_FRONT_FACE: +- return VKD3D_SIV_IS_FRONT_FACE; +- case VKD3D_SHADER_SV_PRIMITIVE_ID: +- return VKD3D_SIV_PRIMITIVE_ID; +- case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX: +- return VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX; +- case VKD3D_SHADER_SV_SAMPLE_INDEX: +- return VKD3D_SIV_SAMPLE_INDEX; +- case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE: +- return VKD3D_SIV_QUAD_U0_TESS_FACTOR + index; +- case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT: +- return VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR + index; +- case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE: +- return VKD3D_SIV_TRIANGLE_U_TESS_FACTOR + index; +- case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT: +- return VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR; +- case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET: +- return VKD3D_SIV_LINE_DETAIL_TESS_FACTOR; +- case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN: +- return VKD3D_SIV_LINE_DENSITY_TESS_FACTOR; +- case VKD3D_SHADER_SV_VERTEX_ID: +- return VKD3D_SIV_VERTEX_ID; +- case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX: +- return VKD3D_SIV_VIEWPORT_ARRAY_INDEX; +- default: +- FIXME("Unhandled sysval %#x, index %u.\n", sysval, index); +- return VKD3D_SIV_NONE; +- } +-} +- + struct vkd3d_spirv_stream + { + uint32_t *words; +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index 6042a76c3c4..08bdc3e645a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -3261,6 +3261,8 @@ static int signature_element_pointer_compare(const void *x, const void *y) + const struct signature_element *f = *(const struct signature_element **)y; + int ret; + ++ if ((ret = vkd3d_u32_compare(e->stream_index, f->stream_index))) ++ return ret; + if ((ret = vkd3d_u32_compare(e->register_index, f->register_index))) + return ret; + return vkd3d_u32_compare(e->mask, f->mask); +@@ -3269,12 +3271,17 @@ static int signature_element_pointer_compare(const void *x, const void *y) + static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_signature *signature, uint32_t tag) + { + bool has_minimum_precision = tpf->program->global_flags & VKD3DSGF_ENABLE_MINIMUM_PRECISION; +- bool output = tag == TAG_OSGN || (tag == TAG_PCSG +- && tpf->program->shader_version.type == VKD3D_SHADER_TYPE_HULL); ++ const struct vkd3d_shader_version *version = &tpf->program->shader_version; + const struct signature_element **sorted_elements; + struct vkd3d_bytecode_buffer buffer = {0}; ++ bool has_stream_index, output; + unsigned int i; + ++ output = tag == TAG_OSGN || (tag == TAG_PCSG && version->type == VKD3D_SHADER_TYPE_HULL); ++ if (output && version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) ++ tag = TAG_OSG5; ++ has_stream_index = tag == TAG_OSG5 || has_minimum_precision; ++ + put_u32(&buffer, signature->element_count); + put_u32(&buffer, 8); /* unknown */ + +@@ -3297,8 +3304,8 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si + if (sysval >= VKD3D_SHADER_SV_TARGET) + sysval = VKD3D_SHADER_SV_NONE; + +- if (has_minimum_precision) +- put_u32(&buffer, 0); /* FIXME: stream index */ ++ if (has_stream_index) ++ put_u32(&buffer, element->stream_index); + put_u32(&buffer, 0); /* name */ + put_u32(&buffer, element->semantic_index); + put_u32(&buffer, sysval); +@@ -3312,13 +3319,16 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si + for (i = 0; i < signature->element_count; ++i) + { + const struct signature_element *element = sorted_elements[i]; ++ size_t name_index = 2 + i * 6; + size_t string_offset; + +- string_offset = put_string(&buffer, element->semantic_name); ++ if (has_stream_index) ++ name_index += i + 1; + if (has_minimum_precision) +- set_u32(&buffer, (2 + i * 8 + 1) * sizeof(uint32_t), string_offset); +- else +- set_u32(&buffer, (2 + i * 6) * sizeof(uint32_t), string_offset); ++ name_index += i; ++ ++ string_offset = put_string(&buffer, element->semantic_name); ++ set_u32(&buffer, name_index * sizeof(uint32_t), string_offset); + } + + if (has_minimum_precision) +@@ -4176,6 +4186,8 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + case VKD3DSIH_CASE: + case VKD3DSIH_CONTINUE: + case VKD3DSIH_CUT: ++ case VKD3DSIH_CUT_STREAM: ++ case VKD3DSIH_DCL_STREAM: + case VKD3DSIH_DEFAULT: + case VKD3DSIH_DISCARD: + case VKD3DSIH_DIV: +@@ -4190,6 +4202,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + case VKD3DSIH_DSY_FINE: + case VKD3DSIH_ELSE: + case VKD3DSIH_EMIT: ++ case VKD3DSIH_EMIT_STREAM: + case VKD3DSIH_ENDIF: + case VKD3DSIH_ENDLOOP: + case VKD3DSIH_ENDSWITCH: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 4f625e3fae5..783f4e6134c 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -1436,13 +1436,14 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + if (context->cf_info_count) + context->cf_info[context->cf_info_count - 1].inside_block = false; + break; +- case VKD3DSIH_TEX: ++ case VKD3DSIH_TEXLD: + if (context->version->major == 1) + sampler_reg = &instruction->dst[0].reg; + else + sampler_reg = &instruction->src[1].reg; + vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg); + break; ++ case VKD3DSIH_TEX: + case VKD3DSIH_TEXBEM: + case VKD3DSIH_TEXBEML: + case VKD3DSIH_TEXDP3TEX: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index d4d76266df2..5dd00f00fe8 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -552,10 +552,12 @@ enum vkd3d_shader_opcode + VKD3DSIH_TEXBEM, + VKD3DSIH_TEXBEML, + VKD3DSIH_TEXCOORD, ++ VKD3DSIH_TEXCRD, + VKD3DSIH_TEXDEPTH, + VKD3DSIH_TEXDP3, + VKD3DSIH_TEXDP3TEX, + VKD3DSIH_TEXKILL, ++ VKD3DSIH_TEXLD, + VKD3DSIH_TEXLDD, + VKD3DSIH_TEXLDL, + VKD3DSIH_TEXM3x2DEPTH, +@@ -966,7 +968,7 @@ struct vkd3d_shader_register + enum vsir_dimension dimension; + /* known address alignment for optimisation, or zero */ + unsigned int alignment; +- union ++ union vsir_immediate_constant + { + uint32_t immconst_u32[VKD3D_VEC4_SIZE]; + float immconst_f32[VKD3D_VEC4_SIZE]; +@@ -1781,14 +1783,6 @@ static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type com + return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; + } + +-enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, +- unsigned int index); +- +-static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_shader_sysval_semantic sysval) +-{ +- return vkd3d_siv_from_sysval_indexed(sysval, 0); +-} +- + static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) + { + unsigned int i; +-- +2.47.2 + diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch new file mode 100644 index 00000000..9cf72b75 --- /dev/null +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-f1b36edc076117970b5a6d05a924b6c4248.patch @@ -0,0 +1,323 @@ +From 6a86ff50e62add7c2739b6508518b5556dcd2289 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 5 Jun 2025 07:25:40 +1000 +Subject: [PATCH] Updated vkd3d to f1b36edc076117970b5a6d05a924b6c4248e082f. + +--- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 69 ++++++++++++--------- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 55 +++++++++------- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 36 ++++++----- + 3 files changed, 91 insertions(+), 69 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index c85b644df15..ff56cd6284f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -6805,6 +6805,7 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ + { + enum vkd3d_shader_opcode op = VKD3DSIH_INVALID; + bool from_int, to_int, from_fp, to_fp; ++ unsigned int from_width, to_width; + bool is_valid = false; + + from_int = sm6_type_is_integer(from); +@@ -6828,66 +6829,58 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ + return VKD3DSIH_INVALID; + } + +- /* DXC emits minimum precision types as 16-bit. These must be emitted +- * as 32-bit in VSIR, so all width extensions to 32 bits are no-ops. */ + switch (code) + { + case CAST_TRUNC: +- /* nop or min precision. TODO: native 16-bit */ +- if (to->u.width == from->u.width || (to->u.width == 16 && from->u.width == 32)) +- op = VKD3DSIH_NOP; +- else +- op = VKD3DSIH_UTOU; ++ op = VKD3DSIH_UTOU; + is_valid = from_int && to_int && to->u.width <= from->u.width; + break; ++ + case CAST_ZEXT: ++ op = VKD3DSIH_UTOU; ++ is_valid = from_int && to_int && to->u.width >= from->u.width; ++ break; ++ + case CAST_SEXT: +- /* nop or min precision. TODO: native 16-bit. +- * Extension instructions could be emitted for min precision, but in Windows +- * the AMD RX 580 simply drops such instructions, which makes sense as no +- * assumptions should be made about any behaviour which depends on bit width. */ +- if (to->u.width == from->u.width || (to->u.width == 32 && from->u.width == 16)) +- { +- op = VKD3DSIH_NOP; +- is_valid = from_int && to_int; +- } +- else if (to->u.width > from->u.width) +- { +- op = (code == CAST_ZEXT) ? VKD3DSIH_UTOU : VKD3DSIH_ITOI; +- VKD3D_ASSERT(from->u.width == 1 || to->u.width == 64); +- is_valid = from_int && to_int; +- } ++ op = VKD3DSIH_ITOI; ++ is_valid = from_int && to_int && to->u.width >= from->u.width; + break; ++ + case CAST_FPTOUI: + op = VKD3DSIH_FTOU; + is_valid = from_fp && to_int && to->u.width > 1; + break; ++ + case CAST_FPTOSI: + op = VKD3DSIH_FTOI; + is_valid = from_fp && to_int && to->u.width > 1; + break; ++ + case CAST_UITOFP: + op = VKD3DSIH_UTOF; + is_valid = from_int && to_fp; + break; ++ + case CAST_SITOFP: + op = VKD3DSIH_ITOF; + is_valid = from_int && to_fp; + break; ++ + case CAST_FPTRUNC: +- /* TODO: native 16-bit */ +- op = (from->u.width == 64) ? VKD3DSIH_DTOF : VKD3DSIH_NOP; +- is_valid = from_fp && to_fp; ++ op = VKD3DSIH_DTOF; ++ is_valid = from_fp && to_fp && to->u.width <= from->u.width; + break; ++ + case CAST_FPEXT: +- /* TODO: native 16-bit */ +- op = (to->u.width == 64) ? VKD3DSIH_FTOD : VKD3DSIH_NOP; +- is_valid = from_fp && to_fp; ++ op = VKD3DSIH_FTOD; ++ is_valid = from_fp && to_fp && to->u.width >= from->u.width; + break; ++ + case CAST_BITCAST: + op = VKD3DSIH_MOV; + is_valid = to->u.width == from->u.width; + break; ++ + default: + FIXME("Unhandled cast op %"PRIu64".\n", code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -6904,6 +6897,20 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ + return VKD3DSIH_INVALID; + } + ++ /* 16-bit values are currently treated as 32-bit, because 16-bit is ++ * interpreted as a minimum precision hint in SM 6.0, and we don't handle ++ * SM > 6.0 yet. */ ++ from_width = from->u.width; ++ if (from_width == 16) ++ from_width = 32; ++ ++ to_width = to->u.width; ++ if (to_width == 16) ++ to_width = 32; ++ ++ if (from->class == to->class && from_width == to_width) ++ op = VKD3DSIH_NOP; ++ + return op; + } + +@@ -6955,9 +6962,11 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor + + instruction_dst_param_init_ssa_scalar(ins, sm6); + +- /* bitcast */ ++ /* VSIR bitcasts are represented by source registers with types different ++ * from the types they were written with, rather than with different types ++ * for the MOV source and destination. */ + if (handler_idx == VKD3DSIH_MOV) +- src_param->reg.data_type = dst->reg.data_type; ++ src_param->reg.data_type = ins->dst[0].reg.data_type; + } + + struct sm6_cmp_info +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index d4cd338f15a..d4e29e16b7c 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -12114,14 +12114,11 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + bool uav) + { + enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES; +- struct vkd3d_shader_structured_resource *structured_resource; +- struct vkd3d_shader_dst_param *dst_param; +- struct vkd3d_shader_semantic *semantic; + struct vkd3d_shader_instruction *ins; + struct hlsl_type *component_type; + enum vkd3d_shader_opcode opcode; + bool multisampled; +- unsigned int i, j; ++ unsigned int i; + + VKD3D_ASSERT(resource->regset == regset); + VKD3D_ASSERT(hlsl_version_lt(ctx, 5, 1) || resource->bind_count == 1); +@@ -12132,6 +12129,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + { + unsigned int array_first = resource->index + i; + unsigned int array_last = resource->index + i; /* FIXME: array end. */ ++ struct vkd3d_shader_resource *vsir_resource; + + if (resource->var && !resource->var->objects_usage[regset][i].used) + continue; +@@ -12169,13 +12167,16 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } +- semantic = &ins->declaration.semantic; +- structured_resource = &ins->declaration.structured_resource; +- dst_param = &semantic->resource.reg; +- vsir_dst_param_init(dst_param, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 0); + +- if (uav && component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) +- structured_resource->byte_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; ++ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) ++ vsir_resource = &ins->declaration.raw_resource.resource; ++ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ vsir_resource = &ins->declaration.structured_resource.resource; ++ else ++ vsir_resource = &ins->declaration.semantic.resource; ++ ++ vsir_dst_param_init(&vsir_resource->reg, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 0); ++ + if (uav && component_type->e.resource.rasteriser_ordered) + ins->flags = VKD3DSUF_RASTERISER_ORDERED_VIEW; + +@@ -12189,29 +12190,35 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + ctx->profile->major_version, ctx->profile->minor_version); + } + +- for (j = 0; j < 4; ++j) +- semantic->resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); ++ vsir_resource->range.first = array_first; ++ vsir_resource->range.last = array_last; ++ vsir_resource->range.space = resource->space; + +- semantic->resource.range.first = array_first; +- semantic->resource.range.last = array_last; +- semantic->resource.range.space = resource->space; +- +- dst_param->reg.idx[0].offset = resource->id; +- dst_param->reg.idx[1].offset = array_first; +- dst_param->reg.idx[2].offset = array_last; +- dst_param->reg.idx_count = 3; ++ vsir_resource->reg.reg.idx[0].offset = resource->id; ++ vsir_resource->reg.reg.idx[1].offset = array_first; ++ vsir_resource->reg.reg.idx[2].offset = array_last; ++ vsir_resource->reg.reg.idx_count = 3; + + ins->resource_type = sm4_generate_vsir_get_resource_type(resource->component_type); +- if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) ++ ++ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) ++ { + ins->raw = true; +- if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ } ++ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + { + ins->structured = true; + ins->resource_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; ++ ins->declaration.structured_resource.byte_stride = ins->resource_stride; + } ++ else ++ { ++ for (unsigned int j = 0; j < 4; ++j) ++ ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); + +- if (multisampled) +- semantic->sample_count = component_type->sample_count; ++ if (multisampled) ++ ins->declaration.semantic.sample_count = component_type->sample_count; ++ } + } + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index 08bdc3e645a..ae3fa1650bf 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -3859,9 +3859,8 @@ static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_dat + + static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) + { +- const struct vkd3d_shader_structured_resource *structured_resource = &ins->declaration.structured_resource; +- const struct vkd3d_shader_semantic *semantic = &ins->declaration.semantic; + const struct vkd3d_shader_version *version = &tpf->program->shader_version; ++ const struct vkd3d_shader_resource *resource; + const struct vkd3d_sm4_opcode_info *info; + struct sm4_instruction instr = {0}; + bool uav; +@@ -3875,27 +3874,38 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s + + instr.opcode = info->opcode; + +- instr.dsts[0] = semantic->resource.reg; +- instr.dst_count = 1; +- + if (ins->opcode == VKD3DSIH_DCL || ins->opcode == VKD3DSIH_DCL_UAV_TYPED) + { +- instr.idx[0] = pack_resource_data_type(semantic->resource_data_type); ++ instr.idx[0] = pack_resource_data_type(ins->declaration.semantic.resource_data_type); + instr.idx_count = 1; ++ instr.extra_bits |= ins->declaration.semantic.sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; ++ resource = &ins->declaration.semantic.resource; ++ } ++ else if (ins->opcode == VKD3DSIH_DCL_RESOURCE_RAW || ins->opcode == VKD3DSIH_DCL_UAV_RAW) ++ { ++ resource = &ins->declaration.raw_resource.resource; ++ } ++ else ++ { ++ instr.byte_stride = ins->declaration.structured_resource.byte_stride; ++ resource = &ins->declaration.structured_resource.resource; + } + ++ instr.dsts[0] = resource->reg; ++ instr.dst_count = 1; ++ + if (vkd3d_shader_ver_ge(version, 5, 1)) + { +- instr.dsts[0].reg.idx[0].offset = semantic->resource.reg.reg.idx[0].offset; +- instr.dsts[0].reg.idx[1].offset = semantic->resource.range.first; +- instr.dsts[0].reg.idx[2].offset = semantic->resource.range.last; ++ instr.dsts[0].reg.idx[0].offset = resource->reg.reg.idx[0].offset; ++ instr.dsts[0].reg.idx[1].offset = resource->range.first; ++ instr.dsts[0].reg.idx[2].offset = resource->range.last; + instr.dsts[0].reg.idx_count = 3; + +- instr.idx[instr.idx_count++] = semantic->resource.range.space; ++ instr.idx[instr.idx_count++] = resource->range.space; + } + else + { +- instr.dsts[0].reg.idx[0].offset = semantic->resource.range.first; ++ instr.dsts[0].reg.idx[0].offset = resource->range.first; + instr.dsts[0].reg.idx_count = 1; + } + +@@ -3903,10 +3913,6 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s + instr.extra_bits |= ins->flags << VKD3D_SM5_UAV_FLAGS_SHIFT; + + instr.extra_bits |= (sm4_resource_dimension(ins->resource_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); +- instr.extra_bits |= semantic->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; +- +- if (ins->structured) +- instr.byte_stride = structured_resource->byte_stride; + + write_sm4_instruction(tpf, &instr); + } +-- +2.47.2 + diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch new file mode 100644 index 00000000..b96c8594 --- /dev/null +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-d65be3d0c5698a1b0df7c39ec0eaa485a8b.patch @@ -0,0 +1,723 @@ +From 981c6b22b1d959588c16002c6176d72615c23cb0 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Fri, 6 Jun 2025 07:10:30 +1000 +Subject: [PATCH] Updated vkd3d to d65be3d0c5698a1b0df7c39ec0eaa485a8bd35de. + +--- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 32 ++-- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 3 + + libs/vkd3d/libs/vkd3d-shader/msl.c | 239 +++++++++++++++++-------- + libs/vkd3d/libs/vkd3d-shader/preproc.h | 2 +- + libs/vkd3d/libs/vkd3d-shader/preproc.l | 38 ++-- + 5 files changed, 210 insertions(+), 104 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index ff56cd6284f..8c71176fb0b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -644,7 +644,6 @@ struct sm6_type + enum sm6_value_type + { + VALUE_TYPE_FUNCTION, +- VALUE_TYPE_REG, + VALUE_TYPE_DATA, + VALUE_TYPE_HANDLE, + VALUE_TYPE_SSA, +@@ -711,6 +710,7 @@ struct sm6_value + enum sm6_value_type value_type; + unsigned int structure_stride; + bool is_back_ref; ++ bool non_uniform; + union + { + struct sm6_function_data function; +@@ -747,7 +747,7 @@ struct incoming_value + + struct sm6_phi + { +- struct vkd3d_shader_register reg; ++ struct sm6_value value; + struct incoming_value *incoming; + size_t incoming_capacity; + size_t incoming_count; +@@ -2275,7 +2275,6 @@ static inline bool sm6_value_is_register(const struct sm6_value *value) + { + switch (value->value_type) + { +- case VALUE_TYPE_REG: + case VALUE_TYPE_SSA: + case VALUE_TYPE_ICB: + case VALUE_TYPE_IDXTEMP: +@@ -2468,10 +2467,6 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + + switch (value->value_type) + { +- case VALUE_TYPE_REG: +- *reg = value->reg; +- break; +- + case VALUE_TYPE_SSA: + register_init_with_id(reg, VKD3DSPR_SSA, data_type, value->u.ssa.id); + reg->dimension = sm6_type_is_scalar(value->type) ? VSIR_DIMENSION_SCALAR : VSIR_DIMENSION_VEC4; +@@ -2514,6 +2509,8 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + case VALUE_TYPE_DATA: + vkd3d_unreachable(); + } ++ ++ reg->non_uniform = value->non_uniform; + } + + static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *value) +@@ -3743,7 +3740,6 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ + + dst = sm6_parser_get_current_value(sm6); + dst->type = type; +- dst->value_type = VALUE_TYPE_REG; + dst->is_back_ref = true; + + if (is_constant && !init) +@@ -6949,10 +6945,9 @@ 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); +- /* 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); ++ *dst = *value; ++ dst->type = type; ++ sm6_register_from_value(&dst->reg, dst, sm6); + return; + } + +@@ -7478,7 +7473,6 @@ 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); + phi->incoming_count = record->operand_count / 2u; + + if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count, +@@ -8004,7 +7998,8 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e + } + else if (metadata_node_get_unary_uint(node, &operand, sm6)) + { +- dst->reg.non_uniform = !!operand; ++ dst->non_uniform = !!operand; ++ sm6_register_from_value(&dst->reg, dst, sm6); + } + } + else +@@ -8076,7 +8071,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun + "A PHI incoming value is not a constant or SSA register."); + return VKD3D_ERROR_INVALID_SHADER; + } +- if (src->reg.data_type != phi->reg.data_type) ++ if (src->type != phi->value.type) + { + WARN("Type mismatch.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, +@@ -8171,7 +8166,6 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const + dst = sm6_parser_get_current_value(sm6); + fwd_type = dst->type; + dst->type = NULL; +- dst->value_type = VALUE_TYPE_REG; + dst->is_back_ref = true; + is_terminator = false; + +@@ -8249,6 +8243,10 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const + if (record->attachment) + metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6); + ++ /* This is specific for PHI nodes, but must happen after attachments have been applied. */ ++ if (record->code == FUNC_CODE_INST_PHI) ++ code_block->phi[code_block->phi_count - 1].value = *dst; ++ + if (is_terminator) + { + ++block_idx; +@@ -8395,7 +8393,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser + } + + dst_param_init(dst_param); +- dst_param->reg = src_phi->reg; ++ sm6_register_from_value(&dst_param->reg, &src_phi->value, sm6); + } + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 5aee1e701cd..bad9d33094b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -2559,6 +2559,9 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Variable '%s' is declared as both \"uniform\" and \"static\".", var->name); + ++ if (modifiers & HLSL_STORAGE_GROUPSHARED) ++ hlsl_fixme(ctx, &var->loc, "Group shared variables."); ++ + /* Mark it as uniform. We need to do this here since synthetic + * variables also get put in the global scope, but shouldn't be + * considered uniforms, and we have no way of telling otherwise. */ +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index d354c7efcb1..62981811ee4 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -48,7 +48,7 @@ struct msl_generator + const char *prefix; + bool failed; + +- bool write_depth; ++ bool read_vertex_id; + + const struct vkd3d_shader_interface_info *interface_info; + }; +@@ -57,10 +57,12 @@ struct msl_resource_type_info + { + size_t read_coord_size; + bool array; +- bool lod; + const char *type_suffix; + }; + ++static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, ++ const struct vkd3d_shader_src_param *rel_addr, unsigned int offset); ++ + static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen, + enum vkd3d_shader_error error, const char *fmt, ...) + { +@@ -76,17 +78,17 @@ static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3 + { + static const struct msl_resource_type_info info[] = + { +- [VKD3D_SHADER_RESOURCE_NONE] = {0, false, false, "none"}, +- [VKD3D_SHADER_RESOURCE_BUFFER] = {1, false, false, "_buffer"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, false, false, "1d"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, false, true, "2d"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, false, false, "2d_ms"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, false, true, "3d"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, false, true, "cube"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, true, false, "1d_array"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, true, true, "2d_array"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, true, false, "2d_ms_array"}, +- [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, true, true, "cube_array"}, ++ [VKD3D_SHADER_RESOURCE_NONE] = {0, 0, "none"}, ++ [VKD3D_SHADER_RESOURCE_BUFFER] = {1, 0, "_buffer"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, 0, "1d"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, 0, "2d"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, 0, "2d_ms"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, 0, "3d"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, 0, "cube"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, 1, "1d_array"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, 1, "2d_array"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, 1, "2d_ms_array"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, 1, "cube_array"}, + }; + + if (!t || t >= ARRAY_SIZE(info)) +@@ -359,22 +361,24 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu + vkd3d_string_buffer_printf(buffer, "", reg->type); + return MSL_DATA_UNION; + } +- if (reg->idx[0].rel_addr || reg->idx[1].rel_addr || reg->idx[2].rel_addr) ++ if (reg->idx[0].rel_addr || reg->idx[1].rel_addr) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled constant buffer register indirect addressing."); + vkd3d_string_buffer_printf(buffer, "", reg->type); + return MSL_DATA_UNION; + } ++ /* FIXME: This should use vkd3d_shader_find_descriptor() to ++ * find the resource index/space from the resource ID. */ + if (!(binding = msl_get_cbv_binding(gen, 0, reg->idx[1].offset))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, +- "Cannot finding binding for CBV register %u.", reg->idx[0].offset); ++ "No descriptor binding specified for CBV %u.", reg->idx[0].offset); + vkd3d_string_buffer_printf(buffer, "", reg->type); + return MSL_DATA_UNION; + } + msl_print_cbv_name(buffer, binding->binding); +- vkd3d_string_buffer_printf(buffer, "[%u]", reg->idx[2].offset); ++ msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); + return MSL_DATA_UNION; + } + +@@ -542,6 +546,25 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, + return write_mask; + } + ++static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, ++ const struct vkd3d_shader_src_param *rel_addr, unsigned int offset) ++{ ++ struct msl_src r; ++ ++ if (!rel_addr) ++ { ++ vkd3d_string_buffer_printf(buffer, "[%u]", offset); ++ return; ++ } ++ ++ msl_src_init(&r, gen, rel_addr, VKD3DSP_WRITEMASK_0); ++ vkd3d_string_buffer_printf(buffer, "[%s", r.str->buffer); ++ if (offset) ++ vkd3d_string_buffer_printf(buffer, " + %u", offset); ++ vkd3d_string_buffer_printf(buffer, "]"); ++ msl_src_cleanup(&r, &gen->string_buffers); ++} ++ + static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment( + struct msl_generator *gen, struct msl_dst *dst, const char *format, ...) + { +@@ -734,6 +757,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + enum vkd3d_shader_resource_type resource_type; + struct vkd3d_string_buffer *read; + enum vkd3d_data_type data_type; ++ unsigned int srv_binding; + uint32_t coord_mask; + struct msl_dst dst; + +@@ -763,30 +787,38 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + data_type = VKD3D_DATA_FLOAT; + } + +- if ((resource_type_info = msl_get_resource_type_info(resource_type))) +- { +- coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size); +- } +- else ++ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS ++ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBE ++ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY ++ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, ++ "Texel fetches from resource type %#x are not supported.", resource_type); ++ ++ if (!(resource_type_info = msl_get_resource_type_info(resource_type))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled resource type %#x.", resource_type); +- coord_mask = vkd3d_write_mask_from_component_count(2); ++ resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); + } ++ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size); + +- if (!(binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) ++ if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) ++ { ++ srv_binding = binding->binding; ++ } ++ else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, +- "Cannot finding binding for SRV register %u index %u space %u.", ++ "No descriptor binding specified for SRV %u (index %u, space %u).", + resource_id, resource_idx, resource_space); +- return; ++ srv_binding = 0; + } + + msl_dst_init(&dst, gen, ins, &ins->dst[0]); + read = vkd3d_string_buffer_get(&gen->string_buffers); + + vkd3d_string_buffer_printf(read, "as_type("); +- msl_print_srv_name(read, gen, binding->binding, resource_type_info, data_type); ++ msl_print_srv_name(read, gen, srv_binding, resource_type_info, data_type); + vkd3d_string_buffer_printf(read, ".read("); + msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); + if (resource_type_info->array) +@@ -794,7 +826,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + vkd3d_string_buffer_printf(read, ", "); + msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT); + } +- if (resource_type_info->lod) ++ if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) + { + vkd3d_string_buffer_printf(read, ", "); + msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); +@@ -1014,21 +1046,48 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) + if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) + continue; + +- if (e->sysval_semantic) ++ switch (e->sysval_semantic) + { +- if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) +- { ++ case VKD3D_SHADER_SV_NONE: ++ break; ++ ++ case VKD3D_SHADER_SV_POSITION: + if (type != VKD3D_SHADER_TYPE_PIXEL) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type); ++ "Internal compiler error: Unhandled SV_POSITION in shader type #%x.", type); ++ msl_print_indent(gen->buffer, 1); ++ vkd3d_string_buffer_printf(buffer, "float4 position [[position]];\n"); ++ continue; ++ ++ case VKD3D_SHADER_SV_VERTEX_ID: ++ if (type != VKD3D_SHADER_TYPE_VERTEX) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled SV_VERTEX_ID in shader type #%x.", type); ++ gen->read_vertex_id = true; ++ continue; + ++ case VKD3D_SHADER_SV_IS_FRONT_FACE: ++ if (type != VKD3D_SHADER_TYPE_PIXEL) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type); + msl_print_indent(gen->buffer, 1); + vkd3d_string_buffer_printf(buffer, "bool is_front_face [[front_facing]];\n"); + continue; +- } +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic); +- continue; ++ ++ case VKD3D_SHADER_SV_SAMPLE_INDEX: ++ if (type != VKD3D_SHADER_TYPE_PIXEL) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled SV_SAMPLE_INDEX in shader type #%x.", type); ++ msl_print_indent(gen->buffer, 1); ++ vkd3d_string_buffer_printf(buffer, "uint sample_index [[sample_id]];\n"); ++ continue; ++ ++ default: ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic); ++ msl_print_indent(gen->buffer, 1); ++ vkd3d_string_buffer_printf(buffer, ";\n", e->sysval_semantic); ++ continue; + } + + if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) +@@ -1065,15 +1124,15 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) + break; + } + +- vkd3d_string_buffer_printf(buffer, "shader_in_%u ", i); ++ vkd3d_string_buffer_printf(buffer, "shader_in_%u [[", i); + + switch (type) + { + case VKD3D_SHADER_TYPE_VERTEX: +- vkd3d_string_buffer_printf(gen->buffer, "[[attribute(%u)]]", e->target_location); ++ vkd3d_string_buffer_printf(gen->buffer, "attribute(%u)", e->target_location); + break; + case VKD3D_SHADER_TYPE_PIXEL: +- vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location); ++ vkd3d_string_buffer_printf(gen->buffer, "user(locn%u)", e->target_location); + break; + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +@@ -1087,13 +1146,16 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) + case VKD3DSIM_LINEAR: + case VKD3DSIM_NONE: + break; ++ case VKD3DSIM_CONSTANT: ++ vkd3d_string_buffer_printf(gen->buffer, ", flat"); ++ break; + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); + break; + } + +- vkd3d_string_buffer_printf(buffer, ";\n"); ++ vkd3d_string_buffer_printf(buffer, "]];\n"); + } + + vkd3d_string_buffer_printf(buffer, "};\n\n"); +@@ -1144,15 +1206,8 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) + { + e = &signature->elements[i]; + +- if (e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) +- { +- gen->write_depth = true; +- msl_print_indent(gen->buffer, 1); +- vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); +- continue; +- } +- +- if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) ++ if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED ++ || e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) + continue; + + if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) +@@ -1215,6 +1270,12 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) + vkd3d_string_buffer_printf(buffer, ";\n"); + } + ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) ++ { ++ msl_print_indent(gen->buffer, 1); ++ vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); ++ } ++ + vkd3d_string_buffer_printf(buffer, "};\n\n"); + } + +@@ -1233,23 +1294,45 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) + continue; + + vkd3d_string_buffer_printf(buffer, " %s_in[%u]", gen->prefix, e->register_index); +- if (e->sysval_semantic == VKD3D_SHADER_SV_NONE) +- { +- msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); +- msl_print_write_mask(buffer, e->mask); +- vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i); +- msl_print_write_mask(buffer, e->mask); +- } +- else if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) +- { +- vkd3d_string_buffer_printf(buffer, ".u = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)"); +- } +- else ++ switch (e->sysval_semantic) + { +- vkd3d_string_buffer_printf(buffer, " = ", e->sysval_semantic); +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic); ++ case VKD3D_SHADER_SV_NONE: ++ msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); ++ msl_print_write_mask(buffer, e->mask); ++ vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i); ++ break; ++ ++ case VKD3D_SHADER_SV_POSITION: ++ msl_print_register_datatype(buffer, gen, VKD3D_DATA_FLOAT); ++ msl_print_write_mask(buffer, e->mask); ++ vkd3d_string_buffer_printf(buffer, " = float4(input.position.xyz, 1.0f / input.position.w)"); ++ break; ++ ++ case VKD3D_SHADER_SV_VERTEX_ID: ++ msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); ++ msl_print_write_mask(buffer, e->mask); ++ vkd3d_string_buffer_printf(buffer, " = uint4(vertex_id, 0u, 0u, 0u)"); ++ break; ++ ++ case VKD3D_SHADER_SV_IS_FRONT_FACE: ++ msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); ++ msl_print_write_mask(buffer, e->mask); ++ vkd3d_string_buffer_printf(buffer, " = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)"); ++ break; ++ ++ case VKD3D_SHADER_SV_SAMPLE_INDEX: ++ msl_print_register_datatype(buffer, gen, VKD3D_DATA_UINT); ++ msl_print_write_mask(buffer, e->mask); ++ vkd3d_string_buffer_printf(buffer, " = uint4(input.sample_index, 0u, 0u, 0u)"); ++ break; ++ ++ default: ++ vkd3d_string_buffer_printf(buffer, " = ", e->sysval_semantic); ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic); ++ break; + } ++ msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, ";\n"); + } + } +@@ -1265,12 +1348,6 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) + { + e = &signature->elements[i]; + +- if (e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) +- { +- vkd3d_string_buffer_printf(buffer, " output.shader_out_depth = shader_out_depth;\n"); +- continue; +- } +- + if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) + continue; + +@@ -1285,6 +1362,8 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) + msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); + msl_print_write_mask(buffer, e->mask); + break; ++ case VKD3D_SHADER_SV_DEPTH: ++ continue; + default: + vkd3d_string_buffer_printf(buffer, " ", e->sysval_semantic); + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +@@ -1322,6 +1401,12 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + "constant descriptor *descriptors [[buffer(0)]],\n"); + } + ++ if (gen->read_vertex_id) ++ { ++ msl_print_indent(gen->buffer, 2); ++ vkd3d_string_buffer_printf(gen->buffer, "uint vertex_id [[vertex_id]],\n"); ++ } ++ + msl_print_indent(gen->buffer, 2); + vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix); + +@@ -1330,14 +1415,13 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, 32); + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix); + +- if (gen->write_depth) +- vkd3d_string_buffer_printf(gen->buffer, " float shader_out_depth;\n"); +- + msl_generate_entrypoint_prologue(gen); + + vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix); +- if (gen->write_depth) +- vkd3d_string_buffer_printf(gen->buffer, ", shader_out_depth"); ++ if (gen->read_vertex_id) ++ vkd3d_string_buffer_printf(gen->buffer, ", vertex_id"); ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) ++ vkd3d_string_buffer_printf(gen->buffer, ", output.shader_out_depth"); + if (gen->program->descriptors.descriptor_count) + vkd3d_string_buffer_printf(gen->buffer, ", descriptors"); + vkd3d_string_buffer_printf(gen->buffer, ");\n"); +@@ -1397,8 +1481,11 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + "static void %s_main(thread vkd3d_vec4 *v, " + "thread vkd3d_vec4 *o", + gen->prefix); +- if (gen->write_depth) +- vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth"); ++ ++ if (gen->read_vertex_id) ++ vkd3d_string_buffer_printf(gen->buffer, ", uint vertex_id"); ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) ++ vkd3d_string_buffer_printf(gen->buffer, ", thread float &o_depth"); + if (gen->program->descriptors.descriptor_count) + vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors"); + vkd3d_string_buffer_printf(gen->buffer, ")\n{\n"); +diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.h b/libs/vkd3d/libs/vkd3d-shader/preproc.h +index a98c8ae3df5..9217237d8d3 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/preproc.h ++++ b/libs/vkd3d/libs/vkd3d-shader/preproc.h +@@ -38,6 +38,7 @@ struct preproc_buffer + { + void *lexer_buffer; + struct vkd3d_shader_location location; ++ bool eof; + }; + + struct preproc_file +@@ -125,7 +126,6 @@ struct preproc_ctx + int lookahead_token; + + bool last_was_newline; +- bool last_was_eof; + bool last_was_defined; + + bool error; +diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l +index d167415c356..5c56fba0229 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/preproc.l ++++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l +@@ -72,8 +72,8 @@ INT_SUFFIX [uUlL]{0,2} + + %% + +-"//" {yy_push_state(CXX_COMMENT, yyscanner);} +-"/*" {yy_push_state(C_COMMENT, yyscanner);} ++"//" {yy_push_state(CXX_COMMENT, yyscanner);} ++"/*" {yy_push_state(C_COMMENT, yyscanner);} + \\{NEWLINE} {} + \n { + yy_pop_state(yyscanner); +@@ -81,7 +81,11 @@ INT_SUFFIX [uUlL]{0,2} + return T_NEWLINE; + } + "*/" {yy_pop_state(yyscanner);} +-<> {yy_pop_state(yyscanner);} ++<> { ++ yy_pop_state(yyscanner); ++ BEGIN(INITIAL); ++ yyterminate(); ++ } + . {} + \n {} + +@@ -197,6 +201,10 @@ INT_SUFFIX [uUlL]{0,2} + BEGIN(INITIAL); + return T_NEWLINE; + } ++<> { ++ BEGIN(INITIAL); ++ yyterminate(); ++ } + + {WS}+ {} + [-()\[\]{},+!*/<>&|^?:] {return yytext[0];} +@@ -251,8 +259,19 @@ static bool should_concat(struct preproc_ctx *ctx) + return !macro || macro->arg_count; + } + ++static struct preproc_buffer *preproc_get_top_buffer(struct preproc_ctx *ctx) ++{ ++ if (ctx->expansion_count) ++ return &ctx->expansion_stack[ctx->expansion_count - 1].buffer; ++ if (ctx->file_count) ++ return &ctx->file_stack[ctx->file_count - 1].buffer; ++ return NULL; ++} ++ + static void preproc_pop_buffer(struct preproc_ctx *ctx) + { ++ struct preproc_buffer *buffer; ++ + if (ctx->expansion_count) + { + struct preproc_expansion *exp = &ctx->expansion_stack[ctx->expansion_count - 1]; +@@ -291,10 +310,8 @@ static void preproc_pop_buffer(struct preproc_ctx *ctx) + TRACE("File stack size is now %zu.\n", ctx->file_count); + } + +- if (ctx->expansion_count) +- yy_switch_to_buffer(ctx->expansion_stack[ctx->expansion_count - 1].buffer.lexer_buffer, ctx->scanner); +- else if (ctx->file_count) +- yy_switch_to_buffer(ctx->file_stack[ctx->file_count - 1].buffer.lexer_buffer, ctx->scanner); ++ if ((buffer = preproc_get_top_buffer(ctx))) ++ yy_switch_to_buffer(buffer->lexer_buffer, ctx->scanner); + } + + static int return_token(int token, YYSTYPE *lval, const char *text) +@@ -348,6 +365,7 @@ static bool preproc_push_expansion(struct preproc_ctx *ctx, + exp->text = text; + exp->buffer.lexer_buffer = yy_scan_bytes(text->text.buffer, text->text.content_size, ctx->scanner); + exp->buffer.location = text->location; ++ exp->buffer.eof = false; + exp->macro = macro; + exp->arg_values = arg_values; + TRACE("Expansion stack size is now %zu.\n", ctx->expansion_count); +@@ -408,18 +426,17 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) + } + else + { +- if (ctx->last_was_eof) ++ if (preproc_get_top_buffer(ctx)->eof) + { + preproc_pop_buffer(ctx); + if (!ctx->file_count) + return 0; + } +- ctx->last_was_eof = false; + + VKD3D_ASSERT(ctx->file_count); + if (!(token = preproc_lexer_lex(lval, lloc, scanner))) + { +- ctx->last_was_eof = true; ++ preproc_get_top_buffer(ctx)->eof = true; + + /* If we have reached the end of an included file, inject a newline. */ + if (ctx->expansion_count) +@@ -782,6 +799,7 @@ bool preproc_push_include(struct preproc_ctx *ctx, char *filename, const struct + file->buffer.location.source_name = file->filename; + file->buffer.location.line = 1; + file->buffer.location.column = 1; ++ file->buffer.eof = false; + TRACE("File stack size is now %zu.\n", ctx->file_count); + ctx->last_was_newline = true; + return true; +-- +2.47.2 +