agx: Plumb through nir_op_txf
nir_op_txf maps to AGX's texture_load, which is encoded like texture_sample. The one outstanding question with this commit is the rules for the sample required ... in NIR and APIs (including Metal), txf is samplerless, but the AGX instruction consumes a sampler. Hopefully any sampler will do, though? Passes dEQP-GLES3.functional.shaders.texture_functions.texelfetch.* Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18380>
This commit is contained in:

committed by
Marge Bot

parent
44d79d39b6
commit
10c9aceadf
@@ -970,6 +970,7 @@ agx_lod_mode_for_nir(nir_texop op)
|
|||||||
case nir_texop_tex: return AGX_LOD_MODE_AUTO_LOD;
|
case nir_texop_tex: return AGX_LOD_MODE_AUTO_LOD;
|
||||||
case nir_texop_txb: return AGX_LOD_MODE_AUTO_LOD_BIAS;
|
case nir_texop_txb: return AGX_LOD_MODE_AUTO_LOD_BIAS;
|
||||||
case nir_texop_txl: return AGX_LOD_MODE_LOD_MIN;
|
case nir_texop_txl: return AGX_LOD_MODE_LOD_MIN;
|
||||||
|
case nir_texop_txf: return AGX_LOD_MODE_LOD_MIN;
|
||||||
default: unreachable("Unhandled texture op");
|
default: unreachable("Unhandled texture op");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -979,6 +980,7 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||||||
{
|
{
|
||||||
switch (instr->op) {
|
switch (instr->op) {
|
||||||
case nir_texop_tex:
|
case nir_texop_tex:
|
||||||
|
case nir_texop_txf:
|
||||||
case nir_texop_txl:
|
case nir_texop_txl:
|
||||||
case nir_texop_txb:
|
case nir_texop_txb:
|
||||||
break;
|
break;
|
||||||
@@ -992,6 +994,8 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||||||
lod = agx_immediate(0),
|
lod = agx_immediate(0),
|
||||||
offset = agx_null();
|
offset = agx_null();
|
||||||
|
|
||||||
|
bool txf = instr->op == nir_texop_txf;
|
||||||
|
|
||||||
for (unsigned i = 0; i < instr->num_srcs; ++i) {
|
for (unsigned i = 0; i < instr->num_srcs; ++i) {
|
||||||
agx_index index = agx_src_index(&instr->src[i].src);
|
agx_index index = agx_src_index(&instr->src[i].src);
|
||||||
|
|
||||||
@@ -1008,6 +1012,9 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||||||
* max(0, min(d - 1, floor(layer + 0.5))) =
|
* max(0, min(d - 1, floor(layer + 0.5))) =
|
||||||
* max(0, min(d - 1, f32_to_u32(layer + 0.5))) =
|
* max(0, min(d - 1, f32_to_u32(layer + 0.5))) =
|
||||||
* min(d - 1, f32_to_u32(layer + 0.5))
|
* min(d - 1, f32_to_u32(layer + 0.5))
|
||||||
|
*
|
||||||
|
* For txf, the coordinates are already integers, so we only need to
|
||||||
|
* clamp (not convert).
|
||||||
*/
|
*/
|
||||||
if (instr->is_array) {
|
if (instr->is_array) {
|
||||||
unsigned nr = nir_src_num_components(instr->src[i].src);
|
unsigned nr = nir_src_num_components(instr->src[i].src);
|
||||||
@@ -1016,15 +1023,18 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||||||
for (unsigned i = 0; i < nr; ++i)
|
for (unsigned i = 0; i < nr; ++i)
|
||||||
channels[i] = agx_emit_extract(b, index, i);
|
channels[i] = agx_emit_extract(b, index, i);
|
||||||
|
|
||||||
agx_index layer = agx_fadd(b, channels[nr - 1],
|
|
||||||
agx_immediate_f(0.5f));
|
|
||||||
|
|
||||||
agx_index d1 = agx_indexed_sysval(b->shader,
|
agx_index d1 = agx_indexed_sysval(b->shader,
|
||||||
AGX_PUSH_ARRAY_SIZE_MINUS_1, AGX_SIZE_16,
|
AGX_PUSH_ARRAY_SIZE_MINUS_1, AGX_SIZE_16,
|
||||||
instr->texture_index, 1);
|
instr->texture_index, 1);
|
||||||
|
|
||||||
layer = agx_convert(b, agx_immediate(AGX_CONVERT_F_TO_U32), layer,
|
agx_index layer = channels[nr - 1];
|
||||||
AGX_ROUND_RTZ);
|
|
||||||
|
if (!txf) {
|
||||||
|
layer = agx_fadd(b, channels[nr - 1], agx_immediate_f(0.5f));
|
||||||
|
|
||||||
|
layer = agx_convert(b, agx_immediate(AGX_CONVERT_F_TO_U32), layer,
|
||||||
|
AGX_ROUND_RTZ);
|
||||||
|
}
|
||||||
|
|
||||||
agx_index layer16 = agx_temp(b->shader, AGX_SIZE_16);
|
agx_index layer16 = agx_temp(b->shader, AGX_SIZE_16);
|
||||||
agx_mov_to(b, layer16, layer);
|
agx_mov_to(b, layer16, layer);
|
||||||
@@ -1058,12 +1068,16 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
agx_index dst = agx_dest_index(&instr->dest);
|
agx_index dst = agx_dest_index(&instr->dest);
|
||||||
agx_texture_sample_to(b, dst, coords, lod, texture, sampler, offset,
|
|
||||||
|
agx_instr *I = agx_texture_sample_to(b, dst, coords, lod, texture, sampler, offset,
|
||||||
agx_tex_dim(instr->sampler_dim, instr->is_array),
|
agx_tex_dim(instr->sampler_dim, instr->is_array),
|
||||||
agx_lod_mode_for_nir(instr->op),
|
agx_lod_mode_for_nir(instr->op),
|
||||||
0xF, /* TODO: wrmask */
|
0xF, /* TODO: wrmask */
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
if (txf)
|
||||||
|
I->op = AGX_OPCODE_TEXTURE_LOAD;
|
||||||
|
|
||||||
agx_wait(b, 0);
|
agx_wait(b, 0);
|
||||||
agx_emit_cached_split(b, dst, 4);
|
agx_emit_cached_split(b, dst, 4);
|
||||||
}
|
}
|
||||||
|
@@ -194,7 +194,10 @@ op("fcmpsel",
|
|||||||
# sources are coordinates, LOD, texture, sampler, offset
|
# sources are coordinates, LOD, texture, sampler, offset
|
||||||
# TODO: anything else?
|
# TODO: anything else?
|
||||||
op("texture_sample",
|
op("texture_sample",
|
||||||
encoding_32 = (0x32, 0x7F, 8, 10), # XXX WRONG SIZE
|
encoding_32 = (0x31, 0x7F, 8, 10), # XXX WRONG SIZE
|
||||||
|
srcs = 5, imms = [DIM, LOD_MODE, MASK, SCOREBOARD])
|
||||||
|
op("texture_load",
|
||||||
|
encoding_32 = (0x71, 0x7F, 8, 10), # XXX WRONG SIZE
|
||||||
srcs = 5, imms = [DIM, LOD_MODE, MASK, SCOREBOARD])
|
srcs = 5, imms = [DIM, LOD_MODE, MASK, SCOREBOARD])
|
||||||
|
|
||||||
# sources are base, index
|
# sources are base, index
|
||||||
|
@@ -570,6 +570,7 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups, agx
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case AGX_OPCODE_TEXTURE_LOAD:
|
||||||
case AGX_OPCODE_TEXTURE_SAMPLE:
|
case AGX_OPCODE_TEXTURE_SAMPLE:
|
||||||
{
|
{
|
||||||
assert(I->mask != 0);
|
assert(I->mask != 0);
|
||||||
@@ -611,6 +612,7 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups, agx
|
|||||||
|
|
||||||
uint64_t raw =
|
uint64_t raw =
|
||||||
0x31 |
|
0x31 |
|
||||||
|
((I->op == AGX_OPCODE_TEXTURE_LOAD) ? (1 << 6) : 0) |
|
||||||
(Rt ? (1 << 8) : 0) |
|
(Rt ? (1 << 8) : 0) |
|
||||||
((R & BITFIELD_MASK(6)) << 9) |
|
((R & BITFIELD_MASK(6)) << 9) |
|
||||||
(L ? (1 << 15) : 0) |
|
(L ? (1 << 15) : 0) |
|
||||||
|
@@ -38,6 +38,7 @@ agx_write_registers(agx_instr *I, unsigned d)
|
|||||||
return I->channels * size;
|
return I->channels * size;
|
||||||
|
|
||||||
case AGX_OPCODE_DEVICE_LOAD:
|
case AGX_OPCODE_DEVICE_LOAD:
|
||||||
|
case AGX_OPCODE_TEXTURE_LOAD:
|
||||||
case AGX_OPCODE_TEXTURE_SAMPLE:
|
case AGX_OPCODE_TEXTURE_SAMPLE:
|
||||||
case AGX_OPCODE_LD_TILE:
|
case AGX_OPCODE_LD_TILE:
|
||||||
/* TODO: mask */
|
/* TODO: mask */
|
||||||
|
Reference in New Issue
Block a user