From a877872a9a095930aed054ee50ed20abae87d04c Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 15 Aug 2025 08:07:30 +1000 Subject: [PATCH] Updated vkd3d-latest patchset --- ...-3163e589bc41b674c46750bef9a3cbbaa90.patch | 4 +- ...-ba545669cd09682960f5da17b9131780642.patch | 4 +- ...-decc155cca45d7c4a60699990452b921a6e.patch | 4 +- ...-68cd72c7fc7a364ecce87a19617acb382c7.patch | 4 +- ...-a4c25b81c59ae783a94c1b25714eb080231.patch | 4 +- ...-b3e367b099cb65d79c5b0044134a02e7e9c.patch | 4 +- ...-f7866df201e491aa6033cc4618ab21cedd1.patch | 4 +- ...-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch | 4 +- ...-75cb4336ec1a0455c347db05b22dc0fd76d.patch | 4 +- ...-bd3d0f3495f6375901df9ca899accf8bc7a.patch | 4 +- ...-721859005f3edfb3d52bc0f810d1da4fe2e.patch | 4 +- ...-4bb880f9ed09dab9a87a56bb065f087e92a.patch | 4 +- ...-44fffee5e1331e1c7e10489d84723c3b9da.patch | 1950 +++++++++++++++++ 13 files changed, 1974 insertions(+), 24 deletions(-) create mode 100644 patches/vkd3d-latest/0013-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch index 28b1b97a..cc254a5b 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch @@ -1,4 +1,4 @@ -From 5e283b117ef5762ed1a5d206496824f36366c064 Mon Sep 17 00:00:00 2001 +From f15f38b33653aef51f701503eeebb305fc966706 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 3163e589bc41b674c46750bef9a3cbbaa90fc560. @@ -20269,5 +20269,5 @@ index 7e54738b19e..9fb6834158f 100644 { VkDescriptorType type; -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch index af6c84a5..5f70079f 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch @@ -1,4 +1,4 @@ -From 86603c42ee097cc0d96b26e99af07612590ddbaf Mon Sep 17 00:00:00 2001 +From 4874b0a352c091813dc9372412ac76e976b5eb64 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 17 Jul 2025 07:20:27 +1000 Subject: [PATCH] Updated vkd3d to ba545669cd09682960f5da17b9131780642daf8e. @@ -131,5 +131,5 @@ index 0a5bd1122e3..9e9811bf922 100644 } -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch index 53e86ba0..bad42045 100644 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch @@ -1,4 +1,4 @@ -From d481fc2bef5bd3df8401ca8ae489012ed352dfb5 Mon Sep 17 00:00:00 2001 +From 97f16d7d3743f07c6dd64999bf3ea0f227c0c2ce Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 22 Jul 2025 07:27:52 +1000 Subject: [PATCH] Updated vkd3d to decc155cca45d7c4a60699990452b921a6e0fa65. @@ -3949,5 +3949,5 @@ index 978af0a2d17..f7bbadac3df 100644 } -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch index 31bca1b3..1f504671 100644 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch @@ -1,4 +1,4 @@ -From 58bfd9084c0a8e46689d8af4e895431b332bf66b Mon Sep 17 00:00:00 2001 +From dc5e92bd8bf82fa50d3d63e556b681862ddf47c7 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 23 Jul 2025 07:16:58 +1000 Subject: [PATCH] Updated vkd3d to 68cd72c7fc7a364ecce87a19617acb382c70762f. @@ -1697,5 +1697,5 @@ index f7bbadac3df..42f3c42033f 100644 return VSIR_DATA_F64; default: -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch index 095eb0d3..1fe89e73 100644 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch @@ -1,4 +1,4 @@ -From 72eb29f46a99984be3c5b9ed39d97d4efb70ab0d Mon Sep 17 00:00:00 2001 +From d6c78db132503243a003082c10a9169e322b7641 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 24 Jul 2025 06:52:52 +1000 Subject: [PATCH] Updated vkd3d to a4c25b81c59ae783a94c1b25714eb080231b86bd. @@ -2298,5 +2298,5 @@ index 42f3c42033f..a0d7faaa407 100644 } } -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch index 0591e9aa..5a4f8b9c 100644 --- a/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch +++ b/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch @@ -1,4 +1,4 @@ -From 89d9cff1b9eb9ebf984793fa1ec2fdb5456d64a7 Mon Sep 17 00:00:00 2001 +From f6b63c8ce9c20192debbe97b2e9673e382842b89 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 25 Jul 2025 07:41:13 +1000 Subject: [PATCH] Updated vkd3d to b3e367b099cb65d79c5b0044134a02e7e9c285a5. @@ -23,5 +23,5 @@ index 2175298a0db..bdb2083e09a 100644 static const struct vkd3d_sm4_opcode_info opcode_table[] = { -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch b/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch index 7c31e7b0..569a1d90 100644 --- a/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch +++ b/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch @@ -1,4 +1,4 @@ -From b46c70ada9fd7838e808e763c63be3e5aa083579 Mon Sep 17 00:00:00 2001 +From 962d21a69b8f5284ed0f4285b6ad303a324ea018 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 29 Jul 2025 18:36:33 +1000 Subject: [PATCH] Updated vkd3d to f7866df201e491aa6033cc4618ab21cedd12a2e2. @@ -819,5 +819,5 @@ index b2636fd5585..67f84aafa29 100644 static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device9 *iface, -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch b/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch index b1c5da59..e6225660 100644 --- a/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch +++ b/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch @@ -1,4 +1,4 @@ -From df7b896cf93f6a402eb67bed8d0c9e8d2b034d17 Mon Sep 17 00:00:00 2001 +From df589f34860797b7a53495423e20bdce4c698ce8 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 30 Jul 2025 08:46:04 +1000 Subject: [PATCH] Updated vkd3d to bb2979aa4c3432bfd5b30ae23de8aaaa57e04c6a. @@ -587,5 +587,5 @@ index d1c2057b38e..5bf3728a325 100644 struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch b/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch index 4238d8f1..7172a625 100644 --- a/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch +++ b/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch @@ -1,4 +1,4 @@ -From 4f4135dd6ab56dbeeaf09d5018c5fad96909117e Mon Sep 17 00:00:00 2001 +From 31ab77ada15b692f5b37d8ddf15f65c375860def Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 31 Jul 2025 09:06:17 +1000 Subject: [PATCH] Updated vkd3d to 75cb4336ec1a0455c347db05b22dc0fd76dd8b5f. @@ -44,5 +44,5 @@ index 1098e4d3950..4c324fef7cf 100644 if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, prev_temp_count)) -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch b/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch index 704b2071..f186376b 100644 --- a/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch +++ b/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch @@ -1,4 +1,4 @@ -From b06ee0c93136bcd51afded65b491fe7c4ba4cfca Mon Sep 17 00:00:00 2001 +From 6d9b7b4891f5ed2c30b6d383fe289637bcc2c6d9 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 1 Aug 2025 07:18:27 +1000 Subject: [PATCH] Updated vkd3d to bd3d0f3495f6375901df9ca899accf8bc7a45345. @@ -146,5 +146,5 @@ index 9e9811bf922..413892789ba 100644 }; static const VkDynamicState dynamic_states[] = -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch b/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch index 2a2d6b74..6099e57d 100644 --- a/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch +++ b/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch @@ -1,4 +1,4 @@ -From ee778296e9c6b83d6559431c09b6ff30ea0e44e7 Mon Sep 17 00:00:00 2001 +From 1031928bdeb67d2a9f6af25ec7948dca4b24bd10 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 5 Aug 2025 13:30:41 +1000 Subject: [PATCH] Updated vkd3d to 721859005f3edfb3d52bc0f810d1da4fe2e5174b. @@ -189,5 +189,5 @@ index 2b73771d0a6..891a33d326f 100644 static const enum vkd3d_shader_target_type fx_types[] = -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch b/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch index 91b9e9ab..4cab1f44 100644 --- a/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch +++ b/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch @@ -1,4 +1,4 @@ -From f6c0f58e3277b570650fd4705200e4c2ad3fad18 Mon Sep 17 00:00:00 2001 +From 00ab2db3813cc8bcd0dc0edf90025365b9dac52f Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 6 Aug 2025 13:39:31 +1000 Subject: [PATCH] Updated vkd3d to 4bb880f9ed09dab9a87a56bb065f087e92a0d62c. @@ -1195,5 +1195,5 @@ index ed19faf945b..ea15c1a9ad5 100644 case VSIR_OP_DCL_RESOURCE_RAW: case VSIR_OP_DCL_UAV_RAW: -- -2.47.2 +2.50.1 diff --git a/patches/vkd3d-latest/0013-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch b/patches/vkd3d-latest/0013-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch new file mode 100644 index 00000000..5d4fbda7 --- /dev/null +++ b/patches/vkd3d-latest/0013-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch @@ -0,0 +1,1950 @@ +From baab59667d933fe15af4b456ea994d7aaf489d27 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Fri, 15 Aug 2025 07:48:03 +1000 +Subject: [PATCH] Updated vkd3d to 44fffee5e1331e1c7e10489d84723c3b9dad7e17. + +--- + libs/vkd3d/include/vkd3d_shader.h | 1 + + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 17 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 5 +- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 3 + + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 122 +++-- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 3 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 24 +- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 27 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 418 +++++++++++------- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 100 +++-- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 161 +++++-- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 51 ++- + 12 files changed, 607 insertions(+), 325 deletions(-) + +diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h +index b50271ce9bb..0fd3c67b7e0 100644 +--- a/libs/vkd3d/include/vkd3d_shader.h ++++ b/libs/vkd3d/include/vkd3d_shader.h +@@ -2966,6 +2966,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver + * - VKD3D_SHADER_SOURCE_DXBC_DXIL + * - VKD3D_SHADER_SOURCE_DXBC_TPF + * - VKD3D_SHADER_SOURCE_D3D_BYTECODE ++ * - VKD3D_SHADER_SOURCE_HLSL + * + * \param compile_info A chained structure containing scan parameters. + * \n +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index 2ec9a74249b..6425a8f62d2 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -1961,7 +1961,7 @@ static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler, + } + + enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_code *out, enum vsir_asm_flags flags) ++ struct vkd3d_shader_code *out, enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context) + { + const struct vkd3d_shader_version *shader_version = &program->shader_version; + enum vkd3d_shader_compile_option_formatting_flags formatting; +@@ -2029,6 +2029,14 @@ enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd + if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) + compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES; + ++ if (compiler.flags & VSIR_ASM_FLAG_ALLOCATE_TEMPS) ++ { ++ if ((result = vsir_allocate_temp_registers(program, message_context)) < 0) ++ return result; ++ if ((result = vsir_update_dcl_temps(program, message_context))) ++ return result; ++ } ++ + buffer = &compiler.buffer; + vkd3d_string_buffer_init(buffer); + +@@ -2250,17 +2258,22 @@ void vsir_program_trace(struct vsir_program *program) + { + const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES + | VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS; ++ struct vkd3d_shader_message_context message_context; + struct vkd3d_shader_code code; + const char *p, *q, *end; + ++ vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_NONE); ++ + trace_signature(&program->input_signature, "Input"); + trace_signature(&program->output_signature, "Output"); + trace_signature(&program->patch_constant_signature, "Patch-constant"); + trace_io_declarations(program); + +- if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK) ++ if (d3d_asm_compile(program, NULL, &code, flags, &message_context) != VKD3D_OK) + return; + ++ vkd3d_shader_message_context_cleanup(&message_context); ++ + end = (const char *)code.code + code.size; + for (p = code.code; p < end; p = q) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index dd13757bf59..751e5578276 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -1513,7 +1513,10 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c + return ret; + } + +- return VKD3D_OK; ++ if (program->normalisation_level >= VSIR_NORMALISED_SM4) ++ ret = vsir_program_lower_d3dbc(program, config_flags, compile_info, message_context); ++ ++ return ret; + } + + bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index e57a4aa2731..dfe0a40ddf0 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -2444,6 +2444,9 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, + if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) + return ret; + ++ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0) ++ return ret; ++ + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index 3199072275b..62335086e20 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -4897,8 +4897,9 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) + hlsl_release_string_buffer(ctx, name); + } + +-static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, +- const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context) ++static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_files, ++ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, ++ struct vkd3d_shader_message_context *message_context) + { + unsigned int i; + +@@ -4908,15 +4909,12 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil + + ctx->message_context = message_context; + +- if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files)))) +- return false; +- if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : ""))) +- { +- vkd3d_free(ctx->source_files); ++ ctx->source_files = source_files; ++ if (!vkd3d_shader_source_list_append(source_files, ++ compile_info->source_name ? compile_info->source_name : "")) + return false; +- } +- ctx->source_files_count = 1; +- ctx->location.source_name = ctx->source_files[0]; ++ ++ ctx->location.source_name = source_files->sources[0]; + ctx->location.line = ctx->location.column = 1; + vkd3d_string_buffer_cache_init(&ctx->string_buffers); + +@@ -4924,8 +4922,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil + + if (!(ctx->dummy_scope = hlsl_new_scope(ctx, NULL))) + { +- vkd3d_free((void *)ctx->source_files[0]); +- vkd3d_free(ctx->source_files); ++ vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); + return false; + } + hlsl_push_scope(ctx); +@@ -5010,9 +5007,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) + struct hlsl_type *type, *next_type; + unsigned int i; + +- for (i = 0; i < ctx->source_files_count; ++i) +- vkd3d_free((void *)ctx->source_files[i]); +- vkd3d_free(ctx->source_files); + vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); + + rb_destroy(&ctx->functions, free_function_rb, NULL); +@@ -5054,26 +5048,13 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) + vkd3d_free(ctx->constant_defs.regs); + } + +-static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, ++static int hlsl_ctx_parse(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_list, ++ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, + struct vkd3d_shader_message_context *message_context) + { + enum vkd3d_shader_target_type target_type = compile_info->target_type; +- const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; +- const struct hlsl_profile_info *profile; + int ret; + +- if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) +- { +- ERR("No HLSL source info given.\n"); +- return VKD3D_ERROR_INVALID_ARGUMENT; +- } +- +- if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) +- { +- FIXME("Unknown compilation target %s.\n", debugstr_a(hlsl_source_info->profile)); +- return VKD3D_ERROR_NOT_IMPLEMENTED; +- } +- + if (target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, +@@ -5099,7 +5080,7 @@ static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil + return VKD3D_ERROR_INVALID_ARGUMENT; + } + +- if (!hlsl_ctx_init(ctx, compile_info, profile, message_context)) ++ if (!hlsl_ctx_init(ctx, source_list, compile_info, profile, message_context)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + if ((ret = hlsl_lexer_compile(ctx, &compile_info->source)) == 2) +@@ -5128,35 +5109,85 @@ static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil + int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) + { ++ const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; ++ struct vkd3d_shader_source_list source_list; ++ const struct hlsl_profile_info *profile; + struct hlsl_ctx ctx; + int ret; + +- if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0) ++ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) ++ { ++ WARN("No HLSL source info given.\n"); ++ return VKD3D_ERROR_INVALID_ARGUMENT; ++ } ++ ++ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) ++ { ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, ++ "Unknown target profile '%s'.", hlsl_source_info->profile); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ vkd3d_shader_source_list_init(&source_list); ++ if ((ret = hlsl_ctx_parse(&ctx, &source_list, compile_info, profile, message_context)) < 0) ++ { ++ vkd3d_shader_source_list_cleanup(&source_list); + return ret; ++ } + + ret = hlsl_emit_effect_binary(&ctx, out); + hlsl_ctx_cleanup(&ctx); ++ vkd3d_shader_source_list_cleanup(&source_list); + + return ret; + } + +-int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) ++int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_message_context *message_context, ++ struct vsir_program *program, struct vkd3d_shader_code *reflection_data) + { + const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; +- uint64_t config_flags = vkd3d_shader_init_config_flags(); + struct hlsl_ir_function_decl *decl, *entry_func = NULL; +- struct vkd3d_shader_code reflection_data = {0}; ++ enum vsir_normalisation_level normalisation_level; ++ const struct hlsl_profile_info *profile; ++ struct vkd3d_shader_version version; + struct hlsl_ir_function *func; +- struct vsir_program program; + const char *entry_point; + struct hlsl_ctx ctx; + int ret; + +- if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0) ++ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) ++ { ++ WARN("No HLSL source info given.\n"); ++ return VKD3D_ERROR_INVALID_ARGUMENT; ++ } ++ ++ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) ++ { ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, ++ "Unknown target profile '%s'.", hlsl_source_info->profile); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ version = (struct vkd3d_shader_version) ++ { ++ .type = profile->type, ++ .major = profile->major_version, ++ .minor = profile->minor_version, ++ }; ++ normalisation_level = VSIR_NORMALISED_SM4; ++ if (version.major < 4 && (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM ++ || compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE)) ++ normalisation_level = VSIR_NORMALISED_SM1; ++ if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, normalisation_level)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ if ((ret = hlsl_ctx_parse(&ctx, &program->source_files, compile_info, profile, message_context)) < 0) ++ { ++ vsir_program_cleanup(program); + return ret; ++ } + +- hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO); + entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; + if ((func = hlsl_get_function(&ctx, entry_point))) + { +@@ -5181,17 +5212,16 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, + hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, + "Entry point \"%s\" is not defined.", entry_point); + hlsl_ctx_cleanup(&ctx); ++ vsir_program_cleanup(program); + return VKD3D_ERROR_INVALID_SHADER; + } + +- if ((ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, &program, &reflection_data)) >= 0) +- { +- vsir_program_trace(&program); +- ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, message_context); +- vkd3d_shader_free_shader_code(&reflection_data); +- vsir_program_cleanup(&program); +- } ++ ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, program, reflection_data); + hlsl_ctx_cleanup(&ctx); ++ if (ret < 0) ++ vsir_program_cleanup(program); ++ else ++ vsir_program_trace(program); + + return ret; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index c3002258aa2..d67f820fe8b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -1093,8 +1093,7 @@ struct hlsl_ctx + { + const struct hlsl_profile_info *profile; + +- const char **source_files; +- unsigned int source_files_count; ++ struct vkd3d_shader_source_list *source_files; + /* Current location being read in the HLSL source, updated while parsing. */ + struct vkd3d_shader_location location; + /* Stores the logging messages and logging configuration. */ +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 66582e884fe..024d96c5663 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -7190,23 +7190,19 @@ declaration_statement_list: + preproc_directive: + PRE_LINE STRING + { +- const char **new_array = NULL; +- +- ctx->location.line = $1; + if (strcmp($2, ctx->location.source_name)) +- new_array = hlsl_realloc(ctx, ctx->source_files, +- sizeof(*ctx->source_files) * (ctx->source_files_count + 1)); +- +- if (new_array) +- { +- ctx->source_files = new_array; +- ctx->source_files[ctx->source_files_count++] = $2; +- ctx->location.source_name = $2; +- } +- else + { +- vkd3d_free($2); ++ if (!vkd3d_shader_source_list_append(ctx->source_files, $2)) ++ { ++ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ else ++ { ++ ctx->location.line = $1; ++ ctx->location.source_name = ctx->source_files->sources[ctx->source_files->count - 1]; ++ } + } ++ vkd3d_free($2); + } + + struct_declaration_without_vars: +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index dbda72eb30f..0b3dee4d2ce 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -9945,6 +9945,11 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co + sm1_generate_vsir_block(ctx, body, program); + + program->ssa_count = ctx->ssa_count; ++ ++ if (ctx->result) ++ return; ++ if (program->normalisation_level >= VSIR_NORMALISED_SM4) ++ ctx->result = vsir_program_lower_d3dbc(program, config_flags, compile_info, ctx->message_context); + } + + D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) +@@ -14272,7 +14277,6 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info + uint32_t config_flags = vkd3d_shader_init_config_flags(); + const struct hlsl_profile_info *profile = ctx->profile; + struct list semantic_vars, patch_semantic_vars; +- struct vkd3d_shader_version version = {0}; + struct hlsl_ir_var *var; + + parse_entry_function_attributes(ctx, entry_func); +@@ -14349,39 +14353,24 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info + if (ctx->result) + return ctx->result; + +- version.major = ctx->profile->major_version; +- version.minor = ctx->profile->minor_version; +- version.type = ctx->profile->type; +- if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) +- { +- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; +- return ctx->result; +- } +- + generate_vsir_signature(ctx, program, entry_func, &semantic_vars); +- if (version.type == VKD3D_SHADER_TYPE_HULL) ++ if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL) + generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars); + +- if (version.major < 4) ++ if (program->shader_version.major < 4) + sm1_generate_ctab(ctx, reflection_data); + else + sm4_generate_rdef(ctx, reflection_data); + if (ctx->result) +- { +- vsir_program_cleanup(program); + return ctx->result; +- } + +- if (version.major < 4) ++ if (program->shader_version.major < 4) + sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program); + else + sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, + &patch_semantic_vars, &patch_body, config_flags, program); + if (ctx->result) +- { + vkd3d_shader_free_shader_code(reflection_data); +- vsir_program_cleanup(program); +- } + + return ctx->result; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 9d93936ac9e..23e059a3490 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -451,6 +451,8 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c + return false; + } + ++ vkd3d_shader_source_list_init(&program->source_files); ++ + return true; + } + +@@ -463,6 +465,7 @@ void vsir_program_cleanup(struct vsir_program *program) + for (i = 0; i < program->block_name_count; ++i) + vkd3d_free((void *)program->block_names[i]); + vkd3d_free(program->block_names); ++ vkd3d_shader_source_list_cleanup(&program->source_files); + shader_instruction_array_destroy(&program->instructions); + shader_signature_cleanup(&program->input_signature); + shader_signature_cleanup(&program->output_signature); +@@ -1387,6 +1390,53 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog + return VKD3D_OK; + } + ++static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program, ++ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) ++{ ++ /* texcrd DST, t# -> mov DST, t# */ ++ ++ if (ins->src[0].modifiers) ++ { ++ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Aborting due to not yet implemented feature: texcrd source modifier."); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ ins->opcode = VSIR_OP_MOV; ++ ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program, ++ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) ++{ ++ unsigned int idx = ins->src[0].reg.idx[0].offset; ++ struct vkd3d_shader_src_param *srcs; ++ ++ /* texld DST, t# -> sample DST, t#, resource#, sampler# */ ++ ++ if (ins->src[0].modifiers) ++ { ++ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Aborting due to not yet implemented feature: texld source modifier."); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ /* Note we run before I/O normalization. */ ++ srcs[0] = ins->src[0]; ++ 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_texldp(struct vsir_program *program, + struct vsir_program_iterator *it, unsigned int *tmp_idx) + { +@@ -1605,6 +1655,45 @@ static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *prog + return VKD3D_OK; + } + ++static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_message_context *message_context = ctx->message_context; ++ struct vkd3d_shader_instruction *ins; ++ unsigned int tmp_idx = ~0u; ++ ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ enum vkd3d_result ret; ++ ++ switch (ins->opcode) ++ { ++ case VSIR_OP_TEXCRD: ++ ret = vsir_program_lower_texcrd(program, ins, message_context); ++ break; ++ ++ case VSIR_OP_TEXLD: ++ if (program->shader_version.major == 1) ++ ret = vsir_program_lower_texld_sm1(program, ins, message_context); ++ else if (ins->flags == VKD3DSI_TEXLD_PROJECT) ++ ret = vsir_program_lower_texldp(program, &it, &tmp_idx); ++ else ++ ret = vsir_program_lower_texld(program, ins, message_context); ++ break; ++ ++ default: ++ ret = VKD3D_OK; ++ break; ++ } ++ ++ if (ret < 0) ++ return ret; ++ } ++ ++ return VKD3D_OK; ++} ++ + static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +@@ -1688,19 +1777,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + } + break; + +- case VSIR_OP_TEXLD: +- if (ins->flags == VKD3DSI_TEXLD_PROJECT) +- { +- if ((ret = vsir_program_lower_texldp(program, &it, &tmp_idx)) < 0) +- return ret; +- } +- else +- { +- if ((ret = vsir_program_lower_texld(program, ins, message_context)) < 0) +- return ret; +- } +- break; +- + case VSIR_OP_TEXLDD: + if ((ret = vsir_program_lower_texldd(program, ins)) < 0) + return ret; +@@ -1714,7 +1790,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + case VSIR_OP_TEXCOORD: +- case VSIR_OP_TEXCRD: + case VSIR_OP_TEXDEPTH: + case VSIR_OP_TEXDP3: + case VSIR_OP_TEXDP3TEX: +@@ -1762,6 +1837,39 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, + return VKD3D_OK; + } + ++/* ps_1_* outputs color in r0. Add an instruction to copy that to oC0. ++ * We don't need to modify the signature since it already contains COLOR. */ ++static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program *program, ++ struct vsir_transformation_context *ctx) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_location loc; ++ ++ if (!(ins = vsir_program_iterator_tail(&it))) ++ return VKD3D_OK; ++ loc = ins->location; ++ ++ if (!(ins = vsir_program_append(program))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1)) ++ { ++ vsir_instruction_init(ins, &loc, VSIR_OP_NOP); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ ++ src_param_init_temp_float4(&ins->src[0], 0); ++ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ /* Note we run before I/O normalization. */ ++ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_COLOROUT, VSIR_DATA_F32, 1); ++ ins->dst[0].reg.idx[0].offset = 0; ++ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; ++ ins->dst[0].modifiers = VKD3DSPDM_SATURATE; ++ ++ return VKD3D_OK; ++} ++ + static struct signature_element *add_signature_element(struct shader_signature *signature, + const char *semantic_name, uint32_t semantic_index, uint32_t mask, uint32_t register_index, + enum vkd3d_shader_interpolation_mode interpolation_mode) +@@ -1814,6 +1922,7 @@ static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *pr + static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; + unsigned int i; +@@ -1825,17 +1934,16 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra + /* Write the instruction after all LABEL, DCL, and NOP instructions. + * We need to skip NOP instructions because they might result from removed + * DCLs, and there could still be DCLs after NOPs. */ +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- + if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) + break; + } + +- if (!shader_instruction_array_insert_at(&program->instructions, i, 1)) ++ vsir_program_iterator_prev(&it); ++ if (!vsir_program_iterator_insert_after(&it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = &program->instructions.elements[i]; ++ ins = vsir_program_iterator_next(&it); + + vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1); +@@ -1936,6 +2044,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + struct vsir_transformation_context *ctx) + { + const struct vkd3d_shader_location location = {.source_name = ctx->compile_info->source_name}; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + const struct vkd3d_shader_compile_info *compile_info = ctx->compile_info; + bool allows_subset_masks = target_allows_subset_masks(compile_info); +@@ -1945,6 +2054,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + struct signature_element *new_elements, *e; + unsigned int uninit_varying_count = 0; + unsigned int subset_varying_count = 0; ++ struct vkd3d_shader_instruction *ins; + unsigned int new_register_count = 0; + unsigned int i; + +@@ -2044,18 +2154,18 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + } + + /* Write each uninitialized varying before each ret. */ +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + struct vkd3d_shader_location loc; + + if (ins->opcode != VSIR_OP_RET) + continue; + + loc = ins->location; +- if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count)) ++ vsir_program_iterator_prev(&it); ++ if (!vsir_program_iterator_insert_after(&it, uninit_varying_count)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = &program->instructions.elements[i]; ++ ins = vsir_program_iterator_next(&it); + + for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) + { +@@ -2065,10 +2175,8 @@ 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; ++ ins = vsir_program_iterator_next(&it); + } +- +- i += uninit_varying_count; + } + + /* Vulkan (without KHR_maintenance4) disallows any mismatching masks, +@@ -2079,10 +2187,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + if (!subset_varying_count || allows_subset_masks) + return VKD3D_OK; + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + for (unsigned int j = 0; j < ins->dst_count; ++j) + remove_unread_output_components(signature, ins, &ins->dst[j]); + } +@@ -2121,10 +2227,9 @@ struct shader_phase_location_array + unsigned int count; + }; + +-static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, +- unsigned int index, struct shader_phase_location_array *locations) ++static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index, ++ struct vkd3d_shader_instruction *ins, struct shader_phase_location_array *locations) + { +- struct vkd3d_shader_instruction *ins = &normaliser->program->instructions.elements[index]; + struct shader_phase_location *loc; + bool b; + +@@ -2289,15 +2394,19 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali + static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct shader_phase_location_array locations; + struct hull_flattener flattener = {program}; ++ struct vkd3d_shader_instruction *ins; + enum vkd3d_result result = VKD3D_OK; + unsigned int i; + + flattener.phase = VSIR_OP_INVALID; +- for (i = 0, locations.count = 0; i < instructions->count; ++i) +- flattener_eliminate_phase_related_dcls(&flattener, i, &locations); ++ locations.count = 0; ++ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) ++ { ++ flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations); ++ } + bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID); + bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID); + +@@ -2315,10 +2424,9 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro + + if (flattener.phase != VSIR_OP_INVALID) + { +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) ++ if (!(ins = vsir_program_append(program))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- vsir_instruction_init(&instructions->elements[instructions->count++], +- &flattener.last_ret_location, VSIR_OP_RET); ++ vsir_instruction_init(ins, &flattener.last_ret_location, VSIR_OP_RET); + } + + return result; +@@ -2436,11 +2544,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p + static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io( + struct vsir_program *program, struct vsir_transformation_context *ctx) + { +- struct vkd3d_shader_instruction_array *instructions; + struct control_point_normaliser normaliser; + unsigned int input_control_point_count; + struct vkd3d_shader_location location; + struct vkd3d_shader_instruction *ins; ++ struct vsir_program_iterator it; + enum vkd3d_result ret; + unsigned int i, j; + +@@ -2458,13 +2566,11 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + return VKD3D_ERROR_OUT_OF_MEMORY; + } + normaliser.instructions = program->instructions; +- instructions = &normaliser.instructions; ++ it = vsir_program_iterator(&normaliser.instructions); + normaliser.phase = VSIR_OP_INVALID; + +- for (i = 0; i < normaliser.instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &instructions->elements[i]; +- + switch (ins->opcode) + { + case VSIR_OP_HS_CONTROL_POINT_PHASE: +@@ -2484,10 +2590,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + normaliser.phase = VSIR_OP_INVALID; + input_control_point_count = 1; + +- for (i = 0; i < instructions->count; ++i) ++ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) + { +- ins = &instructions->elements[i]; +- + switch (ins->opcode) + { + case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: +@@ -2531,7 +2635,6 @@ struct io_normaliser + { + struct vkd3d_shader_message_context *message_context; + enum vkd3d_result result; +- struct vkd3d_shader_instruction_array instructions; + enum vkd3d_shader_type shader_type; + uint8_t major; + struct shader_signature *input_signature; +@@ -3147,10 +3250,10 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi + static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK, program->instructions}; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK}; + struct vkd3d_shader_instruction *ins; + enum vkd3d_result ret; +- unsigned int i; + + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_HULL_CONTROL_POINT_IO); + +@@ -3161,10 +3264,8 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program + normaliser.output_signature = &program->output_signature; + normaliser.patch_constant_signature = &program->patch_constant_signature; + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- + switch (ins->opcode) + { + case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: +@@ -3190,16 +3291,14 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program + normaliser.output_range_map, false)) < 0 + || (ret = shader_signature_merge(&normaliser, &program->patch_constant_signature, + normaliser.pc_range_map, true)) < 0) +- { +- program->instructions = normaliser.instructions; + return ret; +- } + + normaliser.phase = VSIR_OP_INVALID; +- for (i = 0; i < normaliser.instructions.count; ++i) +- shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser); ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) ++ { ++ shader_instruction_normalise_io_params(ins, &normaliser); ++ } + +- program->instructions = normaliser.instructions; + program->use_vocp = normaliser.use_vocp; + program->normalisation_level = VSIR_NORMALISED_SM6; + return normaliser.result; +@@ -3288,13 +3387,13 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par + static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct flat_constants_normaliser normaliser = {0}; +- unsigned int i, j; ++ struct vkd3d_shader_instruction *ins; ++ unsigned int i; + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + if (ins->opcode == VSIR_OP_DEF || ins->opcode == VSIR_OP_DEFI || ins->opcode == VSIR_OP_DEFB) + { + struct flat_constant_def *def; +@@ -3309,15 +3408,19 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr + def = &normaliser.defs[normaliser.def_count++]; + + get_flat_constant_register_type(&ins->dst[0].reg, &def->set, &def->index, NULL); +- for (j = 0; j < 4; ++j) +- def->value[j] = ins->src[0].reg.u.immconst_u32[j]; ++ for (i = 0; i < 4; ++i) ++ { ++ def->value[i] = ins->src[0].reg.u.immconst_u32[i]; ++ } + + vkd3d_shader_instruction_make_nop(ins); + } + else + { +- for (j = 0; j < ins->src_count; ++j) +- shader_register_normalise_flat_constants(&ins->src[j], &normaliser); ++ for (i = 0; i < ins->src_count; ++i) ++ { ++ shader_register_normalise_flat_constants(&ins->src[i], &normaliser); ++ } + } + } + +@@ -3328,13 +3431,13 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr + static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- size_t i, depth = 0; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; + bool dead = false; ++ size_t depth = 0; + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + switch (ins->opcode) + { + case VSIR_OP_IF: +@@ -3707,10 +3810,11 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte + struct vkd3d_shader_message_context *message_context) + { + struct vkd3d_shader_instruction_array *instructions; ++ const struct vkd3d_shader_instruction *instruction; + struct vsir_program *program = flattener->program; + bool is_hull_shader, after_declarations_section; + struct vkd3d_shader_instruction *dst_ins; +- size_t i; ++ struct vsir_program_iterator it; + + instructions = &program->instructions; + is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL; +@@ -3719,10 +3823,10 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte + if (!cf_flattener_require_space(flattener, instructions->count + 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- for (i = 0; i < instructions->count; ++i) ++ it = vsir_program_iterator(instructions); ++ for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it)) + { + unsigned int loop_header_block_id, loop_body_block_id, continue_block_id, merge_block_id, true_block_id; +- const struct vkd3d_shader_instruction *instruction = &instructions->elements[i]; + const struct vkd3d_shader_src_param *src = instruction->src; + struct cf_flattener_info *cf_info; + +@@ -4321,10 +4425,12 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl + static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count; + struct ssas_to_temps_block_info *info, *block_info = NULL; + struct vkd3d_shader_instruction *instructions = NULL; + struct ssas_to_temps_alloc alloc = {0}; ++ struct vkd3d_shader_instruction *ins; + unsigned int current_label = 0; + + VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); +@@ -4338,9 +4444,10 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ + if (!ssas_to_temps_alloc_init(&alloc, program->ssa_count, program->temp_count)) + goto fail; + +- for (i = 0, phi_count = 0, incoming_count = 0; i < program->instructions.count; ++i) ++ phi_count = 0; ++ incoming_count = 0; ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + unsigned int j, temp_idx; + + /* Only phi src/dst SSA values need be converted here. Structurisation may +@@ -4383,9 +4490,9 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ + if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count)) + goto fail; + +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *mov_ins, *ins = &program->instructions.elements[i]; ++ struct vkd3d_shader_instruction *mov_ins; + size_t j; + + for (j = 0; j < ins->dst_count; ++j) +@@ -6826,14 +6933,12 @@ static enum vkd3d_result vsir_program_apply_flat_interpolation(struct vsir_progr + } + + static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func, ++ struct vsir_program_iterator *it, enum vkd3d_shader_comparison_func compare_func, + const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx, +- uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context) ++ uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- const struct vkd3d_shader_location loc = ret->location; ++ struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; + static const struct vkd3d_shader_location no_loc; +- size_t pos = ret - instructions->elements; + struct vkd3d_shader_instruction *ins; + + static const struct +@@ -6854,23 +6959,23 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + + if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER) + { +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); + + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); + ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; + src_param_init_const_uint(&ins->src[0], 0); ++ vsir_program_iterator_next(it); + +- *ret_pos = pos + 1; + return VKD3D_OK; + } + +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 3)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 3)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); + + switch (ref->data_type) + { +@@ -6902,14 +7007,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + ins->src[opcodes[compare_func].swap ? 1 : 0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); + +- ++ins; ++ ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); + ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; + src_param_init_ssa_bool(&ins->src[0], program->ssa_count); + + ++program->ssa_count; + +- ++ins; ++ ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = colour_signature_idx; +@@ -6919,20 +7024,21 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + +- *ret_pos = pos + 3; ++ vsir_program_iterator_next(it); ++ + return VKD3D_OK; + } + + static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL; + uint32_t colour_signature_idx, colour_temp = ~0u; + static const struct vkd3d_shader_location no_loc; + enum vkd3d_shader_comparison_func compare_func; + struct vkd3d_shader_instruction *ins; +- size_t new_pos; + int ret; + + if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) +@@ -6969,19 +7075,16 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro + if (compare_func != VKD3D_SHADER_COMPARISON_FUNC_NEVER) + colour_temp = program->temp_count++; + +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- + if (vsir_instruction_is_dcl(ins)) + continue; + + if (ins->opcode == VSIR_OP_RET) + { +- if ((ret = insert_alpha_test_before_ret(program, ins, compare_func, +- ref, colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) ++ if ((ret = insert_alpha_test_before_ret(program, &it, compare_func, ++ ref, colour_signature_idx, colour_temp, message_context)) < 0) + return ret; +- i = new_pos; + continue; + } + +@@ -7007,19 +7110,17 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro + } + + static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, uint32_t mask, uint32_t position_signature_idx, +- uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos) ++ struct vsir_program_iterator *it, uint32_t mask, uint32_t position_signature_idx, ++ uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- const struct vkd3d_shader_location loc = ret->location; +- size_t pos = ret - instructions->elements; ++ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; + struct vkd3d_shader_instruction *ins; + unsigned int output_idx = 0; + +- if (!shader_instruction_array_insert_at(&program->instructions, pos, vkd3d_popcount(mask) + 1)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); + + for (unsigned int i = 0; i < 8; ++i) + { +@@ -7041,7 +7142,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog + ins->dst[0].write_mask = (1u << (output_idx % 4)); + ++output_idx; + +- ++ins; ++ ins = vsir_program_iterator_next(it); + } + + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); +@@ -7052,14 +7153,15 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog + src_param_init_temp_float(&ins->src[0], position_temp); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ ins = vsir_program_iterator_next(it); + +- *ret_pos = pos + vkd3d_popcount(mask) + 1; + return VKD3D_OK; + } + + static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct shader_signature *signature = &program->output_signature; + unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; + const struct vkd3d_shader_parameter1 *mask_parameter = NULL; +@@ -7068,7 +7170,6 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + struct signature_element *clip_element; + struct vkd3d_shader_instruction *ins; + unsigned int plane_count; +- size_t new_pos; + int ret; + + if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX) +@@ -7144,19 +7245,16 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + + position_temp = program->temp_count++; + +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- + if (vsir_instruction_is_dcl(ins)) + continue; + + if (ins->opcode == VSIR_OP_RET) + { +- if ((ret = insert_clip_planes_before_ret(program, ins, mask, position_signature_idx, +- position_temp, low_signature_idx, high_signature_idx, &new_pos)) < 0) ++ if ((ret = insert_clip_planes_before_ret(program, &it, mask, position_signature_idx, ++ position_temp, low_signature_idx, high_signature_idx)) < 0) + return ret; +- i = new_pos; + continue; + } + +@@ -7185,32 +7283,32 @@ static bool is_pre_rasterization_shader(enum vkd3d_shader_type type) + } + + static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, size_t *ret_pos) ++ struct vsir_program_iterator *it) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- const struct vkd3d_shader_location loc = ret->location; +- size_t pos = ret - instructions->elements; ++ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; + struct vkd3d_shader_instruction *ins; + +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) ++ vsir_program_iterator_prev(it); ++ if (!vsir_program_iterator_insert_after(it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- ins = &program->instructions.elements[pos]; ++ ins = vsir_program_iterator_next(it); + + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VSIR_DATA_F32); ++ ins = vsir_program_iterator_next(it); + +- *ret_pos = pos + 1; + return VKD3D_OK; + } + + static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + const struct vkd3d_shader_parameter1 *size_parameter = NULL; + static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_instruction *ins; + + if (program->has_point_size) + return VKD3D_OK; +@@ -7239,18 +7337,14 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro + program->has_point_size = true; + + /* Append a point size write before each ret. */ +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + if (ins->opcode == VSIR_OP_RET) + { +- size_t new_pos; + int ret; + +- if ((ret = insert_point_size_before_ret(program, ins, &new_pos)) < 0) ++ if ((ret = insert_point_size_before_ret(program, &it)) < 0) + return ret; +- i = new_pos; + } + } + +@@ -7261,7 +7355,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + struct vsir_transformation_context *ctx) + { + const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_instruction *ins; + + if (!program->has_point_size) + return VKD3D_OK; +@@ -7298,9 +7394,8 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + + /* Replace writes to the point size by inserting a clamp before each write. */ + +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + const struct vkd3d_shader_location *loc; + unsigned int ssa_value; + bool clamp = false; +@@ -7324,11 +7419,11 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + if (!clamp) + continue; + +- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter)) ++ if (!vsir_program_iterator_insert_after(&it, !!min_parameter + !!max_parameter)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = &program->instructions.elements[i + 1]; + +- loc = &program->instructions.elements[i].location; ++ loc = &vsir_program_iterator_current(&it)->location; ++ ins = vsir_program_iterator_next(&it); + + if (min_parameter) + { +@@ -7345,8 +7440,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; + } +- ++ins; +- ++i; ++ ins = vsir_program_iterator_next(&it); + } + + if (max_parameter) +@@ -7356,8 +7450,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VSIR_DATA_F32); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; +- +- ++i; ++ ins = vsir_program_iterator_next(&it); + } + } + +@@ -7435,12 +7528,13 @@ static bool replace_texcoord_with_point_coord(struct vsir_program *program, + static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2; + const struct vkd3d_shader_parameter1 *sprite_parameter = NULL; + static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; + bool used_texcoord = false; + unsigned int coord_temp; +- size_t i, insert_pos; ++ size_t i; + + if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) + return VKD3D_OK; +@@ -7481,21 +7575,16 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + /* Construct the new temp after all LABEL, DCL, and NOP instructions. + * We need to skip NOP instructions because they might result from removed + * DCLs, and there could still be DCLs after NOPs. */ +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- + if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) + break; + } + +- insert_pos = i; +- ++ it2 = it; + /* Replace each texcoord read with a read from the point coord. */ +- for (; i < program->instructions.count; ++i) ++ for (; ins; ins = vsir_program_iterator_next(&it2)) + { +- ins = &program->instructions.elements[i]; +- + if (vsir_instruction_is_dcl(ins)) + continue; + +@@ -7524,9 +7613,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + + if (used_texcoord) + { +- if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2)) ++ vsir_program_iterator_prev(&it); ++ if (!vsir_program_iterator_insert_after(&it, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = &program->instructions.elements[insert_pos]; ++ ins = vsir_program_iterator_next(&it); + + vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); + dst_param_init_temp_float4(&ins->dst[0], coord_temp); +@@ -7534,14 +7624,14 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; +- ++ins; ++ ins = vsir_program_iterator_next(&it); + + vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); + dst_param_init_temp_float4(&ins->dst[0], coord_temp); + 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; ++ vsir_program_iterator_next(&it); + + program->has_point_coord = true; + } +@@ -12045,6 +12135,28 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin + return ctx.result; + } + ++enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, ++ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) ++{ ++ struct vsir_transformation_context ctx = ++ { ++ .result = VKD3D_OK, ++ .program = program, ++ .config_flags = config_flags, ++ .compile_info = compile_info, ++ .message_context = message_context, ++ }; ++ ++ vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); ++ if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ++ vsir_transform(&ctx, vsir_program_normalise_ps1_output); ++ ++ if (TRACE_ON()) ++ vsir_program_trace(program); ++ ++ return ctx.result; ++} ++ + enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 4f50eadf714..a4990d982bc 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -5676,6 +5676,48 @@ static unsigned int shader_signature_next_location(const struct shader_signature + return max_row; + } + ++static const struct vkd3d_symbol *spirv_compiler_emit_io_register(struct spirv_compiler *compiler, ++ const struct vkd3d_shader_dst_param *dst) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ const struct vkd3d_shader_register *reg = &dst->reg; ++ const struct vkd3d_spirv_builtin *builtin; ++ struct vkd3d_symbol reg_symbol; ++ SpvStorageClass storage_class; ++ uint32_t write_mask, id; ++ struct rb_entry *entry; ++ ++ VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); ++ VKD3D_ASSERT(reg->idx_count < 2); ++ ++ if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) ++ { ++ builtin = &vkd3d_output_point_size_builtin; ++ storage_class = SpvStorageClassOutput; ++ } ++ else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) ++ { ++ FIXME("Unhandled register %#x.\n", reg->type); ++ return NULL; ++ } ++ ++ /* vPrim may be declared in multiple hull shader phases. */ ++ vkd3d_symbol_make_register(®_symbol, reg); ++ if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) ++ return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); ++ ++ id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); ++ spirv_compiler_emit_register_execution_mode(compiler, reg->type); ++ spirv_compiler_emit_register_debug_name(builder, id, reg); ++ ++ write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); ++ vkd3d_symbol_set_register_info(®_symbol, id, ++ storage_class, builtin->component_type, write_mask); ++ reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; ++ ++ return spirv_compiler_put_symbol(compiler, ®_symbol); ++} ++ + static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + enum vkd3d_shader_register_type reg_type, unsigned int element_idx) + { +@@ -5684,6 +5726,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + const struct signature_element *signature_element; + const struct shader_signature *shader_signature; + enum vkd3d_shader_component_type component_type; ++ enum vkd3d_shader_register_type sysval_reg_type; + const struct vkd3d_spirv_builtin *builtin; + enum vkd3d_shader_sysval_semantic sysval; + uint32_t write_mask, reg_write_mask; +@@ -5708,6 +5751,22 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + if (!signature_element->used_mask) + return; + ++ sysval_reg_type = vsir_register_type_from_sysval_input(signature_element->sysval_semantic); ++ if (sysval_reg_type != VKD3DSPR_INPUT) ++ { ++ struct vkd3d_shader_dst_param dst; ++ const struct vkd3d_symbol *symbol; ++ ++ vsir_dst_param_init(&dst, sysval_reg_type, VSIR_DATA_F32, 0); ++ symbol = spirv_compiler_emit_io_register(compiler, &dst); ++ ++ vkd3d_symbol_make_io(®_symbol, reg_type, element_idx); ++ reg_symbol.id = symbol->id; ++ reg_symbol.info.reg = symbol->info.reg; ++ spirv_compiler_put_symbol(compiler, ®_symbol); ++ return; ++ } ++ + builtin = get_spirv_builtin_for_sysval(compiler, sysval); + + array_sizes[0] = signature_element->register_count; +@@ -5829,47 +5888,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + } + } + +-static void spirv_compiler_emit_io_register(struct spirv_compiler *compiler, +- const struct vkd3d_shader_dst_param *dst) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- const struct vkd3d_shader_register *reg = &dst->reg; +- const struct vkd3d_spirv_builtin *builtin; +- struct vkd3d_symbol reg_symbol; +- SpvStorageClass storage_class; +- uint32_t write_mask, id; +- struct rb_entry *entry; +- +- VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); +- VKD3D_ASSERT(reg->idx_count < 2); +- +- if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) +- { +- builtin = &vkd3d_output_point_size_builtin; +- storage_class = SpvStorageClassOutput; +- } +- else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) +- { +- FIXME("Unhandled register %#x.\n", reg->type); +- return; +- } +- +- /* vPrim may be declared in multiple hull shader phases. */ +- vkd3d_symbol_make_register(®_symbol, reg); +- if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) +- return; +- +- id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); +- +- write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); +- vkd3d_symbol_set_register_info(®_symbol, id, +- storage_class, builtin->component_type, write_mask); +- reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; +- spirv_compiler_put_symbol(compiler, ®_symbol); +- spirv_compiler_emit_register_execution_mode(compiler, reg->type); +- spirv_compiler_emit_register_debug_name(builder, id, reg); +-} +- + static unsigned int get_shader_output_swizzle(const struct spirv_compiler *compiler, + unsigned int register_idx) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 891a33d326f..d1992c9d446 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -57,6 +57,39 @@ uint32_t vkd3d_parse_integer(const char *s) + return ret; + } + ++bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source) ++{ ++ char *s; ++ ++ if (!(s = vkd3d_strdup(source))) ++ return false; ++ ++ if (!vkd3d_array_reserve((void **)&l->sources, &l->capacity, l->count + 1, sizeof(*l->sources))) ++ { ++ vkd3d_free(s); ++ return false; ++ } ++ l->sources[l->count++] = s; ++ ++ return true; ++} ++ ++void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l) ++{ ++ size_t i; ++ ++ for (i = 0; i < l->count; ++i) ++ { ++ vkd3d_free((void *)l->sources[i]); ++ } ++ vkd3d_free(l->sources); ++} ++ ++void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l) ++{ ++ memset(l, 0, sizeof(*l)); ++} ++ + void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) + { + buffer->buffer_size = 16; +@@ -767,12 +800,28 @@ static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_ + } + + static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, +- struct vkd3d_shader_message_context *message_context, struct vsir_program *program) ++ const struct shader_dump_data *dump_data, struct vkd3d_shader_message_context *message_context, ++ struct vsir_program *program, struct vkd3d_shader_code *reflection_data) + { ++ struct vkd3d_shader_compile_info preprocessed_info; ++ struct vkd3d_shader_code preprocessed; + enum vkd3d_result ret; + + switch (compile_info->source_type) + { ++ case VKD3D_SHADER_SOURCE_HLSL: ++ if ((ret = preproc_lexer_parse(compile_info, &preprocessed, message_context)) >= 0) ++ { ++ vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC); ++ ++ preprocessed_info = *compile_info; ++ preprocessed_info.source = preprocessed; ++ ret = hlsl_parse(&preprocessed_info, message_context, program, reflection_data); ++ ++ vkd3d_shader_free_shader_code(&preprocessed); ++ } ++ break; ++ + case VKD3D_SHADER_SOURCE_D3D_BYTECODE: + ret = d3dbc_parse(compile_info, config_flags, message_context, program); + break; +@@ -803,13 +852,19 @@ static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *comp + + if (TRACE_ON()) + vsir_program_trace(program); +- +- vsir_program_cleanup(program); +- return ret; ++ goto fail; + } + +- if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE) +- ret = vsir_program_transform_early(program, config_flags, compile_info, message_context); ++ if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE ++ && (ret = vsir_program_transform_early(program, config_flags, compile_info, message_context)) < 0) ++ goto fail; ++ ++ return ret; ++ ++fail: ++ vkd3d_shader_free_shader_code(reflection_data); ++ vsir_program_cleanup(program); ++ + return ret; + } + +@@ -1233,6 +1288,40 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co + s->sampler_index = sampler_idx; + } + ++static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context, ++ const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler) ++{ ++ unsigned int resource_idx = resource->idx[0].offset; ++ unsigned int sampler_idx = sampler->idx[0].offset; ++ ++ vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler); ++ ++ if (!context->scan_descriptor_info) ++ return; ++ ++ /* Sample instructions lowered from 1.x texture instructions have no ++ * DCL, so we need to add the resource if it didn't already exist. ++ * Such descriptors have a fixed count, type, etc. */ ++ ++ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, ++ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx)) ++ { ++ struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx}; ++ ++ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource, ++ &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32); ++ } ++ ++ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, ++ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx)) ++ { ++ struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; ++ ++ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource, ++ &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); ++ } ++} ++ + static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, + enum vsir_data_type resource_data_type, unsigned int sample_count, +@@ -1436,13 +1525,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_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 VSIR_OP_TEX: + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: +@@ -1459,7 +1541,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + break; + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_C: +- case VSIR_OP_SAMPLE: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_C_LZ: +@@ -1467,6 +1548,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + case VSIR_OP_SAMPLE_LOD: + vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg); + break; ++ case VSIR_OP_SAMPLE: ++ vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg); ++ break; + case VSIR_OP_GATHER4_PO: + case VSIR_OP_GATHER4_PO_C: + vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg); +@@ -1691,7 +1775,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages) + { + struct vkd3d_shader_message_context message_context; ++ struct vkd3d_shader_code reflection_data = {0}; + struct shader_dump_data dump_data; ++ struct vsir_program program; + int ret; + + TRACE("compile_info %p, messages %p.\n", compile_info, messages); +@@ -1709,21 +1795,12 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char + fill_shader_dump_data(compile_info, &dump_data); + vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); + +- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) +- { +- FIXME("HLSL support not implemented.\n"); +- ret = VKD3D_ERROR_NOT_IMPLEMENTED; +- } +- else ++ if (!(ret = vsir_parse(compile_info, vkd3d_shader_init_config_flags(), ++ &dump_data, &message_context, &program, &reflection_data))) + { +- uint64_t config_flags = vkd3d_shader_init_config_flags(); +- struct vsir_program program; +- +- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) +- { +- ret = vsir_program_scan(&program, compile_info, &message_context, false); +- vsir_program_cleanup(&program); +- } ++ ret = vsir_program_scan(&program, compile_info, &message_context, false); ++ vkd3d_shader_free_shader_code(&reflection_data); ++ vsir_program_cleanup(&program); + } + + vkd3d_shader_message_context_trace_messages(&message_context); +@@ -1733,12 +1810,13 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char + return ret; + } + +-int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, ++static int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, + uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) + { + struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info; + struct vkd3d_shader_compile_info scan_info; ++ enum vsir_asm_flags asm_flags; + int ret; + + scan_info = *compile_info; +@@ -1748,7 +1826,11 @@ int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader + case VKD3D_SHADER_TARGET_D3D_ASM: + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) + return ret; +- ret = d3d_asm_compile(program, compile_info, out, VSIR_ASM_FLAG_NONE); ++ asm_flags = VSIR_ASM_FLAG_NONE; ++ if (program->shader_version.major < 6 && compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF ++ && compile_info->source_type != VKD3D_SHADER_SOURCE_D3D_BYTECODE) ++ asm_flags |= VSIR_ASM_FLAG_ALLOCATE_TEMPS; ++ ret = d3d_asm_compile(program, compile_info, out, asm_flags, message_context); + break; + + case VKD3D_SHADER_TARGET_D3D_BYTECODE: +@@ -1795,7 +1877,7 @@ int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader + return ret; + } + +-static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, ++static int fx_compile(const struct vkd3d_shader_compile_info *compile_info, + const struct shader_dump_data *dump_data, struct vkd3d_shader_code *out, + struct vkd3d_shader_message_context *message_context) + { +@@ -1810,10 +1892,7 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, + + preprocessed_info = *compile_info; + preprocessed_info.source = preprocessed; +- if (compile_info->target_type == VKD3D_SHADER_TARGET_FX) +- ret = hlsl_compile_effect(&preprocessed_info, message_context, out); +- else +- ret = hlsl_compile_shader(&preprocessed_info, message_context, out); ++ ret = hlsl_compile_effect(&preprocessed_info, message_context, out); + + vkd3d_shader_free_shader_code(&preprocessed); + return ret; +@@ -1841,9 +1920,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, + fill_shader_dump_data(compile_info, &dump_data); + vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); + +- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) ++ if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL ++ && compile_info->target_type == VKD3D_SHADER_TARGET_FX) + { +- ret = compile_hlsl(compile_info, &dump_data, out, &message_context); ++ ret = fx_compile(compile_info, &dump_data, out, &message_context); + } + else if (compile_info->source_type == VKD3D_SHADER_SOURCE_FX) + { +@@ -1856,11 +1936,14 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, + else + { + uint64_t config_flags = vkd3d_shader_init_config_flags(); ++ struct vkd3d_shader_code reflection_data = {0}; + struct vsir_program program; + +- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) ++ if (!(ret = vsir_parse(compile_info, config_flags, &dump_data, ++ &message_context, &program, &reflection_data))) + { +- ret = vsir_program_compile(&program, NULL, config_flags, compile_info, out, &message_context); ++ ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, &message_context); ++ vkd3d_shader_free_shader_code(&reflection_data); + vsir_program_cleanup(&program); + } + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 5bf3728a325..e758c16b3d4 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -937,6 +937,16 @@ enum vkd3d_shader_type + + struct vkd3d_shader_message_context; + ++struct vkd3d_shader_source_list ++{ ++ const char **sources; ++ size_t capacity, count; ++}; ++ ++bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source); ++void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l); ++void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l); ++ + struct vkd3d_shader_version + { + enum vkd3d_shader_type type; +@@ -1013,6 +1023,20 @@ static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_registe + } + } + ++static inline enum vkd3d_shader_register_type vsir_register_type_from_sysval_input( ++ enum vkd3d_shader_sysval_semantic sysval) ++{ ++ switch (sysval) ++ { ++ case VKD3D_SHADER_SV_PRIMITIVE_ID: ++ return VKD3DSPR_PRIMID; ++ case VKD3D_SHADER_SV_COVERAGE: ++ return VKD3DSPR_COVERAGE; ++ default: ++ return VKD3DSPR_INPUT; ++ } ++} ++ + struct vkd3d_shader_dst_param + { + struct vkd3d_shader_register reg; +@@ -1463,12 +1487,21 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_tail(struct + static inline struct vkd3d_shader_instruction *vsir_program_iterator_next( + struct vsir_program_iterator *iterator) + { +- if (iterator->idx < iterator->array->count) ++ if (iterator->idx < iterator->array->count || iterator->idx == SIZE_MAX) + ++iterator->idx; + + return vsir_program_iterator_current(iterator); + } + ++static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev( ++ struct vsir_program_iterator *iterator) ++{ ++ if (iterator->idx != SIZE_MAX) ++ --iterator->idx; ++ ++ return vsir_program_iterator_current(iterator); ++} ++ + /* When insertion takes place, argument `it' is updated to point to the same + * instruction as before the insertion, but all other iterators and pointers + * to the same container are invalidated and cannot be used any more. */ +@@ -1563,6 +1596,7 @@ struct vsir_program + + struct vsir_features features; + ++ struct vkd3d_shader_source_list source_files; + const char **block_names; + size_t block_name_count; + }; +@@ -1572,14 +1606,13 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context); + void vsir_program_cleanup(struct vsir_program *program); +-int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, +- uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); + const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( + const struct vsir_program *program, enum vkd3d_shader_parameter_name name); + bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, + const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type, + enum vsir_normalisation_level normalisation_level); ++enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, ++ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context); + enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context); + enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags, +@@ -1652,11 +1685,12 @@ enum vsir_asm_flags + VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2, + VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4, + VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8, ++ VSIR_ASM_FLAG_ALLOCATE_TEMPS = 0x10, + }; + + enum vkd3d_result d3d_asm_compile(struct vsir_program *program, +- const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_code *out, enum vsir_asm_flags flags); ++ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, ++ enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context); + void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer); + struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list); + void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer); +@@ -1808,8 +1842,9 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, + + int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); +-int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, +- struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); ++int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_message_context *message_context, ++ struct vsir_program *program, struct vkd3d_shader_code *reflection_data); + + static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) + { +-- +2.50.1 +