From 1ed5f1a4d0aefdcc801c99dbd27cffeda9c707df Mon Sep 17 00:00:00 2001 From: Shaun Ren Date: Tue, 15 Oct 2024 16:33:21 -0400 Subject: [PATCH] vkd3d-shader/tpf: Write the patch constant function in hull shaders. We use a single hs_fork_phase here for the patch constant function. --- libs/vkd3d-shader/hlsl_codegen.c | 31 ++++++++++-------- libs/vkd3d-shader/tpf.c | 41 ++++++++++++++++-------- libs/vkd3d-shader/vkd3d_shader_private.h | 2 +- libs/vkd3d-utils/reflection.c | 7 ++-- tests/hlsl_d3d12.c | 9 +++--- 5 files changed, 55 insertions(+), 35 deletions(-) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index c626eb04..4cf9d5eb 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -6281,29 +6281,24 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) } while (progress); } -static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, - struct vsir_program *program, bool output, struct hlsl_ir_var *var) +static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_program *program, + struct shader_signature *signature, bool output, struct hlsl_ir_var *var) { enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; enum vkd3d_shader_component_type component_type; unsigned int register_index, mask, use_mask; const char *name = var->semantic.name; enum vkd3d_shader_register_type type; - struct shader_signature *signature; struct signature_element *element; - if (output) - signature = &program->output_signature; - else - signature = &program->input_signature; - if (hlsl_version_ge(ctx, 4, 0)) { struct vkd3d_string_buffer *string; bool has_idx, ret; ret = sm4_sysval_semantic_from_semantic_name(&sysval, &program->shader_version, - ctx->semantic_compat_mapping, ctx->domain, var->semantic.name, var->semantic.index, output, false); + ctx->semantic_compat_mapping, ctx->domain, var->semantic.name, var->semantic.index, + output, signature == &program->patch_constant_signature); VKD3D_ASSERT(ret); if (sysval == ~0u) return; @@ -6419,10 +6414,18 @@ static void generate_vsir_signature(struct hlsl_ctx *ctx, LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) { - if (var->is_input_semantic) - generate_vsir_signature_entry(ctx, program, false, var); - if (var->is_output_semantic) - generate_vsir_signature_entry(ctx, program, true, var); + if (func == ctx->patch_constant_func) + { + generate_vsir_signature_entry(ctx, program, + &program->patch_constant_signature, var->is_output_semantic, var); + } + else + { + if (var->is_input_semantic) + generate_vsir_signature_entry(ctx, program, &program->input_signature, false, var); + if (var->is_output_semantic) + generate_vsir_signature_entry(ctx, program, &program->output_signature, true, var); + } } } @@ -7408,6 +7411,8 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl } generate_vsir_signature(ctx, program, entry_func); + if (version.type == VKD3D_SHADER_TYPE_HULL) + generate_vsir_signature(ctx, program, ctx->patch_constant_func); } 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 10456f0e..a712f4b5 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3212,18 +3212,12 @@ static void add_section(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, ctx->result = buffer->status; } -static void tpf_write_signature(struct tpf_compiler *tpf, bool output) +static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_signature *signature, uint32_t tag) { + bool output = tag == TAG_OSGN || tag == TAG_PCSG; struct vkd3d_bytecode_buffer buffer = {0}; - struct shader_signature *signature; - struct hlsl_ctx *ctx = tpf->ctx; unsigned int i; - if (output) - signature = &tpf->program->output_signature; - else - signature = &tpf->program->input_signature; - put_u32(&buffer, signature->element_count); put_u32(&buffer, 8); /* unknown */ @@ -3257,7 +3251,7 @@ static void tpf_write_signature(struct tpf_compiler *tpf, bool output) set_u32(&buffer, (2 + i * 6) * sizeof(uint32_t), string_offset); } - add_section(ctx, &tpf->dxbc, output ? TAG_OSGN : TAG_ISGN, &buffer); + add_section(tpf->ctx, &tpf->dxbc, tag, &buffer); } static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) @@ -4794,7 +4788,8 @@ static void write_sm4_dcl_textures(const struct tpf_compiler *tpf, const struct } } -static void write_sm4_dcl_semantic(const struct tpf_compiler *tpf, const struct hlsl_ir_var *var) +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; @@ -4832,7 +4827,7 @@ static void write_sm4_dcl_semantic(const struct tpf_compiler *tpf, const struct 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, false); + tpf->ctx->domain, var->semantic.name, var->semantic.index, output, is_patch_constant_func); if (semantic == ~0u) semantic = VKD3D_SHADER_SV_NONE; @@ -4997,6 +4992,16 @@ static void tpf_write_hs_control_point_phase(const struct tpf_compiler *tpf) write_sm4_instruction(tpf, &instr); } +static void tpf_write_hs_fork_phase(const struct tpf_compiler *tpf) +{ + struct sm4_instruction instr = + { + .opcode = VKD3D_SM5_OP_HS_FORK_PHASE, + }; + + write_sm4_instruction(tpf, &instr); +} + static void tpf_write_dcl_input_control_point_count(const struct tpf_compiler *tpf, const uint32_t count) { struct sm4_instruction instr = @@ -6513,7 +6518,7 @@ static void tpf_write_shader_function(struct tpf_compiler *tpf, struct hlsl_ir_f { if ((var->is_input_semantic && var->last_read) || (var->is_output_semantic && var->first_write)) - write_sm4_dcl_semantic(tpf, var); + tpf_write_dcl_semantic(tpf, var, func == ctx->patch_constant_func); } if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE) @@ -6613,6 +6618,12 @@ static void tpf_write_shdr(struct tpf_compiler *tpf, struct hlsl_ir_function_dec tpf_write_shader_function(tpf, entry_func); + if (version->type == VKD3D_SHADER_TYPE_HULL) + { + tpf_write_hs_fork_phase(tpf); + tpf_write_shader_function(tpf, ctx->patch_constant_func); + } + set_u32(&buffer, token_count_position, bytecode_get_size(&buffer) / sizeof(uint32_t)); add_section(ctx, &tpf->dxbc, TAG_SHDR, &buffer); @@ -6717,8 +6728,10 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags, init_sm4_lookup_tables(&tpf.lookup); dxbc_writer_init(&tpf.dxbc); - tpf_write_signature(&tpf, false); - tpf_write_signature(&tpf, true); + tpf_write_signature(&tpf, &program->input_signature, TAG_ISGN); + tpf_write_signature(&tpf, &program->output_signature, TAG_OSGN); + if (ctx->profile->type == VKD3D_SHADER_TYPE_HULL) + tpf_write_signature(&tpf, &program->patch_constant_signature, TAG_PCSG); write_sm4_rdef(ctx, &tpf.dxbc); tpf_write_shdr(&tpf, entry_func); tpf_write_sfi0(&tpf); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 3c367c08..0f606c37 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1924,7 +1924,7 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain, #define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t)) #define VKD3D_DXBC_CHUNK_ALIGNMENT sizeof(uint32_t) -#define DXBC_MAX_SECTION_COUNT 6 +#define DXBC_MAX_SECTION_COUNT 7 struct dxbc_writer { diff --git a/libs/vkd3d-utils/reflection.c b/libs/vkd3d-utils/reflection.c index e8363ae4..d13ad700 100644 --- a/libs/vkd3d-utils/reflection.c +++ b/libs/vkd3d-utils/reflection.c @@ -512,9 +512,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetOutputParameterDesc( static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetPatchConstantParameterDesc( ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) { - FIXME("iface %p, index %u, desc %p stub!\n", iface, index, desc); + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); - return E_NOTIMPL; + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + return get_signature_parameter(&reflection->signature_info.patch_constant, index, desc, + /* FIXME: check shader type */true); } static struct ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3d12_reflection_GetVariableByName( diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c index 90d0c0ef..9b007aac 100644 --- a/tests/hlsl_d3d12.c +++ b/tests/hlsl_d3d12.c @@ -2589,9 +2589,8 @@ static void test_signature_reflection(void) "Got %u input parameters.\n", shader_desc.InputParameters); ok(shader_desc.OutputParameters == tests[i].output_count, "Got %u output parameters.\n", shader_desc.OutputParameters); - todo_if(tests[i].patch_constant_count != 0) - ok(shader_desc.PatchConstantParameters == tests[i].patch_constant_count, - "Got %u patch constant parameters.\n", shader_desc.PatchConstantParameters); + ok(shader_desc.PatchConstantParameters == tests[i].patch_constant_count, + "Got %u patch constant parameters.\n", shader_desc.PatchConstantParameters); for (unsigned int j = 0; j < shader_desc.InputParameters; ++j) { @@ -2621,13 +2620,13 @@ static void test_signature_reflection(void) { vkd3d_test_push_context("Patch constant %u", j); hr = reflection->lpVtbl->GetPatchConstantParameterDesc(reflection, j, &desc); - todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); check_signature_element(&desc, &tests[i].patch_constants[j], tests[i].signature_elements_todo); vkd3d_test_pop_context(); } hr = reflection->lpVtbl->GetPatchConstantParameterDesc(reflection, shader_desc.PatchConstantParameters, &desc); - todo ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); ID3D10Blob_Release(code); refcount = reflection->lpVtbl->Release(reflection);