From d3108de72a05a6dfdc9c00a0523d6b722aac23ea Mon Sep 17 00:00:00 2001 From: Francisco Casas Date: Mon, 11 Nov 2024 21:18:00 -0300 Subject: [PATCH] vkd3d-shader/hlsl: Store ROV feature requirement in the vsir_program. --- libs/vkd3d-shader/hlsl.h | 24 ++++++++++++++++++++ libs/vkd3d-shader/hlsl_codegen.c | 19 ++++++++++++++++ libs/vkd3d-shader/tpf.c | 38 ++++---------------------------- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 515553fe..1ab53345 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1650,6 +1650,30 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_code *ctab, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); +struct extern_resource +{ + /* "var" is only not NULL if this resource is a whole variable, so it may + * be responsible for more than one component. */ + const struct hlsl_ir_var *var; + const struct hlsl_buffer *buffer; + + char *name; + bool is_user_packed; + + /* The data type of a single component of the resource. This might be + * different from the data type of the resource itself in 4.0 profiles, + * where an array (or multi-dimensional array) is handled as a single + * resource, unlike in 5.0. */ + struct hlsl_type *component_type; + + enum hlsl_regset regset; + unsigned int id, space, index, bind_count; + + struct vkd3d_shader_location loc; +}; + +struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count); +void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count); int tpf_compile(struct vsir_program *program, uint64_t config_flags, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context, struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 8f45628d..7d0a9aa5 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -9473,6 +9473,23 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, generate_vsir_add_program_instruction(ctx, program, &func->loc, VKD3DSIH_RET, 0, 0); } +static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vsir_program *program) +{ + struct extern_resource *extern_resources; + unsigned int extern_resources_count; + + extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); + for (unsigned int i = 0; i < extern_resources_count; ++i) + { + if (extern_resources[i].component_type && extern_resources[i].component_type->e.resource.rasteriser_ordered) + program->features.rovs = true; + } + sm4_free_extern_resources(extern_resources, extern_resources_count); + + /* FIXME: We also emit code that should require UAVS_AT_EVERY_STAGE, + * STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */ +} + /* OBJECTIVE: Translate all the information from ctx and entry_func to the * vsir_program, so it can be used as input to tpf_compile() without relying * on ctx and entry_func. */ @@ -9512,6 +9529,8 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl &ctx->patch_constant_func->loc, VKD3DSIH_HS_FORK_PHASE, 0, 0); sm4_generate_vsir_add_function(ctx, ctx->patch_constant_func, config_flags, program); } + + generate_vsir_scan_required_features(ctx, program); } static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point, diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index c491c17c..c9de4e47 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3484,28 +3484,6 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ } } -struct extern_resource -{ - /* var is only not NULL if this resource is a whole variable, so it may be responsible for more - * than one component. */ - const struct hlsl_ir_var *var; - const struct hlsl_buffer *buffer; - - char *name; - bool is_user_packed; - - /* The data type of a single component of the resource. - * This might be different from the data type of the resource itself in 4.0 - * profiles, where an array (or multi-dimensional array) is handled as a - * single resource, unlike in 5.0. */ - struct hlsl_type *component_type; - - enum hlsl_regset regset; - unsigned int id, space, index, bind_count; - - struct vkd3d_shader_location loc; -}; - static int sm4_compare_extern_resources(const void *a, const void *b) { const struct extern_resource *aa = (const struct extern_resource *)a; @@ -3521,7 +3499,7 @@ static int sm4_compare_extern_resources(const void *a, const void *b) return vkd3d_u32_compare(aa->index, bb->index); } -static void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) +void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) { unsigned int i; @@ -3537,7 +3515,7 @@ static const char *string_skip_tag(const char *string) return string; } -static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) +struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) { bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0; struct extern_resource *extern_resources = NULL; @@ -4981,20 +4959,12 @@ static void tpf_write_shdr(struct tpf_compiler *tpf, struct hlsl_ir_function_dec static void tpf_write_sfi0(struct tpf_compiler *tpf) { - struct extern_resource *extern_resources; - unsigned int extern_resources_count; - struct hlsl_ctx *ctx = tpf->ctx; uint64_t *flags; flags = vkd3d_calloc(1, sizeof(*flags)); - extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); - for (unsigned int i = 0; i < extern_resources_count; ++i) - { - if (extern_resources[i].component_type && extern_resources[i].component_type->e.resource.rasteriser_ordered) - *flags |= DXBC_SFI0_REQUIRES_ROVS; - } - sm4_free_extern_resources(extern_resources, extern_resources_count); + if (tpf->program->features.rovs) + *flags |= DXBC_SFI0_REQUIRES_ROVS; /* FIXME: We also emit code that should require UAVS_AT_EVERY_STAGE, * STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */