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