agx: Implement texture offsets and comparators

Texture offsets and shadow comparison values get grouped into a vector
passed by register. Comparison values are provided as-is (fp32). Texture
offsets are packed into nibbles, but we can do this on the CPU, as
nonconstant offsets are forbidden in GLSL at least. They're also
forbidden in Vulkan/SPIR-V without ImageGatherExtended/
shaderImageGatherExtended. I'm happy kicking the NIR lowering can down
the line, this commit is complicated enough already.

Passes dEQP-GLES3.functional.shaders.texture_functions.texture.* and
dEQP-GLES3.functional.shaders.texture_functions.textureoffset.*

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18525>
This commit is contained in:
Alyssa Rosenzweig
2022-09-08 18:59:35 -04:00
committed by Marge Bot
parent 4f85a7be8c
commit 7a4e0a4d35
5 changed files with 62 additions and 18 deletions

View File

@@ -1020,7 +1020,8 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
texture = agx_immediate(instr->texture_index),
sampler = agx_immediate(instr->sampler_index),
lod = agx_immediate(0),
offset = agx_null();
compare = agx_null(),
packed_offset = agx_null();
bool txf = instr->op == nir_texop_txf;
@@ -1085,9 +1086,32 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
lod = index;
break;
case nir_tex_src_ms_index:
case nir_tex_src_offset:
case nir_tex_src_comparator:
assert(index.size == AGX_SIZE_32);
compare = index;
break;
case nir_tex_src_offset:
{
assert(instr->src[i].src.is_ssa);
nir_ssa_def *def = instr->src[i].src.ssa;
uint32_t packed = 0;
for (unsigned c = 0; c < def->num_components; ++c) {
nir_ssa_scalar s = nir_ssa_scalar_resolved(def, c);
assert(nir_ssa_scalar_is_const(s) && "no nonconstant offsets");
int32_t val = nir_ssa_scalar_as_uint(s);
assert((val >= -8 && val <= 7) && "out of bounds offset");
packed |= (val & 0xF) << (4 * c);
}
packed_offset = agx_mov_imm(b, 32, packed);
break;
}
case nir_tex_src_ms_index:
case nir_tex_src_texture_offset:
case nir_tex_src_sampler_offset:
default:
@@ -1097,11 +1121,22 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
agx_index dst = agx_dest_index(&instr->dest);
agx_instr *I = agx_texture_sample_to(b, dst, coords, lod, texture, sampler, offset,
/* Pack shadow reference value (compare) and packed offset together */
agx_index compare_offset = agx_null();
if (!agx_is_null(compare) && !agx_is_null(packed_offset))
compare_offset = agx_vec2(b, compare, packed_offset);
else if (!agx_is_null(packed_offset))
compare_offset = packed_offset;
else if (!agx_is_null(compare))
compare_offset = compare;
agx_instr *I = agx_texture_sample_to(b, dst, coords, lod, texture, sampler,
compare_offset,
agx_tex_dim(instr->sampler_dim, instr->is_array),
agx_lod_mode_for_nir(instr->op),
0xF, /* TODO: wrmask */
0);
0, !agx_is_null(packed_offset), !agx_is_null(compare));
if (txf)
I->op = AGX_OPCODE_TEXTURE_LOAD;