Mesa (master): mesa/sso: Add _mesa_sampler_uniforms_pipeline_are_valid

Ian Romanick idr at kemper.freedesktop.org
Tue Mar 25 17:42:26 UTC 2014


Module: Mesa
Branch: master
Commit: 95426b28ac716dafff4c797f66949244896a94fd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=95426b28ac716dafff4c797f66949244896a94fd

Author: Gregory Hainaut <gregory.hainaut at gmail.com>
Date:   Fri Jun 28 19:26:27 2013 -0700

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 at intel.com>
Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/mesa/main/uniform_query.cpp |   77 +++++++++++++++++++++++++++++++++++++++
 src/mesa/main/uniforms.h        |    2 +
 2 files changed, 79 insertions(+)

diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 1f8d48d..5f1af08 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 d7afdc1..c8b555c 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);




More information about the mesa-commit mailing list