summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2011-03-11 09:25:22 -0700
committerBrian Paul <[email protected]>2011-03-11 09:25:22 -0700
commit8cc84b3e454cf03c71282322e988f03bc4a1baa3 (patch)
tree24776b266f98b8ef7aa8fb3c3fcd8153ed170a69
parentdecc6e2a32ef49e673c081f30e19b8970155d887 (diff)
mesa: use check_resources() to check program against limits
Without these checks we could create shaders with more samplers, constants than the driver could handle. Fail linking rather than dying later.
-rw-r--r--src/mesa/program/ir_to_mesa.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 33c262f8ca4..9c77f387593 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2406,6 +2406,11 @@ print_program(struct prog_instruction *mesa_instructions,
}
}
+
+/**
+ * Count resources used by the given gpu program (number of texture
+ * samplers, etc).
+ */
static void
count_resources(struct gl_program *prog)
{
@@ -2429,6 +2434,57 @@ count_resources(struct gl_program *prog)
_mesa_update_shader_textures_used(prog);
}
+
+/**
+ * Check if the given vertex/fragment/shader program is within the
+ * resource limits of the context (number of texture units, etc).
+ * If any of those checks fail, record a linker error.
+ *
+ * XXX more checks are needed...
+ */
+static void
+check_resources(const struct gl_context *ctx,
+ struct gl_shader_program *shader_program,
+ struct gl_program *prog)
+{
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ if (_mesa_bitcount(prog->SamplersUsed) >
+ ctx->Const.MaxVertexTextureImageUnits) {
+ fail_link(shader_program, "Too many vertex shader texture samplers");
+ }
+ if (prog->Parameters->NumParameters >
+ ctx->Const.VertexProgram.MaxParameters) {
+ fail_link(shader_program, "Too many vertex shader constants");
+ }
+ break;
+ case MESA_GEOMETRY_PROGRAM:
+ if (_mesa_bitcount(prog->SamplersUsed) >
+ ctx->Const.GeometryProgram.MaxGeometryTextureImageUnits) {
+ fail_link(shader_program, "Too many geometry shader texture samplers");
+ }
+ if (prog->Parameters->NumParameters >
+ ctx->Const.GeometryProgram.MaxParameters) {
+ fail_link(shader_program, "Too many geometry shader constants");
+ }
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ if (_mesa_bitcount(prog->SamplersUsed) >
+ ctx->Const.MaxTextureImageUnits) {
+ fail_link(shader_program, "Too many fragment shader texture samplers");
+ }
+ if (prog->Parameters->NumParameters >
+ ctx->Const.FragmentProgram.MaxParameters) {
+ fail_link(shader_program, "Too many fragment shader constants");
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "unexpected program type in check_resources()");
+ }
+}
+
+
+
struct uniform_sort {
struct gl_uniform *u;
int pos;
@@ -3026,6 +3082,8 @@ get_mesa_program(struct gl_context *ctx,
do_set_program_inouts(shader->ir, prog);
count_resources(prog);
+ check_resources(ctx, shader_program, prog);
+
_mesa_reference_program(ctx, &shader->Program, prog);
if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {