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:

committed by
Alejandro Piñeiro

parent
691cee751a
commit
ffdb44d3a0
@@ -33,6 +33,85 @@
|
||||
* 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
|
||||
nir_build_program_resource_list(struct gl_context *ctx,
|
||||
struct gl_shader_program *prog)
|
||||
@@ -44,8 +123,37 @@ nir_build_program_resource_list(struct gl_context *ctx,
|
||||
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);
|
||||
|
||||
/* 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
|
||||
*
|
||||
* Here, it is expected that nir_link_uniforms() has already been
|
||||
|
Reference in New Issue
Block a user