diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch index e2b50ea9..120d7478 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch @@ -1,4 +1,4 @@ -From 7e86c25d99b4ebaa196bb0cfe1053d9d9a4cc9f8 Mon Sep 17 00:00:00 2001 +From 0905bfa72229ee6dc12b6081a8067bc20989294b Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 21 Feb 2025 09:15:01 +1100 Subject: [PATCH] Updated vkd3d to f576ecc9929dd98c900bb8bc0335b91a1a0d3bff. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch index 9216fb58..c39258b3 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch @@ -1,4 +1,4 @@ -From 32c6084506f963100eb55be8df149437b5e8d4f0 Mon Sep 17 00:00:00 2001 +From 88f0e01cd04c1948ae376bdfc449372abdfccf61 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 10 Apr 2025 07:44:42 +1000 Subject: [PATCH] Updated vkd3d to cbce3a8631116ec10895e6c9c4a00b89b051f6b0. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch index d303514d..97ebd212 100644 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch @@ -1,4 +1,4 @@ -From 8684d82a0d27ada846a357d0fec558fbb23334c2 Mon Sep 17 00:00:00 2001 +From acaa5f246840cfe3df2acd4fc438c1c2b89de6d2 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 15 Apr 2025 08:45:19 +1000 Subject: [PATCH] Updated vkd3d to f02ea94c428f6b2f662f78fc78eae7f33428e9de. diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch index 1709237b..0fd61780 100644 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch @@ -1,4 +1,4 @@ -From 98ac96121b2336a832083bfdd833e93265291739 Mon Sep 17 00:00:00 2001 +From bd02c5f02ee58313f57ecb8c8a5319d5512eccb3 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 17 Apr 2025 08:02:13 +1000 Subject: [PATCH] Updated vkd3d to c764f71cf58e3a8327b44c588ad3696b422cf8a3. diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-ceb2787d466713096ea9746d2b63a4608fd.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-ceb2787d466713096ea9746d2b63a4608fd.patch new file mode 100644 index 00000000..2b96e671 --- /dev/null +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-ceb2787d466713096ea9746d2b63a4608fd.patch @@ -0,0 +1,638 @@ +From 05976a778863a5ce0c6141b1c5ccf8b78ef7cd49 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +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 +