diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index e2c68d4af..a089651ea 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -5016,9 +5016,12 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, { enum vkd3d_shader_target_type target_type = compile_info->target_type; const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; + uint64_t config_flags = vkd3d_shader_init_config_flags(); struct hlsl_ir_function_decl *decl, *entry_func = NULL; + struct vkd3d_shader_code reflection_data = {0}; const struct hlsl_profile_info *profile; struct hlsl_ir_function *func; + struct vsir_program program; const char *entry_point; struct hlsl_ctx ctx; int ret; @@ -5118,43 +5121,15 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, return VKD3D_ERROR_INVALID_SHADER; } - if (target_type == VKD3D_SHADER_TARGET_SPIRV_BINARY - || target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT - || target_type == VKD3D_SHADER_TARGET_GLSL - || target_type == VKD3D_SHADER_TARGET_D3D_ASM) + if ((ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, &program, &reflection_data)) >= 0) { - uint64_t config_flags = vkd3d_shader_init_config_flags(); - struct vkd3d_shader_compile_info info = *compile_info; - struct vsir_program program; - - if (profile->major_version < 4) - { - if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0) - goto done; - info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE; - ret = d3dbc_parse(&info, config_flags, message_context, &program); - } - else - { - if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0) - goto done; - info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; - ret = tpf_parse(&info, config_flags, message_context, &program); - } - if (ret >= 0) - { - ret = vsir_program_compile(&program, config_flags, &info, out, message_context); - vsir_program_cleanup(&program); - } - vkd3d_shader_free_shader_code(&info.source); + vsir_program_trace(&program); + ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, message_context); + vkd3d_shader_free_shader_code(&reflection_data); + vsir_program_cleanup(&program); } - else - { - ret = hlsl_emit_bytecode(&ctx, entry_func, target_type, out); - } - -done: hlsl_ctx_cleanup(&ctx); + return ret; } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index feed57d0e..6812fd8df 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -278,11 +278,12 @@ struct hlsl_struct_field size_t name_bytecode_offset; }; -/* Information of the register(s) allocated for an instruction node or variable. - * These values are initialized at the end of hlsl_emit_bytecode(), after the compilation passes, - * just before writing the bytecode. - * The type of register (register class) is implied from its use, so it is not stored in this - * struct. */ +/* Information about the register(s) allocated for an instruction node or + * variable. These values are initialised at the end of hlsl_emit_vsir(), + * after the compilation passes, as vsir starts being generated from HLSL IR. + * + * The type of register (register class) is implied by its usage, so it is not + * stored in this structure. */ struct hlsl_reg { /* Register number of the first register allocated. */ @@ -1625,9 +1626,10 @@ struct hlsl_state_block_entry *clone_stateblock_entry(struct hlsl_ctx *ctx, void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body); void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body); -int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out); +int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, + struct hlsl_ir_function_decl *entry_func, struct vsir_program *program, + struct vkd3d_shader_code *reflection_data); bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len); bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 05113ae19..3435c904d 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -9606,8 +9606,9 @@ static void sm1_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo } } -static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct list *semantic_vars, struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) +static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, + struct hlsl_ir_function_decl *func, struct list *semantic_vars, + struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) { struct vkd3d_shader_version version = {0}; struct hlsl_block block; @@ -9615,7 +9616,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl version.major = ctx->profile->major_version; version.minor = ctx->profile->minor_version; version.type = ctx->profile->type; - if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) + if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; @@ -12339,7 +12340,8 @@ static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, /* 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. */ -static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, +static void sm4_generate_vsir(struct hlsl_ctx *ctx, + const struct vkd3d_shader_compile_info *compile_info, struct hlsl_ir_function_decl *func, struct list *semantic_vars, struct hlsl_block *body, struct list *patch_semantic_vars, struct hlsl_block *patch_body, uint64_t config_flags, struct vsir_program *program) { @@ -12352,7 +12354,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl version.minor = ctx->profile->minor_version; version.type = ctx->profile->type; - if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) + if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; @@ -13902,10 +13904,12 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v validate_max_output_size(ctx, semantic_vars, output_reg_count, &entry_func->loc); } -int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) +int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, + struct hlsl_ir_function_decl *entry_func, struct vsir_program *program, + struct vkd3d_shader_code *reflection_data) { struct hlsl_block global_uniform_block, body, patch_body; + uint32_t config_flags = vkd3d_shader_init_config_flags(); const struct hlsl_profile_info *profile = ctx->profile; struct list semantic_vars, patch_semantic_vars; struct hlsl_ir_var *var; @@ -13976,65 +13980,29 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (ctx->result) return ctx->result; - switch (target_type) + if (ctx->profile->major_version < 4) { - case VKD3D_SHADER_TARGET_D3D_BYTECODE: - { - uint32_t config_flags = vkd3d_shader_init_config_flags(); - struct vkd3d_shader_code ctab = {0}; - struct vsir_program program; - int result; + sm1_generate_ctab(ctx, reflection_data); + if (ctx->result) + return ctx->result; - sm1_generate_ctab(ctx, &ctab); - if (ctx->result) - return ctx->result; - - sm1_generate_vsir(ctx, entry_func, &semantic_vars, &body, config_flags, &program); - if (ctx->result) - { - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&ctab); - return ctx->result; - } - - vsir_program_trace(&program); - - result = d3dbc_compile(&program, config_flags, NULL, &ctab, out, ctx->message_context); - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&ctab); - return result; - } - - case VKD3D_SHADER_TARGET_DXBC_TPF: - { - uint32_t config_flags = vkd3d_shader_init_config_flags(); - struct vkd3d_shader_code rdef = {0}; - struct vsir_program program; - int result; - - sm4_generate_rdef(ctx, &rdef); - if (ctx->result) - return ctx->result; - - sm4_generate_vsir(ctx, entry_func, &semantic_vars, &body, - &patch_semantic_vars, &patch_body, config_flags, &program); - if (ctx->result) - { - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&rdef); - return ctx->result; - } - - vsir_program_trace(&program); - - result = tpf_compile(&program, config_flags, &rdef, out, ctx->message_context); - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&rdef); - return result; - } - - default: - ERR("Unsupported shader target type %#x.\n", target_type); - return VKD3D_ERROR_INVALID_ARGUMENT; + sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program); } + else + { + sm4_generate_rdef(ctx, reflection_data); + if (ctx->result) + return ctx->result; + + sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, + &patch_semantic_vars, &patch_body, config_flags, program); + } + + if (ctx->result) + { + vsir_program_cleanup(program); + vkd3d_shader_free_shader_code(reflection_data); + } + + return ctx->result; } diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 872162a7d..94275c29d 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1733,9 +1733,9 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char return ret; } -int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, - struct vkd3d_shader_message_context *message_context) +int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, + uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info; struct vkd3d_shader_compile_info scan_info; @@ -1749,6 +1749,18 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, ret = d3d_asm_compile(program, compile_info, out, VSIR_ASM_FLAG_NONE); break; + case VKD3D_SHADER_TARGET_D3D_BYTECODE: + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) + return ret; + ret = d3dbc_compile(program, config_flags, compile_info, reflection_data, out, message_context); + break; + + case VKD3D_SHADER_TARGET_DXBC_TPF: + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) + return ret; + ret = tpf_compile(program, config_flags, reflection_data, out, message_context); + break; + case VKD3D_SHADER_TARGET_GLSL: combined_sampler_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO; combined_sampler_info.next = scan_info.next; @@ -1843,7 +1855,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) { - ret = vsir_program_compile(&program, config_flags, compile_info, out, &message_context); + ret = vsir_program_compile(&program, NULL, config_flags, compile_info, out, &message_context); vsir_program_cleanup(&program); } } diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index f6d9373a3..1c622b97d 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1565,9 +1565,9 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, struct vkd3d_shader_message_context *message_context); void vsir_program_cleanup(struct vsir_program *program); -int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, - struct vkd3d_shader_message_context *message_context); +int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, + uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( const struct vsir_program *program, enum vkd3d_shader_parameter_name name); bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,