mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 10:40:11 +01:00
nir: fix packing of TCS varyings not read by the TES
Unlike other stages TCS outputs not read by the TES cannot always be demoted to globals e.g. when they are read by other TCS invocations. We were not taking these outputs into account when packing which could result in other outputs being assigned to the same location. Here we make sure to gather information on these outputs and group them together when packing. This fixes rendering issues in QUBE 2 via Proton. Closes: #2653 Fixes:26aa460940("nir: rewrite varying component packing") Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4328> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4328> (cherry picked from commitb5e00f5c2b)
This commit is contained in:
parent
c16dfe1c63
commit
284f3ce6bc
2 changed files with 69 additions and 5 deletions
|
|
@ -589,7 +589,7 @@
|
|||
"description": "nir: fix packing of TCS varyings not read by the TES",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"master_sha": null,
|
||||
"because_sha": "26aa460940f6222565ad5eb40a21c2377c59c3a6"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -443,6 +443,7 @@ struct varying_component {
|
|||
uint8_t interp_loc;
|
||||
bool is_32bit;
|
||||
bool is_patch;
|
||||
bool is_intra_stage_only;
|
||||
bool initialised;
|
||||
};
|
||||
|
||||
|
|
@ -456,6 +457,12 @@ cmp_varying_component(const void *comp1_v, const void *comp2_v)
|
|||
if (comp1->is_patch != comp2->is_patch)
|
||||
return comp1->is_patch ? 1 : -1;
|
||||
|
||||
/* We want to try to group together TCS outputs that are only read by other
|
||||
* TCS invocations and not consumed by the follow stage.
|
||||
*/
|
||||
if (comp1->is_intra_stage_only != comp2->is_intra_stage_only)
|
||||
return comp1->is_intra_stage_only ? 1 : -1;
|
||||
|
||||
/* We can only pack varyings with matching interpolation types so group
|
||||
* them together.
|
||||
*/
|
||||
|
|
@ -471,7 +478,7 @@ cmp_varying_component(const void *comp1_v, const void *comp2_v)
|
|||
}
|
||||
|
||||
static void
|
||||
gather_varying_component_info(nir_shader *consumer,
|
||||
gather_varying_component_info(nir_shader *producer, nir_shader *consumer,
|
||||
struct varying_component **varying_comp_info,
|
||||
unsigned *varying_comp_info_size,
|
||||
bool default_to_smooth_interp)
|
||||
|
|
@ -482,7 +489,7 @@ gather_varying_component_info(nir_shader *consumer,
|
|||
/* Count the number of varying that can be packed and create a mapping
|
||||
* of those varyings to the array we will pass to qsort.
|
||||
*/
|
||||
nir_foreach_variable(var, &consumer->inputs) {
|
||||
nir_foreach_variable(var, &producer->outputs) {
|
||||
|
||||
/* Only remap things that aren't builtins. */
|
||||
if (var->data.location >= VARYING_SLOT_VAR0 &&
|
||||
|
|
@ -493,7 +500,7 @@ gather_varying_component_info(nir_shader *consumer,
|
|||
continue;
|
||||
|
||||
const struct glsl_type *type = var->type;
|
||||
if (nir_is_per_vertex_io(var, consumer->info.stage)) {
|
||||
if (nir_is_per_vertex_io(var, producer->info.stage)) {
|
||||
assert(glsl_type_is_array(type));
|
||||
type = glsl_get_array_element(type);
|
||||
}
|
||||
|
|
@ -561,6 +568,63 @@ gather_varying_component_info(nir_shader *consumer,
|
|||
vc_info->interp_loc = get_interp_loc(in_var);
|
||||
vc_info->is_32bit = glsl_type_is_32bit(type);
|
||||
vc_info->is_patch = in_var->data.patch;
|
||||
vc_info->is_intra_stage_only = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Walk over the shader and populate the varying component info array
|
||||
* for varyings which are read by other TCS instances but are not consumed
|
||||
* by the TES.
|
||||
*/
|
||||
if (producer->info.stage == MESA_SHADER_TESS_CTRL) {
|
||||
impl = nir_shader_get_entrypoint(producer);
|
||||
|
||||
nir_foreach_block(block, impl) {
|
||||
nir_foreach_instr(instr, block) {
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
continue;
|
||||
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic != nir_intrinsic_load_deref)
|
||||
continue;
|
||||
|
||||
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
|
||||
if (deref->mode != nir_var_shader_out)
|
||||
continue;
|
||||
|
||||
/* We only remap things that aren't builtins. */
|
||||
nir_variable *out_var = nir_deref_instr_get_variable(deref);
|
||||
if (out_var->data.location < VARYING_SLOT_VAR0)
|
||||
continue;
|
||||
|
||||
unsigned location = out_var->data.location - VARYING_SLOT_VAR0;
|
||||
if (location >= MAX_VARYINGS_INCL_PATCH)
|
||||
continue;
|
||||
|
||||
unsigned var_info_idx =
|
||||
store_varying_info_idx[location][out_var->data.location_frac];
|
||||
if (!var_info_idx)
|
||||
continue;
|
||||
|
||||
struct varying_component *vc_info =
|
||||
&(*varying_comp_info)[var_info_idx-1];
|
||||
|
||||
if (!vc_info->initialised) {
|
||||
const struct glsl_type *type = out_var->type;
|
||||
if (nir_is_per_vertex_io(out_var, producer->info.stage)) {
|
||||
assert(glsl_type_is_array(type));
|
||||
type = glsl_get_array_element(type);
|
||||
}
|
||||
|
||||
vc_info->var = out_var;
|
||||
vc_info->interp_type =
|
||||
get_interp_type(out_var, type, default_to_smooth_interp);
|
||||
vc_info->interp_loc = get_interp_loc(out_var);
|
||||
vc_info->is_32bit = glsl_type_is_32bit(type);
|
||||
vc_info->is_patch = out_var->data.patch;
|
||||
vc_info->is_intra_stage_only = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -648,7 +712,7 @@ compact_components(nir_shader *producer, nir_shader *consumer,
|
|||
unsigned varying_comp_info_size;
|
||||
|
||||
/* Gather varying component info */
|
||||
gather_varying_component_info(consumer, &varying_comp_info,
|
||||
gather_varying_component_info(producer, consumer, &varying_comp_info,
|
||||
&varying_comp_info_size,
|
||||
default_to_smooth_interp);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue