unsigned actual_array_size;
switch (this->lowered_builtin_array_variable) {
case clip_distance:
- actual_array_size = prog->LastClipDistanceArraySize;
+ actual_array_size = prog->last_vert_prog ?
+ prog->last_vert_prog->info.clip_distance_array_size : 0;
break;
case cull_distance:
- actual_array_size = prog->LastCullDistanceArraySize;
+ actual_array_size = prog->last_vert_prog ?
+ prog->last_vert_prog->info.cull_distance_array_size : 0;
break;
case tess_level_outer:
actual_array_size = 4;
unsigned num_tfeedback_decls,
tfeedback_decl *tfeedback_decls, bool has_xfb_qualifiers)
{
+ if (!prog->last_vert_prog)
+ return true;
+
/* Make sure MaxTransformFeedbackBuffers is less than 32 so the bitmask for
* tracking the number of buffers doesn't overflow.
*/
bool separate_attribs_mode =
prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
- struct gl_program *xfb_prog = prog->xfb_program;
+ struct gl_program *xfb_prog = prog->last_vert_prog;
xfb_prog->sh.LinkedTransformFeedback =
rzalloc(xfb_prog, struct gl_transform_feedback_info);
{
public:
varying_matches(bool disable_varying_packing, bool xfb_enabled,
+ bool enhanced_layouts_enabled,
gl_shader_stage producer_stage,
gl_shader_stage consumer_stage);
~varying_matches();
*/
const bool xfb_enabled;
+ const bool enhanced_layouts_enabled;
+
/**
* Enum representing the order in which varyings are packed within a
* packing class.
varying_matches::varying_matches(bool disable_varying_packing,
bool xfb_enabled,
+ bool enhanced_layouts_enabled,
gl_shader_stage producer_stage,
gl_shader_stage consumer_stage)
: disable_varying_packing(disable_varying_packing),
xfb_enabled(xfb_enabled),
+ enhanced_layouts_enabled(enhanced_layouts_enabled),
producer_stage(producer_stage),
consumer_stage(consumer_stage)
{
if (!disable_varying_packing &&
(needs_flat_qualifier ||
- (consumer_stage != -1 && consumer_stage != MESA_SHADER_FRAGMENT))) {
+ (consumer_stage != MESA_SHADER_NONE && consumer_stage != MESA_SHADER_FRAGMENT))) {
/* Since this varying is not being consumed by the fragment shader, its
* interpolation type varying cannot possibly affect rendering.
* Also, this variable is non-flat and is (or contains) an integer
? consumer_stage : producer_stage;
const glsl_type *type = get_varying_type(var, stage);
+ if (producer_var && consumer_var &&
+ consumer_var->data.must_be_shader_input) {
+ producer_var->data.must_be_shader_input = 1;
+ }
+
this->matches[this->num_matches].packing_class
= this->compute_packing_class(var);
this->matches[this->num_matches].packing_order
= this->compute_packing_order(var);
- if (this->disable_varying_packing && !is_varying_packing_safe(type, var)) {
+ if ((this->disable_varying_packing && !is_varying_packing_safe(type, var)) ||
+ var->data.must_be_shader_input) {
unsigned slots = type->count_attribute_slots(false);
this->matches[this->num_matches].num_components = slots * 4;
} else {
this->matches[this->num_matches].num_components
= type->component_slots();
}
+
this->matches[this->num_matches].producer_var = producer_var;
this->matches[this->num_matches].consumer_var = consumer_var;
this->num_matches++;
* we can pack varyings together that are only used for transform
* feedback.
*/
- if ((this->disable_varying_packing &&
+ if (var->data.must_be_shader_input ||
+ (this->disable_varying_packing &&
!(previous_var_xfb_only && var->data.is_xfb_only)) ||
(i > 0 && this->matches[i - 1].packing_class
!= this->matches[i].packing_class )) {
void
varying_matches::store_locations() const
{
+ /* Check is location needs to be packed with lower_packed_varyings() or if
+ * we can just use ARB_enhanced_layouts packing.
+ */
+ bool pack_loc[MAX_VARYINGS_INCL_PATCH] = { 0 };
+ const glsl_type *loc_type[MAX_VARYINGS_INCL_PATCH][4] = { {NULL, NULL} };
+
for (unsigned i = 0; i < this->num_matches; i++) {
ir_variable *producer_var = this->matches[i].producer_var;
ir_variable *consumer_var = this->matches[i].consumer_var;
consumer_var->data.location = VARYING_SLOT_VAR0 + slot;
consumer_var->data.location_frac = offset;
}
+
+ /* Find locations suitable for native packing via
+ * ARB_enhanced_layouts.
+ */
+ if (producer_var && consumer_var) {
+ if (enhanced_layouts_enabled) {
+ const glsl_type *type =
+ get_varying_type(producer_var, producer_stage);
+ if (type->is_array() || type->is_matrix() || type->is_record() ||
+ type->is_double()) {
+ unsigned comp_slots = type->component_slots() + offset;
+ unsigned slots = comp_slots / 4;
+ if (comp_slots % 4)
+ slots += 1;
+
+ for (unsigned j = 0; j < slots; j++) {
+ pack_loc[slot + j] = true;
+ }
+ } else if (offset + type->vector_elements > 4) {
+ pack_loc[slot] = true;
+ pack_loc[slot + 1] = true;
+ } else {
+ loc_type[slot][offset] = type;
+ }
+ }
+ }
+ }
+
+ /* Attempt to use ARB_enhanced_layouts for more efficient packing if
+ * suitable.
+ */
+ if (enhanced_layouts_enabled) {
+ for (unsigned i = 0; i < this->num_matches; i++) {
+ ir_variable *producer_var = this->matches[i].producer_var;
+ ir_variable *consumer_var = this->matches[i].consumer_var;
+ unsigned generic_location = this->matches[i].generic_location;
+ unsigned slot = generic_location / 4;
+
+ if (pack_loc[slot] || !producer_var || !consumer_var)
+ continue;
+
+ const glsl_type *type =
+ get_varying_type(producer_var, producer_stage);
+ bool type_match = true;
+ for (unsigned j = 0; j < 4; j++) {
+ if (loc_type[slot][j]) {
+ if (type->base_type != loc_type[slot][j]->base_type)
+ type_match = false;
+ }
+ }
+
+ if (type_match) {
+ producer_var->data.explicit_location = 1;
+ consumer_var->data.explicit_location = 1;
+ producer_var->data.explicit_component = 1;
+ consumer_var->data.explicit_component = 1;
+ }
+ }
}
}
* Therefore, the packing class depends only on the interpolation type.
*/
unsigned packing_class = var->data.centroid | (var->data.sample << 1) |
- (var->data.patch << 2);
- packing_class *= 4;
+ (var->data.patch << 2) |
+ (var->data.must_be_shader_input << 3);
+ packing_class *= 8;
packing_class += var->is_interpolation_flat()
? unsigned(INTERP_MODE_FLAT) : var->data.interpolation;
return packing_class;
{
const glsl_type *element_type = var->type;
- while (element_type->base_type == GLSL_TYPE_ARRAY) {
+ while (element_type->is_array()) {
element_type = element_type->fields.array;
}
disable_varying_packing = true;
varying_matches matches(disable_varying_packing, xfb_enabled,
- producer ? producer->Stage : (gl_shader_stage)-1,
- consumer ? consumer->Stage : (gl_shader_stage)-1);
+ ctx->Extensions.ARB_enhanced_layouts,
+ producer ? producer->Stage : MESA_SHADER_NONE,
+ consumer ? consumer->Stage : MESA_SHADER_NONE);
hash_table *tfeedback_candidates =
_mesa_hash_table_create(NULL, _mesa_key_hash_string,
_mesa_key_string_equal);