From 64c4a3a442eee2d27e1151b8ae7bbfab2d91961f Mon Sep 17 00:00:00 2001 From: Shaun Ren Date: Mon, 4 Nov 2024 13:38:09 -0500 Subject: [PATCH] vkd3d-shader/hlsl: Store SM4 semantic declarations in the vsir program. --- libs/vkd3d-shader/hlsl_codegen.c | 125 +++++++++++++++ libs/vkd3d-shader/tpf.c | 187 +++++++++-------------- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 194 insertions(+), 119 deletions(-) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 213e403d..dfb73bbc 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -7642,6 +7642,123 @@ static void replace_instr_with_last_vsir_instr(struct hlsl_ctx *ctx, hlsl_replace_node(instr, vsir_instr); } +static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vsir_program *program, + const struct hlsl_ir_var *var, bool is_patch_constant_func, struct hlsl_block *block, + const struct vkd3d_shader_location *loc) +{ + const struct vkd3d_shader_version *version = &program->shader_version; + const bool output = var->is_output_semantic; + enum vkd3d_shader_sysval_semantic semantic; + struct vkd3d_shader_dst_param *dst_param; + struct vkd3d_shader_instruction *ins; + enum vkd3d_shader_register_type type; + enum vkd3d_shader_opcode opcode; + uint32_t write_mask; + unsigned int idx; + bool has_idx; + + sm4_sysval_semantic_from_semantic_name(&semantic, version, ctx->semantic_compat_mapping, + ctx->domain, var->semantic.name, var->semantic.index, output, is_patch_constant_func); + if (semantic == ~0u) + semantic = VKD3D_SHADER_SV_NONE; + + if (var->is_input_semantic) + { + switch (semantic) + { + case VKD3D_SHADER_SV_NONE: + opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) + ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT; + break; + + case VKD3D_SHADER_SV_INSTANCE_ID: + case VKD3D_SHADER_SV_IS_FRONT_FACE: + case VKD3D_SHADER_SV_PRIMITIVE_ID: + case VKD3D_SHADER_SV_SAMPLE_INDEX: + case VKD3D_SHADER_SV_VERTEX_ID: + opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) + ? VKD3DSIH_DCL_INPUT_PS_SGV : VKD3DSIH_DCL_INPUT_SGV; + break; + + default: + opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) + ? VKD3DSIH_DCL_INPUT_PS_SIV : VKD3DSIH_DCL_INPUT_SIV; + break; + } + } + else + { + if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL) + opcode = VKD3DSIH_DCL_OUTPUT; + else + opcode = VKD3DSIH_DCL_OUTPUT_SIV; + } + + if (sm4_register_from_semantic_name(version, var->semantic.name, output, &type, &has_idx)) + { + if (has_idx) + idx = var->semantic.index; + write_mask = (1u << var->data_type->dimx) - 1; + } + else + { + if (output) + type = VKD3DSPR_OUTPUT; + else if (version->type == VKD3D_SHADER_TYPE_DOMAIN) + type = VKD3DSPR_PATCHCONST; + else + type = VKD3DSPR_INPUT; + + has_idx = true; + idx = var->regs[HLSL_REGSET_NUMERIC].id; + write_mask = var->regs[HLSL_REGSET_NUMERIC].writemask; + } + + if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, opcode, 0, 0))) + return; + + if (opcode == VKD3DSIH_DCL_OUTPUT) + { + VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE + || semantic == VKD3D_SHADER_SV_TARGET || type != VKD3DSPR_OUTPUT); + dst_param = &ins->declaration.dst; + } + else if (opcode == VKD3DSIH_DCL_INPUT || opcode == VKD3DSIH_DCL_INPUT_PS) + { + VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE); + dst_param = &ins->declaration.dst; + } + else + { + VKD3D_ASSERT(semantic != VKD3D_SHADER_SV_NONE); + ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval_indexed(semantic, + var->semantic.index); + dst_param = &ins->declaration.register_semantic.reg; + } + + if (has_idx) + { + vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); + dst_param->reg.idx[0].offset = idx; + } + else + { + vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0); + } + + if (shader_sm4_is_scalar_register(&dst_param->reg)) + dst_param->reg.dimension = VSIR_DIMENSION_SCALAR; + else + dst_param->reg.dimension = VSIR_DIMENSION_VEC4; + + dst_param->write_mask = write_mask; + + if (var->is_input_semantic && version->type == VKD3D_SHADER_TYPE_PIXEL) + ins->flags = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); + + add_last_vsir_instr_to_block(ctx, program, block); +} + static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_program *program, uint32_t temp_count, struct hlsl_block *block, const struct vkd3d_shader_location *loc) { @@ -7731,6 +7848,7 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, uint64_t config_flags, struct vsir_program *program) { + bool is_patch_constant_func = func == ctx->patch_constant_func; struct hlsl_block block = {0}; struct hlsl_scope *scope; struct hlsl_ir_var *var; @@ -7745,6 +7863,13 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, hlsl_block_init(&block); + LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) + { + if ((var->is_input_semantic && var->last_read) + || (var->is_output_semantic && var->first_write)) + sm4_generate_vsir_instr_dcl_semantic(ctx, program, var, is_patch_constant_func, &block, &var->loc); + } + if (temp_count) sm4_generate_vsir_instr_dcl_temps(ctx, program, temp_count, &block, &func->loc); diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 8158f3ab..4978fcbf 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2235,7 +2235,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui return true; } -static bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg) +bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg) { switch (reg->type) { @@ -4856,114 +4856,6 @@ static void write_sm4_dcl_textures(const struct tpf_compiler *tpf, const struct } } -static void tpf_write_dcl_semantic(const struct tpf_compiler *tpf, - const struct hlsl_ir_var *var, bool is_patch_constant_func) -{ - const struct vkd3d_shader_version *version = &tpf->program->shader_version; - const bool output = var->is_output_semantic; - enum vkd3d_shader_sysval_semantic semantic; - bool has_idx; - - struct sm4_instruction instr = - { - .dsts[0].reg.dimension = VSIR_DIMENSION_VEC4, - .dst_count = 1, - }; - - if (sm4_register_from_semantic_name(version, var->semantic.name, output, &instr.dsts[0].reg.type, &has_idx)) - { - if (has_idx) - { - instr.dsts[0].reg.idx[0].offset = var->semantic.index; - instr.dsts[0].reg.idx_count = 1; - } - else - { - instr.dsts[0].reg.idx_count = 0; - } - instr.dsts[0].write_mask = (1 << var->data_type->dimx) - 1; - } - else - { - if (output) - instr.dsts[0].reg.type = VKD3DSPR_OUTPUT; - else if (version->type == VKD3D_SHADER_TYPE_DOMAIN) - instr.dsts[0].reg.type = VKD3DSPR_PATCHCONST; - else - instr.dsts[0].reg.type = VKD3DSPR_INPUT; - - instr.dsts[0].reg.idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; - instr.dsts[0].reg.idx_count = 1; - instr.dsts[0].write_mask = var->regs[HLSL_REGSET_NUMERIC].writemask; - } - - if (shader_sm4_is_scalar_register(&instr.dsts[0].reg)) - instr.dsts[0].reg.dimension = VSIR_DIMENSION_SCALAR; - - sm4_sysval_semantic_from_semantic_name(&semantic, version, tpf->ctx->semantic_compat_mapping, - tpf->ctx->domain, var->semantic.name, var->semantic.index, output, is_patch_constant_func); - if (semantic == ~0u) - semantic = VKD3D_SHADER_SV_NONE; - - if (var->is_input_semantic) - { - switch (semantic) - { - case VKD3D_SHADER_SV_NONE: - instr.opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) - ? VKD3D_SM4_OP_DCL_INPUT_PS : VKD3D_SM4_OP_DCL_INPUT; - break; - - case VKD3D_SHADER_SV_INSTANCE_ID: - case VKD3D_SHADER_SV_IS_FRONT_FACE: - case VKD3D_SHADER_SV_PRIMITIVE_ID: - case VKD3D_SHADER_SV_SAMPLE_INDEX: - case VKD3D_SHADER_SV_VERTEX_ID: - instr.opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) - ? VKD3D_SM4_OP_DCL_INPUT_PS_SGV : VKD3D_SM4_OP_DCL_INPUT_SGV; - break; - - default: - instr.opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) - ? VKD3D_SM4_OP_DCL_INPUT_PS_SIV : VKD3D_SM4_OP_DCL_INPUT_SIV; - break; - } - - if (version->type == VKD3D_SHADER_TYPE_PIXEL) - { - enum vkd3d_shader_interpolation_mode mode; - - mode = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); - instr.extra_bits |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT; - } - } - else - { - if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL) - instr.opcode = VKD3D_SM4_OP_DCL_OUTPUT; - else - instr.opcode = VKD3D_SM4_OP_DCL_OUTPUT_SIV; - } - - if (instr.opcode == VKD3D_SM4_OP_DCL_OUTPUT) - { - VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || semantic == VKD3D_SHADER_SV_TARGET - || instr.dsts[0].reg.type != VKD3DSPR_OUTPUT); - } - else if (instr.opcode == VKD3D_SM4_OP_DCL_INPUT || instr.opcode == VKD3D_SM4_OP_DCL_INPUT_PS) - { - VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE); - } - else - { - VKD3D_ASSERT(semantic != VKD3D_SHADER_SV_NONE); - instr.idx_count = 1; - instr.idx[0] = vkd3d_siv_from_sysval_indexed(semantic, var->semantic.index); - } - - write_sm4_instruction(tpf, &instr); -} - static void tpf_dcl_temps(const struct tpf_compiler *tpf, unsigned int count) { struct sm4_instruction instr = @@ -4990,6 +4882,41 @@ static void tpf_dcl_indexable_temp(const struct tpf_compiler *tpf, const struct write_sm4_instruction(tpf, &instr); } +static void tpf_dcl_semantic(const struct tpf_compiler *tpf, enum vkd3d_sm4_opcode opcode, + const struct vkd3d_shader_dst_param *dst, uint32_t interpolation_flags) +{ + struct sm4_instruction instr = + { + .opcode = opcode, + + .dsts[0] = *dst, + .dst_count = 1, + + .extra_bits = interpolation_flags << VKD3D_SM4_INTERPOLATION_MODE_SHIFT, + }; + + write_sm4_instruction(tpf, &instr); +} + +static void tpf_dcl_siv_semantic(const struct tpf_compiler *tpf, enum vkd3d_sm4_opcode opcode, + const struct vkd3d_shader_register_semantic *semantic, uint32_t interpolation_flags) +{ + struct sm4_instruction instr = + { + .opcode = opcode, + + .dsts[0] = semantic->reg, + .dst_count = 1, + + .idx[0] = semantic->sysval_semantic, + .idx_count = 1, + + .extra_bits = interpolation_flags << VKD3D_SM4_INTERPOLATION_MODE_SHIFT, + }; + + write_sm4_instruction(tpf, &instr); +} + static void tpf_dcl_thread_group(const struct tpf_compiler *tpf, const struct vsir_thread_group_size *group_size) { struct sm4_instruction instr = @@ -6529,6 +6456,38 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ tpf_dcl_indexable_temp(tpf, &ins->declaration.indexable_temp); break; + case VKD3DSIH_DCL_INPUT: + tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT, &ins->declaration.dst, 0); + break; + + case VKD3DSIH_DCL_INPUT_PS: + tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS, &ins->declaration.dst, ins->flags); + break; + + case VKD3DSIH_DCL_INPUT_PS_SGV: + tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SGV, &ins->declaration.register_semantic, 0); + break; + + case VKD3DSIH_DCL_INPUT_PS_SIV: + tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SIV, &ins->declaration.register_semantic, ins->flags); + break; + + case VKD3DSIH_DCL_INPUT_SGV: + tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SGV, &ins->declaration.register_semantic, 0); + break; + + case VKD3DSIH_DCL_INPUT_SIV: + tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SIV, &ins->declaration.register_semantic, 0); + break; + + case VKD3DSIH_DCL_OUTPUT: + tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT, &ins->declaration.dst, 0); + break; + + case VKD3DSIH_DCL_OUTPUT_SIV: + tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SIV, &ins->declaration.register_semantic, 0); + break; + case VKD3DSIH_MOV: tpf_simple_instruction(tpf, ins); break; @@ -6621,16 +6580,6 @@ static void write_sm4_block(struct tpf_compiler *tpf, const struct hlsl_block *b static void tpf_write_shader_function(struct tpf_compiler *tpf, struct hlsl_ir_function_decl *func) { - struct hlsl_ctx *ctx = tpf->ctx; - const struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) - { - if ((var->is_input_semantic && var->last_read) - || (var->is_output_semantic && var->first_write)) - tpf_write_dcl_semantic(tpf, var, func == ctx->patch_constant_func); - } - if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE) tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 07590b66..23f70ce9 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1620,6 +1620,7 @@ bool sm1_usage_from_semantic_name(const char *semantic_name, uint32_t semantic_index, enum vkd3d_decl_usage *usage, uint32_t *usage_idx); bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, bool output, enum vkd3d_shader_register_type *type, bool *has_idx); +bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg); bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *sysval_semantic, const struct vkd3d_shader_version *version, bool semantic_compat_mapping, enum vkd3d_tessellator_domain domain, const char *semantic_name, unsigned int semantic_idx, bool output, bool is_patch_constant_func);