summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAntia Puentes <[email protected]>2018-08-08 14:29:38 +0200
committerAlejandro PiƱeiro <[email protected]>2019-07-12 23:42:41 +0200
commitffdb44d3a0a2199487f17ff566c51280c9708c60 (patch)
treefb20327d2cf356f8d82a234a4d836c6c158fdaa7 /src
parent691cee751a93aa100594a8fcede0869047d86674 (diff)
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/compiler/glsl/gl_nir_linker.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c
index 49ba9501f7a..13d4e839c1b 100644
--- a/src/compiler/glsl/gl_nir_linker.c
+++ b/src/compiler/glsl/gl_nir_linker.c
@@ -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