diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 42ede1c1..e0fd2e2b 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -5168,7 +5168,8 @@ uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_d return allocator.reg_count; } -static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, unsigned int *counter, bool output) +static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, + unsigned int *counter, bool output, bool is_patch_constant_func) { static const char *const shader_names[] = { @@ -5217,8 +5218,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var enum vkd3d_shader_sysval_semantic semantic; bool has_idx; - if (!sm4_sysval_semantic_from_semantic_name(&semantic, &version, - ctx->semantic_compat_mapping, var->semantic.name, output)) + if (!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)) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Invalid semantic '%s'.", var->semantic.name); @@ -5247,15 +5248,16 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { + bool is_patch_constant_func = entry_func == ctx->patch_constant_func; unsigned int input_counter = 0, output_counter = 0; struct hlsl_ir_var *var; LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) { if (var->is_input_semantic) - allocate_semantic_register(ctx, var, &input_counter, false); + allocate_semantic_register(ctx, var, &input_counter, false, is_patch_constant_func); if (var->is_output_semantic) - allocate_semantic_register(ctx, var, &output_counter, true); + allocate_semantic_register(ctx, var, &output_counter, true, is_patch_constant_func); } } @@ -6301,7 +6303,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, bool has_idx, ret; ret = sm4_sysval_semantic_from_semantic_name(&sysval, &program->shader_version, - ctx->semantic_compat_mapping, var->semantic.name, output); + ctx->semantic_compat_mapping, ctx->domain, var->semantic.name, var->semantic.index, output, false); VKD3D_ASSERT(ret); if (sysval == ~0u) return; @@ -7749,10 +7751,18 @@ static void process_entry_function(struct hlsl_ctx *ctx, { var = entry_func->parameters.vars[i]; - if (hlsl_type_is_resource(var->data_type) || (var->storage_modifiers & HLSL_STORAGE_UNIFORM)) + if (hlsl_type_is_resource(var->data_type)) { prepend_uniform_copy(ctx, body, var); } + else if ((var->storage_modifiers & HLSL_STORAGE_UNIFORM)) + { + if (ctx->profile->type == VKD3D_SHADER_TYPE_HULL && entry_func == ctx->patch_constant_func) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Patch constant function parameter \"%s\" cannot be uniform.", var->name); + else + prepend_uniform_copy(ctx, body, var); + } else { if (hlsl_get_multiarray_element_type(var->data_type)->class != HLSL_CLASS_STRUCT @@ -7891,6 +7901,13 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (ctx->result) return ctx->result; + if (profile->type == VKD3D_SHADER_TYPE_HULL) + { + process_entry_function(ctx, &global_uniform_block, ctx->patch_constant_func); + if (ctx->result) + return ctx->result; + } + hlsl_block_cleanup(&global_uniform_block); if (profile->major_version < 4) diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index ffbc1bb6..e1002975 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3047,9 +3047,57 @@ bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, return false; } +static bool get_tessfactor_sysval_semantic(enum vkd3d_shader_sysval_semantic *semantic, + enum vkd3d_tessellator_domain domain, uint32_t index) +{ + switch (domain) + { + case VKD3D_TESSELLATOR_DOMAIN_LINE: + if (index == 0) + *semantic = VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN; + else if (index == 1) + *semantic = VKD3D_SHADER_SV_TESS_FACTOR_LINEDET; + else + return false; + return true; + + case VKD3D_TESSELLATOR_DOMAIN_TRIANGLE: + *semantic = VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE; + return index < 3; + + case VKD3D_TESSELLATOR_DOMAIN_QUAD: + *semantic = VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE; + return index < 4; + + default: + vkd3d_unreachable(); + } +} + +static bool get_insidetessfactor_sysval_semantic(enum vkd3d_shader_sysval_semantic *semantic, + enum vkd3d_tessellator_domain domain, uint32_t index) +{ + switch (domain) + { + case VKD3D_TESSELLATOR_DOMAIN_LINE: + return false; + + case VKD3D_TESSELLATOR_DOMAIN_TRIANGLE: + *semantic = VKD3D_SHADER_SV_TESS_FACTOR_TRIINT; + return index == 0; + + case VKD3D_TESSELLATOR_DOMAIN_QUAD: + *semantic = VKD3D_SHADER_SV_TESS_FACTOR_QUADINT; + return index < 2; + + default: + vkd3d_unreachable(); + } +} + bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *sysval_semantic, - const struct vkd3d_shader_version *version, - bool semantic_compat_mapping, const char *semantic_name, bool output) + 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) { unsigned int i; @@ -3105,6 +3153,32 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s }; bool needs_compat_mapping = ascii_strncasecmp(semantic_name, "sv_", 3); + if (is_patch_constant_func) + { + if (output) + { + if (!ascii_strcasecmp(semantic_name, "sv_tessfactor")) + return get_tessfactor_sysval_semantic(sysval_semantic, domain, semantic_idx); + if (!ascii_strcasecmp(semantic_name, "sv_insidetessfactor")) + return get_insidetessfactor_sysval_semantic(sysval_semantic, domain, semantic_idx); + if (!ascii_strcasecmp(semantic_name, "sv_position")) + { + *sysval_semantic = VKD3D_SHADER_SV_NONE; + return true; + } + } + else + { + if (!ascii_strcasecmp(semantic_name, "sv_primitiveid") + || !ascii_strcasecmp(semantic_name, "sv_position")) + { + *sysval_semantic = ~0u; + return true; + } + return false; + } + } + for (i = 0; i < ARRAY_SIZE(semantics); ++i) { if (!ascii_strcasecmp(semantic_name, semantics[i].name) @@ -4757,8 +4831,8 @@ static void write_sm4_dcl_semantic(const struct tpf_compiler *tpf, const struct 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, var->semantic.name, output); + sm4_sysval_semantic_from_semantic_name(&semantic, version, tpf->ctx->semantic_compat_mapping, + tpf->ctx->domain, var->semantic.name, var->semantic.index, output, false); if (semantic == ~0u) semantic = VKD3D_SHADER_SV_NONE; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 4808eea1..3c367c08 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1609,8 +1609,8 @@ bool sm1_usage_from_semantic_name(const char *semantic_name, 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 sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *sysval_semantic, - const struct vkd3d_shader_version *version, - bool semantic_compat_mapping, const char *semantic_name, bool output); + 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); int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, struct vkd3d_shader_message_context *message_context, struct vsir_program *program); diff --git a/tests/hlsl/hull-shader-syntax.shader_test b/tests/hlsl/hull-shader-syntax.shader_test index ebf11cb1..d860ff62 100644 --- a/tests/hlsl/hull-shader-syntax.shader_test +++ b/tests/hlsl/hull-shader-syntax.shader_test @@ -84,7 +84,7 @@ float4 main() : POSITION return 0; } -[hull shader fail todo] +[hull shader fail] struct patch_constant_data { float edges[2] : SV_TessFactor; @@ -140,7 +140,7 @@ float4 main(uniform float4 b) : POSITION } % Patch constant function can't have uniform parameters. -[hull shader fail todo] +[hull shader fail] struct patch_constant_data { float edges[2] : SV_TessFactor;