nir/linker: pack varyings with different interpolation qualifier

Driver like radeonsi load varying in a scalar manner, so prefer to pack
varying with different interpolation qualifier into same slot to save
space.

But driver like panfrost/bifrost can load varying in vector manner,
so prefer to pack varying with same interpolation qualifier.

Driver can add interpolation qualifiers which are able to be
packed into same varying slot to pack_varying_options nir option.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12537>
This commit is contained in:
Qiang Yu
2021-08-25 14:07:50 +08:00
committed by Marge Bot
parent 5a24aed1ac
commit 7054c1b7fd
2 changed files with 95 additions and 18 deletions

View File

@@ -670,12 +670,60 @@ gather_varying_component_info(nir_shader *producer, nir_shader *consumer,
}
}
static bool
allow_pack_interp_type(nir_pack_varying_options options, int type)
{
int sel;
switch (type) {
case INTERP_MODE_NONE:
sel = nir_pack_varying_interp_mode_none;
break;
case INTERP_MODE_SMOOTH:
sel = nir_pack_varying_interp_mode_smooth;
break;
case INTERP_MODE_FLAT:
sel = nir_pack_varying_interp_mode_flat;
break;
case INTERP_MODE_NOPERSPECTIVE:
sel = nir_pack_varying_interp_mode_noperspective;
break;
default:
return false;
}
return options & sel;
}
static bool
allow_pack_interp_loc(nir_pack_varying_options options, int loc)
{
int sel;
switch (loc) {
case INTERPOLATE_LOC_SAMPLE:
sel = nir_pack_varying_interp_loc_sample;
break;
case INTERPOLATE_LOC_CENTROID:
sel = nir_pack_varying_interp_loc_centroid;
break;
case INTERPOLATE_LOC_CENTER:
sel = nir_pack_varying_interp_loc_center;
break;
default:
return false;
}
return options & sel;
}
static void
assign_remap_locations(struct varying_loc (*remap)[4],
struct assigned_comps *assigned_comps,
struct varying_component *info,
unsigned *cursor, unsigned *comp,
unsigned max_location)
unsigned max_location,
nir_pack_varying_options options)
{
unsigned tmp_cursor = *cursor;
unsigned tmp_comp = *comp;
@@ -683,21 +731,28 @@ assign_remap_locations(struct varying_loc (*remap)[4],
for (; tmp_cursor < max_location; tmp_cursor++) {
if (assigned_comps[tmp_cursor].comps) {
/* We can only pack varyings with matching interpolation types,
* interpolation loc must match also.
* TODO: i965 can handle interpolation locations that don't match,
* but the radeonsi nir backend handles everything as vec4s and so
* expects this to be the same for all components. We could make this
* check driver specfific or drop it if NIR ever become the only
* radeonsi backend.
* TODO2: The radeonsi comment above is not true. Only "flat" is per
* vec4 (128-bit granularity), all other interpolation qualifiers are
* per component (16-bit granularity for float16, 32-bit granularity
* otherwise). Each vec4 (128 bits) must be either vec4 or f16vec8.
/* We can only pack varyings with matching precision. */
if (assigned_comps[tmp_cursor].is_mediump != info->is_mediump) {
tmp_comp = 0;
continue;
}
/* We can only pack varyings with matching interpolation type
* if driver does not support it.
*/
if (assigned_comps[tmp_cursor].interp_type != info->interp_type ||
assigned_comps[tmp_cursor].interp_loc != info->interp_loc ||
assigned_comps[tmp_cursor].is_mediump != info->is_mediump) {
if (assigned_comps[tmp_cursor].interp_type != info->interp_type &&
(!allow_pack_interp_type(options, assigned_comps[tmp_cursor].interp_type) ||
!allow_pack_interp_type(options, info->interp_type))) {
tmp_comp = 0;
continue;
}
/* We can only pack varyings with matching interpolation location
* if driver does not support it.
*/
if (assigned_comps[tmp_cursor].interp_loc != info->interp_loc &&
(!allow_pack_interp_loc(options, assigned_comps[tmp_cursor].interp_loc) ||
!allow_pack_interp_loc(options, info->interp_loc))) {
tmp_comp = 0;
continue;
}
@@ -764,6 +819,8 @@ compact_components(nir_shader *producer, nir_shader *consumer,
qsort(varying_comp_info, varying_comp_info_size,
sizeof(struct varying_component), cmp_varying_component);
nir_pack_varying_options options = consumer->options->pack_varying_options;
unsigned cursor = 0;
unsigned comp = 0;
@@ -783,10 +840,12 @@ compact_components(nir_shader *producer, nir_shader *consumer,
}
assign_remap_locations(remap, assigned_comps, info,
&cursor, &comp, MAX_VARYINGS_INCL_PATCH);
&cursor, &comp, MAX_VARYINGS_INCL_PATCH,
options);
} else {
assign_remap_locations(remap, assigned_comps, info,
&cursor, &comp, MAX_VARYING);
&cursor, &comp, MAX_VARYING,
options);
/* Check if we failed to assign a remap location. This can happen if
* for example there are a bunch of unmovable components with
@@ -799,7 +858,8 @@ compact_components(nir_shader *producer, nir_shader *consumer,
cursor = 0;
comp = 0;
assign_remap_locations(remap, assigned_comps, info,
&cursor, &comp, MAX_VARYING);
&cursor, &comp, MAX_VARYING,
options);
}
}
}