[Mesa-dev] [RFC PATCH 47/56] glsl: support separate vertex count for producer when linking
Chris Forbes
chrisf at ijw.co.nz
Sat Sep 20 18:41:27 PDT 2014
Before tessellation, the only special case was linking VS -> GS, where
the VS has one output vertex and the GS has N input vertices.
Now we also get to deal with the TCS -> TES linking, where both
sides are arrays of vertices.
---
src/glsl/ir_optimization.h | 2 +-
src/glsl/link_varyings.cpp | 19 ++++++++++++++++---
src/glsl/lower_packed_varyings.cpp | 32 ++++++++++++++++----------------
3 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 389aed1..be9d4ad 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -120,7 +120,7 @@ bool lower_packing_builtins(exec_list *instructions, int op_mask);
void lower_ubo_reference(struct gl_shader *shader, exec_list *instructions);
void lower_packed_varyings(void *mem_ctx,
unsigned locations_used, ir_variable_mode mode,
- unsigned gs_input_vertices, gl_shader *shader);
+ unsigned num_vertices, gl_shader *shader);
bool lower_vector_insert(exec_list *instructions, bool lower_nonconstant_index);
void lower_named_interface_blocks(void *mem_ctx, gl_shader *shader);
bool optimize_redundant_jumps(exec_list *instructions);
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 4d45797..05d90a6 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1345,8 +1345,21 @@ assign_varying_locations(struct gl_context *ctx,
};
unsigned consumer_vertices = 0;
- if (consumer && consumer->Stage == MESA_SHADER_GEOMETRY)
- consumer_vertices = prog->Geom.VerticesIn;
+ unsigned producer_vertices = 0;
+
+ if (consumer) {
+ if (consumer->Stage == MESA_SHADER_GEOMETRY)
+ consumer_vertices = prog->Geom.VerticesIn;
+ if (consumer->Stage == MESA_SHADER_TESS_CTRL)
+ consumer_vertices = ctx->Const.MaxPatchVertices;
+ if (consumer->Stage == MESA_SHADER_TESS_EVAL)
+ consumer_vertices = ctx->Const.MaxPatchVertices;
+ }
+
+ if (producer) {
+ if (producer->Stage == MESA_SHADER_TESS_CTRL)
+ producer_vertices = prog->TessCtrl.VerticesOut;
+ }
/* Operate in a total of four passes.
*
@@ -1483,7 +1496,7 @@ assign_varying_locations(struct gl_context *ctx,
} else {
if (producer) {
lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_out,
- 0, producer);
+ producer_vertices, producer);
}
if (consumer) {
lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_in,
diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp
index 0c8696d..41ce8f4 100644
--- a/src/glsl/lower_packed_varyings.cpp
+++ b/src/glsl/lower_packed_varyings.cpp
@@ -162,7 +162,7 @@ class lower_packed_varyings_visitor
public:
lower_packed_varyings_visitor(void *mem_ctx, unsigned locations_used,
ir_variable_mode mode,
- unsigned gs_input_vertices,
+ unsigned num_vertices,
exec_list *out_instructions);
void run(exec_list *instructions);
@@ -210,10 +210,10 @@ private:
const ir_variable_mode mode;
/**
- * If we are currently lowering geometry shader inputs, the number of input
- * vertices the geometry shader accepts. Otherwise zero.
+ * If we are currently lowering an interface consisting of multiple vertices,
+ * the number of vertices accepted. Otherwise zero.
*/
- const unsigned gs_input_vertices;
+ const unsigned num_vertices;
/**
* Exec list into which the visitor should insert the packing instructions.
@@ -227,14 +227,14 @@ 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)
+ unsigned num_vertices, exec_list *out_instructions)
: mem_ctx(mem_ctx),
locations_used(locations_used),
packed_varyings((ir_variable **)
rzalloc_array_size(mem_ctx, sizeof(*packed_varyings),
locations_used)),
mode(mode),
- gs_input_vertices(gs_input_vertices),
+ num_vertices(num_vertices),
out_instructions(out_instructions)
{
}
@@ -269,7 +269,7 @@ lower_packed_varyings_visitor::run(exec_list *instructions)
/* Recursively pack or unpack it. */
this->lower_rvalue(deref, var->data.location * 4 + var->data.location_frac, var,
- var->name, this->gs_input_vertices != 0, 0);
+ var->name, this->num_vertices != 0, 0);
}
}
@@ -540,18 +540,18 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
packed_type = glsl_type::ivec4_type;
else
packed_type = glsl_type::vec4_type;
- if (this->gs_input_vertices != 0) {
+ if (this->num_vertices != 0) {
packed_type =
glsl_type::get_array_instance(packed_type,
- this->gs_input_vertices);
+ this->num_vertices);
}
ir_variable *packed_var = new(this->mem_ctx)
ir_variable(packed_type, packed_name, this->mode);
- if (this->gs_input_vertices != 0) {
+ if (this->num_vertices != 0) {
/* Prevent update_array_sizes() from messing with the size of the
* array.
*/
- packed_var->data.max_array_access = this->gs_input_vertices - 1;
+ packed_var->data.max_array_access = this->num_vertices - 1;
}
packed_var->data.centroid = unpacked_var->data.centroid;
packed_var->data.sample = unpacked_var->data.sample;
@@ -564,7 +564,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
/* For geometry shader inputs, only update the packed variable name the
* first time we visit each component.
*/
- if (this->gs_input_vertices == 0 || vertex_index == 0) {
+ if (this->num_vertices == 0 || vertex_index == 0) {
ralloc_asprintf_append((char **) &this->packed_varyings[slot]->name,
",%s", name);
}
@@ -572,7 +572,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
ir_dereference *deref = new(this->mem_ctx)
ir_dereference_variable(this->packed_varyings[slot]);
- if (this->gs_input_vertices != 0) {
+ if (this->num_vertices != 0) {
/* When lowering GS inputs, the packed variable is an array, so we need
* to dereference it using vertex_index.
*/
@@ -592,7 +592,7 @@ lower_packed_varyings_visitor::needs_lowering(ir_variable *var)
return false;
const glsl_type *type = var->type;
- if (this->gs_input_vertices != 0) {
+ if (this->num_vertices != 0) {
assert(type->is_array());
type = type->element_type();
}
@@ -649,7 +649,7 @@ 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,
+ ir_variable_mode mode, unsigned num_vertices,
gl_shader *shader)
{
exec_list *instructions = shader->ir;
@@ -659,7 +659,7 @@ lower_packed_varyings(void *mem_ctx, unsigned locations_used,
= main_func->matching_signature(NULL, &void_parameters, false);
exec_list new_instructions;
lower_packed_varyings_visitor visitor(mem_ctx, locations_used, mode,
- gs_input_vertices, &new_instructions);
+ num_vertices, &new_instructions);
visitor.run(instructions);
if (mode == ir_var_shader_out) {
if (shader->Stage == MESA_SHADER_GEOMETRY) {
--
2.1.0
More information about the mesa-dev
mailing list