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
|
|
|
|
|