From: Gregory Hainaut Date: Sat, 29 Jun 2013 02:26:27 +0000 (-0700) Subject: mesa/sso: Add _mesa_sampler_uniforms_pipeline_are_valid X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=95426b28ac716dafff4c797f66949244896a94fd;p=mesa.git mesa/sso: Add _mesa_sampler_uniforms_pipeline_are_valid This is much like _mesa_sampler_uniforms_are_valid, but it operates across an entire pipeline object. This function differs from _mesa_sampler_uniforms_are_valid in that it directly creates the gl_pipeline_object::InfoLog instead of writing to some temporary buffer. This was originally included in another patch, but it was split out by Ian Romanick. v2 (idr): Fix the loop bounds. shProg isn't an array, so ARRAY_SIZE(shProg) was 1, so only the vertex program was validated. Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index 1f8d48dd92c..5f1af087321 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -1089,3 +1089,80 @@ _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, return true; } + +extern "C" bool +_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline) +{ + /* Section 2.11.11 (Shader Execution), subheading "Validation," of the + * OpenGL 4.1 spec says: + * + * "[INVALID_OPERATION] is generated by any command that transfers + * vertices to the GL if: + * + * ... + * + * - Any two active samplers in the current program object are of + * different types, but refer to the same texture image unit. + * + * - The number of active samplers in the program exceeds the + * maximum number of texture image units allowed." + */ + unsigned active_samplers = 0; + const struct gl_shader_program **shProg = + (const struct gl_shader_program **) pipeline->CurrentProgram; + + const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; + memset(unit_types, 0, sizeof(unit_types)); + + for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { + if (!shProg[idx]) + continue; + + for (unsigned i = 0; i < shProg[idx]->NumUserUniformStorage; i++) { + const struct gl_uniform_storage *const storage = + &shProg[idx]->UniformStorage[i]; + const glsl_type *const t = (storage->type->is_array()) + ? storage->type->fields.array : storage->type; + + if (!t->is_sampler()) + continue; + + active_samplers++; + + const unsigned count = MAX2(1, storage->type->array_size()); + for (unsigned j = 0; j < count; j++) { + const unsigned unit = storage->storage[j].i; + + /* The types of the samplers associated with a particular texture + * unit must be an exact match. Page 74 (page 89 of the PDF) of + * the OpenGL 3.3 core spec says: + * + * "It is not allowed to have variables of different sampler + * types pointing to the same texture image unit within a + * program object." + */ + if (unit_types[unit] == NULL) { + unit_types[unit] = t; + } else if (unit_types[unit] != t) { + pipeline->InfoLog = + ralloc_asprintf(pipeline, + "Texture unit %d is accessed both as %s " + "and %s", + unit, unit_types[unit]->name, t->name); + return false; + } + } + } + } + + if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) { + pipeline->InfoLog = + ralloc_asprintf(pipeline, + "the number of active samplers %d exceed the " + "maximum %d", + active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS); + return false; + } + + return true; +} diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h index d7afdc10688..c8b555cbea4 100644 --- a/src/mesa/main/uniforms.h +++ b/src/mesa/main/uniforms.h @@ -300,6 +300,8 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg, extern bool _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, char *errMsg, size_t errMsgLength); +extern bool +_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *); extern const struct gl_program_parameter * get_uniform_parameter(struct gl_shader_program *shProg, GLint index);