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:
@@ -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) {
|
||||
|
Reference in New Issue
Block a user