summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Hainaut <gregory.hainaut@gmail.com>2013-06-28 19:26:27 -0700
committerIan Romanick <ian.d.romanick@intel.com>2014-03-25 10:25:26 -0700
commit95426b28ac716dafff4c797f66949244896a94fd (patch)
tree420c02f0321cb9232b7cc10624869bb37a0744b0
parentaa46ad26b13a753858627088d1e8f7cc81beb64e (diff)
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 <ian.d.romanick@intel.com> Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--src/mesa/main/uniform_query.cpp77
-rw-r--r--src/mesa/main/uniforms.h2
2 files changed, 79 insertions, 0 deletions
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 1f8d48dd92..5f1af08732 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 d7afdc1068..c8b555cbea 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);