From e2390e2637df90c73b6e318d1fcf00b98e1ef380 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 7 Aug 2025 07:20:57 +1000 Subject: [PATCH] Updated vkd3d-latest patchset --- ...-3163e589bc41b674c46750bef9a3cbbaa90.patch | 2 +- ...-ba545669cd09682960f5da17b9131780642.patch | 2 +- ...-decc155cca45d7c4a60699990452b921a6e.patch | 2 +- ...-68cd72c7fc7a364ecce87a19617acb382c7.patch | 2 +- ...-a4c25b81c59ae783a94c1b25714eb080231.patch | 2 +- ...-b3e367b099cb65d79c5b0044134a02e7e9c.patch | 2 +- ...-f7866df201e491aa6033cc4618ab21cedd1.patch | 2 +- ...-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch | 2 +- ...-75cb4336ec1a0455c347db05b22dc0fd76d.patch | 2 +- ...-bd3d0f3495f6375901df9ca899accf8bc7a.patch | 4 +- ...-721859005f3edfb3d52bc0f810d1da4fe2e.patch | 193 +++ ...-4bb880f9ed09dab9a87a56bb065f087e92a.patch | 1199 +++++++++++++++++ 12 files changed, 1403 insertions(+), 11 deletions(-) create mode 100644 patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch create mode 100644 patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-3163e589bc41b674c46750bef9a3cbbaa90.patch index d0532455..28b1b97a 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 b180bb5a9e0cc9023e80c703547d23c9d1f0d264 Mon Sep 17 00:00:00 2001 +From 5e283b117ef5762ed1a5d206496824f36366c064 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. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-ba545669cd09682960f5da17b9131780642.patch index 5dbd5f17..af6c84a5 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 e926a5feca44a2f4d87d9b282b9e76a500cf3fec Mon Sep 17 00:00:00 2001 +From 86603c42ee097cc0d96b26e99af07612590ddbaf 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. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-decc155cca45d7c4a60699990452b921a6e.patch index fde53980..53e86ba0 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 13167990b5ba6916b53b88641cf563063124e992 Mon Sep 17 00:00:00 2001 +From d481fc2bef5bd3df8401ca8ae489012ed352dfb5 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. diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-68cd72c7fc7a364ecce87a19617acb382c7.patch index 054c7366..31bca1b3 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 0a466e3e78bebbdc52c77e1dc05c37149e4f8d3b Mon Sep 17 00:00:00 2001 +From 58bfd9084c0a8e46689d8af4e895431b332bf66b 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. diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-a4c25b81c59ae783a94c1b25714eb080231.patch index 023c432e..095eb0d3 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 4b593d3dd67fdc82cd1144ba4b1ac3011c53f797 Mon Sep 17 00:00:00 2001 +From 72eb29f46a99984be3c5b9ed39d97d4efb70ab0d 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. diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-b3e367b099cb65d79c5b0044134a02e7e9c.patch index 8dae6fa8..0591e9aa 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 dbe3f2e5cdbba46a42c74ed3f7ed8e0d0408d0f9 Mon Sep 17 00:00:00 2001 +From 89d9cff1b9eb9ebf984793fa1ec2fdb5456d64a7 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. diff --git a/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch b/patches/vkd3d-latest/0007-Updated-vkd3d-to-f7866df201e491aa6033cc4618ab21cedd1.patch index fb9f6a6c..7c31e7b0 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 e84c7c6b8d6f3c77eeedbe5bfe928968555f0be8 Mon Sep 17 00:00:00 2001 +From b46c70ada9fd7838e808e763c63be3e5aa083579 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. diff --git a/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch b/patches/vkd3d-latest/0008-Updated-vkd3d-to-bb2979aa4c3432bfd5b30ae23de8aaaa57e.patch index b56d5fc2..b1c5da59 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 b81eed1086ba3660ec00639862986ca4544f462f Mon Sep 17 00:00:00 2001 +From df7b896cf93f6a402eb67bed8d0c9e8d2b034d17 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. diff --git a/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch b/patches/vkd3d-latest/0009-Updated-vkd3d-to-75cb4336ec1a0455c347db05b22dc0fd76d.patch index d4227b26..4238d8f1 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 322f54a20a7c189417a2e6d9214e7077023b2495 Mon Sep 17 00:00:00 2001 +From 4f4135dd6ab56dbeeaf09d5018c5fad96909117e 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. diff --git a/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch b/patches/vkd3d-latest/0010-Updated-vkd3d-to-bd3d0f3495f6375901df9ca899accf8bc7a.patch index f7608f0c..704b2071 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 01122d73cdd5d5de8e682877484241177ef0124d Mon Sep 17 00:00:00 2001 +From b06ee0c93136bcd51afded65b491fe7c4ba4cfca 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. @@ -13,7 +13,7 @@ Subject: [PATCH] Updated vkd3d to bd3d0f3495f6375901df9ca899accf8bc7a45345. 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c -index 9d153adff6d..049b9194b5f 100644 +index 03eaab92b39..3f4b55d2916 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -2023,8 +2023,8 @@ START_TEST(msado15) diff --git a/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch b/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch new file mode 100644 index 00000000..2a2d6b74 --- /dev/null +++ b/patches/vkd3d-latest/0011-Updated-vkd3d-to-721859005f3edfb3d52bc0f810d1da4fe2e.patch @@ -0,0 +1,193 @@ +From ee778296e9c6b83d6559431c09b6ff30ea0e44e7 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. + +--- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 6 ++-- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 34 ++++++------------- + libs/vkd3d/libs/vkd3d-shader/ir.c | 7 ++-- + libs/vkd3d/libs/vkd3d-shader/msl.c | 3 ++ + .../libs/vkd3d-shader/vkd3d_shader_main.c | 3 ++ + 5 files changed, 26 insertions(+), 27 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 02e72b28908..c448e000cf9 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -3969,6 +3969,7 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm + + static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&sm6->p.program->instructions); + size_t i, count, base_value_idx = sm6->value_count; + const struct dxil_block *block = &sm6->root_block; + struct vkd3d_shader_instruction *ins; +@@ -4028,9 +4029,8 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + } + + /* Resolve initialiser forward references. */ +- for (i = 0; i < sm6->p.program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &sm6->p.program->instructions.elements[i]; + if (ins->opcode == VSIR_OP_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser) + { + ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser( +@@ -4098,6 +4098,8 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( + + switch (sysval_semantic) + { ++ case VKD3D_SHADER_SV_PRIMITIVE_ID: ++ return VKD3DSPR_PRIMID; + /* VSIR does not use an I/O register for SV_SampleIndex, but its + * signature element has a register index of UINT_MAX and it is + * convenient to return a valid register type here to handle it. */ +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 0b28aa6fe80..5a11547e7a1 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -8282,7 +8282,6 @@ static uint32_t generate_vsir_get_src_swizzle(uint32_t src_writemask, uint32_t d + static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_program *program, + struct hlsl_block *block) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; + struct vkd3d_shader_dst_param *dst_param; + struct vkd3d_shader_src_param *src_param; + struct vkd3d_shader_instruction *ins; +@@ -8292,19 +8291,17 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr + { + const struct hlsl_constant_register *constant_reg = &ctx->constant_defs.regs[i]; + +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) ++ if (!(ins = vsir_program_append(program))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } +- +- ins = &instructions->elements[instructions->count]; + if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VSIR_OP_DEF, 1, 1)) + { ++ vsir_instruction_init(ins, &constant_reg->loc, VSIR_OP_NOP); + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } +- ++instructions->count; + + dst_param = &ins->dst[0]; + vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); +@@ -8328,7 +8325,6 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr + static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, + struct vsir_program *program, struct hlsl_block *block) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; + enum vkd3d_shader_resource_type resource_type; + struct vkd3d_shader_register_range *range; + struct vkd3d_shader_dst_param *dst_param; +@@ -8375,20 +8371,13 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, + break; + } + +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) +- { +- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; +- return; +- } +- +- ins = &instructions->elements[instructions->count]; +- if (!vsir_instruction_init_with_params(program, ins, &var->loc, VSIR_OP_DCL, 0, 0)) ++ if (!(ins = vsir_program_append(program))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } +- ++instructions->count; + ++ vsir_instruction_init(ins, &var->loc, VSIR_OP_DCL); + semantic = &ins->declaration.semantic; + semantic->resource_type = resource_type; + +@@ -8438,26 +8427,25 @@ static enum vkd3d_shader_register_type sm4_get_semantic_register_type(enum vkd3d + return VKD3DSPR_INPUT; + } + +-static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction( +- struct hlsl_ctx *ctx, struct vsir_program *program, +- const struct vkd3d_shader_location *loc, enum vkd3d_shader_opcode opcode, +- unsigned int dst_count, unsigned int src_count) ++static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction(struct hlsl_ctx *ctx, ++ struct vsir_program *program, const struct vkd3d_shader_location *loc, ++ enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; + struct vkd3d_shader_instruction *ins; + +- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) ++ if (!(ins = vsir_program_append(program))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return NULL; + } +- ins = &instructions->elements[instructions->count]; ++ + if (!vsir_instruction_init_with_params(program, ins, loc, opcode, dst_count, src_count)) + { ++ vsir_instruction_init(ins, loc, VSIR_OP_NOP); + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return NULL; + } +- ++instructions->count; ++ + return ins; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 76eb62cfd6f..9d93936ac9e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -12064,8 +12064,11 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t + vsir_transform(&ctx, vsir_program_materialise_phi_ssas_to_temps); + vsir_transform(&ctx, vsir_program_lower_switch_to_selection_ladder); + vsir_transform(&ctx, vsir_program_structurize); +- vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); +- vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); ++ if (compile_info->target_type != VKD3D_SHADER_TARGET_MSL) ++ { ++ vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); ++ vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); ++ } + } + else + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index d07608bd26f..c6e048adb20 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -2196,6 +2196,9 @@ int msl_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/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 2b73771d0a6..891a33d326f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -2119,6 +2119,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( + VKD3D_SHADER_TARGET_SPIRV_TEXT, + # endif + VKD3D_SHADER_TARGET_D3D_ASM, ++#ifdef VKD3D_SHADER_UNSUPPORTED_MSL ++ VKD3D_SHADER_TARGET_MSL, ++#endif + }; + + static const enum vkd3d_shader_target_type fx_types[] = +-- +2.47.2 + diff --git a/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch b/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch new file mode 100644 index 00000000..91b9e9ab --- /dev/null +++ b/patches/vkd3d-latest/0012-Updated-vkd3d-to-4bb880f9ed09dab9a87a56bb065f087e92a.patch @@ -0,0 +1,1199 @@ +From f6c0f58e3277b570650fd4705200e4c2ad3fad18 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. + +--- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 67 ++- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 8 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 + + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 69 ++- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 456 ++++++++++++++++++-- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 21 + + 6 files changed, 561 insertions(+), 61 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index 113ac760731..3199072275b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -2062,7 +2062,7 @@ struct hlsl_ir_node *hlsl_block_add_load_component(struct hlsl_ctx *ctx, struct + return &load->node; + } + +-static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, ++static struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_resource_load *load; +@@ -2098,18 +2098,23 @@ static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, + load->sampling_dim = params->sampling_dim; + if (load->sampling_dim == HLSL_SAMPLER_DIM_GENERIC) + load->sampling_dim = hlsl_deref_get_type(ctx, &load->resource)->sampler_dim; +- return &load->node; ++ return load; + } + + struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) + { +- return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc)); ++ struct hlsl_ir_resource_load *load = hlsl_new_resource_load(ctx, params, loc); ++ ++ if (load && load->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ hlsl_src_from_node(&load->byte_offset, hlsl_block_add_uint_constant(ctx, block, 0, loc)); ++ ++ return append_new_instr(ctx, block, &load->node); + } + +-static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type, +- const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, +- const struct vkd3d_shader_location *loc) ++static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, ++ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, ++ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_resource_store *store; + +@@ -2117,6 +2122,7 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h + return NULL; + init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc); + store->store_type = type; ++ store->writemask = writemask; + + hlsl_copy_deref(ctx, &store->resource, resource); + hlsl_src_from_node(&store->coords, coords); +@@ -2126,9 +2132,9 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h + + void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, +- struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) ++ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) + { +- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc)); ++ append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc)); + } + + struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count, +@@ -2377,6 +2383,19 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index) + return false; + } + ++bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index) ++{ ++ if (index->val.node->type == HLSL_IR_LOAD) ++ { ++ struct hlsl_ir_load *load = hlsl_ir_load(index->val.node); ++ return load->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED; ++ } ++ ++ if (index->val.node->type == HLSL_IR_INDEX) ++ return hlsl_index_chain_has_tgsm_access(hlsl_ir_index(index->val.node)); ++ return false; ++} ++ + static struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) + { +@@ -2648,6 +2667,7 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, + vkd3d_free(dst); + return NULL; + } ++ clone_src(map, &dst->byte_offset, &src->byte_offset); + clone_src(map, &dst->coords, &src->coords); + clone_src(map, &dst->lod, &src->lod); + clone_src(map, &dst->ddx, &src->ddx); +@@ -2668,6 +2688,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, + return NULL; + init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc); + dst->store_type = src->store_type; ++ dst->writemask = src->writemask; + if (!clone_deref(ctx, map, &dst->resource, &src->resource)) + { + vkd3d_free(dst); +@@ -2985,6 +3006,17 @@ bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const + return ret; + } + ++struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) ++{ ++ struct clone_instr_map map = {0}; ++ struct hlsl_ir_node *ret; ++ ++ ret = clone_instr(ctx, &map, instr); ++ vkd3d_free(map.instrs); ++ ++ return ret; ++} ++ + struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, + struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, + const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) +@@ -3219,12 +3251,14 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl + return; + } + +- VKD3D_ASSERT(hlsl_is_numeric_type(type->e.resource.format)); +- VKD3D_ASSERT(type->e.resource.format->e.numeric.type < ARRAY_SIZE(base_types)); + if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) + { + vkd3d_string_buffer_printf(buffer, "Buffer<"); + } ++ else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ { ++ vkd3d_string_buffer_printf(buffer, "StructuredBuffer<"); ++ } + else + { + VKD3D_ASSERT(type->sampler_dim < ARRAY_SIZE(dimensions)); +@@ -3762,6 +3796,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru + dump_deref(buffer, &load->resource); + vkd3d_string_buffer_printf(buffer, ", sampler = "); + dump_deref(buffer, &load->sampler); ++ if (load->byte_offset.node) ++ { ++ vkd3d_string_buffer_printf(buffer, ", byte_offset = "); ++ dump_src(buffer, &load->byte_offset); ++ } + if (load->coords.node) + { + vkd3d_string_buffer_printf(buffer, ", coords = "); +@@ -3800,7 +3839,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru + vkd3d_string_buffer_printf(buffer, ")"); + } + +-static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) ++static void dump_ir_resource_store(struct hlsl_ctx *ctx, ++ struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) + { + static const char *const type_names[] = + { +@@ -3812,6 +3852,8 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str + VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names)); + vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]); + dump_deref(buffer, &store->resource); ++ if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->resource))) ++ vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask)); + if (store->coords.node) + { + vkd3d_string_buffer_printf(buffer, ", coords = "); +@@ -4024,7 +4066,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, + break; + + case HLSL_IR_RESOURCE_STORE: +- dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr)); ++ dump_ir_resource_store(ctx, buffer, hlsl_ir_resource_store(instr)); + break; + + case HLSL_IR_STRING_CONSTANT: +@@ -4230,6 +4272,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) + { + hlsl_cleanup_deref(&load->sampler); + hlsl_cleanup_deref(&load->resource); ++ hlsl_src_remove(&load->byte_offset); + hlsl_src_remove(&load->coords); + hlsl_src_remove(&load->lod); + hlsl_src_remove(&load->ddx); +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index d899c33f8a2..c3002258aa2 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -554,6 +554,7 @@ struct hlsl_ir_var + uint32_t is_param : 1; + uint32_t is_separated_resource : 1; + uint32_t is_synthetic : 1; ++ uint32_t is_tgsm : 1; + uint32_t has_explicit_bind_point : 1; + }; + +@@ -893,7 +894,7 @@ struct hlsl_ir_resource_load + struct hlsl_ir_node node; + enum hlsl_resource_load_type load_type; + struct hlsl_deref resource, sampler; +- struct hlsl_src coords, lod, ddx, ddy, cmp, sample_index, texel_offset; ++ struct hlsl_src byte_offset, coords, lod, ddx, ddy, cmp, sample_index, texel_offset; + enum hlsl_sampler_dim sampling_dim; + }; + +@@ -910,6 +911,7 @@ struct hlsl_ir_resource_store + enum hlsl_resource_store_type store_type; + struct hlsl_deref resource; + struct hlsl_src coords, value; ++ uint8_t writemask; + }; + + struct hlsl_ir_store +@@ -1586,7 +1588,7 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); + void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, +- struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); ++ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc); + void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -1609,6 +1611,7 @@ struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc); + void hlsl_block_cleanup(struct hlsl_block *block); + bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block); ++struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr); + + void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func, + const char *description, const struct hlsl_block *processed_block); +@@ -1709,6 +1712,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls + bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index); + bool hlsl_index_is_resource_access(struct hlsl_ir_index *index); + bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); ++bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index); + + struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, + const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +index d9fd43b5e78..0cdebb8a657 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +@@ -158,6 +158,7 @@ static {return KW_STATIC; } + string {return KW_STRING; } + String {return KW_STRING; } + struct {return KW_STRUCT; } ++StructuredBuffer {return KW_STRUCTUREDBUFFER; } + switch {return KW_SWITCH; } + tbuffer {return KW_TBUFFER; } + (?i:technique) {return KW_TECHNIQUE; } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 40353abd81b..66582e884fe 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -2117,7 +2117,8 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc + VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); + VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count); + +- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, ++ &resource_deref, coords, rhs, writemask, &lhs->loc); + hlsl_cleanup_deref(&resource_deref); + } + else if (matrix_writemask) +@@ -2566,13 +2567,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) + "Ignoring the 'groupshared' modifier in a non-compute shader."); + } + +- if (modifiers & HLSL_STORAGE_GROUPSHARED) +- hlsl_fixme(ctx, &var->loc, "Group shared variables."); +- + /* Mark it as uniform. We need to do this here since synthetic + * variables also get put in the global scope, but shouldn't be + * considered uniforms, and we have no way of telling otherwise. */ +- if (!(modifiers & HLSL_STORAGE_STATIC)) ++ if (!(modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_GROUPSHARED))) + var->storage_modifiers |= HLSL_STORAGE_UNIFORM; + + if (stream_output) +@@ -5065,13 +5063,25 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op + + if (hlsl_deref_get_type(ctx, &dst_deref)->class != HLSL_CLASS_UAV) + { +- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements."); ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Interlocked targets must be UAV or groupshared elements."); + return false; + } + } ++ else if (lhs->type == HLSL_IR_INDEX && hlsl_index_chain_has_tgsm_access(hlsl_ir_index(lhs))) ++ { ++ hlsl_fixme(ctx, loc, "Interlocked operations on indexed groupshared elements."); ++ return false; ++ } ++ else if (lhs->type == HLSL_IR_LOAD && (hlsl_ir_load(lhs)->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED)) ++ { ++ hlsl_init_simple_deref_from_var(&dst_deref, hlsl_ir_load(lhs)->src.var); ++ coords = hlsl_block_add_uint_constant(ctx, params->instrs, 0, loc); ++ } + else + { +- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements."); ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Interlocked targets must be UAV or groupshared elements."); + return false; + } + +@@ -5637,6 +5647,7 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) + case HLSL_SAMPLER_DIM_CUBEARRAY: + case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_RAW_BUFFER: ++ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + /* Offset parameters not supported for these types. */ + return 0; + default: +@@ -6302,6 +6313,7 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block + struct hlsl_ir_node *offset, *rhs; + struct hlsl_deref resource_deref; + unsigned int value_dim; ++ uint32_t writemask; + + if (params->args_count != 2) + { +@@ -6323,11 +6335,12 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); + rhs = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc); ++ writemask = vkd3d_write_mask_from_component_count(value_dim); + + if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) + return false; + +- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, writemask, loc); + hlsl_cleanup_deref(&resource_deref); + + return true; +@@ -6352,7 +6365,7 @@ static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *b + if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc))) + return false; + +- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, 0, loc); + hlsl_cleanup_deref(&so_deref); + + return true; +@@ -6373,7 +6386,7 @@ static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_bl + if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) + return false; + +- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, 0, loc); + hlsl_cleanup_deref(&so_deref); + + return true; +@@ -6554,19 +6567,25 @@ static bool add_object_property_access(struct hlsl_ctx *ctx, + return false; + } + +-static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, +- const struct vkd3d_shader_location *loc) ++static void validate_texture_format_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, ++ struct hlsl_type *format, const struct vkd3d_shader_location *loc) + { +- if (format->class > HLSL_CLASS_VECTOR) +- { +- struct vkd3d_string_buffer *string; ++ struct vkd3d_string_buffer *string; + +- string = hlsl_type_to_string(ctx, format); +- if (string) ++ if (!(string = hlsl_type_to_string(ctx, format))) ++ return; ++ ++ if (dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ { ++ if (!type_contains_only_numerics(format)) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, +- "Texture data type %s is not scalar or vector.", string->buffer); +- hlsl_release_string_buffer(ctx, string); ++ "SRV type %s is not numeric.", string->buffer); + } ++ else if (format->class > HLSL_CLASS_VECTOR) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Texture data type %s is not scalar or vector.", string->buffer); ++ ++ hlsl_release_string_buffer(ctx, string); + } + + static bool check_continue(struct hlsl_ctx *ctx, const struct hlsl_scope *scope, const struct vkd3d_shader_location *loc) +@@ -6834,6 +6853,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + %token KW_STATIC + %token KW_STRING + %token KW_STRUCT ++%token KW_STRUCTUREDBUFFER + %token KW_SWITCH + %token KW_TBUFFER + %token KW_TECHNIQUE +@@ -7921,6 +7941,10 @@ texture_type: + { + $$ = HLSL_SAMPLER_DIM_BUFFER; + } ++ | KW_STRUCTUREDBUFFER ++ { ++ $$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; ++ } + | KW_TEXTURE1D + { + $$ = HLSL_SAMPLER_DIM_1D; +@@ -8144,16 +8168,19 @@ type_no_void: + } + | texture_type + { ++ if ($1 == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Structured buffer type requires an explicit format."); + $$ = hlsl_new_texture_type(ctx, $1, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), 0); + } + | texture_type '<' resource_format '>' + { +- validate_texture_format_type(ctx, $3, &@3); ++ validate_texture_format_type(ctx, $1, $3, &@3); + $$ = hlsl_new_texture_type(ctx, $1, $3, 0); + } + | texture_ms_type '<' resource_format '>' + { +- validate_texture_format_type(ctx, $3, &@3); ++ validate_texture_format_type(ctx, $1, $3, &@3); + + $$ = hlsl_new_texture_type(ctx, $1, $3, 0); + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 5a11547e7a1..dbda72eb30f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -94,6 +94,134 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str + return base_offset; + } + ++static unsigned int base_type_get_byte_size(enum hlsl_base_type t) ++{ ++ switch (t) ++ { ++ case HLSL_TYPE_HALF: ++ case HLSL_TYPE_MIN16UINT: ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_UINT: ++ case HLSL_TYPE_BOOL: ++ return 4; ++ ++ case HLSL_TYPE_DOUBLE: ++ return 8; ++ } ++ ++ return 0; ++} ++ ++static unsigned int hlsl_type_get_packed_alignment(const struct hlsl_type *type) ++{ ++ unsigned int max_align, i; ++ ++ switch (type->class) ++ { ++ case HLSL_CLASS_SCALAR: ++ case HLSL_CLASS_VECTOR: ++ case HLSL_CLASS_MATRIX: ++ return base_type_get_byte_size(type->e.numeric.type); ++ ++ case HLSL_CLASS_ARRAY: ++ return hlsl_type_get_packed_alignment(type->e.array.type); ++ ++ case HLSL_CLASS_STRUCT: ++ for (i = 0, max_align = 0; i < type->e.record.field_count; ++i) ++ { ++ struct hlsl_struct_field *field = &type->e.record.fields[i]; ++ ++ max_align = max(max_align, hlsl_type_get_packed_alignment(field->type)); ++ } ++ ++ return max_align; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++} ++ ++static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) ++{ ++ unsigned int size, i; ++ ++ switch (type->class) ++ { ++ case HLSL_CLASS_SCALAR: ++ case HLSL_CLASS_VECTOR: ++ return type->e.numeric.dimx * base_type_get_byte_size(type->e.numeric.type); ++ ++ case HLSL_CLASS_MATRIX: ++ return type->e.numeric.dimx * type->e.numeric.dimy * base_type_get_byte_size(type->e.numeric.type); ++ ++ case HLSL_CLASS_ARRAY: ++ return type->e.array.elements_count * hlsl_type_get_packed_size(type->e.array.type); ++ ++ case HLSL_CLASS_STRUCT: ++ for (i = 0, size = 0; i < type->e.record.field_count; ++i) ++ { ++ struct hlsl_struct_field *field = &type->e.record.fields[i]; ++ ++ size = align(size, hlsl_type_get_packed_alignment(field->type)) ++ + hlsl_type_get_packed_size(field->type); ++ } ++ size = align(size, hlsl_type_get_packed_alignment(type)); ++ ++ return size; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++} ++ ++static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hlsl_ctx *ctx, ++ struct hlsl_block *block, struct hlsl_ir_node *prev_offset, struct hlsl_ir_node *idx, ++ struct hlsl_type *type, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *idx_offset = NULL, *c; ++ unsigned int field_idx, offset, size, i; ++ ++ switch (type->class) ++ { ++ case HLSL_CLASS_VECTOR: ++ c = hlsl_block_add_uint_constant(ctx, block, base_type_get_byte_size(type->e.numeric.type), loc); ++ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); ++ break; ++ ++ case HLSL_CLASS_MATRIX: ++ size = base_type_get_byte_size(type->e.numeric.type) * hlsl_type_minor_size(type); ++ c = hlsl_block_add_uint_constant(ctx, block, size, loc); ++ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); ++ break; ++ ++ case HLSL_CLASS_ARRAY: ++ size = hlsl_type_get_packed_size(type->e.array.type); ++ c = hlsl_block_add_uint_constant(ctx, block, size, loc); ++ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); ++ break; ++ ++ case HLSL_CLASS_STRUCT: ++ field_idx = hlsl_ir_constant(idx)->value.u[0].u; ++ for (i = 0, offset = 0; i < field_idx; ++i) ++ { ++ struct hlsl_struct_field *field = &type->e.record.fields[i]; ++ ++ offset = align(offset, hlsl_type_get_packed_alignment(field->type)) ++ + hlsl_type_get_packed_size(field->type); ++ } ++ ++ offset = align(offset, hlsl_type_get_packed_alignment(type->e.record.fields[field_idx].type)); ++ idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); ++ break; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++ ++ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, idx_offset, prev_offset); ++} ++ + /* TODO: remove when no longer needed, only used for replace_deref_path_with_offset() */ + static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, unsigned int *offset_component, const struct vkd3d_shader_location *loc) +@@ -1308,6 +1436,73 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return true; + } + ++ if (val->type == HLSL_IR_RESOURCE_LOAD) ++ { ++ struct hlsl_ir_resource_load *parent = hlsl_ir_resource_load(index->val.node); ++ ++ if (parent->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ { ++ if (hlsl_index_is_noncontiguous(index)) ++ { ++ /* For column major matrices, since we have to output a row, ++ * we need to emit dimx loads. */ ++ struct hlsl_ir_node *mat = index->val.node; ++ struct hlsl_deref row_deref; ++ ++ if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) ++ return false; ++ hlsl_init_simple_deref_from_var(&row_deref, var); ++ ++ for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i) ++ { ++ struct hlsl_type *type = parent->node.data_type; ++ struct hlsl_ir_node *c, *c_offset, *idx_offset; ++ struct hlsl_ir_resource_load *column_load; ++ ++ c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc); ++ c_offset = hlsl_block_add_packed_index_offset_append(ctx, ++ block, parent->byte_offset.node, c, type, &instr->loc); ++ type = hlsl_get_element_type_from_path_index(ctx, type, c); ++ ++ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, ++ block, c_offset, index->idx.node, type, &instr->loc); ++ type = hlsl_get_element_type_from_path_index(ctx, type, c_offset); ++ ++ column_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node)); ++ ++ hlsl_src_remove(&column_load->byte_offset); ++ hlsl_src_from_node(&column_load->byte_offset, idx_offset); ++ column_load->node.data_type = type; ++ ++ hlsl_block_add_instr(block, &column_load->node); ++ ++ hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node); ++ } ++ ++ hlsl_block_add_simple_load(ctx, block, var, &instr->loc); ++ } ++ else ++ { ++ struct hlsl_type *type = parent->node.data_type; ++ struct hlsl_ir_resource_load *appended_load; ++ struct hlsl_ir_node *idx_offset; ++ ++ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, block, ++ parent->byte_offset.node, index->idx.node, type, &instr->loc); ++ appended_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node)); ++ type = hlsl_get_element_type_from_path_index(ctx, type, index->idx.node); ++ ++ hlsl_src_remove(&appended_load->byte_offset); ++ hlsl_src_from_node(&appended_load->byte_offset, idx_offset); ++ appended_load->node.data_type = type; ++ ++ hlsl_block_add_instr(block, &appended_load->node); ++ } ++ ++ return true; ++ } ++ } ++ + if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc))) + return false; + hlsl_init_simple_deref_from_var(&var_deref, var); +@@ -1386,6 +1581,67 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s + return false; + } + ++/* Lowers loads from TGSMs to resource loads. */ ++static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++{ ++ struct hlsl_resource_load_params params = {.type = HLSL_RESOURCE_LOAD}; ++ const struct vkd3d_shader_location *loc = &instr->loc; ++ struct hlsl_ir_load *load; ++ struct hlsl_deref *deref; ++ ++ if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type)) ++ return false; ++ load = hlsl_ir_load(instr); ++ deref = &load->src; ++ ++ if (!deref->var->is_tgsm) ++ return false; ++ ++ if (deref->path_len) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM."); ++ return false; ++ } ++ ++ params.resource = hlsl_block_add_simple_load(ctx, block, deref->var, loc); ++ params.format = instr->data_type; ++ params.coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); ++ hlsl_block_add_resource_load(ctx, block, ¶ms, loc); ++ ++ return true; ++} ++ ++/* Lowers stores to TGSMs to resource stores. */ ++static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++{ ++ struct hlsl_ir_store *store; ++ struct hlsl_ir_node *coords; ++ struct hlsl_deref res_deref; ++ struct hlsl_deref *deref; ++ ++ if (instr->type != HLSL_IR_STORE) ++ return false; ++ store = hlsl_ir_store(instr); ++ deref = &store->lhs; ++ ++ if (!deref->var->is_tgsm) ++ return false; ++ ++ if (deref->path_len) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM."); ++ return false; ++ } ++ ++ hlsl_init_simple_deref_from_var(&res_deref, deref->var); ++ coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); ++ ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref, ++ coords, store->rhs.node, store->writemask, &instr->loc); ++ ++ return true; ++} ++ + /* Allocate a unique, ordered index to each instruction, which will be used for + * copy propagation and computing liveness ranges. + * Index 0 means unused, so start at 1. */ +@@ -3217,10 +3473,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + { + struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); + +- if (!load->resource.var->is_uniform) ++ if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, +- "Loaded resource must have a single uniform source."); ++ "Loaded resource must have a single uniform or groupshared source."); + } + else if (validate_component_index_range_from_deref(ctx, &load->resource) == DEREF_VALIDATION_NOT_CONSTANT) + { +@@ -3251,10 +3507,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + { + struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr); + +- if (!store->resource.var->is_uniform) ++ if (!store->resource.var->is_uniform && !store->resource.var->is_tgsm) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, +- "Accessed resource must have a single uniform source."); ++ "Accessed resource must have a single uniform or groupshared source."); + } + else if (validate_component_index_range_from_deref(ctx, &store->resource) == DEREF_VALIDATION_NOT_CONSTANT) + { +@@ -3281,10 +3537,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins + { + struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr); + +- if (!interlocked->dst.var->is_uniform) ++ if (!interlocked->dst.var->is_uniform && !interlocked->dst.var->is_tgsm) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, +- "Accessed resource must have a single uniform source."); ++ "Accessed resource must have a single uniform or groupshared source."); + } + else if (validate_component_index_range_from_deref(ctx, &interlocked->dst) == DEREF_VALIDATION_NOT_CONSTANT) + { +@@ -3482,7 +3738,30 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + hlsl_src_remove(&store->value); + + return true; ++} + ++static void split_resource_load(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, ++ struct hlsl_ir_resource_load *load, const unsigned int idx, struct hlsl_type *type) ++{ ++ struct hlsl_ir_resource_load *vector_load; ++ struct hlsl_ir_node *c, *idx_offset; ++ struct hlsl_block block; ++ ++ hlsl_block_init(&block); ++ ++ c = hlsl_block_add_uint_constant(ctx, &block, idx, &store->node.loc); ++ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, &block, ++ load->byte_offset.node, c, load->node.data_type, &store->node.loc); ++ ++ vector_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &load->node)); ++ hlsl_src_remove(&vector_load->byte_offset); ++ hlsl_src_from_node(&vector_load->byte_offset, idx_offset); ++ vector_load->node.data_type = type; ++ hlsl_block_add_instr(&block, &vector_load->node); ++ ++ hlsl_block_add_store_index(ctx, &block, &store->lhs, c, &vector_load->node, 0, &store->node.loc); ++ ++ list_move_before(&store->node.entry, &block.instrs); + } + + static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -3503,16 +3782,32 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return false; + element_type = hlsl_get_vector_type(ctx, type->e.numeric.type, hlsl_type_minor_size(type)); + +- if (rhs->type != HLSL_IR_LOAD) ++ if (rhs->type != HLSL_IR_LOAD && rhs->type != HLSL_IR_RESOURCE_LOAD) + { + hlsl_fixme(ctx, &instr->loc, "Copying from unsupported node type."); + return false; + } + +- for (i = 0; i < hlsl_type_major_size(type); ++i) ++ if (rhs->type == HLSL_IR_RESOURCE_LOAD) + { +- if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) +- return false; ++ /* As we forbid non-scalar or vector types in non-structured resource ++ * loads, this is specific to structured buffer loads. */ ++ struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(rhs); ++ ++ VKD3D_ASSERT(hlsl_deref_get_type(ctx, &load->resource)->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER); ++ ++ for (i = 0; i < hlsl_type_major_size(type); ++i) ++ { ++ split_resource_load(ctx, store, load, i, element_type); ++ } ++ } ++ else ++ { ++ for (i = 0; i < hlsl_type_major_size(type); ++i) ++ { ++ if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) ++ return false; ++ } + } + + list_remove(&store->node.entry); +@@ -5486,6 +5781,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop + deref_mark_last_read(&load->sampler, last_read); + } + ++ if (load->byte_offset.node) ++ load->byte_offset.node->last_read = last_read; + if (load->coords.node) + load->coords.node->last_read = last_read; + if (load->texel_offset.node) +@@ -5867,6 +6164,9 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls + load = hlsl_ir_resource_load(instr); + var = load->resource.var; + ++ if (var->is_tgsm) ++ return false; ++ + regset = hlsl_deref_get_regset(ctx, &load->resource); + if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) + return false; +@@ -5935,7 +6235,7 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + { + struct hlsl_ir_load *load = hlsl_ir_load(instr); + +- if (!load->src.var->is_uniform) ++ if (!load->src.var->is_uniform && !load->src.var->is_tgsm) + return false; + + /* These will are handled by validate_static_object_references(). */ +@@ -6459,7 +6759,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block + { + LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) + { +- if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform)) ++ if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform || var->is_tgsm)) + memset(var->regs, 0, sizeof(var->regs)); + } + } +@@ -7109,6 +7409,27 @@ static void allocate_stream_outputs(struct hlsl_ctx *ctx) + } + } + ++static void allocate_tgsms(struct hlsl_ctx *ctx) ++{ ++ struct hlsl_ir_var *var; ++ struct hlsl_reg *reg; ++ uint32_t index = 0; ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (!var->is_tgsm || !var->bind_count[HLSL_REGSET_NUMERIC]) ++ continue; ++ ++ reg = &var->regs[HLSL_REGSET_NUMERIC]; ++ reg->space = 0; ++ reg->index = index; ++ reg->id = index; ++ reg->allocated = true; ++ ++ ++index; ++ } ++} ++ + bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + unsigned int *start, unsigned int *count) + { +@@ -8700,6 +9021,15 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p + *writemask = hlsl_reg.writemask; + } + } ++ else if (var->is_tgsm) ++ { ++ VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated); ++ reg->type = VKD3DSPR_GROUPSHAREDMEM; ++ reg->dimension = VSIR_DIMENSION_VEC4; ++ reg->idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; ++ reg->idx_count = 1; ++ *writemask = (1u << data_type->e.numeric.dimx) - 1; ++ } + else + { + return sm4_generate_vsir_numeric_reg_from_deref(ctx, program, reg, writemask, deref); +@@ -10906,6 +11236,8 @@ static bool sm4_generate_vsir_instr_store(struct hlsl_ctx *ctx, + struct vkd3d_shader_src_param *src_param; + struct vkd3d_shader_instruction *ins; + ++ VKD3D_ASSERT(!store->lhs.var->is_tgsm); ++ + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) + return false; + +@@ -10940,6 +11272,7 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr + struct vkd3d_shader_instruction *ins; + struct hlsl_constant_value value; + ++ VKD3D_ASSERT(!load->src.var->is_tgsm); + VKD3D_ASSERT(hlsl_is_numeric_type(type)); + if (type->e.numeric.type == HLSL_TYPE_BOOL && var_is_user_input(version, load->src.var)) + { +@@ -10984,8 +11317,8 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, + struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &store->resource); + struct hlsl_ir_node *coords = store->coords.node, *value = store->value.node; + struct hlsl_ir_node *instr = &store->node; ++ bool tgsm = store->resource.var->is_tgsm; + struct vkd3d_shader_instruction *ins; +- unsigned int writemask; + + if (store->store_type != HLSL_RESOURCE_STORE) + { +@@ -11012,9 +11345,9 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, + return true; + } + +- if (!store->resource.var->is_uniform) ++ if (!store->resource.var->is_uniform && !tgsm) + { +- hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable."); ++ hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform non-groupshared resource variable."); + return false; + } + +@@ -11024,14 +11357,19 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, + return false; + } + +- if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) ++ if (tgsm && !hlsl_is_numeric_type(resource_type)) ++ { ++ hlsl_fixme(ctx, &store->node.loc, "Store to structured TGSM."); ++ return false; ++ } ++ ++ if (tgsm || resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + { + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_RAW, 1, 2))) + return false; + +- writemask = vkd3d_write_mask_from_component_count(value->data_type->e.numeric.dimx); +- if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, +- &ins->dst[0], &store->resource, &instr->loc, writemask)) ++ if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, &ins->dst[0], ++ &store->resource, &instr->loc, store->writemask)) + return false; + } + else +@@ -11092,7 +11430,6 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + const struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &load->resource); + bool uav = (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS); + const struct vkd3d_shader_version *version = &program->shader_version; +- bool raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER; + const struct hlsl_ir_node *sample_index = load->sample_index.node; + const struct hlsl_ir_node *texel_offset = load->texel_offset.node; + const struct hlsl_ir_node *coords = load->coords.node; +@@ -11100,16 +11437,33 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + const struct hlsl_deref *resource = &load->resource; + const struct hlsl_ir_node *instr = &load->node; + enum hlsl_sampler_dim dim = load->sampling_dim; ++ bool tgsm = load->resource.var->is_tgsm; + struct vkd3d_shader_instruction *ins; + enum vkd3d_shader_opcode opcode; +- bool multisampled; ++ bool multisampled, raw; + + VKD3D_ASSERT(load->load_type == HLSL_RESOURCE_LOAD); + ++ if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ { ++ hlsl_fixme(ctx, &load->node.loc, "Structured buffer loads."); ++ return false; ++ } ++ + multisampled = resource_type->class == HLSL_CLASS_TEXTURE + && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); + ++ if (!tgsm) ++ { ++ raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER; ++ } ++ else if (!(raw = hlsl_is_numeric_type(resource_type))) ++ { ++ hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); ++ return false; ++ } ++ + if (uav) + opcode = VSIR_OP_LD_UAV_TYPED; + else if (raw) +@@ -11130,7 +11484,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); + +- if (!uav) ++ if (!uav && !tgsm) + { + /* Mipmap level is in the last component in the IR, but needs to be in + * the W component in the instruction. */ +@@ -11401,7 +11755,7 @@ static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, + return false; + } + +- if (!load->resource.var->is_uniform) ++ if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm) + { + hlsl_fixme(ctx, &load->node.loc, "Load from non-uniform resource variable."); + return false; +@@ -11761,7 +12115,7 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se + { + LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) + { +- if (var->is_uniform || var->is_input_semantic || var->is_output_semantic) ++ if (var->is_uniform || var->is_tgsm || var->is_input_semantic || var->is_output_semantic) + continue; + if (!var->regs[HLSL_REGSET_NUMERIC].allocated) + continue; +@@ -12161,6 +12515,9 @@ static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_t + { + const struct hlsl_type *format = type->e.resource.format; + ++ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ return VSIR_DATA_MIXED; ++ + switch (format->e.numeric.type) + { + case HLSL_TYPE_DOUBLE: +@@ -12299,6 +12656,34 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + } + } + ++static void sm4_generate_vsir_add_dcl_tgsm(struct hlsl_ctx *ctx, ++ struct vsir_program *program, const struct hlsl_ir_var *var) ++{ ++ struct vkd3d_shader_dst_param *dst_param; ++ struct vkd3d_shader_instruction *ins; ++ ++ if (!hlsl_is_numeric_type(var->data_type)) ++ { ++ hlsl_fixme(ctx, &var->loc, "Structured TGSM declaration."); ++ return; ++ } ++ ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VSIR_OP_DCL_TGSM_RAW, 0, 0))) ++ { ++ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; ++ return; ++ } ++ ++ dst_param = &ins->declaration.tgsm_raw.reg; ++ ++ vsir_dst_param_init(dst_param, VKD3DSPR_GROUPSHAREDMEM, VSIR_DATA_F32, 1); ++ dst_param->reg.dimension = VSIR_DIMENSION_NONE; ++ dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; ++ ++ ins->declaration.tgsm_raw.byte_count = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * 4; ++ ins->declaration.tgsm_raw.zero_init = false; ++} ++ + static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct hlsl_ir_var *var) + { +@@ -12327,6 +12712,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, + struct extern_resource *extern_resources; + unsigned int extern_resources_count; + const struct hlsl_buffer *cbuffer; ++ const struct hlsl_ir_var *var; + + if (version->type == VKD3D_SHADER_TYPE_COMPUTE) + { +@@ -12377,10 +12763,14 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, + } + sm4_free_extern_resources(extern_resources, extern_resources_count); + +- if (version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { +- const struct hlsl_ir_var *var; ++ if (var->is_tgsm && var->regs[HLSL_REGSET_NUMERIC].allocated) ++ sm4_generate_vsir_add_dcl_tgsm(ctx, program, var); ++ } + ++ if (version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) ++ { + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->bind_count[HLSL_REGSET_STREAM_OUTPUTS]) +@@ -12489,6 +12879,9 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) + { + const struct hlsl_type *format = type->e.resource.format; + ++ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ return D3D_RETURN_TYPE_MIXED; ++ + switch (format->e.numeric.type) + { + case HLSL_TYPE_DOUBLE: +@@ -13594,6 +13987,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v + lower_ir(ctx, lower_matrix_swizzles, body); + lower_ir(ctx, lower_index_loads, body); + ++ lower_ir(ctx, lower_tgsm_loads, body); ++ lower_ir(ctx, lower_tgsm_stores, body); ++ + if (entry_func->return_var) + { + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) +@@ -13903,7 +14299,14 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) + { + if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) ++ { + prepend_uniform_copy(ctx, &global_uniform_block, var); ++ } ++ else if (var->storage_modifiers & HLSL_STORAGE_GROUPSHARED) ++ { ++ var->is_tgsm = 1; ++ list_add_tail(&ctx->extern_vars, &var->extern_entry); ++ } + } + + process_entry_function(ctx, &semantic_vars, &body, &global_uniform_block, entry_func); +@@ -13932,6 +14335,7 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info + allocate_objects(ctx, &semantic_vars, HLSL_REGSET_TEXTURES); + allocate_objects(ctx, &semantic_vars, HLSL_REGSET_UAVS); + allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS); ++ allocate_tgsms(ctx); + } + + if (TRACE_ON()) +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index ed19faf945b..ea15c1a9ad5 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -3910,6 +3910,23 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s + write_sm4_instruction(tpf, &instr); + } + ++static void tpf_dcl_tgsm_raw(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) ++{ ++ const struct vkd3d_shader_tgsm_raw *tgsm = &ins->declaration.tgsm_raw; ++ struct sm4_instruction instr = ++ { ++ .opcode = VKD3D_SM5_OP_DCL_TGSM_RAW, ++ ++ .dsts[0] = tgsm->reg, ++ .dst_count = 1, ++ ++ .idx[0] = tgsm->byte_count, ++ .idx_count = 1, ++ }; ++ ++ write_sm4_instruction(tpf, &instr); ++} ++ + static void write_sm4_dcl_global_flags(const struct tpf_compiler *tpf, uint32_t flags) + { + struct sm4_instruction instr = +@@ -4199,6 +4216,10 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + tpf_dcl_sampler(tpf, ins); + break; + ++ case VSIR_OP_DCL_TGSM_RAW: ++ tpf_dcl_tgsm_raw(tpf, ins); ++ break; ++ + case VSIR_OP_DCL: + case VSIR_OP_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_UAV_RAW: +-- +2.47.2 +