agx: Split iter and iterproj instructions
These are different (though related) instructions. I've split them in applegpu, let's mirror that here. This simplifies the IR a bit. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23480>
This commit is contained in:

committed by
Marge Bot

parent
b9b71bcae6
commit
2548293e8b
@@ -388,16 +388,18 @@ agx_emit_load_vary(agx_builder *b, agx_index dest, nir_intrinsic_instr *instr)
|
|||||||
nir_component_mask(components) &&
|
nir_component_mask(components) &&
|
||||||
"iter does not handle write-after-write hazards");
|
"iter does not handle write-after-write hazards");
|
||||||
|
|
||||||
/* For perspective interpolation, we need W */
|
|
||||||
agx_index J =
|
|
||||||
!perspective ? agx_zero()
|
|
||||||
: agx_get_cf(b->shader, true, false, VARYING_SLOT_POS, 3, 1);
|
|
||||||
|
|
||||||
agx_index I = agx_get_cf(b->shader, true, perspective,
|
agx_index I = agx_get_cf(b->shader, true, perspective,
|
||||||
sem.location + nir_src_as_uint(*offset),
|
sem.location + nir_src_as_uint(*offset),
|
||||||
nir_intrinsic_component(instr), components);
|
nir_intrinsic_component(instr), components);
|
||||||
|
|
||||||
agx_iter_to(b, dest, I, J, components, perspective);
|
/* For perspective interpolation, we project (multiply by 1/W) */
|
||||||
|
if (perspective) {
|
||||||
|
agx_index J = agx_get_cf(b->shader, true, false, VARYING_SLOT_POS, 3, 1);
|
||||||
|
agx_iterproj_to(b, dest, I, J, components);
|
||||||
|
} else {
|
||||||
|
agx_iter_to(b, dest, I, components);
|
||||||
|
}
|
||||||
|
|
||||||
agx_emit_cached_split(b, dest, components);
|
agx_emit_cached_split(b, dest, components);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,7 +644,7 @@ agx_emit_load_frag_coord(agx_builder *b, agx_index dst,
|
|||||||
agx_get_cf(b->shader, true, false, VARYING_SLOT_POS, i, 1);
|
agx_get_cf(b->shader, true, false, VARYING_SLOT_POS, i, 1);
|
||||||
|
|
||||||
dests[i] = fp32;
|
dests[i] = fp32;
|
||||||
agx_iter_to(b, fp32, cf, agx_null(), 1, false);
|
agx_iter_to(b, fp32, cf, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -296,9 +296,6 @@ typedef struct {
|
|||||||
/* For local access */
|
/* For local access */
|
||||||
enum agx_format format;
|
enum agx_format format;
|
||||||
|
|
||||||
/* For load varying */
|
|
||||||
bool perspective : 1;
|
|
||||||
|
|
||||||
/* Invert icond/fcond */
|
/* Invert icond/fcond */
|
||||||
bool invert_cond : 1;
|
bool invert_cond : 1;
|
||||||
|
|
||||||
@@ -325,7 +322,7 @@ typedef struct {
|
|||||||
bool saturate : 1;
|
bool saturate : 1;
|
||||||
unsigned mask : 4;
|
unsigned mask : 4;
|
||||||
|
|
||||||
unsigned padding : 8;
|
unsigned padding : 9;
|
||||||
} agx_instr;
|
} agx_instr;
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@@ -108,7 +108,6 @@ INVERT_COND = immediate("invert_cond")
|
|||||||
NEST = immediate("nest")
|
NEST = immediate("nest")
|
||||||
TARGET = immediate("target", "agx_block *")
|
TARGET = immediate("target", "agx_block *")
|
||||||
ZS = immediate("zs")
|
ZS = immediate("zs")
|
||||||
PERSPECTIVE = immediate("perspective", "bool")
|
|
||||||
SR = enum("sr", {
|
SR = enum("sr", {
|
||||||
0: 'threadgroup_position_in_grid.x',
|
0: 'threadgroup_position_in_grid.x',
|
||||||
1: 'threadgroup_position_in_grid.y',
|
1: 'threadgroup_position_in_grid.y',
|
||||||
@@ -328,7 +327,8 @@ for is_float in [False, True]:
|
|||||||
|
|
||||||
op("bitop", (0x7E, 0x7F, 6, _), srcs = 2, imms = [TRUTH_TABLE])
|
op("bitop", (0x7E, 0x7F, 6, _), srcs = 2, imms = [TRUTH_TABLE])
|
||||||
op("convert", (0x3E | L, 0x7F | L | (0x3 << 38), 6, _), srcs = 2, imms = [ROUND])
|
op("convert", (0x3E | L, 0x7F | L | (0x3 << 38), 6, _), srcs = 2, imms = [ROUND])
|
||||||
op("iter", (0x21, 0xBF, 8, _), srcs = 2, imms = [CHANNELS, PERSPECTIVE])
|
op("iter", (0x21, 0xBF, 8, _), srcs = 1, imms = [CHANNELS])
|
||||||
|
op("iterproj", (0x21, 0xBF, 8, _), srcs = 2, imms = [CHANNELS])
|
||||||
op("ldcf", (0xA1, 0xBF, 8, _), srcs = 1, imms = [CHANNELS])
|
op("ldcf", (0xA1, 0xBF, 8, _), srcs = 1, imms = [CHANNELS])
|
||||||
op("st_vary", None, dests = 0, srcs = 2, can_eliminate = False)
|
op("st_vary", None, dests = 0, srcs = 2, can_eliminate = False)
|
||||||
op("no_varyings", (0x80000051, 0xFFFFFFFF, 4, _), dests = 0, can_eliminate = False)
|
op("no_varyings", (0x80000051, 0xFFFFFFFF, 4, _), dests = 0, can_eliminate = False)
|
||||||
|
@@ -74,8 +74,6 @@ instrs_equal(const void *_i1, const void *_i2)
|
|||||||
|
|
||||||
if (i1->imm != i2->imm)
|
if (i1->imm != i2->imm)
|
||||||
return false;
|
return false;
|
||||||
if (i1->perspective != i2->perspective)
|
|
||||||
return false;
|
|
||||||
if (i1->invert_cond != i2->invert_cond)
|
if (i1->invert_cond != i2->invert_cond)
|
||||||
return false;
|
return false;
|
||||||
if (i1->dim != i2->dim)
|
if (i1->dim != i2->dim)
|
||||||
|
@@ -525,19 +525,20 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case AGX_OPCODE_ITER:
|
case AGX_OPCODE_ITER:
|
||||||
|
case AGX_OPCODE_ITERPROJ:
|
||||||
case AGX_OPCODE_LDCF: {
|
case AGX_OPCODE_LDCF: {
|
||||||
bool flat = (I->op == AGX_OPCODE_LDCF);
|
bool flat = (I->op == AGX_OPCODE_LDCF);
|
||||||
|
bool perspective = (I->op == AGX_OPCODE_ITERPROJ);
|
||||||
unsigned D = agx_pack_alu_dst(I->dest[0]);
|
unsigned D = agx_pack_alu_dst(I->dest[0]);
|
||||||
unsigned channels = (I->channels & 0x3);
|
unsigned channels = (I->channels & 0x3);
|
||||||
|
|
||||||
agx_index src_I = I->src[0];
|
agx_index src_I = I->src[0];
|
||||||
assert(src_I.type == AGX_INDEX_IMMEDIATE);
|
assert(src_I.type == AGX_INDEX_IMMEDIATE);
|
||||||
assert(!(flat && I->perspective));
|
|
||||||
|
|
||||||
unsigned cf_I = src_I.value;
|
unsigned cf_I = src_I.value;
|
||||||
unsigned cf_J = 0;
|
unsigned cf_J = 0;
|
||||||
|
|
||||||
if (I->perspective) {
|
if (perspective) {
|
||||||
agx_index src_J = I->src[1];
|
agx_index src_J = I->src[1];
|
||||||
assert(src_J.type == AGX_INDEX_IMMEDIATE);
|
assert(src_J.type == AGX_INDEX_IMMEDIATE);
|
||||||
cf_J = src_J.value;
|
cf_J = src_J.value;
|
||||||
@@ -549,7 +550,7 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups,
|
|||||||
bool kill = false; // TODO: optimize
|
bool kill = false; // TODO: optimize
|
||||||
|
|
||||||
uint64_t raw =
|
uint64_t raw =
|
||||||
0x21 | (flat ? (1 << 7) : 0) | (I->perspective ? (1 << 6) : 0) |
|
0x21 | (flat ? (1 << 7) : 0) | (perspective ? (1 << 6) : 0) |
|
||||||
((D & 0xFF) << 7) | (1ull << 15) | /* XXX */
|
((D & 0xFF) << 7) | (1ull << 15) | /* XXX */
|
||||||
((cf_I & BITFIELD_MASK(6)) << 16) | ((cf_J & BITFIELD_MASK(6)) << 24) |
|
((cf_I & BITFIELD_MASK(6)) << 16) | ((cf_J & BITFIELD_MASK(6)) << 24) |
|
||||||
(((uint64_t)channels) << 30) | (!flat ? (1ull << 46) : 0) | /* XXX */
|
(((uint64_t)channels) << 30) | (!flat ? (1ull << 46) : 0) | /* XXX */
|
||||||
|
@@ -31,6 +31,7 @@ agx_write_registers(const agx_instr *I, unsigned d)
|
|||||||
|
|
||||||
switch (I->op) {
|
switch (I->op) {
|
||||||
case AGX_OPCODE_ITER:
|
case AGX_OPCODE_ITER:
|
||||||
|
case AGX_OPCODE_ITERPROJ:
|
||||||
assert(1 <= I->channels && I->channels <= 4);
|
assert(1 <= I->channels && I->channels <= 4);
|
||||||
return I->channels * size;
|
return I->channels * size;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user