mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 06:50:11 +01:00
mesa: faster validation of sampler unit mapping for SSO
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. For my use case: high FS frequency switches with few samplers. Perf event (relative to nouveau_dri.so) goes from 5.01% to 1.68% for the _mesa_sampler_uniforms_pipeline_are_valid function. Signed-off-by: Gregory Hainaut <gregory.hainaut@gmail.com> Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
This commit is contained in:
parent
cb728df967
commit
6a524c76f5
1 changed files with 31 additions and 38 deletions
|
|
@ -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
|
* - The number of active samplers in the program exceeds the
|
||||||
* maximum number of texture image units allowed."
|
* maximum number of texture image units allowed."
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
GLbitfield mask;
|
||||||
|
GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
|
||||||
|
struct gl_shader *shader;
|
||||||
unsigned active_samplers = 0;
|
unsigned active_samplers = 0;
|
||||||
const struct gl_shader_program **shProg =
|
const struct gl_shader_program **shProg =
|
||||||
(const struct gl_shader_program **) pipeline->CurrentProgram;
|
(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++) {
|
for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
|
||||||
if (!shProg[idx])
|
if (!shProg[idx])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (unsigned i = 0; i < shProg[idx]->NumUniformStorage; i++) {
|
shader = shProg[idx]->_LinkedShaders[idx];
|
||||||
const struct gl_uniform_storage *const storage =
|
if (!shader || !shader->Program)
|
||||||
&shProg[idx]->UniformStorage[i];
|
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;
|
continue;
|
||||||
|
|
||||||
active_samplers++;
|
if (TexturesUsed[unit] & ~(1 << tgt)) {
|
||||||
|
pipeline->InfoLog =
|
||||||
const unsigned count = MAX2(1, storage->array_elements);
|
ralloc_asprintf(pipeline,
|
||||||
for (unsigned j = 0; j < count; j++) {
|
"Program %d: "
|
||||||
const unsigned unit = storage->storage[j].i;
|
"Texture unit %d is accessed with 2 different types",
|
||||||
|
shProg[idx]->Name, unit);
|
||||||
/* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
|
return false;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TexturesUsed[unit] |= (1 << tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
active_samplers += shader->num_samplers;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
|
if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue