diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch index 4a3ecb3e..e356f4a3 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch @@ -1,4 +1,4 @@ -From d88e0f20906e9f5d91c0f68de9251f61ec7cb487 Mon Sep 17 00:00:00 2001 +From 758a3c4c4d478bb14d7a582f0f5d919f1d0606d7 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 e69f3da089d472b723b016ef67c04c0f954fa792. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-dddc92ccfd34f941d9b6738c4f54fac43cd.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-dddc92ccfd34f941d9b6738c4f54fac43cd.patch index 6eb0f668..634a1995 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-dddc92ccfd34f941d9b6738c4f54fac43cd.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-dddc92ccfd34f941d9b6738c4f54fac43cd.patch @@ -1,4 +1,4 @@ -From f6d7123b28c0ef30e857fd1bea44c2e326239f3f Mon Sep 17 00:00:00 2001 +From 608249d59683030152ffef768265bb0e2627da2a Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 17 Sep 2025 06:37:38 +1000 Subject: [PATCH] Updated vkd3d to dddc92ccfd34f941d9b6738c4f54fac43cda42b3. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-c48141457203d4cdfcd8315c0735748ba3b.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-c48141457203d4cdfcd8315c0735748ba3b.patch new file mode 100644 index 00000000..c49d18c1 --- /dev/null +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-c48141457203d4cdfcd8315c0735748ba3b.patch @@ -0,0 +1,1009 @@ +From 31a8d5149c3489fa51bad8aa9880eb201f4513bd Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 18 Sep 2025 06:55:52 +1000 +Subject: [PATCH] Updated vkd3d to c48141457203d4cdfcd8315c0735748ba3b9fda2. + +--- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 16 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 3 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 280 ++++++++++++------ + libs/vkd3d/libs/vkd3d-shader/spirv.c | 13 +- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 2 +- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 1 - + .../libs/vkd3d-shader/vkd3d_shader_private.h | 45 ++- + libs/vkd3d/libs/vkd3d/command.c | 90 +++--- + libs/vkd3d/libs/vkd3d/device.c | 24 +- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 5 +- + 10 files changed, 296 insertions(+), 183 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 44d2b8b1142..63dcbd3c08a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -919,6 +919,7 @@ struct sm6_parser + struct vkd3d_shader_dst_param *input_params; + struct vkd3d_shader_dst_param *patch_constant_params; + uint32_t io_regs_declared[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)]; ++ struct vkd3d_shader_src_param *outpointid_param; + + struct sm6_function *functions; + size_t function_count; +@@ -3246,7 +3247,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co + "Out of memory allocating an immediate constant buffer of count %u.", count); + return VKD3D_ERROR_OUT_OF_MEMORY; + } +- if (!shader_instruction_array_add_icb(&sm6->program->instructions, icb)) ++ if (!vsir_program_add_icb(sm6->program, icb)) + { + ERR("Failed to store icb object.\n"); + vkd3d_free(icb); +@@ -4217,7 +4218,10 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade + if (is_control_point) + { + if (reg_type == VKD3DSPR_OUTPUT) +- param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->program); ++ { ++ VKD3D_ASSERT(sm6->outpointid_param); ++ param->reg.idx[count].rel_addr = sm6->outpointid_param; ++ } + param->reg.idx[count++].offset = 0; + } + +@@ -10007,6 +10011,14 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons + &program->patch_constant_signature, tessellator_domain, false)) < 0) + return ret; + ++ if (sm6->program->shader_version.type == VKD3D_SHADER_TYPE_HULL ++ && !(sm6->outpointid_param = vsir_program_create_outpointid_param(sm6->program))) ++ { ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, ++ "Failed to allocate outpointid parameter."); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ + if ((ret = sm6_parser_init_input_signature(sm6, &program->input_signature)) < 0) + return ret; + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index d8eb18e39c7..5a25efdee75 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -3788,8 +3788,9 @@ static void dump_ir_expr(struct vkd3d_string_buffer *buffer, const struct hlsl_i + vkd3d_string_buffer_printf(buffer, "%s (", debug_hlsl_expr_op(expr->op)); + for (i = 0; i < HLSL_MAX_OPERANDS && expr->operands[i].node; ++i) + { ++ if (i) ++ vkd3d_string_buffer_printf(buffer, " "); + dump_src(buffer, &expr->operands[i]); +- vkd3d_string_buffer_printf(buffer, " "); + } + vkd3d_string_buffer_printf(buffer, ")"); + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index eb50aecf8ae..506b397fb02 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -502,22 +502,21 @@ bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *a + return true; + } + +-bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *array, +- struct vkd3d_shader_immediate_constant_buffer *icb) ++bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb) + { +- if (!vkd3d_array_reserve((void **)&array->icbs, &array->icb_capacity, array->icb_count + 1, sizeof(*array->icbs))) ++ if (!vkd3d_array_reserve((void **)&program->icbs, &program->icb_capacity, ++ program->icb_count + 1, sizeof(*program->icbs))) + return false; + +- array->icbs[array->icb_count++] = icb; ++ program->icbs[program->icb_count++] = icb; + + return true; + } + +-static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( +- struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_src_param *params, size_t count); ++static struct vkd3d_shader_src_param *vsir_program_clone_src_params( ++ struct vsir_program *program, const struct vkd3d_shader_src_param *params, size_t count); + +-static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, +- struct vkd3d_shader_instruction_array *array) ++static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, struct vsir_program *program) + { + size_t i; + +@@ -526,45 +525,45 @@ static bool shader_register_clone_relative_addresses(struct vkd3d_shader_registe + if (!reg->idx[i].rel_addr) + continue; + +- if (!(reg->idx[i].rel_addr = shader_instruction_array_clone_src_params(array, reg->idx[i].rel_addr, 1))) ++ if (!(reg->idx[i].rel_addr = vsir_program_clone_src_params(program, reg->idx[i].rel_addr, 1))) + return false; + } + + return true; + } + +-static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( +- struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_dst_param *params, size_t count) ++static struct vkd3d_shader_dst_param *vsir_program_clone_dst_params( ++ struct vsir_program *program, const struct vkd3d_shader_dst_param *params, size_t count) + { + struct vkd3d_shader_dst_param *dst_params; + size_t i; + +- if (!(dst_params = shader_dst_param_allocator_get(&array->dst_params, count))) ++ if (!(dst_params = vsir_program_get_dst_params(program, count))) + return NULL; + + memcpy(dst_params, params, count * sizeof(*params)); + for (i = 0; i < count; ++i) + { +- if (!shader_register_clone_relative_addresses(&dst_params[i].reg, array)) ++ if (!shader_register_clone_relative_addresses(&dst_params[i].reg, program)) + return NULL; + } + + return dst_params; + } + +-static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( +- struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_src_param *params, size_t count) ++static struct vkd3d_shader_src_param *vsir_program_clone_src_params( ++ struct vsir_program *program, const struct vkd3d_shader_src_param *params, size_t count) + { + struct vkd3d_shader_src_param *src_params; + size_t i; + +- if (!(src_params = shader_src_param_allocator_get(&array->src_params, count))) ++ if (!(src_params = vsir_program_get_src_params(program, count))) + return NULL; + + memcpy(src_params, params, count * sizeof(*params)); + for (i = 0; i < count; ++i) + { +- if (!shader_register_clone_relative_addresses(&src_params[i].reg, array)) ++ if (!shader_register_clone_relative_addresses(&src_params[i].reg, program)) + return NULL; + } + +@@ -573,25 +572,12 @@ static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( + + static void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *array) + { +- unsigned int i; +- + vkd3d_free(array->elements); +- shader_param_allocator_destroy(&array->dst_params); +- shader_param_allocator_destroy(&array->src_params); +- for (i = 0; i < array->icb_count; ++i) +- { +- vkd3d_free(array->icbs[i]); +- } +- vkd3d_free(array->icbs); + } + + static bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *array, size_t reserve) + { + memset(array, 0, sizeof(*array)); +- /* Size the parameter initial allocations so they are large enough for most shaders. The +- * code path for chained allocations will be tested if a few shaders need to use it. */ +- shader_param_allocator_init(&array->dst_params, reserve - reserve / 8u, sizeof(struct vkd3d_shader_dst_param)); +- shader_param_allocator_init(&array->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); + + return shader_instruction_array_reserve(array, reserve); + } +@@ -667,6 +653,11 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c + program->shader_version = *version; + program->cf_type = cf_type; + program->normalisation_level = normalisation_level; ++ ++ /* Size the parameter initial allocations so they are large enough for most shaders. The ++ * code path for chained allocations will be tested if a few shaders need to use it. */ ++ shader_param_allocator_init(&program->dst_params, reserve - reserve / 8u, sizeof(struct vkd3d_shader_dst_param)); ++ shader_param_allocator_init(&program->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); + if (!shader_instruction_array_init(&program->instructions, reserve)) + { + if (program->free_parameters) +@@ -694,6 +685,13 @@ void vsir_program_cleanup(struct vsir_program *program) + shader_signature_cleanup(&program->output_signature); + shader_signature_cleanup(&program->patch_constant_signature); + vkd3d_shader_free_scan_descriptor_info1(&program->descriptors); ++ shader_param_allocator_destroy(&program->src_params); ++ shader_param_allocator_destroy(&program->dst_params); ++ for (i = 0; i < program->icb_count; ++i) ++ { ++ vkd3d_free(program->icbs[i]); ++ } ++ vkd3d_free(program->icbs); + } + + const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( +@@ -1089,19 +1087,17 @@ static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *i + + /* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the + * destination is in use. This seems like a reasonable requirement given how this is currently used. */ +-static bool vsir_program_iterator_clone_instruction(struct vsir_program_iterator *dst_it, +- const struct vkd3d_shader_instruction *src) ++static bool vsir_program_iterator_clone_instruction(struct vsir_program *program, ++ struct vsir_program_iterator *dst_it, const struct vkd3d_shader_instruction *src) + { + struct vkd3d_shader_instruction *dst = vsir_program_iterator_current(dst_it); + + *dst = *src; + +- if (dst->dst_count && !(dst->dst = shader_instruction_array_clone_dst_params(dst_it->array, +- dst->dst, dst->dst_count))) ++ if (dst->dst_count && !(dst->dst = vsir_program_clone_dst_params(program, dst->dst, dst->dst_count))) + return false; + +- return !dst->src_count || !!(dst->src = shader_instruction_array_clone_src_params(dst_it->array, +- dst->src, dst->src_count)); ++ return !dst->src_count || (dst->src = vsir_program_clone_src_params(program, dst->src, dst->src_count)); + } + + static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, +@@ -1662,7 +1658,7 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + +- if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3))) ++ if (!(srcs = vsir_program_get_src_params(program, 3))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + /* Note we run before I/O normalization. */ +@@ -1738,7 +1734,7 @@ static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program, + VKD3D_ASSERT(tex->src[1].reg.idx_count == 1); + VKD3D_ASSERT(!tex->src[1].reg.idx[0].rel_addr); + +- if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 4))) ++ if (!(srcs = vsir_program_get_src_params(program, 4))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + srcs[0] = tex->src[0]; +@@ -1781,7 +1777,7 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, + VKD3D_ASSERT(texldd->src[1].reg.idx_count == 1); + VKD3D_ASSERT(!texldd->src[1].reg.idx[0].rel_addr); + +- if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 5))) ++ if (!(srcs = vsir_program_get_src_params(program, 5))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + srcs[0] = texldd->src[0]; +@@ -1807,7 +1803,7 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, + VKD3D_ASSERT(texldl->src[1].reg.idx_count == 1); + VKD3D_ASSERT(!texldl->src[1].reg.idx[0].rel_addr); + +- if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 4))) ++ if (!(srcs = vsir_program_get_src_params(program, 4))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + srcs[0] = texldl->src[0]; +@@ -1825,6 +1821,64 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, + return VKD3D_OK; + } + ++static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *ins) ++{ ++ unsigned int idx = ins->dst[0].reg.idx[0].offset; ++ struct vkd3d_shader_src_param *srcs; ++ ++ /* tex t# -> sample t#, t#, resource#, sampler# ++ * Note that the t# destination will subsequently be turned into a temp. */ ++ ++ /* We run before I/O normalization. */ ++ VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6); ++ ++ if (!(srcs = vsir_program_get_src_params(program, 3))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); ++ srcs[0].reg.idx[0].offset = idx; ++ srcs[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ ++ vsir_src_param_init_resource(&srcs[1], idx, idx); ++ vsir_src_param_init_sampler(&srcs[2], idx, idx); ++ ++ ins->opcode = VSIR_OP_SAMPLE; ++ ins->src = srcs; ++ ins->src_count = 3; ++ ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_lower_texcoord(struct vsir_program *program, ++ struct vkd3d_shader_instruction *ins) ++{ ++ unsigned int idx = ins->dst[0].reg.idx[0].offset; ++ struct vkd3d_shader_src_param *srcs; ++ ++ /* texcoord t# -> mov_sat t#, t# ++ * Note that the t# destination will subsequently be turned into a temp. */ ++ ++ /* We run before I/O normalization. */ ++ VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6); ++ ++ if (!(srcs = vsir_program_get_src_params(program, 1))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); ++ srcs[0].reg.idx[0].offset = idx; ++ srcs[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ ++ ins->dst[0].modifiers |= VKD3DSPDM_SATURATE; ++ ++ ins->opcode = VSIR_OP_MOV; ++ ins->src = srcs; ++ ins->src_count = 1; ++ ++ return VKD3D_OK; ++} ++ + static enum vkd3d_result vsir_program_lower_dcl_input(struct vsir_program *program, + struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) + { +@@ -1917,6 +1971,11 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr + ret = vsir_program_lower_sm1_sincos(program, &it); + break; + ++ case VSIR_OP_TEXCOORD: ++ if ((ret = vsir_program_lower_texcoord(program, ins)) < 0) ++ return ret; ++ break; ++ + case VSIR_OP_TEXCRD: + ret = vsir_program_lower_texcrd(program, ins, message_context); + break; +@@ -1925,6 +1984,10 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr + ret = vsir_program_lower_texkill(program, &it, &tmp_idx); + break; + ++ case VSIR_OP_TEX: ++ ret = vsir_program_lower_tex(program, ins); ++ break; ++ + case VSIR_OP_TEXLD: + if (program->shader_version.major == 1) + ret = vsir_program_lower_texld_sm1(program, ins, message_context); +@@ -1942,6 +2005,26 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr + ret = vsir_program_lower_texldl(program, ins); + break; + ++ case VSIR_OP_TEXBEM: ++ case VSIR_OP_TEXBEML: ++ case VSIR_OP_TEXDEPTH: ++ case VSIR_OP_TEXDP3: ++ case VSIR_OP_TEXDP3TEX: ++ case VSIR_OP_TEXM3x2PAD: ++ case VSIR_OP_TEXM3x2TEX: ++ case VSIR_OP_TEXM3x3DIFF: ++ case VSIR_OP_TEXM3x3PAD: ++ case VSIR_OP_TEXM3x3SPEC: ++ case VSIR_OP_TEXM3x3TEX: ++ case VSIR_OP_TEXM3x3VSPEC: ++ case VSIR_OP_TEXREG2AR: ++ case VSIR_OP_TEXREG2GB: ++ case VSIR_OP_TEXREG2RGB: ++ vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Aborting due to unimplemented feature: Combined sampler instruction \"%s\" (%#x).", ++ vsir_opcode_get_name(ins->opcode, ""), ins->opcode); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ + default: + ret = VKD3D_OK; + break; +@@ -2020,27 +2103,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + return ret; + break; + +- case VSIR_OP_TEXBEM: +- case VSIR_OP_TEXBEML: +- case VSIR_OP_TEXCOORD: +- case VSIR_OP_TEXDEPTH: +- case VSIR_OP_TEXDP3: +- case VSIR_OP_TEXDP3TEX: +- case VSIR_OP_TEXM3x2PAD: +- case VSIR_OP_TEXM3x2TEX: +- case VSIR_OP_TEXM3x3DIFF: +- case VSIR_OP_TEXM3x3PAD: +- case VSIR_OP_TEXM3x3SPEC: +- case VSIR_OP_TEXM3x3TEX: +- case VSIR_OP_TEXM3x3VSPEC: +- case VSIR_OP_TEXREG2AR: +- case VSIR_OP_TEXREG2GB: +- case VSIR_OP_TEXREG2RGB: +- vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, +- "Aborting due to unimplemented feature: Combined sampler instruction \"%s\" (%#x).", +- vsir_opcode_get_name(ins->opcode, ""), ins->opcode); +- return VKD3D_ERROR_NOT_IMPLEMENTED; +- + default: + break; + } +@@ -2049,6 +2111,61 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + return VKD3D_OK; + } + ++/* 1.0-1.3 pixel shaders allow writing t# registers, at which point they ++ * effectively behave like normal r# temps. Convert them to r# registers. ++ * t# registers which are read before being written contain TEXCOORD varyings, ++ * just as in 1.4 and 2.x, and will later be lowered to v# registers. ++ * ++ * Registers which are partially written are rejected by the native validator, ++ * but with a "read of uninitialized component" message that suggests that once ++ * any component of a t# register is written, none of the components contain ++ * texcoord data. */ ++static enum vkd3d_result vsir_program_lower_texture_writes(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; ++ unsigned int texture_temp_idx = ~0u; ++ uint32_t texture_written_mask = 0; ++ ++ /* We run before I/O normalization. */ ++ VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6); ++ ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ for (unsigned int i = 0; i < ins->src_count; ++i) ++ { ++ struct vkd3d_shader_src_param *src = &ins->src[i]; ++ ++ if (src->reg.type == VKD3DSPR_TEXTURE && bitmap_is_set(&texture_written_mask, src->reg.idx[0].offset)) ++ { ++ src->reg.type = VKD3DSPR_TEMP; ++ src->reg.idx[0].offset += texture_temp_idx; ++ } ++ } ++ ++ for (unsigned int i = 0; i < ins->dst_count; ++i) ++ { ++ struct vkd3d_shader_dst_param *dst = &ins->dst[i]; ++ ++ if (dst->reg.type == VKD3DSPR_TEXTURE) ++ { ++ bitmap_set(&texture_written_mask, dst->reg.idx[0].offset); ++ if (texture_temp_idx == ~0u) ++ { ++ texture_temp_idx = program->temp_count; ++ /* These versions have 4 texture registers. */ ++ program->temp_count += 4; ++ } ++ dst->reg.type = VKD3DSPR_TEMP; ++ dst->reg.idx[0].offset += texture_temp_idx; ++ } ++ } ++ } ++ ++ return VKD3D_OK; ++} ++ + /* Ensure that the program closes with a ret. sm1 programs do not, by default. + * Many of our IR passes rely on this in order to insert instructions at the + * end of execution. */ +@@ -2512,7 +2629,7 @@ static enum vkd3d_result flattener_replicate_location(struct hull_flattener *nor + struct vsir_program_iterator *it, size_t instance_count, size_t instruction_count) + { + struct vsir_program_iterator dst_it, src_it, first_it; +- struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_instruction *ins, *src_ins; + unsigned int i, j; + size_t count; + +@@ -2528,7 +2645,8 @@ static enum vkd3d_result flattener_replicate_location(struct hull_flattener *nor + src_it = *it; + for (j = 0; j < instruction_count; ++j) + { +- if (!vsir_program_iterator_clone_instruction(&dst_it, vsir_program_iterator_current(&src_it))) ++ src_ins = vsir_program_iterator_current(&src_it); ++ if (!vsir_program_iterator_clone_instruction(normaliser->program, &dst_it, src_ins)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + vsir_program_iterator_next(&dst_it); +@@ -2650,7 +2768,7 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro + + struct control_point_normaliser + { +- struct vkd3d_shader_instruction_array instructions; ++ struct vsir_program *program; + enum vkd3d_shader_opcode phase; + struct vkd3d_shader_src_param *outpointid_param; + }; +@@ -2662,20 +2780,15 @@ static bool control_point_normaliser_is_in_control_point_phase(const struct cont + + struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_program *program) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; + struct vkd3d_shader_src_param *rel_addr; + +- if (instructions->outpointid_param) +- return instructions->outpointid_param; +- +- if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1))) ++ if (!(rel_addr = vsir_program_get_src_params(program, 1))) + return NULL; + + vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, 0); + rel_addr->swizzle = 0; + rel_addr->modifiers = 0; + +- instructions->outpointid_param = rel_addr; + return rel_addr; + } + +@@ -2720,9 +2833,9 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p + continue; + + vsir_instruction_init(ins, location, VSIR_OP_MOV); +- ins->dst = shader_dst_param_allocator_get(&normaliser->instructions.dst_params, 1); ++ ins->dst = vsir_program_get_dst_params(normaliser->program, 1); + ins->dst_count = 1; +- ins->src = shader_src_param_allocator_get(&normaliser->instructions.src_params, 1); ++ ins->src = vsir_program_get_src_params(normaliser->program, 1); + ins->src_count = 1; + + if (!ins->dst || ! ins->src) +@@ -2731,6 +2844,8 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p + return VKD3D_ERROR_OUT_OF_MEMORY; + } + ++ VKD3D_ASSERT(normaliser->outpointid_param); ++ + vsir_dst_param_init_io(&ins->dst[0], VKD3DSPR_OUTPUT, e, 2); + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].reg.idx[0].offset = 0; +@@ -2775,8 +2890,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + ERR("Failed to allocate src param.\n"); + return VKD3D_ERROR_OUT_OF_MEMORY; + } +- normaliser.instructions = program->instructions; +- it = vsir_program_iterator(&normaliser.instructions); ++ normaliser.program = program; ++ it = vsir_program_iterator(&normaliser.program->instructions); + normaliser.phase = VSIR_OP_INVALID; + + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) +@@ -2808,7 +2923,6 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + input_control_point_count = ins->declaration.count; + break; + case VSIR_OP_HS_CONTROL_POINT_PHASE: +- program->instructions = normaliser.instructions; + program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; + return VKD3D_OK; + case VSIR_OP_HS_FORK_PHASE: +@@ -2817,7 +2931,6 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + location = ins->location; + ret = control_point_normaliser_emit_hs_input(&normaliser, + &program->input_signature, input_control_point_count, &it, &location); +- program->instructions = normaliser.instructions; + program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; + return ret; + default: +@@ -2825,7 +2938,6 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + } + } + +- program->instructions = normaliser.instructions; + program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; + return VKD3D_OK; + } +@@ -2851,12 +2963,7 @@ struct io_normaliser + struct shader_signature *output_signature; + struct shader_signature *patch_constant_signature; + +- unsigned int instance_count; +- unsigned int phase_body_idx; + enum vkd3d_shader_opcode phase; +- unsigned int output_control_point_count; +- +- struct vkd3d_shader_src_param *outpointid_param; + + struct vkd3d_shader_dst_param *input_dcl_params[MAX_REG_OUTPUT]; + struct vkd3d_shader_dst_param *output_dcl_params[MAX_REG_OUTPUT]; +@@ -3478,9 +3585,6 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program + { + switch (ins->opcode) + { +- case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: +- normaliser.output_control_point_count = ins->declaration.count; +- break; + case VSIR_OP_DCL_INDEX_RANGE: + if ((ret = io_normaliser_add_index_range(&normaliser, ins)) < 0) + return ret; +@@ -12569,8 +12673,14 @@ enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_ + + vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); + vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); ++ + if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ++ { ++ if (program->shader_version.minor < 4) ++ vsir_transform(&ctx, vsir_program_lower_texture_writes); ++ + vsir_transform(&ctx, vsir_program_normalise_ps1_output); ++ } + + if (TRACE_ON()) + vsir_program_trace(program); +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 8bc851f9c5b..8ffc68935f3 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -7166,7 +7166,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler + if (alignment) + TRACE("Ignoring alignment %u.\n", alignment); + +- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); + length_id = spirv_compiler_get_constant_uint(compiler, size); + array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); + +@@ -7887,8 +7887,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp + component_count = vsir_write_mask_component_count(dst->write_mask); + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT32_MAX, component_count); + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpIEqual, +- spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), +- val_id, uint_max_id); ++ spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count), val_id, uint_max_id); + rev_val_id = vkd3d_spirv_build_op_isub(builder, type_id, + spirv_compiler_get_constant_uint_vector(compiler, 31, component_count), val_id); + val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, rev_val_id); +@@ -7993,8 +7992,8 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, + { + if (instruction->opcode == VSIR_OP_CMP) + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, +- spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), +- condition_id, spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); ++ spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count), condition_id, ++ spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); + else + condition_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); +@@ -8020,7 +8019,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, + src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); + + component_count = vsir_write_mask_component_count(dst->write_mask); +- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); + + condition_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); +@@ -8056,7 +8055,7 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, + for (i = 0; i < ARRAY_SIZE(src_ids); ++i) + src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], write_mask); + +- type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); ++ type_id = spirv_get_type_id(builder, dst->reg.data_type, 1); + + val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpDot, type_id, src_ids[0], src_ids[1]); +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index ec1d8b91e09..2541aef1314 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -851,7 +851,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui + icb->element_count = icb_size / VKD3D_VEC4_SIZE; + icb->is_null = false; + memcpy(icb->data, tokens, sizeof(*tokens) * icb_size); +- shader_instruction_array_add_icb(&priv->program->instructions, icb); ++ vsir_program_add_icb(priv->program, icb); + ins->declaration.icb = icb; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 6949c1cd38f..f536a8ee08f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -1524,7 +1524,6 @@ 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 VSIR_OP_TEX: + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + case VSIR_OP_TEXDP3TEX: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 3f37dc6076b..6037f7179e7 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -1421,40 +1421,16 @@ struct vkd3d_shader_param_allocator + + void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count); + +-static inline struct vkd3d_shader_src_param *shader_src_param_allocator_get( +- struct vkd3d_shader_param_allocator *allocator, size_t count) +-{ +- VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_src_param)); +- return shader_param_allocator_get(allocator, count); +-} +- +-static inline struct vkd3d_shader_dst_param *shader_dst_param_allocator_get( +- struct vkd3d_shader_param_allocator *allocator, size_t count) +-{ +- VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_dst_param)); +- return shader_param_allocator_get(allocator, count); +-} +- + struct vkd3d_shader_instruction_array + { + struct vkd3d_shader_instruction *elements; + size_t capacity; + size_t count; +- +- struct vkd3d_shader_param_allocator src_params; +- struct vkd3d_shader_param_allocator dst_params; +- struct vkd3d_shader_immediate_constant_buffer **icbs; +- size_t icb_capacity; +- size_t icb_count; +- +- struct vkd3d_shader_src_param *outpointid_param; + }; + + bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve); + bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, + size_t idx, size_t count); +-bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, +- struct vkd3d_shader_immediate_constant_buffer *icb); + + struct vsir_program_iterator + { +@@ -1638,12 +1614,21 @@ struct vsir_program + struct vkd3d_shader_source_list source_files; + const char **block_names; + size_t block_name_count; ++ ++ struct vkd3d_shader_immediate_constant_buffer **icbs; ++ size_t icb_capacity; ++ size_t icb_count; ++ ++ struct vkd3d_shader_param_allocator src_params; ++ struct vkd3d_shader_param_allocator dst_params; + }; + + enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context); + enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context); ++ ++bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb); + void vsir_program_cleanup(struct vsir_program *program); + const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( + const struct vsir_program *program, enum vkd3d_shader_parameter_name name); +@@ -1677,13 +1662,21 @@ static inline struct vkd3d_shader_instruction *vsir_program_append(struct vsir_p + static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params( + struct vsir_program *program, unsigned int count) + { +- return shader_dst_param_allocator_get(&program->instructions.dst_params, count); ++ struct vkd3d_shader_param_allocator *allocator = &program->dst_params; ++ ++ VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_dst_param)); ++ ++ return shader_param_allocator_get(allocator, count); + } + + static inline struct vkd3d_shader_src_param *vsir_program_get_src_params( + struct vsir_program *program, unsigned int count) + { +- return shader_src_param_allocator_get(&program->instructions.src_params, count); ++ struct vkd3d_shader_param_allocator *allocator = &program->src_params; ++ ++ VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_src_param)); ++ ++ return shader_param_allocator_get(allocator, count); + } + + struct vkd3d_shader_parser +diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c +index d933e7ec463..69f42280e8a 100644 +--- a/libs/vkd3d/libs/vkd3d/command.c ++++ b/libs/vkd3d/libs/vkd3d/command.c +@@ -2688,32 +2688,12 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list, + static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList6 *iface, + ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_pipeline_state) + { +- struct d3d12_command_allocator *allocator_impl = unsafe_impl_from_ID3D12CommandAllocator(allocator); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList6(iface); +- HRESULT hr; + + TRACE("iface %p, allocator %p, initial_pipeline_state %p.\n", + iface, allocator, initial_pipeline_state); + +- if (!allocator_impl) +- { +- WARN("Command allocator is NULL.\n"); +- return E_INVALIDARG; +- } +- +- if (list->is_recording) +- { +- WARN("Command list is in the recording state.\n"); +- return E_FAIL; +- } +- +- if (SUCCEEDED(hr = d3d12_command_allocator_allocate_command_buffer(allocator_impl, list))) +- { +- list->allocator = allocator_impl; +- d3d12_command_list_reset_state(list, initial_pipeline_state); +- } +- +- return hr; ++ return d3d12_command_list_reset(list, allocator, initial_pipeline_state); + } + + static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList6 *iface, +@@ -6405,9 +6385,8 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma + return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList6_iface); + } + +-static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device, +- D3D12_COMMAND_LIST_TYPE type, struct d3d12_command_allocator *allocator, +- ID3D12PipelineState *initial_pipeline_state) ++static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, ++ struct d3d12_device *device, D3D12_COMMAND_LIST_TYPE type) + { + HRESULT hr; + +@@ -6421,31 +6400,37 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d + + d3d12_device_add_ref(list->device = device); + +- list->allocator = allocator; ++ return hr; ++} + +- list->descriptor_heap_count = 0; ++HRESULT d3d12_command_list_create(struct d3d12_device *device, UINT node_mask, ++ D3D12_COMMAND_LIST_TYPE type, struct d3d12_command_list **list) ++{ ++ struct d3d12_command_list *object; ++ HRESULT hr; + +- if (SUCCEEDED(hr = d3d12_command_allocator_allocate_command_buffer(allocator, list))) +- { +- list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_GRAPHICS].vk_uav_counter_views = NULL; +- list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_COMPUTE].vk_uav_counter_views = NULL; +- d3d12_command_list_reset_state(list, initial_pipeline_state); +- } +- else ++ debug_ignored_node_mask(node_mask); ++ ++ if (!(object = vkd3d_calloc(1, sizeof(*object)))) ++ return E_OUTOFMEMORY; ++ ++ if (FAILED(hr = d3d12_command_list_init(object, device, type))) + { +- vkd3d_private_store_destroy(&list->private_store); +- d3d12_device_release(device); ++ vkd3d_free(object); ++ return hr; + } + +- return hr; ++ TRACE("Created command list %p.\n", object); ++ ++ *list = object; ++ ++ return S_OK; + } + +-HRESULT d3d12_command_list_create(struct d3d12_device *device, +- UINT node_mask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *allocator_iface, +- ID3D12PipelineState *initial_pipeline_state, struct d3d12_command_list **list) ++HRESULT d3d12_command_list_reset(struct d3d12_command_list *list, ID3D12CommandAllocator *allocator_iface, ++ ID3D12PipelineState *initial_pipeline_state) + { + struct d3d12_command_allocator *allocator; +- struct d3d12_command_list *object; + HRESULT hr; + + if (!(allocator = unsafe_impl_from_ID3D12CommandAllocator(allocator_iface))) +@@ -6454,29 +6439,26 @@ HRESULT d3d12_command_list_create(struct d3d12_device *device, + return E_INVALIDARG; + } + +- if (allocator->type != type) ++ if (allocator->type != list->type) + { + WARN("Command list types do not match (allocator %#x, list %#x).\n", +- allocator->type, type); ++ allocator->type, list->type); + return E_INVALIDARG; + } + +- debug_ignored_node_mask(node_mask); +- +- if (!(object = vkd3d_malloc(sizeof(*object)))) +- return E_OUTOFMEMORY; +- +- if (FAILED(hr = d3d12_command_list_init(object, device, type, allocator, initial_pipeline_state))) ++ if (list->is_recording) + { +- vkd3d_free(object); +- return hr; ++ WARN("Command list is in the recording state.\n"); ++ return E_FAIL; + } + +- TRACE("Created command list %p.\n", object); +- +- *list = object; ++ if (SUCCEEDED(hr = d3d12_command_allocator_allocate_command_buffer(allocator, list))) ++ { ++ list->allocator = allocator; ++ d3d12_command_list_reset_state(list, initial_pipeline_state); ++ } + +- return S_OK; ++ return hr; + } + + /* ID3D12CommandQueue */ +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index 67f84aafa29..6af5e2a5c7d 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -3271,10 +3271,15 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device9 *i + iface, node_mask, type, command_allocator, + initial_pipeline_state, debugstr_guid(riid), command_list); + +- if (FAILED(hr = d3d12_command_list_create(device, node_mask, type, command_allocator, +- initial_pipeline_state, &object))) ++ if (FAILED(hr = d3d12_command_list_create(device, node_mask, type, &object))) + return hr; + ++ if (FAILED(hr = d3d12_command_list_reset(object, command_allocator, initial_pipeline_state))) ++ { ++ ID3D12GraphicsCommandList6_Release(&object->ID3D12GraphicsCommandList6_iface); ++ return hr; ++ } ++ + return return_interface(&object->ID3D12GraphicsCommandList6_iface, + &IID_ID3D12GraphicsCommandList6, riid, command_list); + } +@@ -5082,10 +5087,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device9 * + UINT node_mask, D3D12_COMMAND_LIST_TYPE type, D3D12_COMMAND_LIST_FLAGS flags, + REFIID iid, void **command_list) + { +- FIXME("iface %p, node_mask 0x%08x, type %#x, flags %#x, iid %s, command_list %p stub!\n", ++ struct d3d12_device *device = impl_from_ID3D12Device9(iface); ++ struct d3d12_command_list *object; ++ HRESULT hr; ++ ++ TRACE("iface %p, node_mask 0x%08x, type %#x, flags %#x, iid %s, command_list %p.\n", + iface, node_mask, type, flags, debugstr_guid(iid), command_list); + +- return E_NOTIMPL; ++ if (flags) ++ FIXME("Ignoring flags %#x.\n", flags); ++ ++ if (FAILED(hr = d3d12_command_list_create(device, node_mask, type, &object))) ++ return hr; ++ ++ return return_interface(&object->ID3D12GraphicsCommandList6_iface, ++ &IID_ID3D12GraphicsCommandList6, iid, command_list); + } + + static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3D12Device9 *iface, +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +index 9fb6834158f..0a8c5aef674 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +@@ -1327,8 +1327,9 @@ struct d3d12_command_list + }; + + HRESULT d3d12_command_list_create(struct d3d12_device *device, +- UINT node_mask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *allocator_iface, +- ID3D12PipelineState *initial_pipeline_state, struct d3d12_command_list **list); ++ UINT node_mask, D3D12_COMMAND_LIST_TYPE type, struct d3d12_command_list **list); ++HRESULT d3d12_command_list_reset(struct d3d12_command_list *list, ++ ID3D12CommandAllocator *allocator_iface, ID3D12PipelineState *initial_pipeline_state); + + struct vkd3d_queue + { +-- +2.51.0 + diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-52b9aa416bb4e8be2fb6e28ffd1234cc10d.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-52b9aa416bb4e8be2fb6e28ffd1234cc10d.patch new file mode 100644 index 00000000..1bd01353 --- /dev/null +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-52b9aa416bb4e8be2fb6e28ffd1234cc10d.patch @@ -0,0 +1,626 @@ +From e962b7b825187b410bb18a20c2cd80be39adde17 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 20 Sep 2025 07:06:08 +1000 +Subject: [PATCH] Updated vkd3d to 52b9aa416bb4e8be2fb6e28ffd1234cc10db96c6. + +--- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 3 - + libs/vkd3d/libs/vkd3d-shader/dxil.c | 38 +++-- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1 + + libs/vkd3d/libs/vkd3d-shader/ir.c | 166 +++++++++++++++----- + libs/vkd3d/libs/vkd3d-shader/msl.c | 7 +- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 12 +- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 4 +- + 7 files changed, 166 insertions(+), 65 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index a9195b3454a..b4e079f507e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -2150,9 +2150,6 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, + if ((result = vsir_allocate_temp_registers(program, message_context))) + return result; + +- if ((result = vsir_update_dcl_temps(program, message_context))) +- return result; +- + d3dbc.program = program; + d3dbc.message_context = message_context; + switch (version->type) +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 63dcbd3c08a..5d8ab701cc0 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -4627,6 +4627,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + struct vkd3d_shader_src_param *src_params; + enum vkd3d_shader_opcode handler_idx; + const struct sm6_value *a, *b; ++ uint32_t type_flags = 0; + uint64_t code, flags; + bool silence_warning; + unsigned int i = 0; +@@ -4668,6 +4669,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP)); + break; + case VSIR_OP_ISHR: ++ type_flags |= DXIL_TYPE_SIGNED; ++ /* fall through */ + case VSIR_OP_USHR: + case VSIR_OP_IDIV: + case VSIR_OP_UDIV_SIMPLE: +@@ -4692,8 +4695,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +- src_param_init_from_value(&src_params[0], a, 0, sm6); +- src_param_init_from_value(&src_params[1], b, 0, sm6); ++ src_param_init_from_value(&src_params[0], a, type_flags, sm6); ++ src_param_init_from_value(&src_params[1], b, type_flags, sm6); + if (code == BINOP_SUB) + src_params[1].modifiers = VKD3DSPSM_NEG; + +@@ -4706,7 +4709,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + * do. */ + ins->flags |= VKD3DSI_SHIFT_UNMASKED; + } +- instruction_dst_param_init_ssa_scalar(ins, 0, sm6); ++ instruction_dst_param_init_ssa_scalar(ins, type_flags, sm6); + } + + static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index, +@@ -4972,8 +4975,11 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o + instruction_dst_param_init_ssa_scalar(ins, 0, sm6); + } + +-static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, const struct sm6_type *type) ++static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, ++ const struct sm6_type *type, uint32_t *type_flags) + { ++ *type_flags = 0; ++ + switch (op) + { + case DX_FMAX: +@@ -4981,8 +4987,10 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co + case DX_FMIN: + return type->u.width == 64 ? VSIR_OP_DMIN : VSIR_OP_MIN; + case DX_IMAX: ++ *type_flags |= DXIL_TYPE_SIGNED; + return VSIR_OP_IMAX; + case DX_IMIN: ++ *type_flags |= DXIL_TYPE_SIGNED; + return VSIR_OP_IMIN; + case DX_QUAD_READ_LANE_AT: + return VSIR_OP_QUAD_READ_LANE_AT; +@@ -5002,14 +5010,15 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ + { + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_params; ++ uint32_t type_flags; + +- vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type)); ++ vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type, &type_flags)); + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +- src_param_init_from_value(&src_params[0], operands[0], 0, sm6); +- src_param_init_from_value(&src_params[1], operands[1], 0, sm6); ++ src_param_init_from_value(&src_params[0], operands[0], type_flags, sm6); ++ src_param_init_from_value(&src_params[1], operands[1], type_flags, sm6); + +- instruction_dst_param_init_ssa_scalar(ins, 0, sm6); ++ instruction_dst_param_init_ssa_scalar(ins, type_flags, sm6); + } + + static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6) +@@ -7140,6 +7149,7 @@ struct sm6_cmp_info + { + enum vkd3d_shader_opcode handler_idx; + bool src_swap; ++ uint32_t type_flags; + }; + + static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) +@@ -7169,10 +7179,10 @@ static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) + [ICMP_UGE] = {VSIR_OP_UGE}, + [ICMP_ULT] = {VSIR_OP_ULT}, + [ICMP_ULE] = {VSIR_OP_UGE, true}, +- [ICMP_SGT] = {VSIR_OP_ILT, true}, +- [ICMP_SGE] = {VSIR_OP_IGE}, +- [ICMP_SLT] = {VSIR_OP_ILT}, +- [ICMP_SLE] = {VSIR_OP_IGE, true}, ++ [ICMP_SGT] = {VSIR_OP_ILT, true, DXIL_TYPE_SIGNED}, ++ [ICMP_SGE] = {VSIR_OP_IGE, false, DXIL_TYPE_SIGNED}, ++ [ICMP_SLT] = {VSIR_OP_ILT, false, DXIL_TYPE_SIGNED}, ++ [ICMP_SLE] = {VSIR_OP_IGE, true, DXIL_TYPE_SIGNED}, + }; + + return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL; +@@ -7273,8 +7283,8 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor + + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; +- src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a, 0, sm6); +- src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b, 0, sm6); ++ src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a, cmp->type_flags, sm6); ++ src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b, cmp->type_flags, sm6); + + instruction_dst_param_init_ssa_scalar(ins, 0, sm6); + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index eaf7d7a3d63..bb8fdb8bd60 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -9031,6 +9031,7 @@ static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src + } + + src->reg.dimension = VSIR_DIMENSION_VEC4; ++ src->swizzle = VKD3D_SHADER_NO_SWIZZLE; + for (i = 0, j = 0; i < 4; ++i) + { + if ((map_writemask & (1u << i)) && (j < width)) +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 506b397fb02..a242f32d824 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -1017,16 +1017,15 @@ static void dst_param_init_output(struct vkd3d_shader_dst_param *dst, + dst->write_mask = write_mask; + } + +-void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, +- enum vkd3d_shader_opcode opcode) ++void vsir_instruction_init(struct vkd3d_shader_instruction *ins, ++ const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode) + { +- memset(ins, 0, sizeof(*ins)); +- ins->location = *location; +- ins->opcode = opcode; +- ins->resource_data_type[0] = VSIR_DATA_F32; +- ins->resource_data_type[1] = VSIR_DATA_F32; +- ins->resource_data_type[2] = VSIR_DATA_F32; +- ins->resource_data_type[3] = VSIR_DATA_F32; ++ *ins = (struct vkd3d_shader_instruction) ++ { ++ .location = *location, ++ .opcode = opcode, ++ .resource_data_type = {VSIR_DATA_F32, VSIR_DATA_F32, VSIR_DATA_F32, VSIR_DATA_F32}, ++ }; + } + + bool vsir_instruction_init_with_params(struct vsir_program *program, +@@ -1305,6 +1304,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program + ins->src[1].reg.u.immconst_f32[1] = 0.0f; + ins->src[1].reg.u.immconst_f32[2] = 0.0f; + ins->src[1].reg.u.immconst_f32[3] = 0.0f; ++ ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE; + + /* tmp.x = tmp.x || tmp.y */ + /* tmp.x = tmp.x || tmp.z */ +@@ -2306,6 +2306,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL & ~program->diffuse_written_mask; + vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + for (i = 0; i < 4; ++i) + ins->src[0].reg.u.immconst_f32[i] = 1.0f; + return VKD3D_OK; +@@ -2527,6 +2528,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask); + vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + ins = vsir_program_iterator_next(&it); + } + } +@@ -3669,6 +3671,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par + { + enum vkd3d_shader_d3dbc_constant_register set; + struct vkd3d_shader_src_param *rel_addr; ++ unsigned int c; + uint32_t index; + size_t i, j; + +@@ -3683,7 +3686,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par + param->reg.idx_count = 0; + param->reg.dimension = VSIR_DIMENSION_VEC4; + for (j = 0; j < 4; ++j) +- param->reg.u.immconst_u32[j] = normaliser->defs[i].value[j]; ++ { ++ c = vsir_swizzle_get_component(param->swizzle, j); ++ param->reg.u.immconst_u32[j] = normaliser->defs[i].value[c]; ++ } ++ param->swizzle = VKD3D_SHADER_NO_SWIZZLE; + return; + } + } +@@ -7932,6 +7939,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; + vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + vsir_program_iterator_next(&it); + + program->has_point_coord = true; +@@ -8932,11 +8940,13 @@ struct temp_allocator + uint32_t temp_id; + enum vkd3d_shader_register_type type; + unsigned int idx; ++ bool force_first; + } *ssa_regs, *temp_regs; + size_t ssa_count, temp_count; + unsigned int new_temp_count; + enum vkd3d_result result; + uint8_t *current_allocation; ++ bool ps_1_x; + }; + + static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3d_shader_src_param *src) +@@ -9084,15 +9094,12 @@ static int temp_allocate_compare_open(const void *ptr1, const void *ptr2) + const struct temp_allocator_reg * const *reg1 = ptr1, * const *reg2 = ptr2; + int ret; + ++ if ((ret = vkd3d_u32_compare((*reg1)->force_first, (*reg2)->force_first))) ++ return -ret; + if ((ret = vkd3d_u32_compare((*reg1)->liveness_reg->first_write, (*reg2)->liveness_reg->first_write))) + return ret; + if ((ret = vkd3d_u32_compare((*reg1)->liveness_reg->last_access, (*reg2)->liveness_reg->last_access))) + return ret; +- /* r0 must compare before everything else for SM 1.x PS (see comment below). */ +- if ((*reg1)->type == VKD3DSPR_TEMP && (*reg1)->idx == 0) +- return -1; +- if ((*reg2)->type == VKD3DSPR_TEMP && (*reg2)->idx == 0) +- return 1; + return 0; + } + +@@ -9260,6 +9267,17 @@ static enum vkd3d_result temp_allocator_compute_allocation_map(struct temp_alloc + { + reg->type = VKD3DSPR_TEMP; + reg->idx = i - allocator->ssa_count; ++ ++ /* For SM 1.x ps we need to ensure that r0 is reallocated to itself, ++ * because it doubles as the output register. To do so we ++ * artificially make it alive for the whole program and make it ++ * compare before anything else. */ ++ if (reg->idx == 0 && allocator->ps_1_x) ++ { ++ reg->force_first = true; ++ liveness->ssa_regs[i].first_write = 0; ++ liveness->ssa_regs[i].last_access = UINT_MAX; ++ } + } + + reg->liveness_reg = &liveness->ssa_regs[i]; +@@ -9367,15 +9385,8 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + allocator.temp_regs = regs + program->ssa_count; + allocator.new_temp_count = 0; + +- /* For SM 1.x ps we need to ensure that r0 is reallocated to itself, because +- * it doubles as the output register. To do so we artificially make it +- * alive for the whole program. */ +- if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL +- && program->shader_version.major < 2 && allocator.temp_count >= 1) +- { +- tracker.temp_regs[0].first_write = 0; +- tracker.temp_regs[0].last_access = UINT_MAX; +- } ++ if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && program->shader_version.major < 2) ++ allocator.ps_1_x = true; + + if ((ret = temp_allocator_compute_allocation_map(&allocator, &tracker)) < 0) + { +@@ -9418,6 +9429,9 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + struct vkd3d_shader_instruction *ins; + unsigned int temp_count = 0; + ++ if (program->shader_version.major < 4) ++ return VKD3D_OK; ++ + for (ins = vsir_program_iterator_tail(&it); ins; ins = vsir_program_iterator_prev(&it)) + { + location = ins->location; +@@ -9429,10 +9443,9 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + continue; + } + +- if (temp_count && program->shader_version.major >= 4 +- && (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE +- || ins->opcode == VSIR_OP_HS_FORK_PHASE +- || ins->opcode == VSIR_OP_HS_JOIN_PHASE)) ++ if (temp_count && (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE ++ || ins->opcode == VSIR_OP_HS_FORK_PHASE ++ || ins->opcode == VSIR_OP_HS_JOIN_PHASE)) + { + /* The phase didn't have a dcl_temps instruction, but we added + * temps here, so we need to insert one. */ +@@ -9459,7 +9472,7 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + } + } + +- if (temp_count && program->shader_version.major >= 4) ++ if (temp_count) + { + ins = vsir_program_iterator_head(&it); + location = ins->location; +@@ -10581,6 +10594,16 @@ static void vsir_validate_src_param(struct validation_context *ctx, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source of dimension %u has invalid swizzle %#x.", + src->reg.dimension, src->swizzle); + ++ if (src->reg.dimension == VSIR_DIMENSION_VEC4 && src->reg.type == VKD3DSPR_IMMCONST ++ && src->swizzle != VKD3D_SHADER_NO_SWIZZLE) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, ++ "Immediate constant source has invalid swizzle %#x.", src->swizzle); ++ ++ if (src->reg.dimension == VSIR_DIMENSION_VEC4 && src->reg.type == VKD3DSPR_IMMCONST64 ++ && src->swizzle != VKD3D_SHADER_SWIZZLE(X, Y, X, X)) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, ++ "Immediate constant source has invalid swizzle %#x.", src->swizzle); ++ + if (src->modifiers >= VKD3DSPSM_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.", + src->modifiers); +@@ -11299,6 +11322,7 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_I32] = true, ++ [VSIR_DATA_I64] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; +@@ -11306,6 +11330,18 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex + vsir_validate_elementwise_operation(ctx, instruction, types); + } + ++static void vsir_validate_signed_integer_elementwise_operation(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_I64] = true, ++ }; ++ ++ vsir_validate_elementwise_operation(ctx, instruction, types); ++} ++ + static void vsir_validate_logic_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) + { +@@ -11399,6 +11435,18 @@ static void vsir_validate_integer_comparison_operation(struct validation_context + vsir_validate_comparison_operation(ctx, instruction, types); + } + ++static void vsir_validate_signed_integer_comparison_operation(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_I64] = true, ++ }; ++ ++ vsir_validate_comparison_operation(ctx, instruction, types); ++} ++ + static void vsir_validate_cast_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction, + const bool src_types[VSIR_DATA_TYPE_COUNT], const bool dst_types[VSIR_DATA_TYPE_COUNT]) +@@ -11428,19 +11476,20 @@ static void vsir_validate_cast_operation(struct validation_context *ctx, + } + + static void vsir_validate_shift_operation(struct validation_context *ctx, +- const struct vkd3d_shader_instruction *instruction) ++ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) + { + enum vsir_data_type dst_data_type, src_data_type; + +- static const bool types[] = ++ static const bool shift_types[] = + { + [VSIR_DATA_I32] = true, ++ [VSIR_DATA_I64] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; + + dst_data_type = instruction->dst[0].reg.data_type; +- if ((size_t)dst_data_type >= ARRAY_SIZE(types) || !types[dst_data_type]) ++ if ((size_t)dst_data_type >= VSIR_DATA_TYPE_COUNT || !types[dst_data_type]) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid destination data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, +@@ -11455,7 +11504,7 @@ static void vsir_validate_shift_operation(struct validation_context *ctx, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + + src_data_type = instruction->src[1].reg.data_type; +- if ((size_t)src_data_type >= ARRAY_SIZE(types) || !types[src_data_type]) ++ if ((size_t)src_data_type >= ARRAY_SIZE(shift_types) || !shift_types[src_data_type]) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid source operand 1 data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", + vsir_data_type_get_name(src_data_type, ""), src_data_type, +@@ -12020,6 +12069,32 @@ static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d + vsir_validator_push_block(ctx, VSIR_OP_IF); + } + ++static void vsir_validate_ishl(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_I64] = true, ++ [VSIR_DATA_U32] = true, ++ [VSIR_DATA_U64] = true, ++ }; ++ ++ vsir_validate_shift_operation(ctx, instruction, types); ++} ++ ++static void vsir_validate_ishr(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_I32] = true, ++ [VSIR_DATA_I64] = true, ++ }; ++ ++ vsir_validate_shift_operation(ctx, instruction, types); ++} ++ + static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) + { + static const bool src_types[VSIR_DATA_TYPE_COUNT] = +@@ -12251,6 +12326,18 @@ static void vsir_validate_switch_monolithic(struct validation_context *ctx, + ctx->inside_block = false; + } + ++static void vsir_validate_ushr(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ static const bool types[VSIR_DATA_TYPE_COUNT] = ++ { ++ [VSIR_DATA_U32] = true, ++ [VSIR_DATA_U64] = true, ++ }; ++ ++ vsir_validate_shift_operation(ctx, instruction, types); ++} ++ + struct vsir_validator_instruction_desc + { + unsigned int dst_param_count; +@@ -12330,17 +12417,17 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ + [VSIR_OP_IEQ] = {1, 2, vsir_validate_integer_comparison_operation}, + [VSIR_OP_IF] = {0, 1, vsir_validate_if}, + [VSIR_OP_IFC] = {0, 2, vsir_validate_ifc}, +- [VSIR_OP_IGE] = {1, 2, vsir_validate_integer_comparison_operation}, +- [VSIR_OP_ILT] = {1, 2, vsir_validate_integer_comparison_operation}, ++ [VSIR_OP_IGE] = {1, 2, vsir_validate_signed_integer_comparison_operation}, ++ [VSIR_OP_ILT] = {1, 2, vsir_validate_signed_integer_comparison_operation}, + [VSIR_OP_IMAD] = {1, 3, vsir_validate_integer_elementwise_operation}, +- [VSIR_OP_IMAX] = {1, 2, vsir_validate_integer_elementwise_operation}, +- [VSIR_OP_IMIN] = {1, 2, vsir_validate_integer_elementwise_operation}, ++ [VSIR_OP_IMAX] = {1, 2, vsir_validate_signed_integer_elementwise_operation}, ++ [VSIR_OP_IMIN] = {1, 2, vsir_validate_signed_integer_elementwise_operation}, + [VSIR_OP_INE] = {1, 2, vsir_validate_integer_comparison_operation}, + [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation}, +- [VSIR_OP_ISHL] = {1, 2, vsir_validate_shift_operation}, +- [VSIR_OP_ISHR] = {1, 2, vsir_validate_shift_operation}, ++ [VSIR_OP_ISHL] = {1, 2, vsir_validate_ishl}, ++ [VSIR_OP_ISHR] = {1, 2, vsir_validate_ishr}, + [VSIR_OP_ISINF] = {1, 1, vsir_validate_float_comparison_operation}, + [VSIR_OP_ISNAN] = {1, 1, vsir_validate_float_comparison_operation}, + [VSIR_OP_ITOF] = {1, 1, vsir_validate_itof}, +@@ -12370,6 +12457,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ + [VSIR_OP_SAMPLE_INFO] = {1, 1, vsir_validate_sample_info}, + [VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch}, + [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, ++ [VSIR_OP_USHR] = {1, 2, vsir_validate_ushr}, + }; + + static void vsir_validate_instruction(struct validation_context *ctx, +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index 9150e77e2c6..2005e842201 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -167,6 +167,7 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, + case VSIR_DATA_F32: + vkd3d_string_buffer_printf(buffer, "f"); + break; ++ case VSIR_DATA_BOOL: + case VSIR_DATA_I32: + vkd3d_string_buffer_printf(buffer, "i"); + break; +@@ -799,6 +800,7 @@ static void msl_relop(struct msl_generator *gen, const struct vkd3d_shader_instr + static void msl_cast(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *constructor) + { + unsigned int component_count; ++ const char *negate; + struct msl_src src; + struct msl_dst dst; + uint32_t mask; +@@ -806,10 +808,11 @@ static void msl_cast(struct msl_generator *gen, const struct vkd3d_shader_instru + mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); + msl_src_init(&src, gen, &ins->src[0], mask); + ++ negate = ins->opcode == VSIR_OP_UTOF && data_type_is_bool(ins->src[0].reg.data_type) ? "-" : ""; + if ((component_count = vsir_write_mask_component_count(mask)) > 1) +- msl_print_assignment(gen, &dst, "%s%u(%s)", constructor, component_count, src.str->buffer); ++ msl_print_assignment(gen, &dst, "%s%u(%s%s)", constructor, component_count, negate, src.str->buffer); + else +- msl_print_assignment(gen, &dst, "%s(%s)", constructor, src.str->buffer); ++ msl_print_assignment(gen, &dst, "%s(%s%s)", constructor, negate, src.str->buffer); + + msl_src_cleanup(&src, &gen->string_buffers); + msl_dst_cleanup(&dst, &gen->string_buffers); +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 8ffc68935f3..0fdeba75c58 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -8155,7 +8155,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, + component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); + + int_max_id = spirv_compiler_get_constant_vector(compiler, component_type, component_count, INT_MAX); +- condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ condition_type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); + +@@ -8208,7 +8208,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, + val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id); + + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); +- condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ condition_type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); + +@@ -8233,7 +8233,7 @@ static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler, + + src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); + +- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); + val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id); + if (instruction->flags & VKD3DSI_PRECISE_XYZW) + vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); +@@ -8257,7 +8257,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp + VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids)); + + component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); +- type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); ++ type_id = spirv_get_type_id(builder, dst->reg.data_type, 1); + size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20; + mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); + size_id = spirv_compiler_get_constant_uint(compiler, size); +@@ -8314,8 +8314,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, + unsigned int i, j; + + instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); +- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); +- scalar_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2); ++ scalar_type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1); + + /* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */ + VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index 2541aef1314..7ff2a305cfa 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -3483,7 +3483,9 @@ static uint32_t sm4_encode_register(const struct tpf_compiler *tpf, const struct + switch (sm4_swizzle_type) + { + case VKD3D_SM4_SWIZZLE_NONE: +- VKD3D_ASSERT(sm4_swizzle || register_is_constant(reg)); ++ if (register_is_constant(reg)) ++ break; ++ VKD3D_ASSERT(sm4_swizzle); + token |= (sm4_swizzle << VKD3D_SM4_WRITEMASK_SHIFT) & VKD3D_SM4_WRITEMASK_MASK; + break; + +-- +2.51.0 +