From 090cccbc1bdcb366fe318249a3fba07cc105e6f5 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 11 May 2022 09:26:22 -0400 Subject: [PATCH] zink: fix up sparse texture sampling for shadow samplers the problem here is that this returns a vec2 instead of a vec5, which throws all the existing calculations off given that the shader is (still) expecting a vec2 return from this, and there's no way to sanely rewrite with nir to be valid for both sampler types as well as spirv translation, just pad out to a vec2 here and be done with it Fixes: 73ef54e3424 ("zink: handle residency return value from sparse texture instructions") Reviewed-by: Dave Airlie Part-of: (cherry picked from commit 88912b31119a14ffc99087781a17eeb4af202866) --- .pick_status.json | 2 +- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 8fec2bf97cf..3c6cb6556a1 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1900,7 +1900,7 @@ "description": "zink: fix up sparse texture sampling for shadow samplers", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "because_sha": "73ef54e34242fa59803a3a89b5a6eb92053e917e" }, { diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index 7d7f77d3a26..49f60a92b4a 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -2449,7 +2449,22 @@ extract_sparse_load(struct ntv_context *ctx, SpvId result, SpvId dest_type, nir_ uint32_t idx = 0; SpvId resident = spirv_builder_emit_composite_extract(&ctx->builder, spirv_builder_type_uint(&ctx->builder, 32), result, &idx, 1); idx = 1; - result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, result, &idx, 1); + /* normal vec4 return */ + if (dest_ssa->num_components == 4) + result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, result, &idx, 1); + else { + /* shadow */ + assert(dest_ssa->num_components == 1); + SpvId type = spirv_builder_type_float(&ctx->builder, dest_ssa->bit_size); + SpvId val[2]; + /* pad to 2 components: the upcoming is_sparse_texels_resident instr will always use the + * separate residency value, but the shader still expects this return to be a vec2, + * so give it a vec2 + */ + val[0] = spirv_builder_emit_composite_extract(&ctx->builder, type, result, &idx, 1); + val[1] = emit_float_const(ctx, dest_ssa->bit_size, 0); + result = spirv_builder_emit_composite_construct(&ctx->builder, get_fvec_type(ctx, dest_ssa->bit_size, 2), val, 2); + } assert(resident != 0); assert(dest_ssa->index < ctx->num_defs); ctx->resident_defs[dest_ssa->index] = resident; @@ -3258,8 +3273,10 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) result = emit_unop(ctx, SpvOpFConvert, dest_type, result); } + if (tex->is_sparse && tex->is_shadow) + tex->dest.ssa.num_components++; store_dest(ctx, &tex->dest, result, tex->dest_type); - if (tex->is_sparse) + if (tex->is_sparse && !tex->is_shadow) tex->dest.ssa.num_components++; }