mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
agx: handle min_lod sources
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30633>
This commit is contained in:
parent
03830c9523
commit
907fe00da1
4 changed files with 61 additions and 13 deletions
|
|
@ -2007,23 +2007,33 @@ agx_emit_alu(agx_builder *b, nir_alu_instr *instr)
|
|||
}
|
||||
|
||||
static enum agx_lod_mode
|
||||
agx_lod_mode_for_nir(nir_texop op, bool biased, bool lod_is_zero)
|
||||
agx_lod_mode_for_nir(nir_texop op, bool biased, bool min_lod, bool lod_is_zero)
|
||||
{
|
||||
switch (op) {
|
||||
case nir_texop_tex:
|
||||
case nir_texop_tg4:
|
||||
/* We could support this for tex, but it's never actually seen because tex
|
||||
* is always turned into txb to implement sampler LOD bias in Vulkan.
|
||||
*/
|
||||
assert(!min_lod && "unimplemented");
|
||||
|
||||
return AGX_LOD_MODE_AUTO_LOD;
|
||||
case nir_texop_txb:
|
||||
return AGX_LOD_MODE_AUTO_LOD_BIAS;
|
||||
return min_lod ? AGX_LOD_MODE_AUTO_LOD_BIAS_MIN
|
||||
: AGX_LOD_MODE_AUTO_LOD_BIAS;
|
||||
case nir_texop_lod:
|
||||
assert(!min_lod);
|
||||
return biased ? AGX_LOD_MODE_AUTO_LOD_BIAS : AGX_LOD_MODE_AUTO_LOD;
|
||||
case nir_texop_txd:
|
||||
return AGX_LOD_MODE_LOD_GRAD;
|
||||
return min_lod ? AGX_LOD_MODE_LOD_GRAD_MIN : AGX_LOD_MODE_LOD_GRAD;
|
||||
case nir_texop_txl:
|
||||
assert(!min_lod);
|
||||
return AGX_LOD_MODE_LOD_MIN;
|
||||
case nir_texop_txf:
|
||||
assert(!min_lod);
|
||||
return lod_is_zero ? AGX_LOD_MODE_AUTO_LOD : AGX_LOD_MODE_LOD_MIN;
|
||||
case nir_texop_txf_ms:
|
||||
assert(!min_lod);
|
||||
assert(lod_is_zero && "no mipmapping");
|
||||
return AGX_LOD_MODE_AUTO_LOD;
|
||||
default:
|
||||
|
|
@ -2055,7 +2065,8 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||
agx_index coords = agx_null(), bindless = agx_immediate(0),
|
||||
texture = agx_immediate(instr->texture_index),
|
||||
sampler = agx_immediate(0), lod = agx_immediate(0),
|
||||
compare = agx_null(), packed_offset = agx_null();
|
||||
compare = agx_null(), packed_offset = agx_null(),
|
||||
min_lod = agx_null();
|
||||
|
||||
bool lod_is_zero = true;
|
||||
|
||||
|
|
@ -2078,6 +2089,11 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||
nir_src_as_uint(instr->src[i].src) == 0;
|
||||
break;
|
||||
|
||||
case nir_tex_src_min_lod:
|
||||
assert(index.size == AGX_SIZE_16);
|
||||
min_lod = index;
|
||||
break;
|
||||
|
||||
case nir_tex_src_comparator:
|
||||
assert(index.size == AGX_SIZE_32);
|
||||
compare = index;
|
||||
|
|
@ -2099,20 +2115,37 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||
int y_idx = nir_tex_instr_src_index(instr, nir_tex_src_ddy);
|
||||
assert(y_idx >= 0 && "we only handle gradients");
|
||||
|
||||
int min_idx = nir_tex_instr_src_index(instr, nir_tex_src_min_lod);
|
||||
bool has_min = min_idx >= 0;
|
||||
agx_index min;
|
||||
|
||||
unsigned n = nir_tex_instr_src_size(instr, y_idx);
|
||||
assert((n == 2 || n == 3) && "other sizes not supported");
|
||||
|
||||
agx_index index2 = agx_src_index(&instr->src[y_idx].src);
|
||||
|
||||
if (has_min) {
|
||||
min = agx_src_index(&instr->src[min_idx].src);
|
||||
|
||||
/* Undef extend to 32-bit since our IR is iffy */
|
||||
min = agx_vec2(b, min, agx_undef(AGX_SIZE_16));
|
||||
min.channels_m1--;
|
||||
min.size = AGX_SIZE_32;
|
||||
}
|
||||
|
||||
/* We explicitly don't cache about the split cache for this */
|
||||
lod = agx_vec_temp(b->shader, AGX_SIZE_32, 2 * n);
|
||||
agx_instr *I = agx_collect_to(b, lod, 2 * n);
|
||||
unsigned chans = (2 * n) + (has_min ? 1 : 0);
|
||||
lod = agx_vec_temp(b->shader, AGX_SIZE_32, chans);
|
||||
agx_instr *I = agx_collect_to(b, lod, chans);
|
||||
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
I->src[(2 * i) + 0] = agx_emit_extract(b, index, i);
|
||||
I->src[(2 * i) + 1] = agx_emit_extract(b, index2, i);
|
||||
}
|
||||
|
||||
if (has_min)
|
||||
I->src[2 * n] = min;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2127,11 +2160,14 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
|
|||
|
||||
enum agx_lod_mode lod_mode = agx_lod_mode_for_nir(
|
||||
instr->op, nir_tex_instr_src_index(instr, nir_tex_src_bias) >= 0,
|
||||
lod_is_zero);
|
||||
nir_tex_instr_src_index(instr, nir_tex_src_min_lod) >= 0, lod_is_zero);
|
||||
|
||||
if (lod_mode == AGX_LOD_MODE_AUTO_LOD) {
|
||||
/* Ignored logically but asserted 0 */
|
||||
lod = agx_immediate(0);
|
||||
} else if (lod_mode == AGX_LOD_MODE_AUTO_LOD_BIAS_MIN) {
|
||||
/* Combine min with lod */
|
||||
lod = agx_vec2(b, lod, min_lod);
|
||||
}
|
||||
|
||||
agx_index dst = agx_def_index(&instr->def);
|
||||
|
|
|
|||
|
|
@ -296,9 +296,11 @@ enum agx_lod_mode {
|
|||
AGX_LOD_MODE_AUTO_LOD_BIAS_UNIFORM = 1,
|
||||
AGX_LOD_MODE_LOD_MIN_UNIFORM = 2,
|
||||
AGX_LOD_MODE_AUTO_LOD_BIAS = 5,
|
||||
AGX_LOD_MODE_LOD_MIN = 6,
|
||||
AGX_LOD_MODE_LOD_GRAD = 4,
|
||||
AGX_LOD_MODE_LOD_GRAD_MIN = 12
|
||||
AGX_LOD_MODE_LOD_MIN = 6,
|
||||
AGX_LOD_MODE_AUTO_LOD_BIAS_MIN_UNIFORM = 9,
|
||||
AGX_LOD_MODE_LOD_GRAD_MIN = 12,
|
||||
AGX_LOD_MODE_AUTO_LOD_BIAS_MIN = 13,
|
||||
};
|
||||
|
||||
/* Forward declare for branch target */
|
||||
|
|
|
|||
|
|
@ -298,23 +298,32 @@ agx_read_registers(const agx_instr *I, unsigned s)
|
|||
return agx_coordinate_registers(I);
|
||||
} else if (s == 1) {
|
||||
/* LOD */
|
||||
if (I->lod_mode == AGX_LOD_MODE_LOD_GRAD) {
|
||||
if (I->lod_mode == AGX_LOD_MODE_LOD_GRAD ||
|
||||
I->lod_mode == AGX_LOD_MODE_LOD_GRAD_MIN) {
|
||||
|
||||
/* Technically only 16-bit but we model as 32-bit to keep the IR
|
||||
* simple, since the gradient is otherwise 32-bit.
|
||||
*/
|
||||
unsigned min = I->lod_mode == AGX_LOD_MODE_LOD_GRAD_MIN ? 2 : 0;
|
||||
|
||||
switch (I->dim) {
|
||||
case AGX_DIM_1D:
|
||||
case AGX_DIM_1D_ARRAY:
|
||||
return 2 * 2 * 1;
|
||||
return (2 * 2 * 1) + min;
|
||||
case AGX_DIM_2D:
|
||||
case AGX_DIM_2D_ARRAY:
|
||||
case AGX_DIM_2D_MS_ARRAY:
|
||||
case AGX_DIM_2D_MS:
|
||||
return 2 * 2 * 2;
|
||||
return (2 * 2 * 2) + min;
|
||||
case AGX_DIM_CUBE:
|
||||
case AGX_DIM_CUBE_ARRAY:
|
||||
case AGX_DIM_3D:
|
||||
return 2 * 2 * 3;
|
||||
return (2 * 2 * 3) + min;
|
||||
}
|
||||
|
||||
unreachable("Invalid texture dimension");
|
||||
} else if (I->lod_mode == AGX_LOD_MODE_AUTO_LOD_BIAS_MIN) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -747,6 +747,7 @@ agx_nir_lower_texture(nir_shader *s)
|
|||
[nir_tex_src_lod] = {true, 16},
|
||||
[nir_tex_src_bias] = {true, 16},
|
||||
[nir_tex_src_ms_index] = {true, 16},
|
||||
[nir_tex_src_min_lod] = {true, 16},
|
||||
[nir_tex_src_texture_offset] = {true, 16},
|
||||
[nir_tex_src_sampler_offset] = {true, 16},
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue