[Mesa-dev] [PATCH 1/3] glsl: Count shader inputs and outputs separately
Ian Romanick
idr at freedesktop.org
Fri Sep 27 11:55:51 PDT 2013
From: Ian Romanick <ian.d.romanick at intel.com>
Starting with OpenGL 3.2 input limits and output limits for stages may
not match. This means they need to be accounted separately.
No piglit regressions.
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Brian Paul <brianp at vmware.com>
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Reviewed-by: Paul Berry <stereotype441 at gmail.com>
---
src/glsl/link_varyings.cpp | 101 +++++++++++++++++++++++++++++++++++----------
src/glsl/link_varyings.h | 11 +++--
src/glsl/linker.cpp | 4 +-
3 files changed, 91 insertions(+), 25 deletions(-)
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 905621d..ab48c1e 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1220,39 +1220,98 @@ assign_varying_locations(struct gl_context *ctx,
}
bool
-check_against_varying_limit(struct gl_context *ctx,
- struct gl_shader_program *prog,
- gl_shader *consumer)
+check_against_output_limit(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ gl_shader *producer)
{
- unsigned varying_vectors = 0;
+ unsigned output_vectors = 0;
+
+ foreach_list(node, producer->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var && var->mode == ir_var_shader_out &&
+ is_varying_var(producer->Type, var)) {
+ output_vectors += var->type->count_attribute_slots();
+ }
+ }
+
+ unsigned max_output_components;
+ switch (producer->Type) {
+ case GL_VERTEX_SHADER:
+ max_output_components = ctx->Const.VertexProgram.MaxOutputComponents;
+ break;
+ case GL_GEOMETRY_SHADER:
+ max_output_components = ctx->Const.GeometryProgram.MaxOutputComponents;
+ break;
+ case GL_FRAGMENT_SHADER:
+ default:
+ assert(!"Should not get here.");
+ return false;
+ }
+
+ const unsigned output_components = output_vectors * 4;
+ if (output_components > max_output_components) {
+ if (ctx->API == API_OPENGLES2 || prog->IsES)
+ linker_error(prog, "shader uses too many output vectors "
+ "(%u > %u)\n",
+ output_vectors,
+ max_output_components / 4);
+ else
+ linker_error(prog, "shader uses too many output components "
+ "(%u > %u)\n",
+ output_components,
+ max_output_components);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool
+check_against_input_limit(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ gl_shader *consumer)
+{
+ unsigned input_vectors = 0;
foreach_list(node, consumer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if (var && var->mode == ir_var_shader_in &&
is_varying_var(consumer->Type, var)) {
- /* The packing rules used for vertex shader inputs are also
- * used for fragment shader inputs.
- */
- varying_vectors += var->type->count_attribute_slots();
+ input_vectors += var->type->count_attribute_slots();
}
}
- if (ctx->API == API_OPENGLES2 || prog->IsES) {
- if (varying_vectors > ctx->Const.MaxVarying) {
- linker_error(prog, "shader uses too many varying vectors "
+ unsigned max_input_components;
+ switch (consumer->Type) {
+ case GL_GEOMETRY_SHADER:
+ max_input_components = ctx->Const.GeometryProgram.MaxInputComponents;
+ break;
+ case GL_FRAGMENT_SHADER:
+ max_input_components = ctx->Const.FragmentProgram.MaxInputComponents;
+ break;
+ case GL_VERTEX_SHADER:
+ default:
+ assert(!"Should not get here.");
+ return false;
+ }
+
+ const unsigned input_components = input_vectors * 4;
+ if (input_components > max_input_components) {
+ if (ctx->API == API_OPENGLES2 || prog->IsES)
+ linker_error(prog, "shader uses too many input vectors "
"(%u > %u)\n",
- varying_vectors, ctx->Const.MaxVarying);
- return false;
- }
- } else {
- const unsigned float_components = varying_vectors * 4;
- if (float_components > ctx->Const.MaxVarying * 4) {
- linker_error(prog, "shader uses too many varying components "
+ input_vectors,
+ max_input_components / 4);
+ else
+ linker_error(prog, "shader uses too many input components "
"(%u > %u)\n",
- float_components, ctx->Const.MaxVarying * 4);
- return false;
- }
+ input_components,
+ max_input_components);
+
+ return false;
}
return true;
diff --git a/src/glsl/link_varyings.h b/src/glsl/link_varyings.h
index 6264ef0..5b37e26 100644
--- a/src/glsl/link_varyings.h
+++ b/src/glsl/link_varyings.h
@@ -237,8 +237,13 @@ assign_varying_locations(struct gl_context *ctx,
unsigned gs_input_vertices);
bool
-check_against_varying_limit(struct gl_context *ctx,
- struct gl_shader_program *prog,
- gl_shader *consumer);
+check_against_output_limit(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ gl_shader *producer);
+
+bool
+check_against_input_limit(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ gl_shader *consumer);
#endif /* GLSL_LINK_VARYINGS_H */
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index c54b704..61904dc 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -2203,7 +2203,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
;
/* This must be done after all dead varyings are eliminated. */
- if (!check_against_varying_limit(ctx, prog, sh_next))
+ if (!check_against_output_limit(ctx, prog, sh_i))
+ goto done;
+ if (!check_against_input_limit(ctx, prog, sh_next))
goto done;
next = i;
--
1.8.1.4
More information about the mesa-dev
mailing list