glsl: move gl_nir_link_opts() call out of the st code

Calling this directly in the linker code allows us to place it between
the varying linker and uniform linker calls which allows for better
optimisation/removal of uniforms.

Also in a later patch it allows us to insert a new nir based
lower_const_arrays_to_uniforms() call after the gl_nir_link_opts()
call. This is important because it allows the linking opts to
move constant arrays to later stages if possible before
lower_const_arrays_to_uniforms() turns them into uniforms.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6541

Acked-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16770>
This commit is contained in:
Timothy Arceri
2022-05-31 09:55:02 +10:00
committed by Marge Bot
parent a14e2733ce
commit 1805ee8d7b
3 changed files with 47 additions and 30 deletions

View File

@@ -117,7 +117,7 @@ gl_nir_opts(nir_shader *nir)
} while (progress);
}
void
static void
gl_nir_link_opts(nir_shader *producer, nir_shader *consumer)
{
if (producer->options->lower_to_scalar) {
@@ -756,6 +756,24 @@ gl_nir_link_spirv(const struct gl_constants *consts,
struct gl_shader_program *prog,
const struct gl_nir_linker_options *options)
{
struct gl_linked_shader *linked_shader[MESA_SHADER_STAGES];
unsigned num_shaders = 0;
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
if (prog->_LinkedShaders[i])
linked_shader[num_shaders++] = prog->_LinkedShaders[i];
}
/* Linking the stages in the opposite order (from fragment to vertex)
* ensures that inter-shader outputs written to in an earlier stage
* are eliminated if they are (transitively) not used in a later
* stage.
*/
for (int i = num_shaders - 2; i >= 0; i--) {
gl_nir_link_opts(linked_shader[i]->Program->nir,
linked_shader[i + 1]->Program->nir);
}
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
struct gl_linked_shader *shader = prog->_LinkedShaders[i];
if (shader) {
@@ -919,6 +937,34 @@ gl_nir_link_glsl(const struct gl_constants *consts,
return false;
}
if (prog->data->LinkStatus == LINKING_FAILURE)
return false;
struct gl_linked_shader *linked_shader[MESA_SHADER_STAGES];
unsigned num_shaders = 0;
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
if (prog->_LinkedShaders[i])
linked_shader[num_shaders++] = prog->_LinkedShaders[i];
}
/* Linking the stages in the opposite order (from fragment to vertex)
* ensures that inter-shader outputs written to in an earlier stage
* are eliminated if they are (transitively) not used in a later
* stage.
*/
for (int i = num_shaders - 2; i >= 0; i--) {
gl_nir_link_opts(linked_shader[i]->Program->nir,
linked_shader[i + 1]->Program->nir);
}
/* Tidy up any left overs from the linking process for single shaders.
* For example varying arrays that get packed may have dead elements that
* can be now be eliminated now that array access has been lowered.
*/
if (num_shaders == 1)
gl_nir_opts(linked_shader[0]->Program->nir);
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
struct gl_linked_shader *shader = prog->_LinkedShaders[i];
if (shader) {