From daa13934a4b6c883026d2d52b2bbaca098083870 Mon Sep 17 00:00:00 2001 From: Francisco Casas Date: Tue, 21 May 2024 14:51:17 -0400 Subject: [PATCH] vkd3d-shader/d3dbc: Use vsir_program I/O signatures to write dcls. Instead of relying on ctx->extern vars, semantics are now stored in the vsir_program signatures, and then read to write the declarations. --- libs/vkd3d-shader/d3dbc.c | 35 +++++++------- libs/vkd3d-shader/hlsl_codegen.c | 79 ++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 16 deletions(-) diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index d0b19362..53cf7169 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -2156,7 +2156,8 @@ static void d3dbc_write_constant_defs(struct d3dbc_compiler *d3dbc) } } -static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_var *var, bool output) +static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, + const struct signature_element *element, bool output) { const struct vkd3d_shader_version *version = &d3dbc->program->shader_version; struct vkd3d_bytecode_buffer *buffer = &d3dbc->buffer; @@ -2165,20 +2166,18 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, const struct D3DDECLUSAGE usage; bool ret; - if ((!output && !var->last_read) || (output && !var->first_write)) - return; - - if (hlsl_sm1_register_from_semantic(version, var->semantic.name, var->semantic.index, output, ®.type, ®.reg)) + if (hlsl_sm1_register_from_semantic(version, element->semantic_name, + element->semantic_index, output, ®.type, ®.reg)) { usage = 0; usage_idx = 0; } else { - ret = hlsl_sm1_usage_from_semantic(var->semantic.name, var->semantic.index, &usage, &usage_idx); + ret = hlsl_sm1_usage_from_semantic(element->semantic_name, element->semantic_index, &usage, &usage_idx); assert(ret); reg.type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT; - reg.reg = var->regs[HLSL_REGSET_NUMERIC].id; + reg.reg = element->register_index; } token = D3DSIO_DCL; @@ -2191,17 +2190,17 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, const struct token |= usage_idx << D3DSP_DCL_USAGEINDEX_SHIFT; put_u32(buffer, token); - reg.writemask = (1 << var->data_type->dimx) - 1; + reg.writemask = element->mask; write_sm1_dst_register(buffer, ®); } static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc) { - const struct vkd3d_shader_version *version = &d3dbc->program->shader_version; + struct vsir_program *program = d3dbc->program; + const struct vkd3d_shader_version *version; bool write_in = false, write_out = false; - struct hlsl_ctx *ctx = d3dbc->ctx; - struct hlsl_ir_var *var; + version = &program->shader_version; if (version->type == VKD3D_SHADER_TYPE_PIXEL && version->major >= 2) write_in = true; else if (version->type == VKD3D_SHADER_TYPE_VERTEX && version->major == 3) @@ -2209,12 +2208,16 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc) else if (version->type == VKD3D_SHADER_TYPE_VERTEX && version->major < 3) write_in = true; - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + if (write_in) { - if (write_in && var->is_input_semantic) - d3dbc_write_semantic_dcl(d3dbc, var, false); - if (write_out && var->is_output_semantic) - d3dbc_write_semantic_dcl(d3dbc, var, true); + for (unsigned int i = 0; i < program->input_signature.element_count; ++i) + d3dbc_write_semantic_dcl(d3dbc, &program->input_signature.elements[i], false); + } + + if (write_out) + { + for (unsigned int i = 0; i < program->output_signature.element_count; ++i) + d3dbc_write_semantic_dcl(d3dbc, &program->output_signature.elements[i], true); } } diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 8c4cccc9..f9f5c8ed 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -5527,6 +5527,83 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) } while (progress); } +static void sm1_generate_vsir_signature_entry(struct hlsl_ctx *ctx, + struct vsir_program *program, bool output, struct hlsl_ir_var *var) +{ + enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; + enum vkd3d_shader_register_type type; + struct shader_signature *signature; + struct signature_element *element; + unsigned int register_index, mask; + + if ((!output && !var->last_read) || (output && !var->first_write)) + return; + + if (output) + signature = &program->output_signature; + else + signature = &program->input_signature; + + if (!vkd3d_array_reserve((void **)&signature->elements, &signature->elements_capacity, + signature->element_count + 1, sizeof(*signature->elements))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } + element = &signature->elements[signature->element_count++]; + + if (!hlsl_sm1_register_from_semantic(&program->shader_version, + var->semantic.name, var->semantic.index, output, &type, ®ister_index)) + { + unsigned int usage, usage_idx; + bool ret; + + register_index = var->regs[HLSL_REGSET_NUMERIC].id; + + ret = hlsl_sm1_usage_from_semantic(var->semantic.name, var->semantic.index, &usage, &usage_idx); + assert(ret); + /* With the exception of vertex POSITION output, none of these are + * system values. Pixel POSITION input is not equivalent to + * SV_Position; the closer equivalent is VPOS, which is not declared + * as a semantic. */ + if (program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX + && output && usage == VKD3D_DECL_USAGE_POSITION) + sysval = VKD3D_SHADER_SV_POSITION; + } + mask = (1 << var->data_type->dimx) - 1; + + memset(element, 0, sizeof(*element)); + if (!(element->semantic_name = vkd3d_strdup(var->semantic.name))) + { + --signature->element_count; + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } + element->semantic_index = var->semantic.index; + element->sysval_semantic = sysval; + element->component_type = VKD3D_SHADER_COMPONENT_FLOAT; + element->register_index = register_index; + element->target_location = register_index; + element->register_count = 1; + element->mask = mask; + element->used_mask = mask; + if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) + element->interpolation_mode = VKD3DSIM_LINEAR; +} + +static void sm1_generate_vsir_signature(struct hlsl_ctx *ctx, struct vsir_program *program) +{ + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_input_semantic) + sm1_generate_vsir_signature_entry(ctx, program, false, var); + if (var->is_output_semantic) + sm1_generate_vsir_signature_entry(ctx, program, true, var); + } +} + /* OBJECTIVE: Translate all the information from ctx and entry_func to the * vsir_program and ctab blob, so they can be used as input to d3dbc_compile() * without relying on ctx and entry_func. */ @@ -5554,6 +5631,8 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl } ctab->code = buffer.data; ctab->size = buffer.size; + + sm1_generate_vsir_signature(ctx, program); } int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,