agx: Model interpolation for iter instructions
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
2548293e8b
commit
b7f130fbbc
@@ -376,6 +376,8 @@ agx_emit_load_vary(agx_builder *b, agx_index dest, nir_intrinsic_instr *instr)
|
|||||||
/* TODO: Interpolation modes */
|
/* TODO: Interpolation modes */
|
||||||
assert(bary != NULL);
|
assert(bary != NULL);
|
||||||
assert(bary->intrinsic == nir_intrinsic_load_barycentric_pixel);
|
assert(bary->intrinsic == nir_intrinsic_load_barycentric_pixel);
|
||||||
|
enum agx_interpolation interp = AGX_INTERPOLATION_CENTER;
|
||||||
|
agx_index sample_index = agx_zero();
|
||||||
|
|
||||||
bool perspective =
|
bool perspective =
|
||||||
nir_intrinsic_interp_mode(bary) != INTERP_MODE_NOPERSPECTIVE;
|
nir_intrinsic_interp_mode(bary) != INTERP_MODE_NOPERSPECTIVE;
|
||||||
@@ -395,9 +397,9 @@ agx_emit_load_vary(agx_builder *b, agx_index dest, nir_intrinsic_instr *instr)
|
|||||||
/* For perspective interpolation, we project (multiply by 1/W) */
|
/* For perspective interpolation, we project (multiply by 1/W) */
|
||||||
if (perspective) {
|
if (perspective) {
|
||||||
agx_index J = agx_get_cf(b->shader, true, false, VARYING_SLOT_POS, 3, 1);
|
agx_index J = agx_get_cf(b->shader, true, false, VARYING_SLOT_POS, 3, 1);
|
||||||
agx_iterproj_to(b, dest, I, J, components);
|
agx_iterproj_to(b, dest, I, J, sample_index, components, interp);
|
||||||
} else {
|
} else {
|
||||||
agx_iter_to(b, dest, I, components);
|
agx_iter_to(b, dest, I, sample_index, components, interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
agx_emit_cached_split(b, dest, components);
|
agx_emit_cached_split(b, dest, components);
|
||||||
@@ -644,7 +646,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, 1);
|
agx_iter_to(b, fp32, cf, agx_zero(), 1, AGX_INTERPOLATION_CENTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -305,6 +305,9 @@ typedef struct {
|
|||||||
bool shadow : 1;
|
bool shadow : 1;
|
||||||
enum agx_gather gather : 3;
|
enum agx_gather gather : 3;
|
||||||
|
|
||||||
|
/* TODO: Handle iter ops more efficient */
|
||||||
|
enum agx_interpolation interpolation : 2;
|
||||||
|
|
||||||
/* Final st_vary op */
|
/* Final st_vary op */
|
||||||
bool last : 1;
|
bool last : 1;
|
||||||
|
|
||||||
|
@@ -42,6 +42,8 @@ should_lower(enum agx_opcode op, agx_index uniform, unsigned src_index)
|
|||||||
case AGX_OPCODE_ST_VARY:
|
case AGX_OPCODE_ST_VARY:
|
||||||
case AGX_OPCODE_LOCAL_ATOMIC:
|
case AGX_OPCODE_LOCAL_ATOMIC:
|
||||||
case AGX_OPCODE_SAMPLE_MASK:
|
case AGX_OPCODE_SAMPLE_MASK:
|
||||||
|
case AGX_OPCODE_ITER:
|
||||||
|
case AGX_OPCODE_ITERPROJ:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@@ -153,6 +153,14 @@ ATOMIC_OPC = enum("atomic_opc", {
|
|||||||
10: 'xor',
|
10: 'xor',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
INTERPOLATION = enum("interpolation", {
|
||||||
|
0: 'center',
|
||||||
|
1: 'sample',
|
||||||
|
2: 'centroid',
|
||||||
|
# We translate sample -> sample_register at pack time for simplicity
|
||||||
|
3: 'sample_register',
|
||||||
|
})
|
||||||
|
|
||||||
FUNOP = lambda x: (x << 28)
|
FUNOP = lambda x: (x << 28)
|
||||||
FUNOP_MASK = FUNOP((1 << 14) - 1)
|
FUNOP_MASK = FUNOP((1 << 14) - 1)
|
||||||
|
|
||||||
@@ -327,8 +335,14 @@ 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 = 1, imms = [CHANNELS])
|
|
||||||
op("iterproj", (0x21, 0xBF, 8, _), srcs = 2, imms = [CHANNELS])
|
# Sources are the coeffient register and the sample index (if applicable)
|
||||||
|
op("iter", (0x21, 0xBF, 8, _), srcs = 2, imms = [CHANNELS, INTERPOLATION])
|
||||||
|
|
||||||
|
# Sources are the coeffient register for the varying, the coefficient register
|
||||||
|
# for W, and the sample index (if applicable)
|
||||||
|
op("iterproj", (0x21, 0xBF, 8, _), srcs = 3, imms = [CHANNELS, INTERPOLATION])
|
||||||
|
|
||||||
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)
|
||||||
|
@@ -547,14 +547,28 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups,
|
|||||||
assert(cf_I < 0x100);
|
assert(cf_I < 0x100);
|
||||||
assert(cf_J < 0x100);
|
assert(cf_J < 0x100);
|
||||||
|
|
||||||
|
enum agx_interpolation interp = I->interpolation;
|
||||||
|
agx_index sample_index = flat ? agx_null() : I->src[perspective ? 2 : 1];
|
||||||
|
|
||||||
|
/* Fix up the interpolation enum to distinguish the sample index source */
|
||||||
|
if (interp == AGX_INTERPOLATION_SAMPLE) {
|
||||||
|
if (sample_index.type == AGX_INDEX_REGISTER)
|
||||||
|
interp = AGX_INTERPOLATION_SAMPLE_REGISTER;
|
||||||
|
else
|
||||||
|
assert(sample_index.type == AGX_INDEX_IMMEDIATE);
|
||||||
|
} else {
|
||||||
|
sample_index = agx_zero();
|
||||||
|
}
|
||||||
|
|
||||||
bool kill = false; // TODO: optimize
|
bool kill = false; // TODO: optimize
|
||||||
|
|
||||||
uint64_t raw =
|
uint64_t raw =
|
||||||
0x21 | (flat ? (1 << 7) : 0) | (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) | (((uint64_t)sample_index.value) << 32) |
|
||||||
(kill ? (1ull << 52) : 0) | /* XXX */
|
(!flat ? (1ull << 46) : 0) | /* XXX */
|
||||||
|
(((uint64_t)interp) << 48) | (kill ? (1ull << 52) : 0) | /* XXX */
|
||||||
(((uint64_t)(D >> 8)) << 56) | ((uint64_t)(cf_I >> 6) << 58) |
|
(((uint64_t)(D >> 8)) << 56) | ((uint64_t)(cf_I >> 6) << 58) |
|
||||||
((uint64_t)(cf_J >> 6) << 60);
|
((uint64_t)(cf_J >> 6) << 60);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user