nir: Use a single list for all global variables.
Right now, NIR has a separate list for each variable mode. Well, mostly. We actually lump UBOs and SSBOs in with uniforms and image uniforms also get a bit weird. The point is, though, that we have many lists. This is painful to a number of reasons:
- It makes adding a new variable mode a lot of pain.
- It means that passes which work on multiple modes such as dead_variables and validation have piles of checks to do. Passes which change the mode of a variable (io_to_temporaries) have to move them between lists.
- We have a bunch of code to ensure variables get put on the right list.
What I'd like to propose (if I can get people on-board) is to have a single "vars" or "globals" list in nir_shader
which contains all shader-level variables. Passes will then walk the one variable list and skip any which have modes they don't want to handle rather than having to pick the right list. To make this less painful, I propose a couple of helper iterators as a straw-man:
#define nir_foreach_function_variable(var, impl) \
foreach_list_typed(nir_variable, var, node, &(impl)->locals)
nir_variable *
nir_shader_next_variable_with_modes(const nir_shader *shader,
nir_variable *var,
nir_variable_mode modes);
#define nir_foreach_shader_variable(var, shader, modes) \
for (nir_variable *var = \
nir_shader_next_variable_with_modes(shader, NULL, modes); \
var != NULL; \
var = nir_shader_next_variable_with_modes(shader, var, modes))
#define nir_foreach_shader_input_variable(var, shader) \
nir_foreach_shader_variable(var, shader, nir_var_shader_in)
I started prototyping this here: https://gitlab.freedesktop.org/jekstrand/mesa/-/commits/wip/nir-global-var-list However, I'd really like to not sink a pile of time into it if people think it's a bad idea and/or I can't get people to actually test out my patches. So, thoughts?
cc @cwabbott0 @tarceri @alyssa @karolherbst @kwg @hakzsam @robclark