wine-staging/patches/vkd3d-latest/0006-Updated-vkd3d-to-25232f2b2b35bcf1c265bc380c31cd1d32e.patch
2024-10-05 11:28:16 +10:00

894 lines
38 KiB
Diff

From baf455d7ecc67cac7c6c450535226f67d3af6c21 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
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(&reg->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, "<unhandled 64-bit multiplication>");
+ 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 = "<unhandled 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