diff options
author | Brian Paul <brianp@vmware.com> | 2011-03-11 09:25:22 -0700 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2011-03-11 09:25:22 -0700 |
commit | 8cc84b3e454cf03c71282322e988f03bc4a1baa3 (patch) | |
tree | 24776b266f98b8ef7aa8fb3c3fcd8153ed170a69 /src | |
parent | decc6e2a32ef49e673c081f30e19b8970155d887 (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.
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 58 |
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 33c262f8ca..9c77f38759 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) { |