X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Flink_varyings.cpp;h=910e2eda82b877c15a15b50c89f218cb3073805b;hb=ada3c3aa3da5d04bd597014dc1b5d4b028313513;hp=8cd364441d3fc4960bc5cc29201038e441005118;hpb=4d65f68a9bd225133897bc56c89a0fa9baf6d672;p=mesa.git diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp index 8cd364441d3..910e2eda82b 100644 --- a/src/compiler/glsl/link_varyings.cpp +++ b/src/compiler/glsl/link_varyings.cpp @@ -745,10 +745,12 @@ tfeedback_decl::assign_location(struct gl_context *ctx, 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; @@ -1076,6 +1078,9 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, 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. */ @@ -1084,7 +1089,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, 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); @@ -1212,6 +1217,7 @@ class varying_matches { 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(); @@ -1245,6 +1251,8 @@ private: */ const bool xfb_enabled; + const bool enhanced_layouts_enabled; + /** * Enum representing the order in which varyings are packed within a * packing class. @@ -1321,10 +1329,12 @@ private: 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) { @@ -1402,7 +1412,7 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var) 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 @@ -1456,17 +1466,24 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var) ? 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++; @@ -1539,7 +1556,8 @@ varying_matches::assign_locations(struct gl_shader_program *prog, * 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 )) { @@ -1609,6 +1627,12 @@ varying_matches::assign_locations(struct gl_shader_program *prog, 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; @@ -1626,6 +1650,64 @@ varying_matches::store_locations() const 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; + } + } } } @@ -1655,8 +1737,9 @@ varying_matches::compute_packing_class(const ir_variable *var) * 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; @@ -1673,7 +1756,7 @@ varying_matches::compute_packing_order(const ir_variable *var) { 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; } @@ -2086,8 +2169,9 @@ assign_varying_locations(struct gl_context *ctx, 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);