Updated vkd3d-latest patchset

This commit is contained in:
Alistair Leslie-Hughes 2023-08-31 09:25:00 +10:00
parent 05319e0efd
commit 5361c0277d
9 changed files with 20190 additions and 18629 deletions

View File

@ -1,7 +1,7 @@
From 226088587d4ba04bd8f9ee05b300ce7d03377187 Mon Sep 17 00:00:00 2001
From de371a0eaab2304c0c9f1facb9941d712949686d Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Wed, 17 May 2023 08:35:40 +1000
Subject: [PATCH 1/3] Update vkd3d to 771e442af16228a977eebba82224f06f6d0202fe
Subject: [PATCH] Update vkd3d to 771e442af16228a977eebba82224f06f6d0202fe
(1.8)
---

View File

@ -0,0 +1,947 @@
From 247ab6630dc34db194033b3721d30246c8fb8012 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 29 Aug 2023 07:21:37 +1000
Subject: [PATCH] Updated vkd3d to 269747dbf3ee32bf23e6d1ab388d2a058ca90f9f.
---
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 1 +
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 47 ++-
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 5 +-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 296 +++++++++---------
libs/vkd3d/libs/vkd3d-shader/tpf.c | 144 +++++++--
.../libs/vkd3d-shader/vkd3d_shader_private.h | 37 +++
libs/vkd3d/libs/vkd3d/command.c | 5 +-
7 files changed, 347 insertions(+), 188 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 0a8d3a692a3..070fec74326 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -356,6 +356,7 @@ struct hlsl_attribute
#define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400
#define HLSL_STORAGE_IN 0x00000800
#define HLSL_STORAGE_OUT 0x00001000
+#define HLSL_MODIFIER_INLINE 0x00002000
#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \
HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 29e0ff0c5be..43ea4b4d038 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -493,11 +493,11 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type,
|| !strcmp(attr->name, "fastopt")
|| !strcmp(attr->name, "allow_uav_condition"))
{
- hlsl_fixme(ctx, loc, "Unhandled attribute %s.", attr->name);
+ hlsl_fixme(ctx, loc, "Unhandled attribute '%s'.", attr->name);
}
else
{
- hlsl_warning(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "Unrecognized attribute %s.", attr->name);
+ hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Unrecognized attribute '%s'.", attr->name);
}
}
@@ -5129,6 +5129,9 @@ func_prototype_no_attrs:
struct hlsl_ir_var *var;
struct hlsl_type *type;
+ /* Functions are unconditionally inlined. */
+ modifiers &= ~HLSL_MODIFIER_INLINE;
+
if (modifiers & ~HLSL_MODIFIERS_MAJORITY_MASK)
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
"Only majority modifiers are allowed on functions.");
@@ -5970,6 +5973,10 @@ var_modifiers:
{
$$ = add_modifiers(ctx, $2, HLSL_STORAGE_IN | HLSL_STORAGE_OUT, &@1);
}
+ | KW_INLINE var_modifiers
+ {
+ $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_INLINE, &@1);
+ }
complex_initializer:
@@ -6108,19 +6115,39 @@ jump_statement:
}
selection_statement:
- KW_IF '(' expr ')' if_body
+ attribute_list_optional KW_IF '(' expr ')' if_body
{
- struct hlsl_ir_node *condition = node_from_block($3);
+ struct hlsl_ir_node *condition = node_from_block($4);
+ const struct parse_attribute_list *attributes = &$1;
struct hlsl_ir_node *instr;
+ unsigned int i;
+
+ if (attribute_list_has_duplicates(attributes))
+ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Found duplicate attribute.");
+
+ for (i = 0; i < attributes->count; ++i)
+ {
+ const struct hlsl_attribute *attr = attributes->attrs[i];
+
+ if (!strcmp(attr->name, "branch")
+ || !strcmp(attr->name, "flatten"))
+ {
+ hlsl_warning(ctx, &@1, VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE, "Unhandled attribute '%s'.", attr->name);
+ }
+ else
+ {
+ hlsl_warning(ctx, &@1, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Unrecognized attribute '%s'.", attr->name);
+ }
+ }
- if (!(instr = hlsl_new_if(ctx, condition, $5.then_block, $5.else_block, &@1)))
+ if (!(instr = hlsl_new_if(ctx, condition, $6.then_block, $6.else_block, &@2)))
{
- destroy_block($5.then_block);
- destroy_block($5.else_block);
+ destroy_block($6.then_block);
+ destroy_block($6.else_block);
YYABORT;
}
- destroy_block($5.then_block);
- destroy_block($5.else_block);
+ destroy_block($6.then_block);
+ destroy_block($6.else_block);
if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1)
{
struct vkd3d_string_buffer *string;
@@ -6130,7 +6157,7 @@ selection_statement:
"if condition type %s is not scalar.", string->buffer);
hlsl_release_string_buffer(ctx, string);
}
- $$ = $3;
+ $$ = $4;
hlsl_block_add_instr($$, instr);
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index bfa605f4ba7..bae8e5f9a5f 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -321,9 +321,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, s
if (!semantic->name)
return;
- vector_type_src = hlsl_get_vector_type(ctx, type->base_type,
- (ctx->profile->major_version < 4) ? 4 : hlsl_type_minor_size(type));
vector_type_dst = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type));
+ vector_type_src = vector_type_dst;
+ if (ctx->profile->major_version < 4 && ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX)
+ vector_type_src = hlsl_get_vector_type(ctx, type->base_type, 4);
for (i = 0; i < hlsl_type_major_size(type); ++i)
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index fa605f185ae..9b3084538ba 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -204,11 +204,6 @@ static inline bool register_is_undef(const struct vkd3d_shader_register *reg)
return reg->type == VKD3DSPR_UNDEF;
}
-static inline bool register_is_constant(const struct vkd3d_shader_register *reg)
-{
- return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64);
-}
-
static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg)
{
return register_is_constant(reg) || register_is_undef(reg);
@@ -2599,8 +2594,8 @@ static struct vkd3d_push_constant_buffer_binding *spirv_compiler_find_push_const
return NULL;
}
-static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *compiler,
- const struct vkd3d_shader_resource *resource, const struct vkd3d_shader_sampler *sampler)
+static bool spirv_compiler_has_combined_sampler_for_resource(const struct spirv_compiler *compiler,
+ const struct vkd3d_shader_register_range *range)
{
const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface;
const struct vkd3d_shader_combined_resource_sampler *combined_sampler;
@@ -2609,10 +2604,35 @@ static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *com
if (!shader_interface->combined_sampler_count)
return false;
- if (resource && (resource->reg.reg.type == VKD3DSPR_UAV || resource->range.last != resource->range.first))
+ if (range->last != range->first)
+ return false;
+
+ for (i = 0; i < shader_interface->combined_sampler_count; ++i)
+ {
+ combined_sampler = &shader_interface->combined_samplers[i];
+
+ if (!spirv_compiler_check_shader_visibility(compiler, combined_sampler->shader_visibility))
+ continue;
+
+ if ((combined_sampler->resource_space == range->space
+ && combined_sampler->resource_index == range->first))
+ return true;
+ }
+
+ return false;
+}
+
+static bool spirv_compiler_has_combined_sampler_for_sampler(const struct spirv_compiler *compiler,
+ const struct vkd3d_shader_register_range *range)
+{
+ const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface;
+ const struct vkd3d_shader_combined_resource_sampler *combined_sampler;
+ unsigned int i;
+
+ if (!shader_interface->combined_sampler_count)
return false;
- if (sampler && sampler->range.first != sampler->range.last)
+ if (range->last != range->first)
return false;
for (i = 0; i < shader_interface->combined_sampler_count; ++i)
@@ -2622,10 +2642,8 @@ static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *com
if (!spirv_compiler_check_shader_visibility(compiler, combined_sampler->shader_visibility))
continue;
- if ((!resource || (combined_sampler->resource_space == resource->range.space
- && combined_sampler->resource_index == resource->range.first))
- && (!sampler || (combined_sampler->sampler_space == sampler->range.space
- && combined_sampler->sampler_index == sampler->range.first)))
+ if (combined_sampler->sampler_space == range->space
+ && combined_sampler->sampler_index == range->first)
return true;
}
@@ -2643,6 +2661,16 @@ static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_error(struct spirv_compiler *
compiler->failed = true;
}
+static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_warning(struct spirv_compiler *compiler,
+ enum vkd3d_shader_error error, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vkd3d_shader_vwarning(compiler->message_context, &compiler->location, error, format, args);
+ va_end(args);
+}
+
static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spirv_compiler *compiler,
const struct vkd3d_shader_register_range *range)
{
@@ -5538,8 +5566,8 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler *
return var_id;
}
-static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler, unsigned int size,
- const struct vkd3d_shader_register_range *range, const struct vkd3d_shader_register *reg)
+static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t vec4_id, array_type_id, length_id, struct_id, var_id;
@@ -5548,13 +5576,20 @@ static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler,
struct vkd3d_descriptor_variable_info var_info;
struct vkd3d_symbol reg_symbol;
+ struct vkd3d_shader_register reg =
+ {
+ .type = VKD3DSPR_CONSTBUFFER,
+ .idx[0].offset = register_id,
+ .idx_count = 1,
+ };
+
if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range)))
{
/* Push constant buffers are handled in
* spirv_compiler_emit_push_constant_buffers().
*/
unsigned int cb_size_in_bytes = size * VKD3D_VEC4_SIZE * sizeof(uint32_t);
- push_cb->reg = *reg;
+ push_cb->reg = reg;
push_cb->size = size;
if (cb_size_in_bytes > push_cb->pc.size)
{
@@ -5575,9 +5610,9 @@ static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler,
vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", size);
var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, struct_id,
- reg, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info);
+ &reg, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info);
- vkd3d_symbol_make_register(&reg_symbol, reg);
+ vkd3d_symbol_make_register(&reg_symbol, &reg);
vkd3d_symbol_set_register_info(&reg_symbol, var_id, storage_class,
VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL);
reg_symbol.descriptor_array = var_info.array_symbol;
@@ -5585,16 +5620,6 @@ static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler,
spirv_compiler_put_symbol(compiler, &reg_symbol);
}
-static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
-{
- const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
-
- assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC));
-
- spirv_compiler_emit_constant_buffer(compiler, cb->size, &cb->range, &cb->src.reg);
-}
-
static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
@@ -5628,29 +5653,34 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi
spirv_compiler_put_symbol(compiler, &reg_symbol);
}
-static void spirv_compiler_emit_dcl_sampler(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
+static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_register_range *range, unsigned int register_id)
{
- const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler;
const SpvStorageClass storage_class = SpvStorageClassUniformConstant;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- const struct vkd3d_shader_register *reg = &sampler->src.reg;
struct vkd3d_descriptor_variable_info var_info;
struct vkd3d_symbol reg_symbol;
uint32_t type_id, var_id;
- vkd3d_symbol_make_sampler(&reg_symbol, reg);
- reg_symbol.info.sampler.range = sampler->range;
+ const struct vkd3d_shader_register reg =
+ {
+ .type = VKD3DSPR_SAMPLER,
+ .idx[0].offset = register_id,
+ .idx_count = 1,
+ };
+
+ vkd3d_symbol_make_sampler(&reg_symbol, &reg);
+ reg_symbol.info.sampler.range = *range;
spirv_compiler_put_symbol(compiler, &reg_symbol);
- if (spirv_compiler_has_combined_sampler(compiler, NULL, sampler))
+ if (spirv_compiler_has_combined_sampler_for_sampler(compiler, range))
return;
type_id = vkd3d_spirv_get_op_type_sampler(builder);
- var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
- &sampler->range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info);
+ var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, &reg,
+ range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info);
- vkd3d_symbol_make_register(&reg_symbol, reg);
+ vkd3d_symbol_make_register(&reg_symbol, &reg);
vkd3d_symbol_set_register_info(&reg_symbol, var_id, storage_class,
VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL);
reg_symbol.descriptor_array = var_info.array_symbol;
@@ -5832,20 +5862,30 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi
}
static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *compiler,
- const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type,
- enum vkd3d_data_type resource_data_type, unsigned int structure_stride, bool raw)
+ const struct vkd3d_shader_register_range *range, unsigned int register_id,
+ unsigned int sample_count, bool is_uav, enum vkd3d_shader_resource_type resource_type,
+ enum vkd3d_shader_resource_data_type resource_data_type, unsigned int structure_stride, bool raw)
{
struct vkd3d_descriptor_variable_info var_info, counter_var_info = {0};
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
SpvStorageClass storage_class = SpvStorageClassUniformConstant;
uint32_t counter_type_id, type_id, var_id, counter_var_id = 0;
- const struct vkd3d_shader_register *reg = &resource->reg.reg;
const struct vkd3d_spirv_resource_type *resource_type_info;
enum vkd3d_shader_component_type sampled_type;
struct vkd3d_symbol resource_symbol;
- bool is_uav;
- is_uav = reg->type == VKD3DSPR_UAV;
+ struct vkd3d_shader_register reg =
+ {
+ .type = is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE,
+ .idx[0].offset = register_id,
+ .idx_count = 1,
+ };
+
+ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && sample_count == 1)
+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
+ else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY && sample_count == 1)
+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY;
+
if (!(resource_type_info = spirv_compiler_enable_resource_type(compiler,
resource_type, is_uav)))
{
@@ -5853,11 +5893,11 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
return;
}
- sampled_type = vkd3d_component_type_from_data_type(resource_data_type);
+ sampled_type = vkd3d_component_type_from_resource_data_type(resource_data_type);
- if (spirv_compiler_has_combined_sampler(compiler, resource, NULL))
+ if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range))
{
- spirv_compiler_emit_combined_sampler_declarations(compiler, reg, &resource->range,
+ spirv_compiler_emit_combined_sampler_declarations(compiler, &reg, range,
resource_type, sampled_type, structure_stride, raw, resource_type_info);
return;
}
@@ -5880,19 +5920,18 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
}
else
{
- type_id = spirv_compiler_get_image_type_id(compiler, reg, &resource->range,
+ type_id = spirv_compiler_get_image_type_id(compiler, &reg, range,
resource_type_info, sampled_type, structure_stride || raw, 0);
}
- var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
- &resource->range, resource_type, false, &var_info);
+ var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, &reg,
+ range, resource_type, false, &var_info);
if (is_uav)
{
const struct vkd3d_shader_descriptor_info1 *d;
- d = spirv_compiler_get_descriptor_info(compiler,
- VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, &resource->range);
+ d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range);
if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ))
vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0);
@@ -5924,15 +5963,15 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
type_id = struct_id;
}
- counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
- &resource->range, resource_type, true, &counter_var_info);
+ counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class,
+ type_id, &reg, range, resource_type, true, &counter_var_info);
}
}
- vkd3d_symbol_make_resource(&resource_symbol, reg);
+ vkd3d_symbol_make_resource(&resource_symbol, &reg);
resource_symbol.id = var_id;
resource_symbol.descriptor_array = var_info.array_symbol;
- resource_symbol.info.resource.range = resource->range;
+ resource_symbol.info.resource.range = *range;
resource_symbol.info.resource.sampled_type = sampled_type;
resource_symbol.info.resource.type_id = type_id;
resource_symbol.info.resource.resource_type_info = resource_type_info;
@@ -5945,58 +5984,6 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
spirv_compiler_put_symbol(compiler, &resource_symbol);
}
-static void spirv_compiler_emit_dcl_resource(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
-{
- const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic;
- enum vkd3d_shader_resource_type resource_type = semantic->resource_type;
- uint32_t flags = instruction->flags;
-
- /* We don't distinguish between APPEND and COUNTER UAVs. */
- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER;
- if (flags)
- FIXME("Unhandled UAV flags %#x.\n", flags);
-
- if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && semantic->sample_count == 1)
- resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
- else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY && semantic->sample_count == 1)
- resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY;
-
- spirv_compiler_emit_resource_declaration(compiler, &semantic->resource,
- resource_type, semantic->resource_data_type[0], 0, false);
-}
-
-static void spirv_compiler_emit_dcl_resource_raw(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
-{
- const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource;
- uint32_t flags = instruction->flags;
-
- /* We don't distinguish between APPEND and COUNTER UAVs. */
- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER;
- if (flags)
- FIXME("Unhandled UAV flags %#x.\n", flags);
-
- spirv_compiler_emit_resource_declaration(compiler, &resource->resource,
- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, true);
-}
-
-static void spirv_compiler_emit_dcl_resource_structured(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
-{
- const struct vkd3d_shader_structured_resource *resource = &instruction->declaration.structured_resource;
- unsigned int stride = resource->byte_stride;
- uint32_t flags = instruction->flags;
-
- /* We don't distinguish between APPEND and COUNTER UAVs. */
- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER;
- if (flags)
- FIXME("Unhandled UAV flags %#x.\n", flags);
-
- spirv_compiler_emit_resource_declaration(compiler, &resource->resource,
- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, stride / 4, false);
-}
-
static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler,
const struct vkd3d_shader_register *reg, unsigned int size, unsigned int structure_stride)
{
@@ -7466,7 +7453,13 @@ static int spirv_compiler_emit_control_flow_instruction(struct spirv_compiler *c
assert(compiler->control_flow_depth);
assert(cf_info->current_block == VKD3D_BLOCK_SWITCH);
- assert(src->swizzle == VKD3D_SHADER_NO_SWIZZLE && src->reg.type == VKD3DSPR_IMMCONST);
+ if (src->swizzle != VKD3D_SHADER_SWIZZLE(X, X, X, X))
+ {
+ WARN("Unexpected src swizzle %#x.\n", src->swizzle);
+ spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE,
+ "The swizzle for a switch case value is not scalar.");
+ }
+ assert(src->reg.type == VKD3DSPR_IMMCONST);
value = *src->reg.u.immconst_uint;
if (!vkd3d_array_reserve((void **)&cf_info->u.switch_.case_blocks, &cf_info->u.switch_.case_blocks_size,
@@ -9174,27 +9167,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
case VKD3DSIH_DCL_INDEXABLE_TEMP:
spirv_compiler_emit_dcl_indexable_temp(compiler, instruction);
break;
- case VKD3DSIH_DCL_CONSTANT_BUFFER:
- spirv_compiler_emit_dcl_constant_buffer(compiler, instruction);
- break;
case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER:
spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction);
break;
- case VKD3DSIH_DCL_SAMPLER:
- spirv_compiler_emit_dcl_sampler(compiler, instruction);
- break;
- case VKD3DSIH_DCL:
- case VKD3DSIH_DCL_UAV_TYPED:
- spirv_compiler_emit_dcl_resource(compiler, instruction);
- break;
- case VKD3DSIH_DCL_RESOURCE_RAW:
- case VKD3DSIH_DCL_UAV_RAW:
- spirv_compiler_emit_dcl_resource_raw(compiler, instruction);
- break;
- case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
- case VKD3DSIH_DCL_UAV_STRUCTURED:
- spirv_compiler_emit_dcl_resource_structured(compiler, instruction);
- break;
case VKD3DSIH_DCL_TGSM_RAW:
spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction);
break;
@@ -9490,8 +9465,16 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
case VKD3DSIH_CUT_STREAM:
spirv_compiler_emit_cut_stream(compiler, instruction);
break;
+ case VKD3DSIH_DCL:
+ case VKD3DSIH_DCL_CONSTANT_BUFFER:
case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
+ case VKD3DSIH_DCL_RESOURCE_RAW:
+ case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
+ case VKD3DSIH_DCL_SAMPLER:
case VKD3DSIH_DCL_TEMPS:
+ 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 */
@@ -9503,24 +9486,48 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
return ret;
}
-static void spirv_compiler_emit_sm1_constant_buffer(struct spirv_compiler *compiler,
- const struct vkd3d_shader_desc *desc, enum vkd3d_shader_d3dbc_constant_register set,
- enum vkd3d_data_type data_type)
+static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler)
{
- struct vkd3d_shader_register_range range = {.space = 0, .first = set, .last = set};
- uint32_t count = desc->flat_constant_count[set].external;
- struct vkd3d_shader_register reg =
+ unsigned int i;
+
+ for (i = 0; i < compiler->scan_descriptor_info->descriptor_count; ++i)
{
- .type = VKD3DSPR_CONSTBUFFER,
- .idx[0].offset = set, /* register ID */
- .idx[1].offset = set, /* register index */
- .idx[2].offset = count, /* size */
- .idx_count = 3,
- .data_type = data_type,
- };
+ const struct vkd3d_shader_descriptor_info1 *descriptor = &compiler->scan_descriptor_info->descriptors[i];
+ struct vkd3d_shader_register_range range;
+
+ range.first = descriptor->register_index;
+ if (descriptor->count == ~0u)
+ range.last = ~0u;
+ else
+ range.last = descriptor->register_index + descriptor->count - 1;
+ range.space = descriptor->register_space;
+
+ switch (descriptor->type)
+ {
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
+ spirv_compiler_emit_sampler_declaration(compiler, &range, descriptor->register_id);
+ break;
+
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
+ spirv_compiler_emit_cbv_declaration(compiler, &range, descriptor->register_id, descriptor->buffer_size);
+ break;
- if (count)
- spirv_compiler_emit_constant_buffer(compiler, count, &range, &reg);
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
+ spirv_compiler_emit_resource_declaration(compiler, &range, descriptor->register_id,
+ descriptor->sample_count, false, descriptor->resource_type, descriptor->resource_data_type,
+ descriptor->structure_stride / 4, descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER);
+ break;
+
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
+ spirv_compiler_emit_resource_declaration(compiler, &range, descriptor->register_id,
+ descriptor->sample_count, true, descriptor->resource_type, descriptor->resource_data_type,
+ descriptor->structure_stride / 4, descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER);
+ break;
+
+ default:
+ vkd3d_unreachable();
+ }
+ }
}
static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
@@ -9538,12 +9545,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
if (parser->shader_desc.temp_count)
spirv_compiler_emit_temps(compiler, parser->shader_desc.temp_count);
- spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc,
- VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, VKD3D_DATA_FLOAT);
- spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc,
- VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, VKD3D_DATA_INT);
- spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc,
- VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, VKD3D_DATA_UINT);
+ spirv_compiler_emit_descriptor_declarations(compiler);
compiler->location.column = 0;
compiler->location.line = 1;
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 550f9b27cc7..7949be150bf 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -507,7 +507,7 @@ enum vkd3d_sm4_input_primitive_type
enum vkd3d_sm4_swizzle_type
{
- VKD3D_SM4_SWIZZLE_NONE = 0x0,
+ VKD3D_SM4_SWIZZLE_NONE = 0x0, /* swizzle bitfield contains a mask */
VKD3D_SM4_SWIZZLE_VEC4 = 0x1,
VKD3D_SM4_SWIZZLE_SCALAR = 0x2,
};
@@ -707,6 +707,19 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins,
VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z;
}
+static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode,
+ uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
+{
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT,
+ (struct vkd3d_shader_src_param *)&ins->src[0]);
+ if (ins->src[0].reg.type != VKD3DSPR_IMMCONST)
+ {
+ FIXME("Switch case value is not a 32-bit constant.\n");
+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_CASE_VALUE,
+ "Switch case value is not a 32-bit immediate constant register.");
+ }
+}
+
static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token,
const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
@@ -1215,7 +1228,8 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] =
{VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""},
{VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u",
shader_sm4_read_conditional_op},
- {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u"},
+ {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u",
+ shader_sm4_read_case_condition},
{VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""},
{VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u",
shader_sm4_read_conditional_op},
@@ -2012,6 +2026,7 @@ static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_pa
static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param)
{
+ unsigned int dimension, mask;
DWORD token;
if (*ptr >= end)
@@ -2027,37 +2042,63 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons
return false;
}
- if (src_param->reg.type == VKD3DSPR_IMMCONST || src_param->reg.type == VKD3DSPR_IMMCONST64)
+ switch ((dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT))
{
- src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
- }
- else
- {
- enum vkd3d_sm4_swizzle_type swizzle_type =
- (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT;
+ case VKD3D_SM4_DIMENSION_NONE:
+ case VKD3D_SM4_DIMENSION_SCALAR:
+ src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
+ break;
- switch (swizzle_type)
+ case VKD3D_SM4_DIMENSION_VEC4:
{
- case VKD3D_SM4_SWIZZLE_NONE:
- if (shader_sm4_is_scalar_register(&src_param->reg))
- src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
- else
+ enum vkd3d_sm4_swizzle_type swizzle_type =
+ (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT;
+
+ switch (swizzle_type)
+ {
+ case VKD3D_SM4_SWIZZLE_NONE:
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
- break;
- case VKD3D_SM4_SWIZZLE_SCALAR:
- src_param->swizzle = (token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT;
- src_param->swizzle = (src_param->swizzle & 0x3) * 0x01010101;
- break;
+ mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT;
+ /* Mask seems only to be used for vec4 constants and is always zero. */
+ if (!register_is_constant(&src_param->reg))
+ {
+ FIXME("Source mask %#x is not for a constant.\n", mask);
+ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK,
+ "Unhandled mask %#x for a non-constant source register.", mask);
+ }
+ else if (mask)
+ {
+ FIXME("Unhandled mask %#x.\n", mask);
+ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK,
+ "Unhandled source register mask %#x.", mask);
+ }
- case VKD3D_SM4_SWIZZLE_VEC4:
- src_param->swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT);
- break;
+ break;
- default:
- FIXME("Unhandled swizzle type %#x.\n", swizzle_type);
- break;
+ case VKD3D_SM4_SWIZZLE_SCALAR:
+ src_param->swizzle = (token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT;
+ src_param->swizzle = (src_param->swizzle & 0x3) * 0x01010101;
+ break;
+
+ case VKD3D_SM4_SWIZZLE_VEC4:
+ src_param->swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT);
+ break;
+
+ default:
+ FIXME("Unhandled swizzle type %#x.\n", swizzle_type);
+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE,
+ "Source register swizzle type %#x is invalid.", swizzle_type);
+ break;
+ }
+ break;
}
+
+ default:
+ FIXME("Unhandled dimension %#x.\n", dimension);
+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION,
+ "Source register dimension %#x is invalid.", dimension);
+ break;
}
if (register_is_input_output(&src_param->reg) && !shader_sm4_validate_input_output_register(priv,
@@ -2070,7 +2111,9 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons
static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param)
{
+ enum vkd3d_sm4_swizzle_type swizzle_type;
enum vkd3d_shader_src_modifier modifier;
+ unsigned int dimension, swizzle;
DWORD token;
if (*ptr >= end)
@@ -2092,10 +2135,53 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons
return false;
}
- dst_param->write_mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT;
+ switch ((dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT))
+ {
+ case VKD3D_SM4_DIMENSION_NONE:
+ dst_param->write_mask = 0;
+ break;
+
+ case VKD3D_SM4_DIMENSION_SCALAR:
+ dst_param->write_mask = VKD3DSP_WRITEMASK_0;
+ break;
+
+ case VKD3D_SM4_DIMENSION_VEC4:
+ swizzle_type = (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT;
+ switch (swizzle_type)
+ {
+ case VKD3D_SM4_SWIZZLE_NONE:
+ dst_param->write_mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT;
+ break;
+
+ case VKD3D_SM4_SWIZZLE_VEC4:
+ swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT);
+ if (swizzle != VKD3D_SHADER_NO_SWIZZLE)
+ {
+ FIXME("Unhandled swizzle %#x.\n", swizzle);
+ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_SWIZZLE,
+ "Unhandled destination register swizzle %#x.", swizzle);
+ }
+ dst_param->write_mask = VKD3DSP_WRITEMASK_ALL;
+ break;
+
+ default:
+ FIXME("Unhandled swizzle type %#x.\n", swizzle_type);
+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE,
+ "Destination register swizzle type %#x is invalid.", swizzle_type);
+ break;
+ }
+ break;
+
+ default:
+ FIXME("Unhandled dimension %#x.\n", dimension);
+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION,
+ "Destination register dimension %#x is invalid.", dimension);
+ break;
+ }
+
if (data_type == VKD3D_DATA_DOUBLE)
dst_param->write_mask = vkd3d_write_mask_64_from_32(dst_param->write_mask);
- /* Scalar registers are declared with no write mask in shader bytecode. */
+ /* Some scalar registers are declared with no write mask in shader bytecode. */
if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg))
dst_param->write_mask = VKD3DSP_WRITEMASK_0;
dst_param->modifiers = 0;
@@ -3715,8 +3801,10 @@ static void sm4_src_from_constant_value(struct sm4_src_register *src,
src->reg.dim = VKD3D_SM4_DIMENSION_VEC4;
for (i = 0; i < 4; ++i)
{
- if (map_writemask & (1u << i))
+ if ((map_writemask & (1u << i)) && (j < width))
src->reg.immconst_uint[i] = value->u[j++].u;
+ else
+ src->reg.immconst_uint[i] = 0;
}
}
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index bf925a44690..84614a4eb79 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -78,9 +78,14 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_TPF_TOO_MANY_REGISTERS = 1004,
VKD3D_SHADER_ERROR_TPF_INVALID_IO_REGISTER = 1005,
VKD3D_SHADER_ERROR_TPF_INVALID_INDEX_RANGE_DCL = 1006,
+ VKD3D_SHADER_ERROR_TPF_INVALID_CASE_VALUE = 1007,
+ VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION = 1008,
+ VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE = 1009,
VKD3D_SHADER_WARNING_TPF_MASK_NOT_CONTIGUOUS = 1300,
VKD3D_SHADER_WARNING_TPF_UNHANDLED_INDEX_RANGE_MASK = 1301,
+ VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK = 1302,
+ VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_SWIZZLE = 1303,
VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND = 2000,
VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001,
@@ -88,6 +93,8 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003,
VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004,
+ VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300,
+
VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY = 3000,
VKD3D_SHADER_ERROR_RS_INVALID_VERSION = 3001,
VKD3D_SHADER_ERROR_RS_INVALID_ROOT_PARAMETER_TYPE = 3002,
@@ -140,6 +147,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE = 5302,
VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT = 5303,
VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT = 5304,
+ VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305,
VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000,
@@ -1012,6 +1020,11 @@ static inline bool vkd3d_shader_register_is_patch_constant(const struct vkd3d_sh
return reg->type == VKD3DSPR_PATCHCONST;
}
+static inline bool register_is_constant(const struct vkd3d_shader_register *reg)
+{
+ return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64);
+}
+
struct vkd3d_shader_location
{
const char *source_name;
@@ -1310,6 +1323,30 @@ static inline enum vkd3d_data_type vkd3d_data_type_from_component_type(
}
}
+static inline enum vkd3d_shader_component_type vkd3d_component_type_from_resource_data_type(
+ enum vkd3d_shader_resource_data_type data_type)
+{
+ switch (data_type)
+ {
+ case VKD3D_SHADER_RESOURCE_DATA_FLOAT:
+ case VKD3D_SHADER_RESOURCE_DATA_UNORM:
+ case VKD3D_SHADER_RESOURCE_DATA_SNORM:
+ return VKD3D_SHADER_COMPONENT_FLOAT;
+ case VKD3D_SHADER_RESOURCE_DATA_UINT:
+ return VKD3D_SHADER_COMPONENT_UINT;
+ case VKD3D_SHADER_RESOURCE_DATA_INT:
+ return VKD3D_SHADER_COMPONENT_INT;
+ case VKD3D_SHADER_RESOURCE_DATA_DOUBLE:
+ case VKD3D_SHADER_RESOURCE_DATA_CONTINUED:
+ return VKD3D_SHADER_COMPONENT_DOUBLE;
+ default:
+ FIXME("Unhandled data type %#x.\n", data_type);
+ /* fall-through */
+ case VKD3D_SHADER_RESOURCE_DATA_MIXED:
+ return VKD3D_SHADER_COMPONENT_UINT;
+ }
+}
+
enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval,
unsigned int index);
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
index 8b5f7899cf3..42a98763438 100644
--- a/libs/vkd3d/libs/vkd3d/command.c
+++ b/libs/vkd3d/libs/vkd3d/command.c
@@ -3225,7 +3225,10 @@ static void command_list_add_descriptor_heap(struct d3d12_command_list *list, st
{
/* Descriptors can be written after binding. */
FIXME("Flushing descriptor updates while list %p is not closed.\n", list);
- command_list_flush_vk_heap_updates(list);
+ vkd3d_mutex_lock(&heap->vk_sets_mutex);
+ d3d12_desc_flush_vk_heap_updates_locked(heap, list->device);
+ vkd3d_mutex_unlock(&heap->vk_sets_mutex);
+ return;
}
list->descriptor_heaps[list->descriptor_heap_count++] = heap;
}
--
2.40.1

View File

@ -1,458 +0,0 @@
From 0d536e339fc3dcc3d90ef593818e2f6af63301d7 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 4 Aug 2023 19:27:19 +1000
Subject: [PATCH] Updated vkd3d to f649db23a596c1865bc7f110ca1feb3868451375.
---
libs/vkd3d/include/vkd3d_shader.h | 107 +++++++++++++++++-
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 8 +-
libs/vkd3d/libs/vkd3d-shader/dxbc.c | 1 +
libs/vkd3d/libs/vkd3d-shader/ir.c | 73 +++++++++++-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 16 ++-
.../libs/vkd3d-shader/vkd3d_shader_main.c | 38 +++++++
.../libs/vkd3d-shader/vkd3d_shader_private.h | 11 +-
7 files changed, 245 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index d6653d18e56..e98aad4fe95 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -90,6 +90,11 @@ enum vkd3d_shader_structure_type
* \since 1.9
*/
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO,
+ /**
+ * The structure is a vkd3d_shader_next_stage_info structure.
+ * \since 1.9
+ */
+ VKD3D_SHADER_STRUCTURE_TYPE_NEXT_STAGE_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
};
@@ -1676,6 +1681,76 @@ struct vkd3d_shader_scan_signature_info
struct vkd3d_shader_signature patch_constant;
};
+/**
+ * Describes the mapping of a output varying register in a shader stage,
+ * to an input varying register in the following shader stage.
+ *
+ * This structure is used in struct vkd3d_shader_next_stage_info.
+ */
+struct vkd3d_shader_varying_map
+{
+ /**
+ * The signature index (in the output signature) of the output varying.
+ * If greater than or equal to the number of elements in the output
+ * signature, signifies that the varying is consumed by the next stage but
+ * not written by this one.
+ */
+ unsigned int output_signature_index;
+ /** The register index of the input varying to map this register to. */
+ unsigned int input_register_index;
+ /** The mask consumed by the destination register. */
+ unsigned int input_mask;
+};
+
+/**
+ * A chained structure which describes the next shader in the pipeline.
+ *
+ * This structure is optional, and should only be provided if there is in fact
+ * another shader in the pipeline.
+ * However, depending on the input and output formats, this structure may be
+ * necessary in order to generate shaders which correctly match each other.
+ * If the structure or its individual fields are not provided, vkd3d-shader
+ * will generate shaders which may be correct in isolation, but are not
+ * guaranteed to correctly match each other.
+ *
+ * This structure is passed to vkd3d_shader_compile() and extends
+ * vkd3d_shader_compile_info.
+ *
+ * This structure contains only input parameters.
+ *
+ * \since 1.9
+ */
+struct vkd3d_shader_next_stage_info
+{
+ /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_NEXT_STAGE_INFO. */
+ enum vkd3d_shader_structure_type type;
+ /** Optional pointer to a structure containing further parameters. */
+ const void *next;
+
+ /**
+ * A mapping of output varyings in this shader stage to input varyings
+ * in the next shader stage.
+ *
+ * This mapping should include exactly one element for each varying
+ * consumed by the next shader stage.
+ * If this shader stage outputs a varying that is not consumed by the next
+ * shader stage, that varying should be absent from this array.
+ *
+ * If this field is absent, vkd3d-shader will map varyings from one stage
+ * to another based on their register index.
+ * For Direct3D shader model 3.0, such a default mapping will be incorrect
+ * unless the registers are allocated in the same order, and hence this
+ * field is necessary to correctly match inter-stage varyings.
+ * This mapping may also be necessary under other circumstances where the
+ * varying interface does not match exactly.
+ *
+ * This mapping may be constructed by vkd3d_shader_build_varying_map().
+ */
+ const struct vkd3d_shader_varying_map *varying_map;
+ /** The number of registers provided in \ref varying_map. */
+ unsigned int varying_count;
+};
+
#ifdef LIBVKD3D_SHADER_SOURCE
# define VKD3D_SHADER_API VKD3D_EXPORT
#else
@@ -1748,13 +1823,14 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
*
* Depending on the source and target types, this function may support the
* following chained structures:
+ * - vkd3d_shader_hlsl_source_info
* - vkd3d_shader_interface_info
+ * - vkd3d_shader_next_stage_info
* - vkd3d_shader_scan_descriptor_info
* - vkd3d_shader_scan_signature_info
* - vkd3d_shader_spirv_domain_shader_target_info
* - vkd3d_shader_spirv_target_info
* - vkd3d_shader_transform_feedback_info
- * - vkd3d_shader_hlsl_source_info
*
* \param compile_info A chained structure containing compilation parameters.
*
@@ -2188,6 +2264,35 @@ VKD3D_SHADER_API int vkd3d_shader_serialize_dxbc(size_t section_count,
*/
VKD3D_SHADER_API void vkd3d_shader_free_scan_signature_info(struct vkd3d_shader_scan_signature_info *info);
+/**
+ * Build a mapping of output varyings in a shader stage to input varyings in
+ * the following shader stage.
+ *
+ * This mapping should be used in struct vkd3d_shader_next_stage_info to
+ * compile the first shader.
+ *
+ * \param output_signature The output signature of the first shader.
+ *
+ * \param input_signature The input signature of the second shader.
+ *
+ * \param count On output, contains the number of entries written into
+ * \ref varyings.
+ *
+ * \param varyings Pointer to an output array of varyings.
+ * This must point to space for N varyings, where N is the number of elements
+ * in the input signature.
+ *
+ * \remark Valid legacy Direct3D pixel shaders have at most 12 varying inputs:
+ * 10 inter-stage varyings, face, and position.
+ * Therefore, in practice, it is safe to call this function with a
+ * pre-allocated array with a fixed size of 12.
+ *
+ * \since 1.9
+ */
+VKD3D_SHADER_API void vkd3d_shader_build_varying_map(const struct vkd3d_shader_signature *output_signature,
+ const struct vkd3d_shader_signature *input_signature,
+ unsigned int *count, struct vkd3d_shader_varying_map *varyings);
+
#endif /* VKD3D_SHADER_NO_PROTOTYPES */
/** Type of vkd3d_shader_get_version(). */
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index fe739339bd1..35e5c454d57 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -524,6 +524,8 @@ static struct signature_element *find_signature_element_by_register_index(
return NULL;
}
+#define SM1_COLOR_REGISTER_OFFSET 8
+
static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool output,
const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval,
unsigned int register_index, bool is_dcl, unsigned int mask)
@@ -555,6 +557,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
element->sysval_semantic = sysval;
element->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
element->register_index = register_index;
+ element->target_location = register_index;
element->register_count = 1;
element->mask = mask;
element->used_mask = is_dcl ? 0 : mask;
@@ -606,7 +609,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *
return true;
}
return add_signature_element(sm1, false, "COLOR", register_index,
- VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask);
+ VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask);
case VKD3DSPR_TEXTURE:
/* For vertex shaders, this is ADDR. */
@@ -633,6 +636,9 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *
/* fall through */
case VKD3DSPR_ATTROUT:
+ return add_signature_element(sm1, true, "COLOR", register_index,
+ VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask);
+
case VKD3DSPR_COLOROUT:
return add_signature_element(sm1, true, "COLOR", register_index,
VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask);
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
index 716b7bdb721..cedc3da4a83 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
@@ -391,6 +391,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
read_dword(&ptr, &e[i].sysval_semantic);
read_dword(&ptr, &e[i].component_type);
read_dword(&ptr, &e[i].register_index);
+ e[i].target_location = e[i].register_index;
e[i].register_count = 1;
read_dword(&ptr, &mask);
e[i].mask = mask & 0xff;
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index d74f81afc39..705905f7888 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -85,6 +85,72 @@ static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_i
shader_register_eliminate_phase_addressing((struct vkd3d_shader_register *)&ins->dst[i].reg, instance_id);
}
+static const struct vkd3d_shader_varying_map *find_varying_map(
+ const struct vkd3d_shader_next_stage_info *next_stage, unsigned int signature_idx)
+{
+ unsigned int i;
+
+ for (i = 0; i < next_stage->varying_count; ++i)
+ {
+ if (next_stage->varying_map[i].output_signature_index == signature_idx)
+ return &next_stage->varying_map[i];
+ }
+
+ return NULL;
+}
+
+static enum vkd3d_result remap_output_signature(struct vkd3d_shader_parser *parser,
+ const struct vkd3d_shader_compile_info *compile_info)
+{
+ struct shader_signature *signature = &parser->shader_desc.output_signature;
+ const struct vkd3d_shader_next_stage_info *next_stage;
+ unsigned int i;
+
+ if (!(next_stage = vkd3d_find_struct(compile_info->next, NEXT_STAGE_INFO)))
+ return VKD3D_OK;
+
+ for (i = 0; i < signature->element_count; ++i)
+ {
+ const struct vkd3d_shader_varying_map *map = find_varying_map(next_stage, i);
+ struct signature_element *e = &signature->elements[i];
+
+ if (map)
+ {
+ unsigned int input_mask = map->input_mask;
+
+ e->target_location = map->input_register_index;
+
+ /* It is illegal in Vulkan if the next shader uses the same varying
+ * location with a different mask. */
+ if (input_mask && input_mask != e->mask)
+ {
+ vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "Aborting due to not yet implemented feature: "
+ "Output mask %#x does not match input mask %#x.",
+ e->mask, input_mask);
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+ }
+ else
+ {
+ e->target_location = SIGNATURE_TARGET_LOCATION_UNUSED;
+ }
+ }
+
+ for (i = 0; i < next_stage->varying_count; ++i)
+ {
+ if (next_stage->varying_map[i].output_signature_index >= signature->element_count)
+ {
+ vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "Aborting due to not yet implemented feature: "
+ "The next stage consumes varyings not written by this stage.");
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+ }
+
+ return VKD3D_OK;
+}
+
struct hull_flattener
{
struct vkd3d_shader_instruction_array instructions;
@@ -1194,7 +1260,8 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d
return VKD3D_OK;
}
-enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser)
+enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
+ const struct vkd3d_shader_compile_info *compile_info)
{
struct vkd3d_shader_instruction_array *instructions = &parser->instructions;
enum vkd3d_result result = VKD3D_OK;
@@ -1202,6 +1269,10 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser)
if (parser->shader_desc.is_dxil)
return result;
+ if (parser->shader_version.type != VKD3D_SHADER_TYPE_PIXEL
+ && (result = remap_output_signature(parser, compile_info)) < 0)
+ return result;
+
if (parser->shader_version.type == VKD3D_SHADER_TYPE_HULL
&& (result = instruction_array_flatten_hull_shader_phases(instructions)) >= 0)
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index d71f0a698d9..2725ed80cd1 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -4602,7 +4602,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
}
else
{
- unsigned int location = signature_element->register_index;
+ unsigned int location = signature_element->target_location;
input_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream,
storage_class, component_type, input_component_count, array_sizes, 2);
@@ -4978,9 +4978,15 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
spirv_compiler_emit_register_execution_mode(compiler, &dst->reg);
}
+ else if (signature_element->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
+ {
+ storage_class = SpvStorageClassPrivate;
+ id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream,
+ storage_class, component_type, output_component_count, array_sizes, 2);
+ }
else
{
- unsigned int location = signature_element->register_index;
+ unsigned int location = signature_element->target_location;
if (is_patch_constant)
location += shader_signature_next_location(&compiler->output_signature);
@@ -4989,10 +4995,10 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
storage_class, component_type, output_component_count, array_sizes, 2);
vkd3d_spirv_add_iface_variable(builder, id);
- if (is_dual_source_blending(compiler) && signature_element->register_index < 2)
+ if (is_dual_source_blending(compiler) && location < 2)
{
vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationLocation, 0);
- vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationIndex, signature_element->register_index);
+ vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationIndex, location);
}
else
{
@@ -9542,7 +9548,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
compiler->location.column = 0;
compiler->location.line = 1;
- if ((result = vkd3d_shader_normalise(parser)) < 0)
+ if ((result = vkd3d_shader_normalise(parser, compile_info)) < 0)
return result;
instructions = parser->instructions;
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index d59cd704ceb..512d9ea41e7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -1891,3 +1891,41 @@ void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *ins
vkd3d_free(instructions->icbs[i]);
vkd3d_free(instructions->icbs);
}
+
+void vkd3d_shader_build_varying_map(const struct vkd3d_shader_signature *output_signature,
+ const struct vkd3d_shader_signature *input_signature,
+ unsigned int *ret_count, struct vkd3d_shader_varying_map *varyings)
+{
+ unsigned int count = 0;
+ unsigned int i;
+
+ TRACE("output_signature %p, input_signature %p, ret_count %p, varyings %p.\n",
+ output_signature, input_signature, ret_count, varyings);
+
+ for (i = 0; i < input_signature->element_count; ++i)
+ {
+ const struct vkd3d_shader_signature_element *input_element, *output_element;
+
+ input_element = &input_signature->elements[i];
+
+ if (input_element->sysval_semantic != VKD3D_SHADER_SV_NONE)
+ continue;
+
+ varyings[count].input_register_index = input_element->register_index;
+ varyings[count].input_mask = input_element->mask;
+
+ if ((output_element = vkd3d_shader_find_signature_element(output_signature,
+ input_element->semantic_name, input_element->semantic_index, 0)))
+ {
+ varyings[count].output_signature_index = output_element - output_signature->elements;
+ }
+ else
+ {
+ varyings[count].output_signature_index = output_signature->element_count;
+ }
+
+ ++count;
+ }
+
+ *ret_count = count;
+}
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index d35f49a63a2..dc43175d4b5 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -168,6 +168,8 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_DXIL_INVALID_BLOCK_LENGTH = 8302,
VKD3D_SHADER_WARNING_DXIL_INVALID_MODULE_LENGTH = 8303,
VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS = 8304,
+
+ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
};
enum vkd3d_shader_opcode
@@ -807,6 +809,8 @@ enum vkd3d_shader_input_sysval_semantic
VKD3D_SIV_LINE_DENSITY_TESS_FACTOR = 22,
};
+#define SIGNATURE_TARGET_LOCATION_UNUSED (~0u)
+
struct signature_element
{
unsigned int sort_index;
@@ -815,11 +819,15 @@ struct signature_element
unsigned int stream_index;
enum vkd3d_shader_sysval_semantic sysval_semantic;
enum vkd3d_shader_component_type component_type;
+ /* Register index in the source shader. */
unsigned int register_index;
unsigned int register_count;
unsigned int mask;
unsigned int used_mask;
enum vkd3d_shader_minimum_precision min_precision;
+ /* Register index / location in the target shader.
+ * If SIGNATURE_TARGET_LOCATION_UNUSED, this element should not be written. */
+ unsigned int target_location;
};
struct shader_signature
@@ -1406,6 +1414,7 @@ void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void
void dxbc_writer_init(struct dxbc_writer *dxbc);
int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *code);
-enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser);
+enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
+ const struct vkd3d_shader_compile_info *compile_info);
#endif /* __VKD3D_SHADER_PRIVATE_H */
--
2.40.1