diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-2ac7f650a196e47a18ea1957eac5953255c.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-2ac7f650a196e47a18ea1957eac5953255c.patch index 749b83f6..5282141c 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-2ac7f650a196e47a18ea1957eac5953255c.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-2ac7f650a196e47a18ea1957eac5953255c.patch @@ -1,4 +1,4 @@ -From 8197153f5099eec17d017d9369b8e23a37963dba Mon Sep 17 00:00:00 2001 +From 77787c434c8a936f72753bf770273d39316c9917 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 3 Sep 2024 07:18:49 +1000 Subject: [PATCH] Updated vkd3d to 2ac7f650a196e47a18ea1957eac5953255cf424d. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-a2aeb3a1421c5540b7f4d0e68ec3ff211e1.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-a2aeb3a1421c5540b7f4d0e68ec3ff211e1.patch index b98184e5..ae4242aa 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-a2aeb3a1421c5540b7f4d0e68ec3ff211e1.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-a2aeb3a1421c5540b7f4d0e68ec3ff211e1.patch @@ -1,4 +1,4 @@ -From f7442f283e45fca56616dc6dbbd9db472bebef3a Mon Sep 17 00:00:00 2001 +From 1b1edbf05da10281bbb9b0ef228752ec9c21ab28 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 24 Sep 2024 08:29:40 +1000 Subject: [PATCH] Updated vkd3d to a2aeb3a1421c5540b7f4d0e68ec3ff211e15f646. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-e8b14d765dbebae32d83aa5d2a7521932d9.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-e8b14d765dbebae32d83aa5d2a7521932d9.patch index aa8c10cb..b61ca4d5 100644 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-e8b14d765dbebae32d83aa5d2a7521932d9.patch +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-e8b14d765dbebae32d83aa5d2a7521932d9.patch @@ -1,4 +1,4 @@ -From 06ac76ef4dafe44bc7c05d3ccea10f773f6dfc47 Mon Sep 17 00:00:00 2001 +From 3bca6a7e645ca8f48f2ec73a13b63a412cb7f2be Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 25 Sep 2024 07:29:36 +1000 Subject: [PATCH] Updated vkd3d to e8b14d765dbebae32d83aa5d2a7521932d9943f9. diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-f28d39b609036ce9bc3a4baaf6cda012fc2.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-f28d39b609036ce9bc3a4baaf6cda012fc2.patch index ca2dee9e..62ab691e 100644 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-f28d39b609036ce9bc3a4baaf6cda012fc2.patch +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-f28d39b609036ce9bc3a4baaf6cda012fc2.patch @@ -1,4 +1,4 @@ -From 1a7fe5c66183d5193808f6280e25a4b6ccd15a04 Mon Sep 17 00:00:00 2001 +From 9ddf8bb46c1ecb41b9c5dc6abd3e4148ba2db043 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 1 Oct 2024 21:50:23 +1000 Subject: [PATCH] Updated vkd3d to f28d39b609036ce9bc3a4baaf6cda012fc2e3002. diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-ae27fded1a039fda84b526cd9bd7b64aeb5.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-ae27fded1a039fda84b526cd9bd7b64aeb5.patch index 3c2cd368..280eadbe 100644 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-ae27fded1a039fda84b526cd9bd7b64aeb5.patch +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-ae27fded1a039fda84b526cd9bd7b64aeb5.patch @@ -1,4 +1,4 @@ -From 10e8e5d62381bc132ac64fd9a5a7f1e39b3c843b Mon Sep 17 00:00:00 2001 +From f12a3f3127f1bb47c8b2e6b7b9a5eaad1434ae3d Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 3 Oct 2024 10:05:51 +1000 Subject: [PATCH] Updated vkd3d to ae27fded1a039fda84b526cd9bd7b64aeb5573b5. diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-25232f2b2b35bcf1c265bc380c31cd1d32e.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-25232f2b2b35bcf1c265bc380c31cd1d32e.patch new file mode 100644 index 00000000..716d1c5a --- /dev/null +++ b/patches/vkd3d-latest/0006-Updated-vkd3d-to-25232f2b2b35bcf1c265bc380c31cd1d32e.patch @@ -0,0 +1,893 @@ +From baf455d7ecc67cac7c6c450535226f67d3af6c21 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 5 Oct 2024 11:26:42 +1000 +Subject: [PATCH] Updated vkd3d to 25232f2b2b35bcf1c265bc380c31cd1d32e4f4a6. + +--- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 7 +- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 474 +++++++++++++++++- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 4 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 42 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 36 ++ + .../libs/vkd3d-shader/vkd3d_shader_main.c | 7 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 2 + + 7 files changed, 553 insertions(+), 19 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 165ab222fca..d4296ef4bc5 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -4864,8 +4864,10 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg); ++ /* Differently from other descriptors, constant buffers require an ++ * additional index, used to index within the constant buffer itself. */ ++ src_param->reg.idx_count = 3; + register_index_address_init(&src_param->reg.idx[2], operands[1], sm6); +- VKD3D_ASSERT(src_param->reg.idx_count == 3); + + type = sm6_type_get_scalar_type(dst->type, 0); + VKD3D_ASSERT(type); +@@ -4964,8 +4966,7 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int + dst->u.handle.d = d; + + reg = &dst->u.handle.reg; +- /* Set idx_count to 3 for use with load/store instructions. */ +- vsir_register_init(reg, d->reg_type, d->reg_data_type, 3); ++ vsir_register_init(reg, d->reg_type, d->reg_data_type, 2); + reg->dimension = VSIR_DIMENSION_VEC4; + reg->idx[0].offset = id; + register_index_address_init(®->idx[1], operands[2], sm6); +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index e2bcca56f05..c2fb58c55e6 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -18,6 +18,13 @@ + + #include "vkd3d_shader_private.h" + ++struct glsl_resource_type_info ++{ ++ size_t coord_size; ++ bool shadow; ++ const char *sampler_type; ++}; ++ + struct glsl_src + { + struct vkd3d_string_buffer *str; +@@ -52,6 +59,7 @@ struct vkd3d_glsl_generator + const struct vkd3d_shader_interface_info *interface_info; + const struct vkd3d_shader_descriptor_offset_info *offset_info; + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info; ++ const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; + }; + + static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error( +@@ -87,11 +95,81 @@ static const char *shader_glsl_get_prefix(enum vkd3d_shader_type type) + } + } + ++static const struct glsl_resource_type_info *shader_glsl_get_resource_type_info(enum vkd3d_shader_resource_type t) ++{ ++ static const struct glsl_resource_type_info info[] = ++ { ++ {0, 0, "samplerNone"}, /* VKD3D_SHADER_RESOURCE_NONE */ ++ {1, 0, "samplerBuffer"}, /* VKD3D_SHADER_RESOURCE_BUFFER */ ++ {1, 1, "sampler1D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1D */ ++ {2, 1, "sampler2D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2D */ ++ {2, 0, "sampler2DMS"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMS */ ++ {3, 0, "sampler3D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_3D */ ++ {3, 1, "samplerCube"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBE */ ++ {2, 1, "sampler1DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ ++ {3, 1, "sampler2DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ ++ {3, 0, "sampler2DMSArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ ++ {4, 1, "samplerCubeArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */ ++ }; ++ ++ if (!t || t >= ARRAY_SIZE(info)) ++ return NULL; ++ ++ return &info[t]; ++} ++ ++static const struct vkd3d_shader_descriptor_info1 *shader_glsl_get_descriptor(struct vkd3d_glsl_generator *gen, ++ enum vkd3d_shader_descriptor_type type, unsigned int idx, unsigned int space) ++{ ++ const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info; ++ ++ for (unsigned int i = 0; i < info->descriptor_count; ++i) ++ { ++ const struct vkd3d_shader_descriptor_info1 *d = &info->descriptors[i]; ++ ++ if (d->type == type && d->register_space == space && d->register_index == idx) ++ return d; ++ } ++ ++ return NULL; ++} ++ ++static const struct vkd3d_shader_descriptor_info1 *shader_glsl_get_descriptor_by_id( ++ struct vkd3d_glsl_generator *gen, enum vkd3d_shader_descriptor_type type, unsigned int id) ++{ ++ const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info; ++ ++ for (unsigned int i = 0; i < info->descriptor_count; ++i) ++ { ++ const struct vkd3d_shader_descriptor_info1 *d = &info->descriptors[i]; ++ ++ if (d->type == type && d->register_id == id) ++ return d; ++ } ++ ++ return NULL; ++} ++ + static void shader_glsl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int indent) + { + vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, ""); + } + ++static void shader_glsl_print_combined_sampler_name(struct vkd3d_string_buffer *buffer, ++ struct vkd3d_glsl_generator *gen, unsigned int resource_index, ++ unsigned int resource_space, unsigned int sampler_index, unsigned int sampler_space) ++{ ++ vkd3d_string_buffer_printf(buffer, "%s_t_%u", gen->prefix, resource_index); ++ if (resource_space) ++ vkd3d_string_buffer_printf(buffer, "_%u", resource_space); ++ if (sampler_index != VKD3D_SHADER_DUMMY_SAMPLER_INDEX) ++ { ++ vkd3d_string_buffer_printf(buffer, "_s_%u", sampler_index); ++ if (sampler_space) ++ vkd3d_string_buffer_printf(buffer, "_%u", sampler_space); ++ } ++} ++ + static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, + struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_register *reg) + { +@@ -360,14 +438,12 @@ static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_gener + return write_mask; + } + +-static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( +- struct vkd3d_glsl_generator *gen, struct glsl_dst *dst, const char *format, ...) ++static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_glsl_generator *gen, ++ struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, va_list args) + { +- const struct vkd3d_shader_register *dst_reg = &dst->vsir->reg; + struct vkd3d_string_buffer *buffer = gen->buffer; + uint32_t modifiers = dst->vsir->modifiers; + bool close = true; +- va_list args; + + if (dst->vsir->shift) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +@@ -381,11 +457,11 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( + if (modifiers & VKD3DSPDM_SATURATE) + vkd3d_string_buffer_printf(buffer, "clamp("); + +- switch (dst_reg->data_type) ++ switch (data_type) + { + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled destination register data type %#x.", dst_reg->data_type); ++ "Internal compiler error: Unhandled destination register data type %#x.", data_type); + /* fall through */ + case VKD3D_DATA_FLOAT: + close = false; +@@ -398,9 +474,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( + break; + } + +- va_start(args, format); + vkd3d_string_buffer_vprintf(buffer, format, args); +- va_end(args); + + if (close) + vkd3d_string_buffer_printf(buffer, ")"); +@@ -409,6 +483,26 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( + vkd3d_string_buffer_printf(buffer, ";\n"); + } + ++static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( ++ struct vkd3d_glsl_generator *gen, struct glsl_dst *dst, const char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ shader_glsl_vprint_assignment(gen, dst, dst->vsir->reg.data_type, format, args); ++ va_end(args); ++} ++ ++static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3d_glsl_generator *gen, ++ struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ shader_glsl_vprint_assignment(gen, dst, data_type, format, args); ++ va_end(args); ++} ++ + static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + shader_glsl_print_indent(gen->buffer, gen->indent); +@@ -561,6 +655,159 @@ static void shader_glsl_endif(struct vkd3d_glsl_generator *gen) + vkd3d_string_buffer_printf(gen->buffer, "}\n"); + } + ++static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ const struct glsl_resource_type_info *resource_type_info; ++ unsigned int resource_id, resource_idx, resource_space; ++ const struct vkd3d_shader_descriptor_info1 *d; ++ enum vkd3d_shader_component_type sampled_type; ++ enum vkd3d_shader_resource_type resource_type; ++ struct vkd3d_string_buffer *fetch; ++ enum vkd3d_data_type data_type; ++ struct glsl_src coord, lod; ++ struct glsl_dst dst; ++ uint32_t coord_mask; ++ ++ if (vkd3d_shader_instruction_has_texel_offset(ins)) ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled texel fetch offset."); ++ ++ if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, ++ "Descriptor indexing is not supported."); ++ ++ resource_id = ins->src[1].reg.idx[0].offset; ++ resource_idx = ins->src[1].reg.idx[1].offset; ++ if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) ++ { ++ resource_type = d->resource_type; ++ resource_space = d->register_space; ++ sampled_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); ++ data_type = vkd3d_data_type_from_component_type(sampled_type); ++ } ++ else ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Undeclared resource descriptor %u.", resource_id); ++ resource_space = 0; ++ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; ++ data_type = VKD3D_DATA_FLOAT; ++ } ++ ++ if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) ++ { ++ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); ++ } ++ else ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled resource type %#x.", resource_type); ++ coord_mask = vkd3d_write_mask_from_component_count(2); ++ } ++ ++ glsl_dst_init(&dst, gen, ins, &ins->dst[0]); ++ glsl_src_init(&coord, gen, &ins->src[0], coord_mask); ++ glsl_src_init(&lod, gen, &ins->src[0], VKD3DSP_WRITEMASK_3); ++ fetch = vkd3d_string_buffer_get(&gen->string_buffers); ++ ++ vkd3d_string_buffer_printf(fetch, "texelFetch("); ++ shader_glsl_print_combined_sampler_name(fetch, gen, resource_idx, ++ resource_space, VKD3D_SHADER_DUMMY_SAMPLER_INDEX, 0); ++ vkd3d_string_buffer_printf(fetch, ", %s", coord.str->buffer); ++ if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) ++ vkd3d_string_buffer_printf(fetch, ", %s", lod.str->buffer); ++ vkd3d_string_buffer_printf(fetch, ")"); ++ shader_glsl_print_swizzle(fetch, ins->src[1].swizzle, ins->dst[0].write_mask); ++ ++ shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", fetch->buffer); ++ ++ vkd3d_string_buffer_release(&gen->string_buffers, fetch); ++ glsl_src_cleanup(&lod, &gen->string_buffers); ++ glsl_src_cleanup(&coord, &gen->string_buffers); ++ glsl_dst_cleanup(&dst, &gen->string_buffers); ++} ++ ++static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ const struct glsl_resource_type_info *resource_type_info; ++ unsigned int resource_id, resource_idx, resource_space; ++ unsigned int sampler_id, sampler_idx, sampler_space; ++ const struct vkd3d_shader_descriptor_info1 *d; ++ enum vkd3d_shader_component_type sampled_type; ++ enum vkd3d_shader_resource_type resource_type; ++ struct vkd3d_string_buffer *sample; ++ enum vkd3d_data_type data_type; ++ struct glsl_src coord; ++ struct glsl_dst dst; ++ uint32_t coord_mask; ++ ++ if (vkd3d_shader_instruction_has_texel_offset(ins)) ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled texel sample offset."); ++ ++ if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr ++ || ins->src[2].reg.idx[0].rel_addr || ins->src[2].reg.idx[1].rel_addr) ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, ++ "Descriptor indexing is not supported."); ++ ++ resource_id = ins->src[1].reg.idx[0].offset; ++ resource_idx = ins->src[1].reg.idx[1].offset; ++ if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) ++ { ++ resource_type = d->resource_type; ++ resource_space = d->register_space; ++ sampled_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); ++ data_type = vkd3d_data_type_from_component_type(sampled_type); ++ } ++ else ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Undeclared resource descriptor %u.", resource_id); ++ resource_space = 0; ++ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; ++ data_type = VKD3D_DATA_FLOAT; ++ } ++ ++ if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) ++ { ++ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); ++ } ++ else ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled resource type %#x.", resource_type); ++ coord_mask = vkd3d_write_mask_from_component_count(2); ++ } ++ ++ sampler_id = ins->src[2].reg.idx[0].offset; ++ sampler_idx = ins->src[2].reg.idx[1].offset; ++ if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_id))) ++ { ++ sampler_space = d->register_space; ++ } ++ else ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Undeclared sampler descriptor %u.", sampler_id); ++ sampler_space = 0; ++ } ++ ++ glsl_dst_init(&dst, gen, ins, &ins->dst[0]); ++ glsl_src_init(&coord, gen, &ins->src[0], coord_mask); ++ sample = vkd3d_string_buffer_get(&gen->string_buffers); ++ ++ vkd3d_string_buffer_printf(sample, "texture("); ++ shader_glsl_print_combined_sampler_name(sample, gen, resource_idx, resource_space, sampler_idx, sampler_space); ++ vkd3d_string_buffer_printf(sample, ", %s)", coord.str->buffer); ++ shader_glsl_print_swizzle(sample, ins->src[1].swizzle, ins->dst[0].write_mask); ++ ++ shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", sample->buffer); ++ ++ vkd3d_string_buffer_release(&gen->string_buffers, sample); ++ glsl_src_cleanup(&coord, &gen->string_buffers); ++ glsl_dst_cleanup(&dst, &gen->string_buffers); ++} ++ + static void shader_glsl_unary_op(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_instruction *ins, const char *op) + { +@@ -617,6 +864,37 @@ static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3 + glsl_dst_cleanup(&dst, &gen->string_buffers); + } + ++static void shader_glsl_mul_extended(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ struct glsl_src src[2]; ++ struct glsl_dst dst; ++ uint32_t mask; ++ ++ if (ins->dst[0].reg.type != VKD3DSPR_NULL) ++ { ++ /* FIXME: imulExtended()/umulExtended() from ARB_gpu_shader5/GLSL 4.00+. */ ++ mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); ++ shader_glsl_print_assignment(gen, &dst, ""); ++ glsl_dst_cleanup(&dst, &gen->string_buffers); ++ ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled 64-bit integer multiplication."); ++ } ++ ++ if (ins->dst[1].reg.type != VKD3DSPR_NULL) ++ { ++ mask = glsl_dst_init(&dst, gen, ins, &ins->dst[1]); ++ glsl_src_init(&src[0], gen, &ins->src[0], mask); ++ glsl_src_init(&src[1], gen, &ins->src[1], mask); ++ ++ shader_glsl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer); ++ ++ glsl_src_cleanup(&src[1], &gen->string_buffers); ++ glsl_src_cleanup(&src[0], &gen->string_buffers); ++ glsl_dst_cleanup(&dst, &gen->string_buffers); ++ } ++} ++ + static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, + enum vkd3d_shader_sysval_semantic sysval, unsigned int idx) + { +@@ -817,6 +1095,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + shader_glsl_cast(gen, ins, "uint", "uvec"); + break; + case VKD3DSIH_GEO: ++ case VKD3DSIH_IGE: + shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); + break; + case VKD3DSIH_IF: +@@ -825,6 +1104,13 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VKD3DSIH_MAD: + shader_glsl_intrinsic(gen, ins, "fma"); + break; ++ case VKD3DSIH_ILT: ++ case VKD3DSIH_LTO: ++ shader_glsl_relop(gen, ins, "<", "lessThan"); ++ break; ++ case VKD3DSIH_IMUL: ++ shader_glsl_mul_extended(gen, ins); ++ break; + case VKD3DSIH_ISHL: + shader_glsl_binop(gen, ins, "<<"); + break; +@@ -832,9 +1118,6 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VKD3DSIH_USHR: + shader_glsl_binop(gen, ins, ">>"); + break; +- case VKD3DSIH_LTO: +- shader_glsl_relop(gen, ins, "<", "lessThan"); +- break; + case VKD3DSIH_MAX: + shader_glsl_intrinsic(gen, ins, "max"); + break; +@@ -849,6 +1132,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VKD3DSIH_UTOF: + shader_glsl_cast(gen, ins, "float", "vec"); + break; ++ case VKD3DSIH_LD: ++ shader_glsl_ld(gen, ins); ++ break; + case VKD3DSIH_LOG: + shader_glsl_intrinsic(gen, ins, "log2"); + break; +@@ -885,6 +1171,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VKD3DSIH_RSQ: + shader_glsl_intrinsic(gen, ins, "inversesqrt"); + break; ++ case VKD3DSIH_SAMPLE: ++ shader_glsl_sample(gen, ins); ++ break; + case VKD3DSIH_SQRT: + shader_glsl_intrinsic(gen, ins, "sqrt"); + break; +@@ -1012,8 +1301,156 @@ static void shader_glsl_generate_cbv_declaration(struct vkd3d_glsl_generator *ge + binding->binding, prefix, cbv->register_id, prefix, cbv->register_id, size); + } + ++static bool shader_glsl_get_combined_sampler_binding(const struct vkd3d_glsl_generator *gen, ++ const struct vkd3d_shader_combined_resource_sampler_info *crs, ++ enum vkd3d_shader_resource_type resource_type, unsigned int *binding_idx) ++{ ++ const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; ++ const struct vkd3d_shader_combined_resource_sampler *s; ++ enum vkd3d_shader_binding_flag resource_type_flag; ++ unsigned int i; ++ ++ if (!interface_info) ++ return false; ++ ++ resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER ++ ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; ++ ++ for (i = 0; i < interface_info->combined_sampler_count; ++i) ++ { ++ s = &interface_info->combined_samplers[i]; ++ ++ if (s->resource_space != crs->resource_space) ++ continue; ++ if (s->resource_index != crs->resource_index) ++ continue; ++ if (crs->sampler_index != VKD3D_SHADER_DUMMY_SAMPLER_INDEX) ++ { ++ if (s->sampler_space != crs->sampler_space) ++ continue; ++ if (s->sampler_index != crs->sampler_index) ++ continue; ++ } ++ if (!shader_glsl_check_shader_visibility(gen, s->shader_visibility)) ++ continue; ++ if (!(s->flags & resource_type_flag)) ++ continue; ++ *binding_idx = i; ++ return true; ++ } ++ ++ return false; ++} ++ ++static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator *gen, ++ const struct vkd3d_shader_combined_resource_sampler_info *crs) ++{ ++ const struct vkd3d_shader_descriptor_info1 *sampler, *srv; ++ const struct glsl_resource_type_info *resource_type_info; ++ const struct vkd3d_shader_descriptor_binding *binding; ++ struct vkd3d_string_buffer *buffer = gen->buffer; ++ enum vkd3d_shader_component_type component_type; ++ const char *sampler_type, *sampler_type_prefix; ++ unsigned int binding_idx; ++ bool shadow = false; ++ ++ if (crs->sampler_index != VKD3D_SHADER_DUMMY_SAMPLER_INDEX) ++ { ++ if (!(sampler = shader_glsl_get_descriptor(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, ++ crs->sampler_index, crs->sampler_space))) ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: No descriptor found for sampler %u, space %u.", ++ crs->sampler_index, crs->sampler_space); ++ return; ++ } ++ shadow = sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; ++ } ++ ++ if (!(srv = shader_glsl_get_descriptor(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, ++ crs->resource_index, crs->resource_space))) ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: No descriptor found for resource %u, space %u.", ++ crs->resource_index, crs->resource_space); ++ return; ++ } ++ ++ if ((resource_type_info = shader_glsl_get_resource_type_info(srv->resource_type))) ++ { ++ sampler_type = resource_type_info->sampler_type; ++ if (shadow && !resource_type_info->shadow) ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, ++ "Comparison samplers are not supported with resource type %#x.", srv->resource_type); ++ } ++ else ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled resource type %#x for combined resource/sampler " ++ "for resource %u, space %u and sampler %u, space %u.", srv->resource_type, ++ crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); ++ sampler_type = ""; ++ } ++ ++ switch ((component_type = vkd3d_component_type_from_resource_data_type(srv->resource_data_type))) ++ { ++ case VKD3D_SHADER_COMPONENT_UINT: ++ sampler_type_prefix = "u"; ++ break; ++ case VKD3D_SHADER_COMPONENT_INT: ++ sampler_type_prefix = "i"; ++ break; ++ case VKD3D_SHADER_COMPONENT_FLOAT: ++ sampler_type_prefix = ""; ++ break; ++ default: ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled component type %#x for combined resource/sampler " ++ "for resource %u, space %u and sampler %u, space %u.", component_type, ++ crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); ++ sampler_type_prefix = ""; ++ break; ++ } ++ ++ if (!shader_glsl_get_combined_sampler_binding(gen, crs, srv->resource_type, &binding_idx)) ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, ++ "No descriptor binding specified for combined resource/sampler " ++ "for resource %u, space %u and sampler %u, space %u.", ++ crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); ++ return; ++ } ++ ++ binding = &gen->interface_info->combined_samplers[binding_idx].binding; ++ ++ if (binding->set != 0) ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, ++ "Unsupported binding set %u specified for combined resource/sampler " ++ "for resource %u, space %u and sampler %u, space %u.", binding->set, ++ crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); ++ return; ++ } ++ ++ if (binding->count != 1) ++ { ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, ++ "Unsupported binding count %u specified for combined resource/sampler " ++ "for resource %u, space %u and sampler %u, space %u.", binding->count, ++ crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); ++ return; ++ } ++ ++ vkd3d_string_buffer_printf(buffer, "layout(binding = %u) uniform %s%s%s ", ++ binding->binding, sampler_type_prefix, sampler_type, shadow ? "Shadow" : ""); ++ shader_glsl_print_combined_sampler_name(buffer, gen, crs->resource_index, ++ crs->resource_space, crs->sampler_index, crs->sampler_space); ++ vkd3d_string_buffer_printf(buffer, ";\n"); ++} ++ + static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_generator *gen) + { ++ const struct vkd3d_shader_scan_combined_resource_sampler_info *sampler_info = gen->combined_sampler_info; + const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info; + const struct vkd3d_shader_descriptor_info1 *descriptor; + unsigned int i; +@@ -1024,6 +1461,11 @@ static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_gener + + switch (descriptor->type) + { ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: ++ /* GLSL uses combined resource/sampler descriptors.*/ ++ break; ++ + case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: + shader_glsl_generate_cbv_declaration(gen, descriptor); + break; +@@ -1035,6 +1477,10 @@ static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_gener + break; + } + } ++ for (i = 0; i < sampler_info->combined_sampler_count; ++i) ++ { ++ shader_glsl_generate_sampler_declaration(gen, &sampler_info->combined_samplers[i]); ++ } + if (info->descriptor_count) + vkd3d_string_buffer_printf(gen->buffer, "\n"); + } +@@ -1259,6 +1705,7 @@ static void shader_glsl_init_limits(struct vkd3d_glsl_generator *gen, const stru + static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, + struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, ++ const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, + struct vkd3d_shader_message_context *message_context) + { + enum vkd3d_shader_type type = program->shader_version.type; +@@ -1282,10 +1729,12 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, + gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO); + gen->offset_info = vkd3d_find_struct(compile_info->next, DESCRIPTOR_OFFSET_INFO); + gen->descriptor_info = descriptor_info; ++ gen->combined_sampler_info = combined_sampler_info; + } + + int glsl_compile(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, ++ const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, + const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) + { +@@ -1295,7 +1744,8 @@ 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; + +- vkd3d_glsl_generator_init(&generator, program, compile_info, descriptor_info, message_context); ++ vkd3d_glsl_generator_init(&generator, program, compile_info, ++ descriptor_info, combined_sampler_info, message_context); + ret = vkd3d_glsl_generator_generate(&generator, out); + vkd3d_glsl_generator_cleanup(&generator); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index ce3dd91f04f..9ace1930c1b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -4408,8 +4408,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) + struct hlsl_type *type, *next_type; + unsigned int i; + +- hlsl_block_cleanup(&ctx->static_initializers); +- + for (i = 0; i < ctx->source_files_count; ++i) + vkd3d_free((void *)ctx->source_files[i]); + vkd3d_free(ctx->source_files); +@@ -4417,6 +4415,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) + + rb_destroy(&ctx->functions, free_function_rb, NULL); + ++ hlsl_block_cleanup(&ctx->static_initializers); ++ + /* State blocks must be free before the variables, because they contain instructions that may + * refer to them. */ + LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &ctx->scopes, struct hlsl_scope, entry) +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index b4d9f0988b0..ef37eb75f03 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -1972,6 +1972,12 @@ static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hls + hlsl_block_add_block(block1, block2); + destroy_block(block2); + ++ if (arg1->data_type->class == HLSL_CLASS_ERROR || arg2->data_type->class == HLSL_CLASS_ERROR) ++ { ++ block1->value = ctx->error_instr; ++ return block1; ++ } ++ + if (add_binary_expr(ctx, block1, op, arg1, arg2, loc) == NULL) + return NULL; + +@@ -2085,6 +2091,12 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc + unsigned int writemask = 0, width = 0; + bool matrix_writemask = false; + ++ if (lhs->data_type->class == HLSL_CLASS_ERROR || rhs->data_type->class == HLSL_CLASS_ERROR) ++ { ++ block->value = ctx->error_instr; ++ return true; ++ } ++ + if (assign_op == ASSIGN_OP_SUB) + { + if (!(rhs = add_unary_arithmetic_expr(ctx, block, HLSL_OP1_NEG, rhs, &rhs->loc))) +@@ -5141,6 +5153,15 @@ static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name, + struct intrinsic_function *intrinsic; + struct hlsl_ir_function_decl *decl; + ++ for (unsigned int i = 0; i < args->args_count; ++i) ++ { ++ if (args->args[i]->data_type->class == HLSL_CLASS_ERROR) ++ { ++ args->instrs->value = ctx->error_instr; ++ return args->instrs; ++ } ++ } ++ + if ((decl = find_function_call(ctx, name, args, false, loc))) + { + if (!add_user_call(ctx, decl, args, false, loc)) +@@ -6071,6 +6092,21 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru + const struct hlsl_type *object_type = object->data_type; + const struct method_function *method; + ++ if (object_type->class == HLSL_CLASS_ERROR) ++ { ++ block->value = ctx->error_instr; ++ return true; ++ } ++ ++ for (unsigned int i = 0; i < params->args_count; ++i) ++ { ++ if (params->args[i]->data_type->class == HLSL_CLASS_ERROR) ++ { ++ block->value = ctx->error_instr; ++ return true; ++ } ++ } ++ + if (object_type->class != HLSL_CLASS_TEXTURE || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string; +@@ -8682,7 +8718,11 @@ primary_expr: + else + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Identifier \"%s\" is not declared.", $1); +- YYABORT; ++ vkd3d_free($1); ++ ++ if (!($$ = make_empty_block(ctx))) ++ YYABORT; ++ $$->value = ctx->error_instr; + } + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 2fe5472167f..6a74e2eb8de 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -6186,6 +6186,18 @@ static void vsir_validate_register(struct validation_context *ctx, + if (reg->dimension == VSIR_DIMENSION_SCALAR) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, + "Invalid dimension SCALAR for a SAMPLER register."); ++ ++ if (reg->idx_count != 2) ++ { ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, ++ "Invalid index count %u for a SAMPLER register.", ++ reg->idx_count); ++ break; ++ } ++ ++ if (reg->idx[0].rel_addr) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, ++ "Non-NULL relative address for the descriptor index of a SAMPLER register."); + break; + + case VKD3DSPR_RESOURCE: +@@ -6203,6 +6215,18 @@ static void vsir_validate_register(struct validation_context *ctx, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, + "Invalid dimension %#x for a RESOURCE register.", + reg->dimension); ++ ++ if (reg->idx_count != 2) ++ { ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, ++ "Invalid index count %u for a RESOURCE register.", ++ reg->idx_count); ++ break; ++ } ++ ++ if (reg->idx[0].rel_addr) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, ++ "Non-NULL relative address for the descriptor index of a RESOURCE register."); + break; + + case VKD3DSPR_UAV: +@@ -6221,6 +6245,18 @@ static void vsir_validate_register(struct validation_context *ctx, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, + "Invalid dimension %#x for a UAV register.", + reg->dimension); ++ ++ if (reg->idx_count != 2) ++ { ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, ++ "Invalid index count %u for a UAV register.", ++ reg->idx_count); ++ break; ++ } ++ ++ if (reg->idx[0].rel_addr) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, ++ "Non-NULL relative address for the descriptor index of a UAV register."); + break; + + case VKD3DSPR_DEPTHOUT: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index fc217860403..ee8a633431a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -1620,6 +1620,7 @@ int vsir_program_compile(struct vsir_program *program, 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_scan_descriptor_info1 scan_descriptor_info; + struct vkd3d_shader_compile_info scan_info; + int ret; +@@ -1633,10 +1634,14 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, + break; + + case VKD3D_SHADER_TARGET_GLSL: ++ combined_sampler_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO; ++ combined_sampler_info.next = scan_info.next; ++ scan_info.next = &combined_sampler_info; + if ((ret = vsir_program_scan(program, &scan_info, message_context, &scan_descriptor_info)) < 0) + return ret; + ret = glsl_compile(program, config_flags, &scan_descriptor_info, +- compile_info, out, message_context); ++ &combined_sampler_info, compile_info, out, message_context); ++ vkd3d_shader_free_scan_combined_resource_sampler_info(&combined_sampler_info); + vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info); + break; + +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index d9d5b4a405e..eab164cc848 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -173,6 +173,7 @@ enum vkd3d_shader_error + + VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, + VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND = 6001, ++ VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED = 6002, + + VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF = 7000, + VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN = 7001, +@@ -1599,6 +1600,7 @@ int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, + + int glsl_compile(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, ++ const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, + const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); + +-- +2.45.2 +