[Mesa-dev] [PATCH] mesa: faster validation of sampler unit mapping for SSO
Gregory Hainaut
gregory.hainaut at gmail.com
Fri Jun 24 08:07:02 UTC 2016
Code was inspired from _mesa_update_shader_textures_used
However unlike _mesa_update_shader_textures_used that only check for a single
stage, it will check all stages.
It avoids to loop on all uniforms, only active samplers are checked.
Signed-off-by: Gregory Hainaut <gregory.hainaut at gmail.com>
---
src/mesa/main/uniform_query.cpp | 69 ++++++++++++++++++-----------------------
1 file changed, 31 insertions(+), 38 deletions(-)
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 127f097..4fa4e6e 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -1068,58 +1068,51 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
* - The number of active samplers in the program exceeds the
* maximum number of texture image units allowed."
*/
+
+ GLbitfield mask;
+ GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+ struct gl_shader *shader;
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));
+
+ memset(TexturesUsed, 0, sizeof(TexturesUsed));
for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
if (!shProg[idx])
continue;
- for (unsigned i = 0; i < shProg[idx]->NumUniformStorage; i++) {
- const struct gl_uniform_storage *const storage =
- &shProg[idx]->UniformStorage[i];
+ shader = shProg[idx]->_LinkedShaders[idx];
+ if (!shader || !shader->Program)
+ continue;
- if (!storage->type->is_sampler())
+ mask = shader->Program->SamplersUsed;
+ while (mask) {
+ const int s = u_bit_scan(&mask);
+ GLuint unit = shader->SamplerUnits[s];
+ GLuint tgt = shader->SamplerTargets[s];
+
+ /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
+ * great job of eliminating unused uniforms currently so for now
+ * don't throw an error if two sampler types both point to 0.
+ */
+ if (unit == 0)
continue;
- active_samplers++;
-
- const unsigned count = MAX2(1, storage->array_elements);
- for (unsigned j = 0; j < count; j++) {
- const unsigned unit = storage->storage[j].i;
-
- /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
- * great job of eliminating unused uniforms currently so for now
- * don't throw an error if two sampler types both point to 0.
- */
- if (unit == 0)
- continue;
-
- /* 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] = storage->type;
- } else if (unit_types[unit] != storage->type) {
- pipeline->InfoLog =
- ralloc_asprintf(pipeline,
- "Texture unit %d is accessed both as %s "
- "and %s",
- unit, unit_types[unit]->name,
- storage->type->name);
- return false;
- }
+ if (TexturesUsed[unit] & ~(1 << tgt)) {
+ pipeline->InfoLog =
+ ralloc_asprintf(pipeline,
+ "Program %d: "
+ "Texture unit %d is accessed with 2 different types",
+ shProg[idx]->Name, unit);
+ return false;
}
+
+ TexturesUsed[unit] |= (1 << tgt);
}
+
+ active_samplers += shader->num_samplers;
}
if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
--
2.1.4
More information about the mesa-dev
mailing list