uint8_t interp_loc;
bool is_32bit;
bool is_patch;
+ bool is_intra_stage_only;
bool initialised;
};
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.
*/
}
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)
/* 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 &&
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);
}
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;
+ }
}
}
}
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);