[Mesa-dev] [PATCH] mesa: faster validation of sampler unit mapping for SSO
Timothy Arceri
timothy.arceri at collabora.com
Sat Jun 25 03:54:56 UTC 2016
On Fri, 2016-06-24 at 10:07 +0200, Gregory Hainaut wrote:
> 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.
Hi Gregory,
Is there any measurable change as a result of this? Normally
performance changes should come with some results in the commit
message.
Tim
>
> 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) {
More information about the mesa-dev
mailing list