wine-staging/patches/vkd3d-latest/0009-Updated-vkd3d-to-32ced3bd8f52e19d184c8191f420dcb7bad.patch
2024-09-21 09:44:13 +10:00

821 lines
36 KiB
Diff

From 72a24faa48be8d8a3b396a94fb8e028b7eaf6898 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 20 Sep 2024 07:31:45 +1000
Subject: [PATCH] Updated vkd3d to 32ced3bd8f52e19d184c8191f420dcb7badbbad2.
---
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 35 +-
libs/vkd3d/libs/vkd3d-shader/glsl.c | 334 +++++++++++++++++-
libs/vkd3d/libs/vkd3d-shader/msl.c | 146 ++++++++
libs/vkd3d/libs/vkd3d-shader/tpf.c | 18 +-
.../libs/vkd3d-shader/vkd3d_shader_main.c | 3 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 6 +-
6 files changed, 506 insertions(+), 36 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 9c7be1f08bb..10f2e5e5e6d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -104,6 +104,19 @@ enum vkd3d_sm1_resource_type
VKD3D_SM1_RESOURCE_TEXTURE_3D = 0x4,
};
+enum vkd3d_sm1_misc_register
+{
+ VKD3D_SM1_MISC_POSITION = 0x0,
+ VKD3D_SM1_MISC_FACE = 0x1,
+};
+
+enum vkd3d_sm1_rastout_register
+{
+ VKD3D_SM1_RASTOUT_POSITION = 0x0,
+ VKD3D_SM1_RASTOUT_FOG = 0x1,
+ VKD3D_SM1_RASTOUT_POINT_SIZE = 0x2,
+};
+
enum vkd3d_sm1_opcode
{
VKD3D_SM1_OP_NOP = 0x00,
@@ -1385,22 +1398,22 @@ bool hlsl_sm1_register_from_semantic(const struct vkd3d_shader_version *version,
{"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_DEPTHOUT},
{"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_DEPTHOUT},
{"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_COLOROUT},
- {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, D3DSMO_POSITION},
- {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, D3DSMO_FACE},
- {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, D3DSMO_POSITION},
+ {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION},
+ {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_FACE},
+ {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION},
{"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_ATTROUT},
- {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, D3DSRO_FOG},
- {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, D3DSRO_POSITION},
- {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, D3DSRO_POINT_SIZE},
- {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, D3DSRO_POSITION},
+ {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_FOG},
+ {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION},
+ {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POINT_SIZE},
+ {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION},
{"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_TEXCRDOUT},
{"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_ATTROUT},
- {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, D3DSRO_FOG},
- {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, D3DSRO_POSITION},
- {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, D3DSRO_POINT_SIZE},
- {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, D3DSRO_POSITION},
+ {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_FOG},
+ {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION},
+ {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POINT_SIZE},
+ {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION},
{"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_TEXCRDOUT},
};
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index f8fec6ac2bc..ac101d44214 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -48,6 +48,10 @@ struct vkd3d_glsl_generator
} limits;
bool interstage_input;
bool interstage_output;
+
+ 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;
};
static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error(
@@ -133,6 +137,40 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer,
vkd3d_string_buffer_printf(buffer, "%s_out[%u]", gen->prefix, reg->idx[0].offset);
break;
+ case VKD3DSPR_IMMCONST:
+ switch (reg->dimension)
+ {
+ case VSIR_DIMENSION_SCALAR:
+ vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]);
+ break;
+
+ default:
+ vkd3d_string_buffer_printf(buffer, "<unhandled_dimension %#x>", reg->dimension);
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled dimension %#x.", reg->dimension);
+ break;
+ }
+ break;
+
+ case VKD3DSPR_CONSTBUFFER:
+ if (reg->idx_count != 3)
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled constant buffer register index count %u.", reg->idx_count);
+ vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
+ break;
+ }
+ if (reg->idx[0].rel_addr || reg->idx[2].rel_addr)
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled constant buffer register indirect addressing.");
+ vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
+ break;
+ }
+ vkd3d_string_buffer_printf(buffer, "%s_cb_%u[%u]",
+ gen->prefix, reg->idx[0].offset, reg->idx[2].offset);
+ break;
+
default:
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled register type %#x.", reg->type);
@@ -172,23 +210,86 @@ static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_ca
vkd3d_string_buffer_release(cache, src->str);
}
+static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vkd3d_glsl_generator *gen,
+ const char *src, enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type)
+{
+ if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM)
+ dst_data_type = VKD3D_DATA_FLOAT;
+ if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM)
+ src_data_type = VKD3D_DATA_FLOAT;
+
+ if (dst_data_type == src_data_type)
+ {
+ vkd3d_string_buffer_printf(dst, "%s", src);
+ return;
+ }
+
+ if (src_data_type == VKD3D_DATA_FLOAT && dst_data_type == VKD3D_DATA_UINT)
+ {
+ vkd3d_string_buffer_printf(dst, "floatBitsToUint(%s)", src);
+ return;
+ }
+
+ if (src_data_type == VKD3D_DATA_UINT && dst_data_type == VKD3D_DATA_FLOAT)
+ {
+ vkd3d_string_buffer_printf(dst, "uintBitsToFloat(%s)", src);
+ return;
+ }
+
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled bitcast from %#x to %#x.",
+ src_data_type, dst_data_type);
+ vkd3d_string_buffer_printf(dst, "%s", src);
+}
+
static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator *gen,
const struct vkd3d_shader_src_param *vsir_src, uint32_t mask)
{
const struct vkd3d_shader_register *reg = &vsir_src->reg;
+ struct vkd3d_string_buffer *register_name, *str;
+ enum vkd3d_data_type src_data_type;
glsl_src->str = vkd3d_string_buffer_get(&gen->string_buffers);
+ register_name = vkd3d_string_buffer_get(&gen->string_buffers);
if (reg->non_uniform)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled 'non-uniform' modifier.");
- if (vsir_src->modifiers)
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
- shader_glsl_print_register_name(glsl_src->str, gen, reg);
+ if (reg->type == VKD3DSPR_IMMCONST)
+ src_data_type = VKD3D_DATA_UINT;
+ else
+ src_data_type = VKD3D_DATA_FLOAT;
+
+ shader_glsl_print_register_name(register_name, gen, reg);
+
+ if (!vsir_src->modifiers)
+ str = glsl_src->str;
+ else
+ str = vkd3d_string_buffer_get(&gen->string_buffers);
+
+ shader_glsl_print_bitcast(str, gen, register_name->buffer, reg->data_type, src_data_type);
if (reg->dimension == VSIR_DIMENSION_VEC4)
- shader_glsl_print_swizzle(glsl_src->str, vsir_src->swizzle, mask);
+ shader_glsl_print_swizzle(str, vsir_src->swizzle, mask);
+
+ switch (vsir_src->modifiers)
+ {
+ case VKD3DSPSM_NONE:
+ break;
+ case VKD3DSPSM_ABS:
+ vkd3d_string_buffer_printf(glsl_src->str, "abs(%s)", str->buffer);
+ break;
+ default:
+ vkd3d_string_buffer_printf(glsl_src->str, "<unhandled modifier %#x>(%s)",
+ vsir_src->modifiers, str->buffer);
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
+ break;
+ }
+
+ if (str != glsl_src->str)
+ vkd3d_string_buffer_release(&gen->string_buffers, str);
+ vkd3d_string_buffer_release(&gen->string_buffers, register_name);
}
static void glsl_dst_cleanup(struct glsl_dst *dst, struct vkd3d_string_buffer_cache *cache)
@@ -222,6 +323,9 @@ static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_gener
static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment(
struct vkd3d_glsl_generator *gen, struct glsl_dst *dst, const char *format, ...)
{
+ const struct vkd3d_shader_register *dst_reg = &dst->vsir->reg;
+ struct vkd3d_string_buffer *buffer = gen->buffer;
+ bool close = true;
va_list args;
if (dst->vsir->shift)
@@ -231,14 +335,28 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment(
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled destination modifier(s) %#x.", dst->vsir->modifiers);
- shader_glsl_print_indent(gen->buffer, gen->indent);
- vkd3d_string_buffer_printf(gen->buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer);
+ shader_glsl_print_indent(buffer, gen->indent);
+ vkd3d_string_buffer_printf(buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer);
+
+ switch (dst_reg->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);
+ /* fall through */
+ case VKD3D_DATA_FLOAT:
+ close = false;
+ break;
+ case VKD3D_DATA_UINT:
+ vkd3d_string_buffer_printf(buffer, "uintBitsToFloat(");
+ break;
+ }
va_start(args, format);
- vkd3d_string_buffer_vprintf(gen->buffer, format, args);
+ vkd3d_string_buffer_vprintf(buffer, format, args);
va_end(args);
- vkd3d_string_buffer_printf(gen->buffer, ";\n");
+ vkd3d_string_buffer_printf(buffer, "%s;\n", close ? ")" : "");
}
static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
@@ -249,6 +367,24 @@ static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct
"Internal compiler error: Unhandled instruction %#x.", ins->opcode);
}
+static void shader_glsl_binop(struct vkd3d_glsl_generator *gen,
+ const struct vkd3d_shader_instruction *ins, const char *op)
+{
+ struct glsl_src src[2];
+ struct glsl_dst dst;
+ uint32_t mask;
+
+ mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]);
+ 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 %s", src[0].str->buffer, op, 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_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
struct glsl_src src;
@@ -267,11 +403,12 @@ static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d
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)
{
+ const struct vkd3d_shader_version *version = &gen->program->shader_version;
+
switch (sysval)
{
case VKD3D_SHADER_SV_POSITION:
- if (gen->program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL
- || gen->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE)
+ if (version->type == VKD3D_SHADER_TYPE_PIXEL || version->type == VKD3D_SHADER_TYPE_COMPUTE)
{
vkd3d_string_buffer_printf(buffer, "<unhandled sysval %#x>", sysval);
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
@@ -286,6 +423,13 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st
}
break;
+ case VKD3D_SHADER_SV_TARGET:
+ if (version->type != VKD3D_SHADER_TYPE_PIXEL)
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled SV_TARGET in shader type #%x.", version->type);
+ vkd3d_string_buffer_printf(buffer, "shader_out_%u", idx);
+ break;
+
default:
vkd3d_string_buffer_printf(buffer, "<unhandled sysval %#x>", sysval);
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
@@ -400,6 +544,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
switch (ins->opcode)
{
+ case VKD3DSIH_ADD:
+ shader_glsl_binop(gen, ins, "+");
+ break;
+ case VKD3DSIH_AND:
+ shader_glsl_binop(gen, ins, "&");
+ break;
case VKD3DSIH_DCL_INPUT:
case VKD3DSIH_DCL_OUTPUT:
case VKD3DSIH_DCL_OUTPUT_SIV:
@@ -417,6 +567,151 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
}
}
+static bool shader_glsl_check_shader_visibility(const struct vkd3d_glsl_generator *gen,
+ enum vkd3d_shader_visibility visibility)
+{
+ enum vkd3d_shader_type t = gen->program->shader_version.type;
+
+ switch (visibility)
+ {
+ case VKD3D_SHADER_VISIBILITY_ALL:
+ return true;
+ case VKD3D_SHADER_VISIBILITY_VERTEX:
+ return t == VKD3D_SHADER_TYPE_VERTEX;
+ case VKD3D_SHADER_VISIBILITY_HULL:
+ return t == VKD3D_SHADER_TYPE_HULL;
+ case VKD3D_SHADER_VISIBILITY_DOMAIN:
+ return t == VKD3D_SHADER_TYPE_DOMAIN;
+ case VKD3D_SHADER_VISIBILITY_GEOMETRY:
+ return t == VKD3D_SHADER_TYPE_GEOMETRY;
+ case VKD3D_SHADER_VISIBILITY_PIXEL:
+ return t == VKD3D_SHADER_TYPE_PIXEL;
+ case VKD3D_SHADER_VISIBILITY_COMPUTE:
+ return t == VKD3D_SHADER_TYPE_COMPUTE;
+ default:
+ WARN("Invalid shader visibility %#x.\n", visibility);
+ return false;
+ }
+}
+
+static bool shader_glsl_get_cbv_binding(const struct vkd3d_glsl_generator *gen,
+ unsigned int register_space, unsigned int register_idx, unsigned int *binding_idx)
+{
+ const struct vkd3d_shader_interface_info *interface_info = gen->interface_info;
+ const struct vkd3d_shader_resource_binding *binding;
+ unsigned int i;
+
+ if (!interface_info)
+ return false;
+
+ for (i = 0; i < interface_info->binding_count; ++i)
+ {
+ binding = &interface_info->bindings[i];
+
+ if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV)
+ continue;
+ if (binding->register_space != register_space)
+ continue;
+ if (binding->register_index != register_idx)
+ continue;
+ if (!shader_glsl_check_shader_visibility(gen, binding->shader_visibility))
+ continue;
+ if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER))
+ continue;
+ *binding_idx = i;
+ return true;
+ }
+
+ return false;
+}
+
+static void shader_glsl_generate_cbv_declaration(struct vkd3d_glsl_generator *gen,
+ const struct vkd3d_shader_descriptor_info1 *cbv)
+{
+ const struct vkd3d_shader_descriptor_binding *binding;
+ const struct vkd3d_shader_descriptor_offset *offset;
+ struct vkd3d_string_buffer *buffer = gen->buffer;
+ const char *prefix = gen->prefix;
+ unsigned int binding_idx;
+ size_t size;
+
+ if (cbv->count != 1)
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND,
+ "Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count);
+ return;
+ }
+
+ if (!shader_glsl_get_cbv_binding(gen, cbv->register_space, cbv->register_index, &binding_idx))
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND,
+ "No descriptor binding specified for constant buffer %u.", cbv->register_id);
+ return;
+ }
+
+ binding = &gen->interface_info->bindings[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 constant buffer %u.", binding->set, cbv->register_id);
+ return;
+ }
+
+ if (binding->count != 1)
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND,
+ "Unsupported binding count %u specified for constant buffer %u.", binding->count, cbv->register_id);
+ return;
+ }
+
+ if (gen->offset_info && gen->offset_info->binding_offsets)
+ {
+ offset = &gen->offset_info->binding_offsets[binding_idx];
+ if (offset->static_offset || offset->dynamic_offset_index != ~0u)
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled descriptor offset specified for constant buffer %u.",
+ cbv->register_id);
+ return;
+ }
+ }
+
+ size = align(cbv->buffer_size, VKD3D_VEC4_SIZE * sizeof(uint32_t));
+ size /= VKD3D_VEC4_SIZE * sizeof(uint32_t);
+
+ vkd3d_string_buffer_printf(buffer,
+ "layout(std140, binding = %u) uniform block_%s_cb_%u { vec4 %s_cb_%u[%zu]; };\n",
+ binding->binding, prefix, cbv->register_id, prefix, cbv->register_id, size);
+}
+
+static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_generator *gen)
+{
+ const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info;
+ const struct vkd3d_shader_descriptor_info1 *descriptor;
+ unsigned int i;
+
+ for (i = 0; i < info->descriptor_count; ++i)
+ {
+ descriptor = &info->descriptors[i];
+
+ switch (descriptor->type)
+ {
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
+ shader_glsl_generate_cbv_declaration(gen, descriptor);
+ break;
+
+ default:
+ vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled descriptor type %#x> */\n", descriptor->type);
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled descriptor type %#x.", descriptor->type);
+ break;
+ }
+ }
+ if (info->descriptor_count)
+ vkd3d_string_buffer_printf(gen->buffer, "\n");
+}
+
static void shader_glsl_generate_interface_block(struct vkd3d_string_buffer *buffer,
const char *type, unsigned int count)
{
@@ -545,6 +840,7 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen)
const struct vsir_program *program = gen->program;
struct vkd3d_string_buffer *buffer = gen->buffer;
+ shader_glsl_generate_descriptor_declarations(gen);
shader_glsl_generate_input_declarations(gen);
shader_glsl_generate_output_declarations(gen);
@@ -634,7 +930,9 @@ 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, struct vkd3d_shader_message_context *message_context)
+ struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
+ const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info,
+ struct vkd3d_shader_message_context *message_context)
{
enum vkd3d_shader_type type = program->shader_version.type;
@@ -642,6 +940,7 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen,
gen->program = program;
vkd3d_string_buffer_cache_init(&gen->string_buffers);
gen->buffer = vkd3d_string_buffer_get(&gen->string_buffers);
+ gen->location.source_name = compile_info->source_name;
gen->message_context = message_context;
if (!(gen->prefix = shader_glsl_get_prefix(type)))
{
@@ -652,11 +951,16 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen,
shader_glsl_init_limits(gen, &program->shader_version);
gen->interstage_input = type != VKD3D_SHADER_TYPE_VERTEX;
gen->interstage_output = type != VKD3D_SHADER_TYPE_PIXEL;
+
+ 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;
}
int glsl_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)
+ const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info,
+ const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
{
struct vkd3d_glsl_generator generator;
int ret;
@@ -664,7 +968,7 @@ 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, message_context);
+ vkd3d_glsl_generator_init(&generator, program, compile_info, descriptor_info, message_context);
ret = vkd3d_glsl_generator_generate(&generator, out);
vkd3d_glsl_generator_cleanup(&generator);
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c
index 2923494feed..7d2e713cddc 100644
--- a/libs/vkd3d/libs/vkd3d-shader/msl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c
@@ -18,6 +18,18 @@
#include "vkd3d_shader_private.h"
+struct msl_src
+{
+ struct vkd3d_string_buffer *str;
+};
+
+struct msl_dst
+{
+ const struct vkd3d_shader_dst_param *vsir;
+ struct vkd3d_string_buffer *register_name;
+ struct vkd3d_string_buffer *mask;
+};
+
struct msl_generator
{
struct vsir_program *program;
@@ -43,6 +55,113 @@ static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int in
vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, "");
}
+static void msl_print_register_name(struct vkd3d_string_buffer *buffer,
+ struct msl_generator *gen, const struct vkd3d_shader_register *reg)
+{
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled register type %#x.", reg->type);
+ vkd3d_string_buffer_printf(buffer, "<unrecognised register %#x>", reg->type);
+}
+
+static void msl_print_swizzle(struct vkd3d_string_buffer *buffer, uint32_t swizzle, uint32_t mask)
+{
+ const char swizzle_chars[] = "xyzw";
+ unsigned int i;
+
+ vkd3d_string_buffer_printf(buffer, ".");
+ for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
+ {
+ if (mask & (VKD3DSP_WRITEMASK_0 << i))
+ vkd3d_string_buffer_printf(buffer, "%c", swizzle_chars[vsir_swizzle_get_component(swizzle, i)]);
+ }
+}
+
+static void msl_print_write_mask(struct vkd3d_string_buffer *buffer, uint32_t write_mask)
+{
+ vkd3d_string_buffer_printf(buffer, ".");
+ if (write_mask & VKD3DSP_WRITEMASK_0)
+ vkd3d_string_buffer_printf(buffer, "x");
+ if (write_mask & VKD3DSP_WRITEMASK_1)
+ vkd3d_string_buffer_printf(buffer, "y");
+ if (write_mask & VKD3DSP_WRITEMASK_2)
+ vkd3d_string_buffer_printf(buffer, "z");
+ if (write_mask & VKD3DSP_WRITEMASK_3)
+ vkd3d_string_buffer_printf(buffer, "w");
+}
+
+static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cache *cache)
+{
+ vkd3d_string_buffer_release(cache, src->str);
+}
+
+static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen,
+ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask)
+{
+ const struct vkd3d_shader_register *reg = &vsir_src->reg;
+
+ msl_src->str = vkd3d_string_buffer_get(&gen->string_buffers);
+
+ if (reg->non_uniform)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled 'non-uniform' modifier.");
+ if (vsir_src->modifiers)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
+
+ msl_print_register_name(msl_src->str, gen, reg);
+ if (reg->dimension == VSIR_DIMENSION_VEC4)
+ msl_print_swizzle(msl_src->str, vsir_src->swizzle, mask);
+}
+
+static void msl_dst_cleanup(struct msl_dst *dst, struct vkd3d_string_buffer_cache *cache)
+{
+ vkd3d_string_buffer_release(cache, dst->mask);
+ vkd3d_string_buffer_release(cache, dst->register_name);
+}
+
+static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen,
+ const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst)
+{
+ uint32_t write_mask = vsir_dst->write_mask;
+
+ if (ins->flags & VKD3DSI_PRECISE_XYZW)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled 'precise' modifier.");
+ if (vsir_dst->reg.non_uniform)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled 'non-uniform' modifier.");
+
+ msl_dst->vsir = vsir_dst;
+ msl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers);
+ msl_dst->mask = vkd3d_string_buffer_get(&gen->string_buffers);
+
+ msl_print_register_name(msl_dst->register_name, gen, &vsir_dst->reg);
+ msl_print_write_mask(msl_dst->mask, write_mask);
+
+ return write_mask;
+}
+
+static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment(
+ struct msl_generator *gen, struct msl_dst *dst, const char *format, ...)
+{
+ va_list args;
+
+ if (dst->vsir->shift)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift);
+ if (dst->vsir->modifiers)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled destination modifier(s) %#x.", dst->vsir->modifiers);
+
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer);
+
+ va_start(args, format);
+ vkd3d_string_buffer_vprintf(gen->buffer, format, args);
+ va_end(args);
+
+ vkd3d_string_buffer_printf(gen->buffer, ";\n");
+}
static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
@@ -52,6 +171,27 @@ static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_i
"Internal compiler error: Unhandled instruction %#x.", ins->opcode);
}
+static void msl_mov(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ struct msl_src src;
+ struct msl_dst dst;
+ uint32_t mask;
+
+ mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]);
+ msl_src_init(&src, gen, &ins->src[0], mask);
+
+ msl_print_assignment(gen, &dst, "%s", src.str->buffer);
+
+ msl_src_cleanup(&src, &gen->string_buffers);
+ msl_dst_cleanup(&dst, &gen->string_buffers);
+}
+
+static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "return;\n");
+}
+
static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
gen->location = ins->location;
@@ -60,6 +200,12 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
{
case VKD3DSIH_NOP:
break;
+ case VKD3DSIH_MOV:
+ msl_mov(gen, ins);
+ break;
+ case VKD3DSIH_RET:
+ msl_ret(gen, ins);
+ break;
default:
msl_unhandled(gen, ins);
break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 48efe1e2d72..cbf28f5ec50 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -645,6 +645,9 @@ enum vkd3d_sm4_stat_field
VKD3D_STAT_TESS_PARTITIONING,
VKD3D_STAT_TESS_OUTPUT_PRIMITIVE,
VKD3D_STAT_TESS_CONTROL_POINT_COUNT,
+ VKD3D_STAT_BARRIER,
+ VKD3D_STAT_LOD,
+ VKD3D_STAT_GATHER,
VKD3D_STAT_COUNT,
};
@@ -1793,17 +1796,16 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup)
{VKD3D_SM4_OP_SAMPLE_LOD, VKD3D_STAT_SAMPLE},
{VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3D_STAT_SAMPLE},
{VKD3D_SM5_OP_SAMPLE_CL_S, VKD3D_STAT_SAMPLE},
- {VKD3D_SM4_OP_GATHER4, VKD3D_STAT_SAMPLE},
- {VKD3D_SM5_OP_GATHER4_PO, VKD3D_STAT_SAMPLE},
{VKD3D_SM4_OP_SAMPLE_C, VKD3D_STAT_SAMPLE_C},
{VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3D_STAT_SAMPLE_C},
{VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3D_STAT_SAMPLE_C},
{VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3D_STAT_SAMPLE_C},
- {VKD3D_SM5_OP_GATHER4_C, VKD3D_STAT_SAMPLE_C},
- {VKD3D_SM5_OP_GATHER4_PO_C, VKD3D_STAT_SAMPLE_C},
{VKD3D_SM4_OP_SAMPLE_GRAD, VKD3D_STAT_SAMPLE_GRAD},
{VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3D_STAT_SAMPLE_GRAD},
{VKD3D_SM4_OP_SAMPLE_B, VKD3D_STAT_SAMPLE_BIAS},
+ {VKD3D_SM4_OP_GATHER4, VKD3D_STAT_GATHER},
+ {VKD3D_SM5_OP_GATHER4_PO, VKD3D_STAT_GATHER},
+ {VKD3D_SM4_OP_LOD, VKD3D_STAT_LOD},
{VKD3D_SM4_OP_LD, VKD3D_STAT_LOAD},
{VKD3D_SM4_OP_LD2DMS, VKD3D_STAT_LOAD},
@@ -1857,6 +1859,8 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup)
{VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3D_STAT_TESS_OUTPUT_PRIMITIVE},
{VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3D_STAT_TESS_CONTROL_POINT_COUNT},
{VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3D_STAT_TESS_CONTROL_POINT_COUNT},
+
+ {VKD3D_SM5_OP_SYNC, VKD3D_STAT_BARRIER},
};
memset(lookup, 0, sizeof(*lookup));
@@ -6433,8 +6437,8 @@ static void write_sm4_stat(struct hlsl_ctx *ctx, const struct sm4_stat *stat, st
put_u32(&buffer, stat->fields[VKD3D_STAT_DCL_INPUT_PRIMITIVE]);
put_u32(&buffer, stat->fields[VKD3D_STAT_DCL_OUTPUT_TOPOLOGY]);
put_u32(&buffer, stat->fields[VKD3D_STAT_DCL_VERTICES_OUT]);
- put_u32(&buffer, 0); /* Unknown */
- put_u32(&buffer, 0); /* Unknown */
+ put_u32(&buffer, stat->fields[VKD3D_STAT_GATHER]);
+ put_u32(&buffer, stat->fields[VKD3D_STAT_LOD]);
put_u32(&buffer, 0); /* Sample frequency */
if (hlsl_version_ge(ctx, 5, 0))
@@ -6444,7 +6448,7 @@ static void write_sm4_stat(struct hlsl_ctx *ctx, const struct sm4_stat *stat, st
put_u32(&buffer, stat->fields[VKD3D_STAT_TESS_OUTPUT_PRIMITIVE]);
put_u32(&buffer, stat->fields[VKD3D_STAT_TESS_PARTITIONING]);
put_u32(&buffer, stat->fields[VKD3D_STAT_TESS_DOMAIN]);
- put_u32(&buffer, 0); /* Barrier instructions */
+ put_u32(&buffer, stat->fields[VKD3D_STAT_BARRIER]);
put_u32(&buffer, stat->fields[VKD3D_STAT_ATOMIC]);
put_u32(&buffer, stat->fields[VKD3D_STAT_STORE]);
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index ee98a504a5b..fc217860403 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -1635,7 +1635,8 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
case VKD3D_SHADER_TARGET_GLSL:
if ((ret = vsir_program_scan(program, &scan_info, message_context, &scan_descriptor_info)) < 0)
return ret;
- ret = glsl_compile(program, config_flags, compile_info, out, message_context);
+ ret = glsl_compile(program, config_flags, &scan_descriptor_info,
+ compile_info, out, message_context);
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 8146a393a4c..a5d869172d3 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -168,6 +168,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE = 5306,
VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000,
+ VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND = 6001,
VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF = 7000,
VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN = 7001,
@@ -1593,8 +1594,9 @@ int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_message_context *message_context, struct shader_signature *signature);
int glsl_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);
+ const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info,
+ const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
#define SPIRV_MAX_SRC_COUNT 6
--
2.45.2