wine-staging/patches/vkd3d-latest/0004-Updated-vkd3d-to-cd249a47b86545fe0b3a4b477f854965e85.patch

1534 lines
66 KiB
Diff
Raw Permalink Normal View History

2024-10-17 13:32:33 -07:00
From 52de9a875b2a75a0d32486b990e685fed075bcab Mon Sep 17 00:00:00 2001
2024-10-14 15:23:52 -07:00
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 11 Oct 2024 07:30:59 +1100
Subject: [PATCH] Updated vkd3d to cd249a47b86545fe0b3a4b477f854965e858b744.
---
libs/vkd3d/include/vkd3d_shader.h | 52 +++
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 26 +-
libs/vkd3d/libs/vkd3d-shader/glsl.c | 297 +++++++++++++--
libs/vkd3d/libs/vkd3d-shader/ir.c | 349 ++++++++++++++++--
libs/vkd3d/libs/vkd3d-shader/msl.c | 226 +++++++++++-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 35 +-
.../libs/vkd3d-shader/vkd3d_shader_main.c | 5 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 11 +
8 files changed, 921 insertions(+), 80 deletions(-)
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index d08ee74a3a0..e22f236ecd1 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -648,6 +648,58 @@ enum vkd3d_shader_parameter_name
VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_5,
VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_6,
VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_7,
+ /**
+ * Point size.
+ *
+ * When this parameter is provided to a vertex, tessellation, or geometry
+ * shader, and the source shader does not write point size, it specifies a
+ * uniform value which will be written to point size.
+ * If the source shader writes point size, this parameter is ignored.
+ *
+ * This parameter can be used to implement fixed function point size, as
+ * present in Direct3D versions 8 and 9, if the target environment does not
+ * support point size as part of its own fixed-function API (as Vulkan and
+ * core OpenGL).
+ *
+ * The data type for this parameter must be
+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32.
+ *
+ * \since 1.14
+ */
+ VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE,
+ /**
+ * Minimum point size.
+ *
+ * When this parameter is provided to a vertex, tessellation, or geometry
+ * shader, and the source shader writes point size or uses the
+ * VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE parameter, the point size will
+ * be clamped to the provided minimum value.
+ * If point size is not written in one of these ways,
+ * this parameter is ignored.
+ * If this parameter is not provided, the point size will not be clamped
+ * to a minimum size by vkd3d-shader.
+ *
+ * This parameter can be used to implement fixed function point size, as
+ * present in Direct3D versions 8 and 9, if the target environment does not
+ * support point size as part of its own fixed-function API (as Vulkan and
+ * core OpenGL).
+ *
+ * The data type for this parameter must be
+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32.
+ *
+ * \since 1.14
+ */
+ VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN,
+ /**
+ * Maximum point size.
+ *
+ * This parameter has identical behaviour to
+ * VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, except that it provides
+ * the maximum size rather than the minimum.
+ *
+ * \since 1.14
+ */
+ VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME),
};
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 589b800f8c9..44b1714b56b 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -110,13 +110,6 @@ enum vkd3d_sm1_misc_register
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,
@@ -957,6 +950,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const
shader_sm1_parse_src_param(addr_token, NULL, dst_rel_addr);
}
shader_sm1_parse_dst_param(token, dst_rel_addr, dst_param);
+
+ if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
+ sm1->p.program->has_point_size = true;
}
static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1,
@@ -1434,17 +1430,17 @@ bool hlsl_sm1_register_from_semantic(const struct vkd3d_shader_version *version,
{"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, 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},
+ {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG},
+ {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION},
+ {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE},
+ {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_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, 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},
+ {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG},
+ {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION},
+ {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE},
+ {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_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 91ee355ed39..c8efdae3386 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -22,7 +22,7 @@ struct glsl_resource_type_info
{
size_t coord_size;
bool shadow;
- const char *sampler_type;
+ const char *type_suffix;
};
struct glsl_src
@@ -102,17 +102,17 @@ static const struct glsl_resource_type_info *shader_glsl_get_resource_type_info(
{
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 */
+ {0, 0, "None"}, /* VKD3D_SHADER_RESOURCE_NONE */
+ {1, 0, "Buffer"}, /* VKD3D_SHADER_RESOURCE_BUFFER */
+ {1, 1, "1D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1D */
+ {2, 1, "2D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2D */
+ {2, 0, "2DMS"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMS */
+ {3, 0, "3D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_3D */
+ {3, 1, "Cube"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBE */
+ {2, 1, "1DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY */
+ {3, 1, "2DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY */
+ {3, 0, "2DMSArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */
+ {4, 1, "CubeArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */
};
if (!t || t >= ARRAY_SIZE(info))
@@ -173,6 +173,14 @@ static void shader_glsl_print_combined_sampler_name(struct vkd3d_string_buffer *
}
}
+static void shader_glsl_print_image_name(struct vkd3d_string_buffer *buffer,
+ struct vkd3d_glsl_generator *gen, unsigned int idx, unsigned int space)
+{
+ vkd3d_string_buffer_printf(buffer, "%s_image_%u", gen->prefix, idx);
+ if (space)
+ vkd3d_string_buffer_printf(buffer, "_%u", space);
+}
+
static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer,
struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_register *reg)
{
@@ -363,15 +371,14 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk
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)
+static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen,
+ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type)
{
const struct vkd3d_shader_register *reg = &vsir_src->reg;
struct vkd3d_string_buffer *register_name, *str;
enum vkd3d_data_type src_data_type;
unsigned int size;
- glsl_src->str = vkd3d_string_buffer_get(&gen->string_buffers);
register_name = vkd3d_string_buffer_get(&gen->string_buffers);
if (reg->non_uniform)
@@ -386,12 +393,12 @@ static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator
shader_glsl_print_register_name(register_name, gen, reg);
if (!vsir_src->modifiers)
- str = glsl_src->str;
+ str = buffer;
else
str = vkd3d_string_buffer_get(&gen->string_buffers);
size = reg->dimension == VSIR_DIMENSION_VEC4 ? 4 : 1;
- shader_glsl_print_bitcast(str, gen, register_name->buffer, reg->data_type, src_data_type, size);
+ shader_glsl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, size);
if (reg->dimension == VSIR_DIMENSION_VEC4)
shader_glsl_print_swizzle(str, vsir_src->swizzle, mask);
@@ -400,24 +407,31 @@ static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator
case VKD3DSPSM_NONE:
break;
case VKD3DSPSM_NEG:
- vkd3d_string_buffer_printf(glsl_src->str, "-%s", str->buffer);
+ vkd3d_string_buffer_printf(buffer, "-%s", str->buffer);
break;
case VKD3DSPSM_ABS:
- vkd3d_string_buffer_printf(glsl_src->str, "abs(%s)", str->buffer);
+ vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer);
break;
default:
- vkd3d_string_buffer_printf(glsl_src->str, "<unhandled modifier %#x>(%s)",
+ vkd3d_string_buffer_printf(buffer, "<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)
+ if (str != buffer)
vkd3d_string_buffer_release(&gen->string_buffers, str);
vkd3d_string_buffer_release(&gen->string_buffers, register_name);
}
+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)
+{
+ glsl_src->str = vkd3d_string_buffer_get(&gen->string_buffers);
+ shader_glsl_print_src(glsl_src->str, gen, vsir_src, mask, vsir_src->reg.data_type);
+}
+
static void glsl_dst_cleanup(struct glsl_dst *dst, struct vkd3d_string_buffer_cache *cache)
{
vkd3d_string_buffer_release(cache, dst->mask);
@@ -892,6 +906,85 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk
glsl_dst_cleanup(&dst, &gen->string_buffers);
}
+static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ const struct glsl_resource_type_info *resource_type_info;
+ enum vkd3d_shader_component_type component_type;
+ const struct vkd3d_shader_descriptor_info1 *d;
+ enum vkd3d_shader_resource_type resource_type;
+ unsigned int uav_id, uav_idx, uav_space;
+ struct vkd3d_string_buffer *image_data;
+ struct glsl_src image_coord;
+ uint32_t coord_mask;
+
+ if (ins->dst[0].reg.idx[0].rel_addr || ins->dst[0].reg.idx[1].rel_addr)
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED,
+ "Descriptor indexing is not supported.");
+
+ uav_id = ins->dst[0].reg.idx[0].offset;
+ uav_idx = ins->dst[0].reg.idx[1].offset;
+ if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, uav_id)))
+ {
+ resource_type = d->resource_type;
+ uav_space = d->register_space;
+ component_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type);
+ }
+ else
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Undeclared UAV descriptor %u.", uav_id);
+ uav_space = 0;
+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
+ component_type = VKD3D_SHADER_COMPONENT_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 UAV type %#x.", resource_type);
+ coord_mask = vkd3d_write_mask_from_component_count(2);
+ }
+
+ glsl_src_init(&image_coord, gen, &ins->src[0], coord_mask);
+ image_data = vkd3d_string_buffer_get(&gen->string_buffers);
+
+ if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR)
+ {
+ switch (component_type)
+ {
+ case VKD3D_SHADER_COMPONENT_UINT:
+ vkd3d_string_buffer_printf(image_data, "uvec4(");
+ break;
+ case VKD3D_SHADER_COMPONENT_INT:
+ vkd3d_string_buffer_printf(image_data, "ivec4(");
+ break;
+ default:
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled component type %#x.", component_type);
+ /* fall through */
+ case VKD3D_SHADER_COMPONENT_FLOAT:
+ vkd3d_string_buffer_printf(image_data, "vec4(");
+ break;
+ }
+ }
+ shader_glsl_print_src(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL,
+ vkd3d_data_type_from_component_type(component_type));
+ if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR)
+ vkd3d_string_buffer_printf(image_data, ", 0, 0, 0)");
+
+ shader_glsl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "imageStore(");
+ shader_glsl_print_image_name(gen->buffer, gen, uav_idx, uav_space);
+ vkd3d_string_buffer_printf(gen->buffer, ", %s, %s);\n", image_coord.str->buffer, image_data->buffer);
+
+ vkd3d_string_buffer_release(&gen->string_buffers, image_data);
+ glsl_src_cleanup(&image_coord, &gen->string_buffers);
+}
+
static void shader_glsl_unary_op(struct vkd3d_glsl_generator *gen,
const struct vkd3d_shader_instruction *ins, const char *op)
{
@@ -1336,6 +1429,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
case VKD3DSIH_SQRT:
shader_glsl_intrinsic(gen, ins, "sqrt");
break;
+ case VKD3DSIH_STORE_UAV_TYPED:
+ shader_glsl_store_uav_typed(gen, ins);
+ break;
case VKD3DSIH_SWITCH:
shader_glsl_switch(gen, ins);
break;
@@ -1372,6 +1468,137 @@ static bool shader_glsl_check_shader_visibility(const struct vkd3d_glsl_generato
}
}
+static bool shader_glsl_get_uav_binding(const struct vkd3d_glsl_generator *gen, unsigned int register_space,
+ unsigned int register_idx, 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_resource_binding *binding;
+ 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->binding_count; ++i)
+ {
+ binding = &interface_info->bindings[i];
+
+ if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
+ 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 & resource_type_flag))
+ continue;
+ *binding_idx = i;
+ return true;
+ }
+
+ return false;
+}
+
+static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *gen,
+ const struct vkd3d_shader_descriptor_info1 *uav)
+{
+ const struct glsl_resource_type_info *resource_type_info;
+ const char *image_type_prefix, *image_type, *read_format;
+ const struct vkd3d_shader_descriptor_binding *binding;
+ const struct vkd3d_shader_descriptor_offset *offset;
+ struct vkd3d_string_buffer *buffer = gen->buffer;
+ enum vkd3d_shader_component_type component_type;
+ unsigned int binding_idx;
+
+ if (uav->count != 1)
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED,
+ "UAV %u has unsupported descriptor array size %u.", uav->register_id, uav->count);
+ return;
+ }
+
+ if (!shader_glsl_get_uav_binding(gen, uav->register_space,
+ uav->register_index, uav->resource_type, &binding_idx))
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND,
+ "No descriptor binding specified for UAV %u.", uav->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 UAV %u.", binding->set, uav->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 UAV %u.", binding->count, uav->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 UAV %u.",
+ uav->register_id);
+ return;
+ }
+ }
+
+ if ((resource_type_info = shader_glsl_get_resource_type_info(uav->resource_type)))
+ {
+ image_type = resource_type_info->type_suffix;
+ }
+ else
+ {
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled UAV type %#x.", uav->resource_type);
+ image_type = "<unhandled image type>";
+ }
+
+ switch ((component_type = vkd3d_component_type_from_resource_data_type(uav->resource_data_type)))
+ {
+ case VKD3D_SHADER_COMPONENT_UINT:
+ image_type_prefix = "u";
+ read_format = "r32ui";
+ break;
+ case VKD3D_SHADER_COMPONENT_INT:
+ image_type_prefix = "i";
+ read_format = "r32i";
+ break;
+ default:
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled component type %#x for UAV %u.",
+ component_type, uav->register_id);
+ /* fall through */
+ case VKD3D_SHADER_COMPONENT_FLOAT:
+ image_type_prefix = "";
+ read_format = "r32f";
+ break;
+ }
+
+ vkd3d_string_buffer_printf(buffer, "layout(binding = %u", binding->binding);
+ if (uav->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)
+ vkd3d_string_buffer_printf(buffer, ", %s) ", read_format);
+ else
+ vkd3d_string_buffer_printf(buffer, ") writeonly ");
+ vkd3d_string_buffer_printf(buffer, "uniform %simage%s ", image_type_prefix, image_type);
+ shader_glsl_print_image_name(buffer, gen, uav->register_index, uav->register_space);
+ vkd3d_string_buffer_printf(buffer, ";\n");
+}
+
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)
{
@@ -1415,7 +1642,7 @@ static void shader_glsl_generate_cbv_declaration(struct vkd3d_glsl_generator *ge
if (cbv->count != 1)
{
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND,
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED,
"Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count);
return;
}
@@ -1540,7 +1767,7 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator
if ((resource_type_info = shader_glsl_get_resource_type_info(srv->resource_type)))
{
- sampler_type = resource_type_info->sampler_type;
+ sampler_type = resource_type_info->type_suffix;
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);
@@ -1603,7 +1830,7 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator
return;
}
- vkd3d_string_buffer_printf(buffer, "layout(binding = %u) uniform %s%s%s ",
+ vkd3d_string_buffer_printf(buffer, "layout(binding = %u) uniform %ssampler%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);
@@ -1628,6 +1855,10 @@ static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_gener
/* GLSL uses combined resource/sampler descriptors.*/
break;
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
+ shader_glsl_generate_uav_declaration(gen, descriptor);
+ break;
+
case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
shader_glsl_generate_cbv_declaration(gen, descriptor);
break;
@@ -1820,7 +2051,7 @@ static void shader_glsl_generate_output_declarations(struct vkd3d_glsl_generator
"Internal compiler error: Unhandled output component type %#x.", e->component_type);
break;
}
- vkd3d_string_buffer_printf(buffer, " shader_out_%u;\n", i);
+ vkd3d_string_buffer_printf(buffer, " shader_out_%u;\n", e->semantic_index);
++count;
}
if (count)
@@ -1837,6 +2068,14 @@ 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;
+ const struct vsir_thread_group_size *group_size;
+
+ if (program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE)
+ {
+ group_size = &program->thread_group_size;
+ vkd3d_string_buffer_printf(buffer, "layout(local_size_x = %u, local_size_y = %u, local_size_z = %u) in;\n\n",
+ group_size->x, group_size->y, group_size->z);
+ }
shader_glsl_generate_descriptor_declarations(gen);
shader_glsl_generate_input_declarations(gen);
@@ -1918,6 +2157,10 @@ static void shader_glsl_init_limits(struct vkd3d_glsl_generator *gen, const stru
limits->input_count = 32;
limits->output_count = 8;
break;
+ case VKD3D_SHADER_TYPE_COMPUTE:
+ limits->input_count = 0;
+ limits->output_count = 0;
+ break;
default:
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled shader type %#x.", version->type);
@@ -1948,8 +2191,8 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen,
gen->prefix = "unknown";
}
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->interstage_input = type != VKD3D_SHADER_TYPE_VERTEX && type != VKD3D_SHADER_TYPE_COMPUTE;
+ gen->interstage_output = type != VKD3D_SHADER_TYPE_PIXEL && type != VKD3D_SHADER_TYPE_COMPUTE;
gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO);
gen->offset_info = vkd3d_find_struct(compile_info->next, DESCRIPTOR_OFFSET_INFO);
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index affbae3ea4e..9d24126fba8 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -203,6 +203,12 @@ static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned
src->reg.idx[0].offset = idx;
}
+static void src_param_init_ssa_float(struct vkd3d_shader_src_param *src, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1);
+ src->reg.idx[0].offset = idx;
+}
+
static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
{
vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
@@ -244,6 +250,12 @@ static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned
dst->reg.idx[0].offset = idx;
}
+static void dst_param_init_ssa_float(struct vkd3d_shader_dst_param *dst, unsigned int idx)
+{
+ vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1);
+ dst->reg.idx[0].offset = idx;
+}
+
static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
{
vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
@@ -254,7 +266,6 @@ static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigne
{
vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
dst->reg.idx[0].offset = idx;
- dst->write_mask = VKD3DSP_WRITEMASK_0;
}
void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
@@ -682,6 +693,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
case VKD3DSIH_DCL_SAMPLER:
case VKD3DSIH_DCL_TEMPS:
case VKD3DSIH_DCL_THREAD_GROUP:
+ case VKD3DSIH_DCL_UAV_TYPED:
vkd3d_shader_instruction_make_nop(ins);
break;
@@ -1221,7 +1233,7 @@ static bool shader_signature_find_element_for_reg(const struct shader_signature
unsigned int reg_idx, unsigned int write_mask, unsigned int *element_idx)
{
const struct signature_element *e;
- unsigned int i, base_write_mask;
+ unsigned int i;
for (i = 0; i < signature->element_count; ++i)
{
@@ -1234,14 +1246,6 @@ static bool shader_signature_find_element_for_reg(const struct shader_signature
}
}
- /* Validated in the TPF reader, but failure in signature_element_range_expand_mask()
- * can land us here on an unmatched vector mask. */
- FIXME("Failed to find signature element for register index %u, mask %#x; using scalar mask.\n",
- reg_idx, write_mask);
- base_write_mask = 1u << vsir_write_mask_get_component_idx(write_mask);
- if (base_write_mask != write_mask)
- return shader_signature_find_element_for_reg(signature, reg_idx, base_write_mask, element_idx);
-
return false;
}
@@ -1655,6 +1659,9 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
break;
case VKD3DSPR_RASTOUT:
+ /* Leave point size as a system value for the backends to consume. */
+ if (reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
+ return true;
reg_idx = SM1_RASTOUT_REGISTER_OFFSET + reg->idx[0].offset;
signature = normaliser->output_signature;
reg->type = VKD3DSPR_OUTPUT;
@@ -5777,11 +5784,12 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog
return VKD3D_OK;
}
-static bool find_position_signature_idx(const struct shader_signature *signature, uint32_t *idx)
+static bool find_sysval_signature_idx(const struct shader_signature *signature,
+ enum vkd3d_shader_sysval_semantic sysval, uint32_t *idx)
{
for (unsigned int i = 0; i < signature->element_count; ++i)
{
- if (signature->elements[i].sysval_semantic == VKD3D_SHADER_SV_POSITION)
+ if (signature->elements[i].sysval_semantic == sysval)
{
*idx = i;
return true;
@@ -5846,7 +5854,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr
}
}
- if (!find_position_signature_idx(signature, &position_signature_idx))
+ if (!find_sysval_signature_idx(signature, VKD3D_SHADER_SV_POSITION, &position_signature_idx))
{
vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC,
"Shader does not write position.");
@@ -5923,6 +5931,191 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr
return VKD3D_OK;
}
+static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *program,
+ const struct vkd3d_shader_instruction *ret, size_t *ret_pos)
+{
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
+ size_t pos = ret - instructions->elements;
+ struct vkd3d_shader_instruction *ins;
+
+ if (!shader_instruction_array_insert_at(&program->instructions, pos, 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ ins = &program->instructions.elements[pos];
+
+ vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_MOV, 1, 1);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
+ ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VKD3D_DATA_FLOAT);
+
+ *ret_pos = pos + 1;
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
+{
+ const struct vkd3d_shader_parameter1 *size_parameter = NULL;
+ static const struct vkd3d_shader_location no_loc;
+
+ if (program->has_point_size)
+ return VKD3D_OK;
+
+ if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX
+ && program->shader_version.type != VKD3D_SHADER_TYPE_GEOMETRY
+ && program->shader_version.type != VKD3D_SHADER_TYPE_HULL
+ && program->shader_version.type != VKD3D_SHADER_TYPE_DOMAIN)
+ return VKD3D_OK;
+
+ for (unsigned int i = 0; i < program->parameter_count; ++i)
+ {
+ const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i];
+
+ if (parameter->name == VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE)
+ size_parameter = parameter;
+ }
+
+ if (!size_parameter)
+ return VKD3D_OK;
+
+ if (size_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32)
+ {
+ vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid point size parameter data type %#x.", size_parameter->data_type);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+
+ program->has_point_size = true;
+
+ /* Append a point size write before each ret. */
+ for (size_t i = 0; i < program->instructions.count; ++i)
+ {
+ struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+
+ if (ins->opcode == VKD3DSIH_RET)
+ {
+ size_t new_pos;
+ int ret;
+
+ if ((ret = insert_point_size_before_ret(program, ins, &new_pos)) < 0)
+ return ret;
+ i = new_pos;
+ }
+ }
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
+{
+ const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL;
+ static const struct vkd3d_shader_location no_loc;
+
+ if (!program->has_point_size)
+ return VKD3D_OK;
+
+ if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX
+ && program->shader_version.type != VKD3D_SHADER_TYPE_GEOMETRY
+ && program->shader_version.type != VKD3D_SHADER_TYPE_HULL
+ && program->shader_version.type != VKD3D_SHADER_TYPE_DOMAIN)
+ return VKD3D_OK;
+
+ for (unsigned int i = 0; i < program->parameter_count; ++i)
+ {
+ const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i];
+
+ if (parameter->name == VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN)
+ min_parameter = parameter;
+ else if (parameter->name == VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX)
+ max_parameter = parameter;
+ }
+
+ if (!min_parameter && !max_parameter)
+ return VKD3D_OK;
+
+ if (min_parameter && min_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32)
+ {
+ vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid minimum point size parameter data type %#x.", min_parameter->data_type);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (max_parameter && max_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32)
+ {
+ vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid maximum point size parameter data type %#x.", max_parameter->data_type);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+
+ /* Replace writes to the point size by inserting a clamp before each write. */
+
+ for (size_t i = 0; i < program->instructions.count; ++i)
+ {
+ struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+ const struct vkd3d_shader_location *loc;
+ unsigned int ssa_value;
+ bool clamp = false;
+
+ if (vsir_instruction_is_dcl(ins))
+ continue;
+
+ for (size_t j = 0; j < ins->dst_count; ++j)
+ {
+ struct vkd3d_shader_dst_param *dst = &ins->dst[j];
+
+ /* Note we run after I/O normalization. */
+ if (dst->reg.type == VKD3DSPR_RASTOUT)
+ {
+ dst_param_init_ssa_float(dst, program->ssa_count);
+ ssa_value = program->ssa_count++;
+ clamp = true;
+ }
+ }
+
+ if (!clamp)
+ continue;
+
+ if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ loc = &program->instructions.elements[i].location;
+ ins = &program->instructions.elements[i + 1];
+
+ if (min_parameter)
+ {
+ vsir_instruction_init_with_params(program, ins, loc, VKD3DSIH_MAX, 1, 2);
+ src_param_init_ssa_float(&ins->src[0], ssa_value);
+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VKD3D_DATA_FLOAT);
+ if (max_parameter)
+ {
+ dst_param_init_ssa_float(&ins->dst[0], program->ssa_count);
+ ssa_value = program->ssa_count++;
+ }
+ else
+ {
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
+ ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
+ }
+ ++ins;
+ ++i;
+ }
+
+ if (max_parameter)
+ {
+ vsir_instruction_init_with_params(program, ins, loc, VKD3DSIH_MIN, 1, 2);
+ src_param_init_ssa_float(&ins->src[0], ssa_value);
+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VKD3D_DATA_FLOAT);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
+ ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
+
+ ++i;
+ }
+ }
+
+ return VKD3D_OK;
+}
+
struct validation_context
{
struct vkd3d_shader_message_context *message_context;
@@ -6395,23 +6588,18 @@ static void vsir_validate_dst_param(struct validation_context *ctx,
break;
case VKD3DSPR_IMMCONST:
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid IMMCONST register used as destination parameter.");
- break;
-
case VKD3DSPR_IMMCONST64:
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid IMMCONST64 register used as destination parameter.");
- break;
-
case VKD3DSPR_SAMPLER:
+ case VKD3DSPR_RESOURCE:
+ case VKD3DSPR_INPUT:
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid SAMPLER register used as destination parameter.");
+ "Invalid %#x register used as destination parameter.", dst->reg.type);
break;
- case VKD3DSPR_RESOURCE:
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid RESOURCE register used as destination parameter.");
+ case VKD3DSPR_PATCHCONST:
+ if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "PATCHCONST register used as destination parameters are only allowed in Hull Shaders.");
break;
default:
@@ -6454,6 +6642,20 @@ static void vsir_validate_src_param(struct validation_context *ctx,
"Invalid NULL register used as source parameter.");
break;
+ case VKD3DSPR_OUTPUT:
+ if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL
+ || (ctx->phase != VKD3DSIH_HS_FORK_PHASE && ctx->phase != VKD3DSIH_HS_JOIN_PHASE))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid OUTPUT register used as source parameter.");
+ break;
+
+ case VKD3DSPR_PATCHCONST:
+ if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_DOMAIN
+ && ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "PATCHCONST register used as source parameters are only allowed in Hull and Domain Shaders.");
+ break;
+
default:
break;
}
@@ -6510,6 +6712,7 @@ static void vsir_validate_signature_element(struct validation_context *ctx,
unsigned int idx)
{
const struct signature_element *element = &signature->elements[idx];
+ bool integer_type = false;
if (element->register_count == 0)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
@@ -6518,6 +6721,97 @@ static void vsir_validate_signature_element(struct validation_context *ctx,
if (element->mask == 0 || (element->mask & ~0xf))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
"element %u of %s signature: Invalid mask %#x.", idx, signature_type, element->mask);
+
+ /* Here we'd likely want to validate that the usage mask is a subset of the
+ * signature mask. Unfortunately the D3DBC parser sometimes violates this.
+ * For example I've seen a shader like this:
+ * ps_3_0
+ * [...]
+ * dcl_texcoord0 v0
+ * [...]
+ * texld r2.xyzw, v0.xyzw, s1.xyzw
+ * [...]
+ *
+ * The dcl_textcoord0 instruction secretly has a .xy mask, which is used to
+ * compute the signature mask, but the texld instruction apparently uses all
+ * the components. Of course the last two components are ignored, but
+ * formally they seem to be used. So we end up with a signature element with
+ * mask .xy and usage mask .xyzw.
+ *
+ * The correct fix would probably be to make the D3DBC parser aware of which
+ * components are really used for each instruction, but that would take some
+ * time. */
+ if (element->used_mask & ~0xf)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
+ "element %u of %s signature: Invalid usage mask %#x.",
+ idx, signature_type, element->used_mask);
+
+ switch (element->sysval_semantic)
+ {
+ case VKD3D_SHADER_SV_NONE:
+ case VKD3D_SHADER_SV_POSITION:
+ case VKD3D_SHADER_SV_CLIP_DISTANCE:
+ case VKD3D_SHADER_SV_CULL_DISTANCE:
+ case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX:
+ case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX:
+ case VKD3D_SHADER_SV_VERTEX_ID:
+ case VKD3D_SHADER_SV_PRIMITIVE_ID:
+ case VKD3D_SHADER_SV_INSTANCE_ID:
+ case VKD3D_SHADER_SV_IS_FRONT_FACE:
+ case VKD3D_SHADER_SV_SAMPLE_INDEX:
+ case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE:
+ case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT:
+ case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE:
+ case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT:
+ case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET:
+ case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN:
+ case VKD3D_SHADER_SV_TARGET:
+ case VKD3D_SHADER_SV_DEPTH:
+ case VKD3D_SHADER_SV_COVERAGE:
+ case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL:
+ case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL:
+ case VKD3D_SHADER_SV_STENCIL_REF:
+ break;
+
+ default:
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
+ "element %u of %s signature: Invalid system value semantic %#x.",
+ idx, signature_type, element->sysval_semantic);
+ break;
+ }
+
+ switch (element->component_type)
+ {
+ case VKD3D_SHADER_COMPONENT_INT:
+ case VKD3D_SHADER_COMPONENT_UINT:
+ integer_type = true;
+ break;
+
+ case VKD3D_SHADER_COMPONENT_FLOAT:
+ break;
+
+ default:
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
+ "element %u of %s signature: Invalid component type %#x.",
+ idx, signature_type, element->component_type);
+ break;
+ }
+
+ if (element->min_precision >= VKD3D_SHADER_MINIMUM_PRECISION_COUNT)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
+ "element %u of %s signature: Invalid minimum precision %#x.",
+ idx, signature_type, element->min_precision);
+
+ if (element->interpolation_mode >= VKD3DSIM_COUNT)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
+ "element %u of %s signature: Invalid interpolation mode %#x.",
+ idx, signature_type, element->interpolation_mode);
+
+ if (integer_type && element->interpolation_mode != VKD3DSIM_NONE
+ && element->interpolation_mode != VKD3DSIM_CONSTANT)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
+ "element %u of %s signature: Invalid interpolation mode %#x for integer component type.",
+ idx, signature_type, element->interpolation_mode);
}
static void vsir_validate_signature(struct validation_context *ctx,
@@ -7060,6 +7354,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c
.null_location = {.source_name = source_name},
.status = VKD3D_OK,
.phase = VKD3DSIH_INVALID,
+ .invalid_instruction_idx = true,
};
unsigned int i;
@@ -7088,6 +7383,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c
if (!(ctx.ssas = vkd3d_calloc(ctx.program->ssa_count, sizeof(*ctx.ssas))))
goto fail;
+ ctx.invalid_instruction_idx = false;
+
for (ctx.instruction_idx = 0; ctx.instruction_idx < program->instructions.count
&& ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; ++ctx.instruction_idx)
vsir_validate_instruction(&ctx);
@@ -7190,6 +7487,8 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t
vsir_transform(&ctx, vsir_program_insert_alpha_test);
vsir_transform(&ctx, vsir_program_insert_clip_planes);
+ vsir_transform(&ctx, vsir_program_insert_point_size);
+ vsir_transform(&ctx, vsir_program_insert_point_size_clamp);
if (TRACE_ON())
vsir_program_trace(program);
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c
index bfc013959e7..36750de1fd8 100644
--- a/libs/vkd3d/libs/vkd3d-shader/msl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c
@@ -39,6 +39,8 @@ struct msl_generator
struct vkd3d_shader_message_context *message_context;
unsigned int indent;
const char *prefix;
+ const struct vkd3d_shader_interface_info *interface_info;
+ const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info;
};
static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen,
@@ -109,6 +111,64 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer,
vkd3d_string_buffer_printf(buffer, "r[%u]", reg->idx[0].offset);
msl_print_register_datatype(buffer, gen, reg->data_type);
break;
+
+ case VKD3DSPR_INPUT:
+ if (reg->idx_count != 1)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled input register index count %u.", reg->idx_count);
+ vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
+ break;
+ }
+ if (reg->idx[0].rel_addr)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled input register indirect addressing.");
+ vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
+ break;
+ }
+ vkd3d_string_buffer_printf(buffer, "v[%u]", reg->idx[0].offset);
+ msl_print_register_datatype(buffer, gen, reg->data_type);
+ break;
+
+ case VKD3DSPR_OUTPUT:
+ if (reg->idx_count != 1)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled output register index count %u.", reg->idx_count);
+ vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
+ break;
+ }
+ if (reg->idx[0].rel_addr)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled output register indirect addressing.");
+ vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
+ break;
+ }
+ vkd3d_string_buffer_printf(buffer, "o[%u]", reg->idx[0].offset);
+ msl_print_register_datatype(buffer, gen, reg->data_type);
+ break;
+
+ case VKD3DSPR_CONSTBUFFER:
+ if (reg->idx_count != 3)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_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)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_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, "descriptors.cb_%u[%u]", reg->idx[0].offset, reg->idx[2].offset);
+ msl_print_register_datatype(buffer, gen, reg->data_type);
+ break;
+
default:
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
"Internal compiler error: Unhandled register type %#x.", reg->type);
@@ -266,6 +326,144 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
}
}
+static bool msl_check_shader_visibility(const struct msl_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 msl_get_cbv_binding(const struct msl_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 (!msl_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 msl_generate_cbv_declaration(struct msl_generator *gen,
+ const struct vkd3d_shader_descriptor_info1 *cbv)
+{
+ const struct vkd3d_shader_descriptor_binding *binding;
+ struct vkd3d_string_buffer *buffer = gen->buffer;
+ unsigned int binding_idx;
+ size_t size;
+
+ if (cbv->count != 1)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
+ "Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count);
+ return;
+ }
+
+ if (!msl_get_cbv_binding(gen, cbv->register_space, cbv->register_index, &binding_idx))
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_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)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
+ "Unsupported binding set %u specified for constant buffer %u.", binding->set, cbv->register_id);
+ return;
+ }
+
+ if (binding->count != 1)
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
+ "Unsupported binding count %u specified for constant buffer %u.", binding->count, 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,
+ "constant vkd3d_vec4 (&cb_%u)[%zu] [[id(%u)]];", cbv->register_id, size, binding->binding);
+};
+
+static void msl_generate_descriptor_struct_declarations(struct msl_generator *gen)
+{
+ const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info;
+ const struct vkd3d_shader_descriptor_info1 *descriptor;
+ struct vkd3d_string_buffer *buffer = gen->buffer;
+ unsigned int i;
+
+ if (!info->descriptor_count)
+ return;
+
+ vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_descriptors\n{\n", gen->prefix);
+
+ for (i = 0; i < info->descriptor_count; ++i)
+ {
+ descriptor = &info->descriptors[i];
+
+ msl_print_indent(buffer, 1);
+ switch (descriptor->type)
+ {
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
+ msl_generate_cbv_declaration(gen, descriptor);
+ break;
+
+ default:
+ vkd3d_string_buffer_printf(buffer, "/* <unhandled descriptor type %#x> */", descriptor->type);
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled descriptor type %#x.", descriptor->type);
+ break;
+ }
+ vkd3d_string_buffer_printf(buffer, "\n");
+ }
+
+ vkd3d_string_buffer_printf(buffer, "};\n\n");
+}
+
static void msl_generate_input_struct_declarations(struct msl_generator *gen)
{
const struct shader_signature *signature = &gen->program->input_signature;
@@ -550,9 +748,15 @@ static void msl_generate_entrypoint(struct msl_generator *gen)
vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out shader_entry(\n", gen->prefix);
- /* TODO: descriptor declaration */
+ if (gen->descriptor_info->descriptor_count)
+ {
+ msl_print_indent(gen->buffer, 2);
+ /* TODO: Configurable argument buffer binding location. */
+ vkd3d_string_buffer_printf(gen->buffer,
+ "constant vkd3d_%s_descriptors& descriptors [[buffer(0)]],\n", gen->prefix);
+ }
- msl_print_indent(gen->buffer, 1);
+ msl_print_indent(gen->buffer, 2);
vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix);
/* TODO: declare #maximum_register + 1 */
@@ -562,7 +766,10 @@ static void msl_generate_entrypoint(struct msl_generator *gen)
msl_generate_entrypoint_prologue(gen);
- vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out);\n", gen->prefix, gen->prefix, gen->prefix);
+ vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix);
+ if (gen->descriptor_info->descriptor_count)
+ vkd3d_string_buffer_printf(gen->buffer, ", descriptors");
+ vkd3d_string_buffer_printf(gen->buffer, ");\n");
msl_generate_entrypoint_epilogue(gen);
@@ -583,13 +790,17 @@ static void msl_generator_generate(struct msl_generator *gen)
vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n");
vkd3d_string_buffer_printf(gen->buffer, " float4 f;\n};\n\n");
+ msl_generate_descriptor_struct_declarations(gen);
msl_generate_input_struct_declarations(gen);
msl_generate_output_struct_declarations(gen);
vkd3d_string_buffer_printf(gen->buffer,
"void %s_main(thread vkd3d_vec4 *v, "
- "thread vkd3d_vec4 *o)\n{\n",
+ "thread vkd3d_vec4 *o",
gen->prefix);
+ if (gen->descriptor_info->descriptor_count)
+ vkd3d_string_buffer_printf(gen->buffer, ", constant vkd3d_%s_descriptors& descriptors", gen->prefix);
+ vkd3d_string_buffer_printf(gen->buffer, ")\n{\n");
++gen->indent;
@@ -621,6 +832,8 @@ static void msl_generator_cleanup(struct msl_generator *gen)
}
static int msl_generator_init(struct msl_generator *gen, 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;
@@ -640,11 +853,14 @@ static int msl_generator_init(struct msl_generator *gen, struct vsir_program *pr
"Internal compiler error: Unhandled shader type %#x.", type);
return VKD3D_ERROR_INVALID_SHADER;
}
+ gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO);
+ gen->descriptor_info = descriptor_info;
return VKD3D_OK;
}
int msl_compile(struct vsir_program *program, uint64_t config_flags,
+ const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
{
struct msl_generator generator;
@@ -653,7 +869,7 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags,
if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0)
return ret;
- if ((ret = msl_generator_init(&generator, program, message_context)) < 0)
+ if ((ret = msl_generator_init(&generator, program, compile_info, descriptor_info, message_context)) < 0)
return ret;
msl_generator_generate(&generator);
msl_generator_cleanup(&generator);
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 692432d5513..1efd717e970 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -2662,8 +2662,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p
if ((shader_interface = vkd3d_find_struct(compile_info->next, INTERFACE_INFO)))
{
compiler->xfb_info = vkd3d_find_struct(compile_info->next, TRANSFORM_FEEDBACK_INFO);
- compiler->emit_point_size = compiler->xfb_info && compiler->xfb_info->element_count
- && compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY;
compiler->shader_interface = *shader_interface;
if (shader_interface->push_constant_buffer_count)
@@ -2690,6 +2688,11 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p
}
}
+ if (compiler->shader_type == VKD3D_SHADER_TYPE_VERTEX)
+ compiler->emit_point_size = true;
+ else if (compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY)
+ compiler->emit_point_size = compiler->xfb_info && compiler->xfb_info->element_count;
+
compiler->scan_descriptor_info = scan_descriptor_info;
compiler->phase = VKD3DSIH_INVALID;
@@ -4860,6 +4863,10 @@ static const struct vkd3d_spirv_builtin vkd3d_pixel_shader_position_builtin =
{
VKD3D_SHADER_COMPONENT_FLOAT, 4, SpvBuiltInFragCoord, frag_coord_fixup,
};
+static const struct vkd3d_spirv_builtin vkd3d_output_point_size_builtin =
+{
+ VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInPointSize,
+};
static const struct
{
enum vkd3d_shader_register_type reg_type;
@@ -5449,7 +5456,11 @@ static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler,
VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr);
VKD3D_ASSERT(reg->idx_count < 2);
- if (!(builtin = get_spirv_builtin_for_register(reg->type)))
+ if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
+ {
+ builtin = &vkd3d_output_point_size_builtin;
+ }
+ else if (!(builtin = get_spirv_builtin_for_register(reg->type)))
{
FIXME("Unhandled register %#x.\n", reg->type);
return;
@@ -6746,7 +6757,8 @@ static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compi
static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler)
{
- static const struct vkd3d_spirv_builtin point_size = {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInPointSize};
+ if (compiler->program->has_point_size)
+ return;
/* Set the point size. Point sprites are not supported in d3d10+, but
* point primitives can still be used with e.g. stream output. Vulkan
@@ -6760,7 +6772,8 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler)
|| compiler->write_tess_geom_point_size)
{
vkd3d_spirv_build_op_store(&compiler->spirv_builder,
- spirv_compiler_emit_builtin_variable(compiler, &point_size, SpvStorageClassOutput, 0),
+ spirv_compiler_emit_builtin_variable(compiler,
+ &vkd3d_output_point_size_builtin, SpvStorageClassOutput, 0),
spirv_compiler_get_constant_float(compiler, 1.0f), SpvMemoryAccessMaskNone);
}
}
@@ -7427,7 +7440,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
uint32_t components[VKD3D_VEC4_SIZE];
if (register_is_constant_or_undef(&src->reg) || src->reg.type == VKD3DSPR_SSA || dst->reg.type == VKD3DSPR_SSA
- || dst->modifiers || src->modifiers)
+ || src->reg.type == VKD3DSPR_PARAMETER || dst->modifiers || src->modifiers)
goto general_implementation;
spirv_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info);
@@ -10538,7 +10551,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
case VKD3DSIH_DCL_UAV_RAW:
case VKD3DSIH_DCL_UAV_STRUCTURED:
- case VKD3DSIH_DCL_UAV_TYPED:
case VKD3DSIH_HS_DECLS:
case VKD3DSIH_NOP:
/* nothing to do */
@@ -10575,6 +10587,15 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
else
spirv_compiler_emit_input(compiler, VKD3DSPR_PATCHCONST, i);
}
+
+ if (compiler->program->has_point_size)
+ {
+ struct vkd3d_shader_dst_param dst;
+
+ vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
+ dst.reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
+ spirv_compiler_emit_output_register(compiler, &dst);
+ }
}
static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler)
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index f84ac551272..cde8dc3146c 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -1655,7 +1655,10 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
break;
case VKD3D_SHADER_TARGET_MSL:
- ret = msl_compile(program, config_flags, compile_info, message_context);
+ if ((ret = vsir_program_scan(program, &scan_info, message_context, &scan_descriptor_info)) < 0)
+ return ret;
+ ret = msl_compile(program, config_flags, &scan_descriptor_info, compile_info, message_context);
+ vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
break;
default:
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 41b879af4b4..9ca3c328147 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -60,6 +60,7 @@
#define VKD3D_DVEC2_SIZE 2
#define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_UINT64 + 1)
+#define VKD3D_SHADER_MINIMUM_PRECISION_COUNT (VKD3D_SHADER_MINIMUM_PRECISION_UINT_16 + 1)
enum vkd3d_shader_error
{
@@ -250,6 +251,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300,
VKD3D_SHADER_ERROR_MSL_INTERNAL = 10000,
+ VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND = 10001,
};
enum vkd3d_shader_opcode
@@ -648,6 +650,13 @@ enum vkd3d_shader_register_type
VKD3DSPR_INVALID = ~0u,
};
+enum vsir_rastout_register
+{
+ VSIR_RASTOUT_POSITION = 0x0,
+ VSIR_RASTOUT_FOG = 0x1,
+ VSIR_RASTOUT_POINT_SIZE = 0x2,
+};
+
enum vkd3d_shader_register_precision
{
VKD3D_SHADER_REGISTER_PRECISION_DEFAULT,
@@ -1400,6 +1409,7 @@ struct vsir_program
unsigned int temp_count;
unsigned int ssa_count;
bool use_vocp;
+ bool has_point_size;
enum vsir_control_flow_type cf_type;
const char **block_names;
@@ -1617,6 +1627,7 @@ int spirv_compile(struct vsir_program *program, uint64_t config_flags,
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
int msl_compile(struct vsir_program *program, uint64_t config_flags,
+ const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
enum vkd3d_md5_variant
--
2.45.2