[Mesa-dev] [PATCH] mesa: faster validation of sampler unit mapping for SSO
Gregory Hainaut
gregory.hainaut at gmail.com
Sat Jun 25 08:32:56 UTC 2016
Hello Timothy,
On my use case: high FS frequency switches. Few sampler.
Perf event (relative to nouveau_dri.so) goes from 5.01% to 1.68% for
the _mesa_sampler_uniforms_pipeline_are_valid function.
Unfortunately it didn't translate into measurable speed change. I have
too much FPS variation (cache? temperature, GPU turbo?).
Honestly I was reluctant to send the patch, but the code isn't more
complex. I let's you judge.
Gregory
On 6/25/16, Timothy Arceri <timothy.arceri at collabora.com> wrote:
> 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