iris/gen11+: Calculate pixel hashing tables instead of hardcoding.

Pixel hashing tables are a pain to type in, review and maintain IMHO.
In order to obtain satisfactory load balancing on all Gen12 parts
currently in production this series would need to add 5 different
additional tables.  Instead this introduces a simple algorithm able to
calculate a table on the fly based on a handful of parameters.

Note that the Gen11 tables generated with this algorithm are not
identical to the hardcoded ones, however the only difference should be
a phase shift that isn't expected to have any effect on performance,
since it shouldn't change the fraction of work submitted to each pixel
pipe.

The CPU overhead from this change is negligible since the tables only
need to be programmed once at context init time.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8749>
This commit is contained in:
Francisco Jerez 2021-01-13 23:06:55 -08:00
parent e2ef1c4676
commit f9bcdc5bc7
1 changed files with 46 additions and 47 deletions

View File

@ -802,14 +802,53 @@ iris_enable_obj_preemption(struct iris_batch *batch, bool enable)
}
#endif
/**
* Compute an \p n x \p m pixel hashing table usable as slice, subslice or
* pixel pipe hashing table. The resulting table is the cyclic repetition of
* a fixed pattern with periodicity equal to \p period.
*
* If \p index is specified to be equal to \p period, a 2-way hashing table
* will be generated such that indices 0 and 1 are returned for the following
* fractions of entries respectively:
*
* p_0 = ceil(period / 2) / period
* p_1 = floor(period / 2) / period
*
* If \p index is even and less than \p period, a 3-way hashing table will be
* generated such that indices 0, 1 and 2 are returned for the following
* fractions of entries:
*
* p_0 = (ceil(period / 2) - 1) / period
* p_1 = floor(period / 2) / period
* p_2 = 1 / period
*
* The equations above apply if \p flip is equal to 0, if it is equal to 1 p_0
* and p_1 will be swapped for the result. Note that in the context of pixel
* pipe hashing this can be always 0 on Gen12 platforms, since the hardware
* transparently remaps logical indices found on the table to physical pixel
* pipe indices from the highest to lowest EU count.
*/
UNUSED static void
calculate_pixel_hashing_table(unsigned n, unsigned m,
unsigned period, unsigned index, bool flip,
uint32_t *p)
{
for (unsigned i = 0; i < n; i++) {
for (unsigned j = 0; j < m; j++) {
const unsigned k = (i + j) % period;
p[j + m * i] = (k == index ? 2 : (k & 1) ^ flip);
}
}
}
#if GEN_GEN == 11
static void
iris_upload_slice_hashing_state(struct iris_batch *batch)
{
const struct gen_device_info *devinfo = &batch->screen->devinfo;
int subslices_delta =
devinfo->ppipe_subslices[0] - devinfo->ppipe_subslices[1];
if (subslices_delta == 0)
assert(devinfo->ppipe_subslices[2] == 0);
if (devinfo->ppipe_subslices[0] == devinfo->ppipe_subslices[1])
return;
struct iris_context *ice = batch->ice;
@ -823,51 +862,11 @@ iris_upload_slice_hashing_state(struct iris_batch *batch)
size, 64, &hash_address);
pipe_resource_reference(&tmp, NULL);
struct GENX(SLICE_HASH_TABLE) table0 = {
.Entry = {
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
{ 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
{ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 }
}
};
const bool flip = devinfo->ppipe_subslices[0] < devinfo->ppipe_subslices[1];
struct GENX(SLICE_HASH_TABLE) table;
calculate_pixel_hashing_table(16, 16, 3, 3, flip, table.Entry[0]);
struct GENX(SLICE_HASH_TABLE) table1 = {
.Entry = {
{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
{ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
{ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
{ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
{ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
{ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 }
}
};
const struct GENX(SLICE_HASH_TABLE) *table =
subslices_delta < 0 ? &table0 : &table1;
GENX(SLICE_HASH_TABLE_pack)(NULL, map, table);
GENX(SLICE_HASH_TABLE_pack)(NULL, map, &table);
iris_emit_cmd(batch, GENX(3DSTATE_SLICE_TABLE_STATE_POINTERS), ptr) {
ptr.SliceHashStatePointerValid = true;