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.
This commit is contained in:
Brian Paul
2011-03-11 09:25:22 -07:00
parent decc6e2a32
commit 8cc84b3e45

View File

@@ -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) {