Files
wine-staging/patches/vkd3d-latest/0005-Updated-vkd3d-to-ceb2787d466713096ea9746d2b63a4608fd.patch

639 lines
26 KiB
Diff
Raw Permalink Normal View History

2025-05-01 06:49:44 +10:00
From c6753750e48f1d5055b9b6780c0feccfbe48b913 Mon Sep 17 00:00:00 2001
2025-04-26 09:07:11 +10:00
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Thu, 24 Apr 2025 06:51:10 +1000
Subject: [PATCH] Updated vkd3d to ceb2787d466713096ea9746d2b63a4608fdc35f6.
---
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 57 ++++++++---
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 18 +++-
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 87 +++++++++++++---
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 108 ++++++++++++++++++--
libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +-
libs/vkd3d/libs/vkd3d-shader/tpf.c | 36 ++++---
6 files changed, 255 insertions(+), 53 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index d1d20b7384c..a6b46474812 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -387,6 +387,9 @@ static enum hlsl_regset type_get_regset(const struct hlsl_type *type)
case HLSL_CLASS_UAV:
return HLSL_REGSET_UAVS;
+ case HLSL_CLASS_STREAM_OUTPUT:
+ return HLSL_REGSET_STREAM_OUTPUTS;
+
default:
break;
}
@@ -493,6 +496,10 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
type->reg_size[HLSL_REGSET_UAVS] = 1;
break;
+ case HLSL_CLASS_STREAM_OUTPUT:
+ type->reg_size[HLSL_REGSET_STREAM_OUTPUTS] = 1;
+ break;
+
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
@@ -511,7 +518,6 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
- case HLSL_CLASS_STREAM_OUTPUT:
case HLSL_CLASS_NULL:
break;
}
@@ -591,6 +597,7 @@ static bool type_is_single_component(const struct hlsl_type *type)
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_STREAM_OUTPUT:
case HLSL_CLASS_NULL:
return true;
@@ -605,7 +612,6 @@ static bool type_is_single_component(const struct hlsl_type *type)
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
- case HLSL_CLASS_STREAM_OUTPUT:
break;
}
vkd3d_unreachable();
@@ -751,6 +757,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_STREAM_OUTPUT:
VKD3D_ASSERT(idx == 0);
break;
@@ -762,7 +769,6 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_CONSTANT_BUFFER:
case HLSL_CLASS_NULL:
- case HLSL_CLASS_STREAM_OUTPUT:
vkd3d_unreachable();
}
type = next_type;
@@ -984,6 +990,7 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx,
type->class = HLSL_CLASS_STREAM_OUTPUT;
type->e.so.so_type = so_type;
type->e.so.type = data_type;
+ hlsl_type_calculate_reg_size(ctx, type);
list_add_tail(&ctx->types, &type->entry);
@@ -1366,6 +1373,10 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
type->e.version = old->e.version;
break;
+ case HLSL_CLASS_STREAM_OUTPUT:
+ type->e.so.so_type = old->e.so.so_type;
+ break;
+
default:
break;
}
@@ -2053,24 +2064,28 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h
return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc));
}
-static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource,
- struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
+static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type,
+ const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value,
+ const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_resource_store *store;
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
return NULL;
init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc);
+ store->store_type = type;
+
hlsl_copy_deref(ctx, &store->resource, resource);
hlsl_src_from_node(&store->coords, coords);
hlsl_src_from_node(&store->value, value);
return &store->node;
}
-void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource,
- struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
+void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
+ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
+ struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
{
- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, resource, coords, value, loc));
+ append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc));
}
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count,
@@ -2589,6 +2604,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx,
if (!(dst = hlsl_alloc(ctx, sizeof(*dst))))
return NULL;
init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc);
+ dst->store_type = src->store_type;
if (!clone_deref(ctx, map, &dst->resource, &src->resource))
{
vkd3d_free(dst);
@@ -3720,12 +3736,26 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store)
{
- vkd3d_string_buffer_printf(buffer, "store_resource(resource = ");
+ static const char *const type_names[] =
+ {
+ [HLSL_RESOURCE_STORE] = "store_resource",
+ [HLSL_RESOURCE_STREAM_APPEND] = "stream_append",
+ [HLSL_RESOURCE_STREAM_RESTART] = "stream_restart",
+ };
+
+ VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names));
+ vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]);
dump_deref(buffer, &store->resource);
- vkd3d_string_buffer_printf(buffer, ", coords = ");
- dump_src(buffer, &store->coords);
- vkd3d_string_buffer_printf(buffer, ", value = ");
- dump_src(buffer, &store->value);
+ if (store->coords.node)
+ {
+ vkd3d_string_buffer_printf(buffer, ", coords = ");
+ dump_src(buffer, &store->coords);
+ }
+ if (store->value.node)
+ {
+ vkd3d_string_buffer_printf(buffer, ", value = ");
+ dump_src(buffer, &store->value);
+ }
vkd3d_string_buffer_printf(buffer, ")");
}
@@ -4829,6 +4859,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
ctx->input_control_point_count = UINT_MAX;
ctx->max_vertex_count = 0;
ctx->input_primitive_type = VKD3D_PT_UNDEFINED;
+ ctx->output_topology_type = VKD3D_PT_UNDEFINED;
return true;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index fafa5740963..8cb805a2e66 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -141,7 +141,8 @@ enum hlsl_regset
HLSL_REGSET_SAMPLERS,
HLSL_REGSET_TEXTURES,
HLSL_REGSET_UAVS,
- HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_UAVS,
+ HLSL_REGSET_STREAM_OUTPUTS,
+ HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_STREAM_OUTPUTS,
HLSL_REGSET_NUMERIC,
HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC,
};
@@ -894,9 +895,17 @@ struct hlsl_ir_resource_load
enum hlsl_sampler_dim sampling_dim;
};
+enum hlsl_resource_store_type
+{
+ HLSL_RESOURCE_STORE,
+ HLSL_RESOURCE_STREAM_APPEND,
+ HLSL_RESOURCE_STREAM_RESTART,
+};
+
struct hlsl_ir_resource_store
{
struct hlsl_ir_node node;
+ enum hlsl_resource_store_type store_type;
struct hlsl_deref resource;
struct hlsl_src coords, value;
};
@@ -1204,6 +1213,8 @@ struct hlsl_ctx
unsigned int max_vertex_count;
/* The input primitive type of a geometry shader. */
enum vkd3d_primitive_type input_primitive_type;
+ /* The output topology type of a geometry shader. */
+ enum vkd3d_primitive_type output_topology_type;
/* In some cases we generate opcodes by parsing an HLSL function and then
* invoking it. If not NULL, this field is the name of the function that we
@@ -1554,8 +1565,9 @@ void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block,
unsigned int unroll_limit, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
-void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource,
- struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
+void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
+ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
+ struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc);
void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 40fd142f58d..702fd30bda3 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -2115,7 +2115,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT);
VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count);
- hlsl_block_add_resource_store(ctx, block, &resource_deref, coords, rhs, &lhs->loc);
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc);
hlsl_cleanup_deref(&resource_deref);
}
else if (matrix_writemask)
@@ -6220,12 +6220,58 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object))
return false;
- hlsl_block_add_resource_store(ctx, block, &resource_deref, offset, rhs, loc);
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc);
hlsl_cleanup_deref(&resource_deref);
return true;
}
+static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_deref so_deref;
+ struct hlsl_ir_node *rhs;
+
+ if (params->args_count != 1)
+ {
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
+ "Wrong number of arguments to method '%s': expected 1.", name);
+ return false;
+ }
+
+ if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object))
+ return false;
+
+ if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc)))
+ return false;
+
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc);
+ hlsl_cleanup_deref(&so_deref);
+
+ return true;
+}
+
+static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_deref so_deref;
+
+ if (params->args_count)
+ {
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
+ "Wrong number of arguments to method '%s': expected 0.", name);
+ return false;
+ }
+
+ if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object))
+ return false;
+
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc);
+ hlsl_cleanup_deref(&so_deref);
+
+ return true;
+}
+
static const struct method_function
{
const char *name;
@@ -6269,6 +6315,12 @@ static const struct method_function uav_methods[] =
{ "Store4", add_store_method_call, "00000000000001" },
};
+static const struct method_function so_methods[] =
+{
+ { "Append", add_so_append_method_call, "" },
+ { "RestartStrip", add_so_restartstrip_method_call, "" },
+};
+
static int object_method_function_name_compare(const void *a, const void *b)
{
const struct method_function *func = b;
@@ -6280,8 +6332,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
const struct hlsl_type *object_type = object->data_type;
- const struct method_function *method, *methods;
- unsigned int count;
+ const struct method_function *method;
if (object_type->class == HLSL_CLASS_ERROR)
{
@@ -6300,13 +6351,24 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
if (object_type->class == HLSL_CLASS_TEXTURE)
{
- count = ARRAY_SIZE(texture_methods);
- methods = texture_methods;
+ method = bsearch(name, texture_methods, ARRAY_SIZE(texture_methods), sizeof(*method),
+ object_method_function_name_compare);
+
+ if (method && method->valid_dims[object_type->sampler_dim] != '1')
+ method = NULL;
}
else if (object_type->class == HLSL_CLASS_UAV)
{
- count = ARRAY_SIZE(uav_methods);
- methods = uav_methods;
+ method = bsearch(name, uav_methods, ARRAY_SIZE(uav_methods), sizeof(*method),
+ object_method_function_name_compare);
+
+ if (method && method->valid_dims[object_type->sampler_dim] != '1')
+ method = NULL;
+ }
+ else if (object_type->class == HLSL_CLASS_STREAM_OUTPUT)
+ {
+ method = bsearch(name, so_methods, ARRAY_SIZE(so_methods), sizeof(*method),
+ object_method_function_name_compare);
}
else
{
@@ -6319,17 +6381,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
return false;
}
- method = bsearch(name, methods, count, sizeof(*method),
- object_method_function_name_compare);
-
- if (method && method->valid_dims[object_type->sampler_dim] == '1')
- {
+ if (method)
return method->handler(ctx, block, object, name, params, loc);
- }
else
- {
return raise_invalid_method_object_type(ctx, object_type, name, loc);
- }
}
static bool add_object_property_access(struct hlsl_ctx *ctx,
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 1c684e7b9c1..8dff48ee83e 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -5191,6 +5191,8 @@ static char get_regset_name(enum hlsl_regset regset)
return 't';
case HLSL_REGSET_UAVS:
return 'u';
+ case HLSL_REGSET_STREAM_OUTPUTS:
+ return 'm';
case HLSL_REGSET_NUMERIC:
vkd3d_unreachable();
}
@@ -5359,8 +5361,10 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
var = store->resource.var;
var->last_read = max(var->last_read, last_read);
deref_mark_last_read(&store->resource, last_read);
- store->coords.node->last_read = last_read;
- store->value.node->last_read = last_read;
+ if (store->coords.node)
+ store->coords.node->last_read = last_read;
+ if (store->value.node)
+ store->value.node->last_read = last_read;
break;
}
case HLSL_IR_SWIZZLE:
@@ -6877,6 +6881,28 @@ static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
}
}
+static void allocate_stream_outputs(struct hlsl_ctx *ctx)
+{
+ struct hlsl_ir_var *var;
+ uint32_t index = 0;
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ if (!var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS])
+ continue;
+
+ /* We should have ensured that all stream output objects are single-element. */
+ VKD3D_ASSERT(var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS] == 1);
+
+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].space = 0;
+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].index = index;
+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].id = index;
+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated = true;
+
+ ++index;
+ }
+}
+
bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
unsigned int *start, unsigned int *count)
{
@@ -7557,6 +7583,64 @@ static void validate_and_record_prim_type(struct hlsl_ctx *ctx, struct hlsl_ir_v
ctx->input_primitive_param = var;
}
+static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx)
+{
+ static const enum vkd3d_primitive_type prim_types[] =
+ {
+ [HLSL_STREAM_OUTPUT_POINT_STREAM] = VKD3D_PT_POINTLIST,
+ [HLSL_STREAM_OUTPUT_LINE_STREAM] = VKD3D_PT_LINESTRIP,
+ [HLSL_STREAM_OUTPUT_TRIANGLE_STREAM] = VKD3D_PT_TRIANGLESTRIP,
+ };
+
+ bool reported_non_point_multistream = false, reported_nonzero_index = false, reported_invalid_index = false;
+ enum hlsl_so_object_type so_type;
+ const struct hlsl_type *type;
+ struct hlsl_ir_var *var;
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ if (!var->bind_count[HLSL_REGSET_STREAM_OUTPUTS])
+ continue;
+
+ type = hlsl_get_stream_output_type(var->data_type);
+ so_type = type->e.so.so_type;
+
+ VKD3D_ASSERT(so_type < ARRAY_SIZE(prim_types));
+
+ if (ctx->output_topology_type == VKD3D_PT_UNDEFINED)
+ {
+ ctx->output_topology_type = prim_types[so_type];
+ }
+ else
+ {
+ if ((so_type != HLSL_STREAM_OUTPUT_POINT_STREAM || ctx->output_topology_type != VKD3D_PT_POINTLIST)
+ && !reported_non_point_multistream)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "Multiple output streams are only allowed with PointStream objects.");
+ reported_non_point_multistream = true;
+ }
+ }
+
+ if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index && hlsl_version_lt(ctx, 5, 0) && !reported_nonzero_index)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
+ "Multiple output streams are only supported in shader model 5.0 or higher.");
+ reported_nonzero_index = true;
+ }
+
+ if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index >= VKD3D_MAX_STREAM_COUNT && !reported_invalid_index)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE,
+ "Output stream index %u exceeds the maximum index %u.",
+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, VKD3D_MAX_STREAM_COUNT - 1);
+ reported_invalid_index = true;
+ }
+ }
+
+ /* TODO: check that maxvertexcount * outputdatasize <= 1024. */
+}
+
static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *body)
{
struct hlsl_ir_node *instr, *next;
@@ -10632,6 +10716,12 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx,
struct vkd3d_shader_instruction *ins;
unsigned int writemask;
+ if (store->store_type != HLSL_RESOURCE_STORE)
+ {
+ hlsl_fixme(ctx, &instr->loc, "Stream output operations.");
+ return false;
+ }
+
if (!store->resource.var->is_uniform)
{
hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable.");
@@ -11963,7 +12053,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
{
program->input_control_point_count = ctx->input_control_point_count;
program->input_primitive = ctx->input_primitive_type;
- program->output_topology = VKD3D_PT_UNDEFINED; /* TODO: obtain from stream output parameters. */
+ program->output_topology = ctx->output_topology_type;
program->vertices_out_count = ctx->max_vertex_count;
}
@@ -13240,7 +13330,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
validate_and_record_prim_type(ctx, var);
prepend_input_var_copy(ctx, entry_func, var);
}
- else if (hlsl_get_stream_output_type(var->data_type))
+ else if (var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS])
{
if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY)
{
@@ -13253,9 +13343,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
"Stream output parameter \"%s\" must be declared as \"inout\".", var->name);
- /* TODO: check that maxvertexcount * component_count(element_type) <= 1024. */
-
- continue;
+ prepend_uniform_copy(ctx, body, var);
}
else
{
@@ -13369,6 +13457,12 @@ static void process_entry_function(struct hlsl_ctx *ctx,
else
sort_synthetic_separated_samplers_first(ctx);
+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
+ {
+ allocate_stream_outputs(ctx);
+ validate_and_record_stream_outputs(ctx);
+ }
+
if (profile->major_version < 4)
{
while (lower_ir(ctx, lower_nonconstant_array_loads, body));
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 05cc0b9a55e..6a393c5f35d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -426,7 +426,7 @@ static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser)
major = (version & VKD3D_SPIRV_VERSION_MAJOR_MASK) >> VKD3D_SPIRV_VERSION_MAJOR_SHIFT;
minor = (version & VKD3D_SPIRV_VERSION_MINOR_MASK) >> VKD3D_SPIRV_VERSION_MINOR_SHIFT;
- if (major != 1 || minor > 0)
+ if (major != 1 || minor > 6)
{
spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
"Unable to parse SPIR-V version %u.%u.", major, minor);
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 3be1d743acf..c29bedfaaa9 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -3822,6 +3822,25 @@ static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_s
write_sm4_instruction(tpf, &instr);
}
+static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_data_type)
+{
+ unsigned int i, k, type = 0;
+
+ for (k = 0; k < 4; ++k)
+ {
+ for (i = ARRAY_SIZE(data_type_table) - 1; i < ARRAY_SIZE(data_type_table); --i)
+ {
+ if (resource_data_type[k] == data_type_table[i])
+ {
+ type |= i << (4 * k);
+ break;
+ }
+ }
+ }
+
+ return type;
+}
+
static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins)
{
const struct vkd3d_shader_structured_resource *structured_resource = &ins->declaration.structured_resource;
@@ -3829,7 +3848,6 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s
const struct vkd3d_shader_version *version = &tpf->program->shader_version;
const struct vkd3d_sm4_opcode_info *info;
struct sm4_instruction instr = {0};
- unsigned int i, k;
bool uav;
info = get_info_from_vsir_opcode(&tpf->lookup, ins->opcode);
@@ -3844,18 +3862,11 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s
instr.dsts[0] = semantic->resource.reg;
instr.dst_count = 1;
- for (k = 0; k < 4; ++k)
+ if (ins->opcode == VKD3DSIH_DCL || ins->opcode == VKD3DSIH_DCL_UAV_TYPED)
{
- for (i = ARRAY_SIZE(data_type_table) - 1; i < ARRAY_SIZE(data_type_table); --i)
- {
- if (semantic->resource_data_type[k] == data_type_table[i])
- {
- instr.idx[0] |= i << (4 * k);
- break;
- }
- }
+ instr.idx[0] = pack_resource_data_type(semantic->resource_data_type);
+ instr.idx_count = 1;
}
- instr.idx_count = 1;
if (vkd3d_shader_ver_ge(version, 5, 1))
{
@@ -3864,8 +3875,7 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s
instr.dsts[0].reg.idx[2].offset = semantic->resource.range.last;
instr.dsts[0].reg.idx_count = 3;
- instr.idx[1] = semantic->resource.range.space;
- instr.idx_count = 2;
+ instr.idx[instr.idx_count++] = semantic->resource.range.space;
}
else
{
--
2.47.2