This actually tries to pack any input with an explicit location we just let the optimisiation passes clean up the extra assignments if there was no actual packing done. --- src/glsl/ir_optimization.h | 1 + src/glsl/link_varyings.cpp | 33 ++++++++++++++++++++++++++------- src/glsl/lower_packed_varyings.cpp | 28 +++++++++++++++------------- 3 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index eab76ff..a313e30 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -129,6 +129,7 @@ void lower_ubo_reference(struct gl_shader *shader); void lower_packed_varyings(void *mem_ctx, unsigned locations_used, ir_variable_mode mode, unsigned gs_input_vertices, gl_shader *shader, + unsigned base_location, bool disable_varying_packing, bool has_enhanced_layouts); bool lower_vector_insert(exec_list *instructions, bool lower_nonconstant_index); diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp index 7066481..7f77f7c 100644 --- a/src/glsl/link_varyings.cpp +++ b/src/glsl/link_varyings.cpp @@ -1582,7 +1582,8 @@ canonicalize_shader_io(exec_list *ir, enum ir_variable_mode io_mode) * In theory a 32 bits value will be enough but a 64 bits value is future proof. */ uint64_t -reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode) +reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode, + int base_location) { assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out); assert(MAX_VARYING <= 64); /* avoid an overflow of the returned value */ @@ -1598,10 +1599,10 @@ reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode) if (var == NULL || var->data.mode != io_mode || !var->data.explicit_location || - var->data.location < VARYING_SLOT_VAR0) + var->data.location < base_location) continue; - var_slot = var->data.location - VARYING_SLOT_VAR0; + var_slot = var->data.location - base_location; unsigned num_elements = get_varying_type(var, stage->Stage) ->count_attribute_slots(stage->Stage == MESA_SHADER_VERTEX); @@ -1792,8 +1793,8 @@ assign_varying_locations(struct gl_context *ctx, } const uint64_t reserved_slots = - reserved_varying_slot(producer, ir_var_shader_out) | - reserved_varying_slot(consumer, ir_var_shader_in); + reserved_varying_slot(producer, ir_var_shader_out, VARYING_SLOT_VAR0) | + reserved_varying_slot(consumer, ir_var_shader_in, VARYING_SLOT_VAR0); /* Add varyings with explicit locations to varyings with implicit locations * to get the total number of slots used. @@ -1875,14 +1876,32 @@ assign_varying_locations(struct gl_context *ctx, } if (producer) { + if (producer->Stage == MESA_SHADER_VERTEX) { + /* Since we only pack vertex inputs with an explicit location we only + * need to count those inputs. + */ + const uint64_t reserved_slots = + reserved_varying_slot(producer, ir_var_shader_in, + VERT_ATTRIB_GENERIC0); + + /* Pack vertex inputs with the component layout qualifier */ + unsigned vertex_attributes = _mesa_bitcount_64(reserved_slots); + if (vertex_attributes > 0) + lower_packed_varyings(mem_ctx, vertex_attributes, + ir_var_shader_in, 0, producer, + VERT_ATTRIB_GENERIC0, true, + ctx->Extensions.ARB_enhanced_layouts); + } + lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_out, - 0, producer, disable_varying_packing, + 0, producer, VARYING_SLOT_VAR0, + disable_varying_packing, ctx->Extensions.ARB_enhanced_layouts); } if (consumer) { lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_in, - consumer_vertices, consumer, + consumer_vertices, consumer, VARYING_SLOT_VAR0, disable_varying_packing, ctx->Extensions.ARB_enhanced_layouts); } diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp index 1696373..3ba0af8 100644 --- a/src/glsl/lower_packed_varyings.cpp +++ b/src/glsl/lower_packed_varyings.cpp @@ -169,6 +169,7 @@ public: unsigned gs_input_vertices, exec_list *out_instructions, exec_list *out_variables, + unsigned base_location, bool disable_varying_packing, bool has_enhanced_layouts); @@ -197,11 +198,13 @@ private: */ void * const mem_ctx; + const unsigned base_location; + /** * Number of generic varying slots which are used by this shader. This is * used to allocate temporary intermediate data structures. If any varying * used by this shader has a location greater than or equal to - * VARYING_SLOT_VAR0 + locations_used, an assertion will fire. + * base_location + locations_used, an assertion will fire. */ const unsigned locations_used; @@ -245,9 +248,10 @@ private: lower_packed_varyings_visitor::lower_packed_varyings_visitor( void *mem_ctx, unsigned locations_used, ir_variable_mode mode, unsigned gs_input_vertices, exec_list *out_instructions, - exec_list *out_variables, bool disable_varying_packing, - bool has_enhanced_layouts) + exec_list *out_variables, unsigned base_location, + bool disable_varying_packing, bool has_enhanced_layouts) : mem_ctx(mem_ctx), + base_location(base_location), locations_used(locations_used), packed_varyings((ir_variable **) rzalloc_array_size(mem_ctx, sizeof(*packed_varyings), @@ -270,7 +274,7 @@ lower_packed_varyings_visitor::run(struct gl_shader *shader) continue; if (var->data.mode != this->mode || - var->data.location < VARYING_SLOT_VAR0 || + var->data.location < (int) this->base_location || !this->needs_lowering(var)) continue; @@ -594,7 +598,6 @@ lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue, } else { char *subscripted_name = ralloc_asprintf(this->mem_ctx, "%s[%d]", name, i); - fine_location = this->lower_rvalue(dereference_array, fine_location, unpacked_var, subscripted_name, @@ -621,7 +624,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref( unsigned location, ir_variable *unpacked_var, const char *name, unsigned vertex_index) { - unsigned slot = location - VARYING_SLOT_VAR0; + unsigned slot = location - this->base_location; assert(slot < locations_used); if (this->packed_varyings[slot] == NULL) { char *packed_name = ralloc_asprintf(this->mem_ctx, "packed:%s", name); @@ -748,8 +751,8 @@ lower_packed_varyings_gs_splicer::visit_leave(ir_emit_vertex *ev) void lower_packed_varyings(void *mem_ctx, unsigned locations_used, ir_variable_mode mode, unsigned gs_input_vertices, - gl_shader *shader, bool disable_varying_packing, - bool has_enhanced_layouts) + gl_shader *shader, unsigned base_location, + bool disable_varying_packing, bool has_enhanced_layouts) { ir_function *main_func = shader->symbols->get_function("main"); exec_list void_parameters; @@ -760,21 +763,20 @@ lower_packed_varyings(void *mem_ctx, unsigned locations_used, shader->Stage == MESA_SHADER_TESS_EVAL)) { exec_list *instructions = shader->ir; exec_list new_instructions, new_variables; - lower_packed_varyings_visitor visitor(mem_ctx, locations_used, mode, gs_input_vertices, &new_instructions, &new_variables, + base_location, disable_varying_packing, has_enhanced_layouts); visitor.run(shader); if (mode == ir_var_shader_out) { if (shader->Stage == MESA_SHADER_GEOMETRY) { - /* For geometry shaders, outputs need to be lowered before each - * call to EmitVertex() + /* For geometry shaders, outputs need to be lowered before each call + * to EmitVertex() */ - lower_packed_varyings_gs_splicer splicer(mem_ctx, - &new_instructions); + lower_packed_varyings_gs_splicer splicer(mem_ctx, &new_instructions); /* Add all the variables in first. */ main_func_sig->body.head->insert_before(&new_variables); -- 2.4.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev