mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 20:00:10 +01:00
nir/linker: Add inputs/outputs to the program resource list
v2: added TODO comment hinting possible future refactoring of
nir_build_program_resource_list and build_program_resource_list,
to avoid code duplication (Alejandro, to explicitly reflect a
valid concern from Timothy during the review).
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
This commit is contained in:
parent
691cee751a
commit
ffdb44d3a0
1 changed files with 108 additions and 0 deletions
|
|
@ -33,6 +33,85 @@
|
||||||
* Also note that this is tailored for ARB_gl_spirv needs and particularities
|
* Also note that this is tailored for ARB_gl_spirv needs and particularities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static bool
|
||||||
|
add_interface_variables(const struct gl_context *cts,
|
||||||
|
struct gl_shader_program *prog,
|
||||||
|
struct set *resource_set,
|
||||||
|
unsigned stage, GLenum programInterface)
|
||||||
|
{
|
||||||
|
const struct exec_list *var_list = NULL;
|
||||||
|
|
||||||
|
struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
|
||||||
|
if (!sh)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
nir_shader *nir = sh->Program->nir;
|
||||||
|
assert(nir);
|
||||||
|
|
||||||
|
switch (programInterface) {
|
||||||
|
case GL_PROGRAM_INPUT:
|
||||||
|
var_list = &nir->inputs;
|
||||||
|
break;
|
||||||
|
case GL_PROGRAM_OUTPUT:
|
||||||
|
var_list = &nir->outputs;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert("!Should not get here");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nir_foreach_variable(var, var_list) {
|
||||||
|
if (var->data.how_declared == nir_var_hidden)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int loc_bias = 0;
|
||||||
|
switch(var->data.mode) {
|
||||||
|
case nir_var_system_value:
|
||||||
|
case nir_var_shader_in:
|
||||||
|
if (programInterface != GL_PROGRAM_INPUT)
|
||||||
|
continue;
|
||||||
|
loc_bias = (stage == MESA_SHADER_VERTEX) ? VERT_ATTRIB_GENERIC0
|
||||||
|
: VARYING_SLOT_VAR0;
|
||||||
|
break;
|
||||||
|
case nir_var_shader_out:
|
||||||
|
if (programInterface != GL_PROGRAM_OUTPUT)
|
||||||
|
continue;
|
||||||
|
loc_bias = (stage == MESA_SHADER_FRAGMENT) ? FRAG_RESULT_DATA0
|
||||||
|
: VARYING_SLOT_VAR0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var->data.patch)
|
||||||
|
loc_bias = VARYING_SLOT_PATCH0;
|
||||||
|
|
||||||
|
struct gl_shader_variable *sh_var =
|
||||||
|
rzalloc(prog, struct gl_shader_variable);
|
||||||
|
|
||||||
|
/* In the ARB_gl_spirv spec, names are considered optional debug info, so
|
||||||
|
* the linker needs to work without them. Returning them is optional.
|
||||||
|
* For simplicity, we ignore names.
|
||||||
|
*/
|
||||||
|
sh_var->name = NULL;
|
||||||
|
sh_var->type = var->type;
|
||||||
|
sh_var->location = var->data.location - loc_bias;
|
||||||
|
sh_var->index = var->data.index;
|
||||||
|
|
||||||
|
if (!link_util_add_program_resource(prog, resource_set,
|
||||||
|
programInterface,
|
||||||
|
sh_var, 1 << stage)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: as we keep adding features, this method is becoming more and more
|
||||||
|
* similar to its GLSL counterpart at linker.cpp. Eventually it would be good
|
||||||
|
* to check if they could be refactored, and reduce code duplication somehow
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
nir_build_program_resource_list(struct gl_context *ctx,
|
nir_build_program_resource_list(struct gl_context *ctx,
|
||||||
struct gl_shader_program *prog)
|
struct gl_shader_program *prog)
|
||||||
|
|
@ -44,8 +123,37 @@ nir_build_program_resource_list(struct gl_context *ctx,
|
||||||
prog->data->NumProgramResourceList = 0;
|
prog->data->NumProgramResourceList = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int input_stage = MESA_SHADER_STAGES, output_stage = 0;
|
||||||
|
|
||||||
|
/* Determine first input and final output stage. These are used to
|
||||||
|
* detect which variables should be enumerated in the resource list
|
||||||
|
* for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.
|
||||||
|
*/
|
||||||
|
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||||
|
if (!prog->_LinkedShaders[i])
|
||||||
|
continue;
|
||||||
|
if (input_stage == MESA_SHADER_STAGES)
|
||||||
|
input_stage = i;
|
||||||
|
output_stage = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty shader, no resources. */
|
||||||
|
if (input_stage == MESA_SHADER_STAGES && output_stage == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
struct set *resource_set = _mesa_pointer_set_create(NULL);
|
struct set *resource_set = _mesa_pointer_set_create(NULL);
|
||||||
|
|
||||||
|
/* Add inputs and outputs to the resource list. */
|
||||||
|
if (!add_interface_variables(ctx, prog, resource_set, input_stage,
|
||||||
|
GL_PROGRAM_INPUT)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!add_interface_variables(ctx, prog, resource_set, output_stage,
|
||||||
|
GL_PROGRAM_OUTPUT)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add uniforms
|
/* Add uniforms
|
||||||
*
|
*
|
||||||
* Here, it is expected that nir_link_uniforms() has already been
|
* Here, it is expected that nir_link_uniforms() has already been
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue