Re: [Mesa-dev] [PATCH v3] nir/linker: Add the start of a pure-NIR linker for XFB
On 24/07/18 23:29, Alejandro Piñeiro wrote: From: Neil Roberts v2: ignore names on purpose, for consistency with other places where we are doing the same (Alejandro) v3: changes proposed by Timothy Arceri, implemented by Alejandro Piñeiro: * Remove redundant 'struct active_xfb_varying' * Update several comments, including spec quotes if needed * Rename struct 'active_xfb_varying_array' to 'active_xfb_varyings' * Rename variable 'array' to 'active_varyings' * Replace one if condition for an assert ( Signed-off-by: Alejandro Piñeiro --- src/compiler/Makefile.sources | 1 + src/compiler/glsl/gl_nir_link_xfb.c | 317 src/compiler/glsl/gl_nir_linker.h | 3 + src/compiler/glsl/meson.build | 1 + 4 files changed, 322 insertions(+) create mode 100644 src/compiler/glsl/gl_nir_link_xfb.c diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources index db4dd1e89f4..fe9f607d2b1 100644 --- a/src/compiler/Makefile.sources +++ b/src/compiler/Makefile.sources @@ -31,6 +31,7 @@ LIBGLSL_FILES = \ glsl/gl_nir_link_atomics.c \ glsl/gl_nir_link_uniform_initializers.c \ glsl/gl_nir_link_uniforms.c \ + glsl/gl_nir_link_xfb.c \ glsl/gl_nir_linker.c \ glsl/gl_nir_linker.h \ glsl/gl_nir.h \ diff --git a/src/compiler/glsl/gl_nir_link_xfb.c b/src/compiler/glsl/gl_nir_link_xfb.c new file mode 100644 index 000..4703ac43400 --- /dev/null +++ b/src/compiler/glsl/gl_nir_link_xfb.c @@ -0,0 +1,317 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "nir.h" +#include "gl_nir_linker.h" +#include "ir_uniform.h" /* for gl_uniform_storage */ +#include "linker_util.h" +#include "main/context.h" + +/* + * This file does the linking of GLSL transform feedback using NIR. + * + * Note: This linking pass is currently tailored for ARB_gl_spirv needs and + * particularities. + */ + +struct active_xfb_buffer { + GLuint stride; + GLuint num_varyings; +}; + +struct active_xfb_varyings { + unsigned num_varyings; + unsigned num_outputs; + unsigned buffer_size; + struct nir_variable **varyings; + struct active_xfb_buffer buffers[MAX_FEEDBACK_BUFFERS]; +}; + +static unsigned +get_num_outputs(nir_variable *var) +{ + return glsl_count_attribute_slots(var->type, + false /* is_vertex_input */); +} + +static void +add_xfb_varying(struct active_xfb_varyings *active_varyings, +nir_variable *var) +{ + if (active_varyings->num_varyings >= active_varyings->buffer_size) { + if (active_varyings->buffer_size == 0) + active_varyings->buffer_size = 1; + else + active_varyings->buffer_size *= 2; + + active_varyings->varyings = realloc(active_varyings->varyings, + sizeof(nir_variable*) * + active_varyings->buffer_size); + } + + active_varyings->varyings[active_varyings->num_varyings++] = var; + + active_varyings->num_outputs += get_num_outputs(var); +} + +static int +cmp_xfb_offset(const void *x_generic, const void *y_generic) +{ + const nir_variable *const *x = x_generic; + const nir_variable *const *y = y_generic; + + if ((*x)->data.xfb_buffer != (*y)->data.xfb_buffer) + return (*x)->data.xfb_buffer - (*y)->data.xfb_buffer; + return (*x)->data.offset - (*y)->data.offset; +} + +static void +get_active_xfb_varyings(struct gl_shader_program *prog, +struct active_xfb_varyings *active_varyings) +{ + for (unsigned i = 0; i < MESA_SHADER_STAGES; ++i) { + struct gl_linked_shader *sh = prog->_LinkedShaders[i]; + if (sh == NULL) + continue; + + nir_shader *nir = sh->Program->nir; + + nir_foreach_variable(var, >outputs) { + if
[Mesa-dev] [PATCH v3] nir/linker: Add the start of a pure-NIR linker for XFB
From: Neil Roberts v2: ignore names on purpose, for consistency with other places where we are doing the same (Alejandro) v3: changes proposed by Timothy Arceri, implemented by Alejandro Piñeiro: * Remove redundant 'struct active_xfb_varying' * Update several comments, including spec quotes if needed * Rename struct 'active_xfb_varying_array' to 'active_xfb_varyings' * Rename variable 'array' to 'active_varyings' * Replace one if condition for an assert ( Signed-off-by: Alejandro Piñeiro --- src/compiler/Makefile.sources | 1 + src/compiler/glsl/gl_nir_link_xfb.c | 317 src/compiler/glsl/gl_nir_linker.h | 3 + src/compiler/glsl/meson.build | 1 + 4 files changed, 322 insertions(+) create mode 100644 src/compiler/glsl/gl_nir_link_xfb.c diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources index db4dd1e89f4..fe9f607d2b1 100644 --- a/src/compiler/Makefile.sources +++ b/src/compiler/Makefile.sources @@ -31,6 +31,7 @@ LIBGLSL_FILES = \ glsl/gl_nir_link_atomics.c \ glsl/gl_nir_link_uniform_initializers.c \ glsl/gl_nir_link_uniforms.c \ + glsl/gl_nir_link_xfb.c \ glsl/gl_nir_linker.c \ glsl/gl_nir_linker.h \ glsl/gl_nir.h \ diff --git a/src/compiler/glsl/gl_nir_link_xfb.c b/src/compiler/glsl/gl_nir_link_xfb.c new file mode 100644 index 000..4703ac43400 --- /dev/null +++ b/src/compiler/glsl/gl_nir_link_xfb.c @@ -0,0 +1,317 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "nir.h" +#include "gl_nir_linker.h" +#include "ir_uniform.h" /* for gl_uniform_storage */ +#include "linker_util.h" +#include "main/context.h" + +/* + * This file does the linking of GLSL transform feedback using NIR. + * + * Note: This linking pass is currently tailored for ARB_gl_spirv needs and + * particularities. + */ + +struct active_xfb_buffer { + GLuint stride; + GLuint num_varyings; +}; + +struct active_xfb_varyings { + unsigned num_varyings; + unsigned num_outputs; + unsigned buffer_size; + struct nir_variable **varyings; + struct active_xfb_buffer buffers[MAX_FEEDBACK_BUFFERS]; +}; + +static unsigned +get_num_outputs(nir_variable *var) +{ + return glsl_count_attribute_slots(var->type, + false /* is_vertex_input */); +} + +static void +add_xfb_varying(struct active_xfb_varyings *active_varyings, +nir_variable *var) +{ + if (active_varyings->num_varyings >= active_varyings->buffer_size) { + if (active_varyings->buffer_size == 0) + active_varyings->buffer_size = 1; + else + active_varyings->buffer_size *= 2; + + active_varyings->varyings = realloc(active_varyings->varyings, + sizeof(nir_variable*) * + active_varyings->buffer_size); + } + + active_varyings->varyings[active_varyings->num_varyings++] = var; + + active_varyings->num_outputs += get_num_outputs(var); +} + +static int +cmp_xfb_offset(const void *x_generic, const void *y_generic) +{ + const nir_variable *const *x = x_generic; + const nir_variable *const *y = y_generic; + + if ((*x)->data.xfb_buffer != (*y)->data.xfb_buffer) + return (*x)->data.xfb_buffer - (*y)->data.xfb_buffer; + return (*x)->data.offset - (*y)->data.offset; +} + +static void +get_active_xfb_varyings(struct gl_shader_program *prog, +struct active_xfb_varyings *active_varyings) +{ + for (unsigned i = 0; i < MESA_SHADER_STAGES; ++i) { + struct gl_linked_shader *sh = prog->_LinkedShaders[i]; + if (sh == NULL) + continue; + + nir_shader *nir = sh->Program->nir; + + nir_foreach_variable(var, >outputs) { + if (var->data.explicit_xfb_buffer && +