From 4290d853974ec02025f622c356b69443daf91b2c Mon Sep 17 00:00:00 2001 From: Elizabeth Figura Date: Mon, 4 Nov 2024 22:46:56 -0600 Subject: [PATCH] vkd3d-shader/hlsl: Write all writemask components for PSIZE and FOG outputs. Matching fxc/d3dcompiler. --- libs/vkd3d-shader/hlsl_codegen.c | 26 +++++++++++++++++++++----- tests/vkd3d_shader_api.c | 5 ++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 3f1ff5a6..832a378c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -6519,16 +6519,22 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog sysval = VKD3D_SHADER_SV_POSITION; } + mask = (1 << var->data_type->dimx) - 1; + if (!ascii_strcasecmp(var->semantic.name, "PSIZE") && output - && program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX && var->data_type->dimx > 1) - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, - "PSIZE output must have only 1 component in this shader model."); + && program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX) + { + if (var->data_type->dimx > 1) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + "PSIZE output must have only 1 component in this shader model."); + /* For some reason the writemask has all components set. */ + mask = VKD3DSP_WRITEMASK_ALL; + } if (!ascii_strcasecmp(var->semantic.name, "FOG") && output && program->shader_version.major < 3 && program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX && var->data_type->dimx > 1) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "FOG output must have only 1 component in this shader model."); - mask = (1 << var->data_type->dimx) - 1; use_mask = mask; /* FIXME: retrieve use mask accurately. */ component_type = VKD3D_SHADER_COMPONENT_FLOAT; } @@ -7251,6 +7257,8 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, if (deref->var->is_output_semantic) { + const char *semantic_name = deref->var->semantic.name; + version.major = ctx->profile->major_version; version.minor = ctx->profile->minor_version; version.type = ctx->profile->type; @@ -7260,7 +7268,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, type = VKD3DSPR_TEMP; register_index = 0; } - else if (!sm1_register_from_semantic_name(&version, deref->var->semantic.name, + else if (!sm1_register_from_semantic_name(&version, semantic_name, deref->var->semantic.index, true, &type, ®ister_index)) { VKD3D_ASSERT(reg.allocated); @@ -7269,6 +7277,14 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, } else writemask = (1u << deref->var->data_type->dimx) - 1; + + if (version.type == VKD3D_SHADER_TYPE_PIXEL && (!ascii_strcasecmp(semantic_name, "PSIZE") + || (!ascii_strcasecmp(semantic_name, "FOG") && version.major < 3))) + { + /* These are always 1-component, but for some reason are written + * with a writemask containing all components. */ + writemask = VKD3DSP_WRITEMASK_ALL; + } } else VKD3D_ASSERT(reg.allocated); diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c index 727b06c3..15223fb1 100644 --- a/tests/vkd3d_shader_api.c +++ b/tests/vkd3d_shader_api.c @@ -438,7 +438,7 @@ static void check_signature_element(const struct vkd3d_shader_signature_element ok(element->component_type == expect->component_type, "Got component type %#x.\n", element->component_type); ok(element->register_index == expect->register_index, "Got register index %u.\n", element->register_index); ok(element->mask == expect->mask, "Got mask %#x.\n", element->mask); - todo_if (expect->used_mask != expect->mask) + todo_if (expect->used_mask != expect->mask && strcmp(expect->semantic_name, "PSIZE")) ok(element->used_mask == expect->used_mask, "Got used mask %#x.\n", element->used_mask); ok(element->min_precision == expect->min_precision, "Got minimum precision %#x.\n", element->min_precision); } @@ -574,8 +574,7 @@ static void test_scan_signatures(void) {"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf}, {"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 4, 0xf, 0xf}, {"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 5, 0xf, 0xf}, - /* FIXME: This doesn't match native, which always declares and writes all 4 components. */ - {"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 6, 0x1, 0x1}, + {"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 6, 0xf, 0x1}, }; static const char ps1_source[] =