Mesa (master): nir/xfb: move varyings info out of nir_xfb_info

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Mar 15 11:01:19 UTC 2019


Module: Mesa
Branch: master
Commit: 34b3b92bbee1f68a9c121cd26e30e113c8cd39a8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=34b3b92bbee1f68a9c121cd26e30e113c8cd39a8

Author: Alejandro Piñeiro <apinheiro at igalia.com>
Date:   Thu Mar 14 11:02:52 2019 +0100

nir/xfb: move varyings info out of nir_xfb_info

When varyings was added we moved to use to dynamycally allocated
pointers, instead of allocating just one block for everything. That
breaks some assumptions of some vulkan drivers (like anv), that make
serialization and copying easier. And at the same time, varyings are
not needed for vulkan.

So this commit moves them out. Although it seems a little an overkill,
fixing the anv side would require a similar, or more, changes, so in
the end it is about to decide where do we want to put our effort.

v2: (from Jason review)
  * Don't use a temp variable on the _create methods, just return
    result of rzalloc_size
  * Wrap some lines too long.

Fixes: cf0b2ad486c9 ("nir/xfb: adding varyings on nir_xfb_info and gather_info")

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>

---

 src/compiler/glsl/gl_nir_link_xfb.c    | 17 +++++-----
 src/compiler/nir/nir_gather_xfb_info.c | 60 +++++++++++++++++++++++++---------
 src/compiler/nir/nir_xfb_info.h        | 17 ++++++----
 3 files changed, 64 insertions(+), 30 deletions(-)

diff --git a/src/compiler/glsl/gl_nir_link_xfb.c b/src/compiler/glsl/gl_nir_link_xfb.c
index 7623492ba96..5b80a3e0373 100644
--- a/src/compiler/glsl/gl_nir_link_xfb.c
+++ b/src/compiler/glsl/gl_nir_link_xfb.c
@@ -68,13 +68,14 @@ gl_nir_link_assign_xfb_resources(struct gl_context *ctx,
    free(prog->TransformFeedback.VaryingNames);
 
    nir_xfb_info *xfb_info = NULL;
+   nir_xfb_varyings_info *varyings_info = NULL;
 
    /* Find last stage before fragment shader */
    for (int stage = MESA_SHADER_FRAGMENT - 1; stage >= 0; stage--) {
       struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
 
       if (sh && stage != MESA_SHADER_TESS_CTRL) {
-         xfb_info = nir_gather_xfb_info(sh->Program->nir, NULL);
+         xfb_info = nir_gather_xfb_info_with_varyings(sh->Program->nir, NULL, &varyings_info);
          break;
       }
    }
@@ -94,9 +95,9 @@ gl_nir_link_assign_xfb_resources(struct gl_context *ctx,
    for (unsigned buf = 0; buf < MAX_FEEDBACK_BUFFERS; buf++)
       prog->TransformFeedback.BufferStride[buf] = xfb_info->buffers[buf].stride;
 
-   prog->TransformFeedback.NumVarying = xfb_info->varying_count;
+   prog->TransformFeedback.NumVarying = varyings_info->varying_count;
    prog->TransformFeedback.VaryingNames =
-      malloc(sizeof(GLchar *) * xfb_info->varying_count);
+      malloc(sizeof(GLchar *) * varyings_info->varying_count);
 
    linked_xfb->Outputs =
       rzalloc_array(xfb_prog,
@@ -107,16 +108,16 @@ gl_nir_link_assign_xfb_resources(struct gl_context *ctx,
    linked_xfb->Varyings =
       rzalloc_array(xfb_prog,
                     struct gl_transform_feedback_varying_info,
-                    xfb_info->varying_count);
-   linked_xfb->NumVarying = xfb_info->varying_count;
+                    varyings_info->varying_count);
+   linked_xfb->NumVarying = varyings_info->varying_count;
 
    int buffer_index = 0; /* Corresponds to GL_TRANSFORM_FEEDBACK_BUFFER_INDEX */
    int xfb_buffer =
-      (xfb_info->varying_count > 0) ?
+      (varyings_info->varying_count > 0) ?
       xfb_info->outputs[0].buffer : 0;
 
-   for (unsigned i = 0; i < xfb_info->varying_count; i++) {
-      nir_xfb_varying_info *xfb_varying = &xfb_info->varyings[i];
+   for (unsigned i = 0; i < varyings_info->varying_count; i++) {
+      nir_xfb_varying_info *xfb_varying = &varyings_info->varyings[i];
 
       /* From ARB_gl_spirv spec:
        *
diff --git a/src/compiler/nir/nir_gather_xfb_info.c b/src/compiler/nir/nir_gather_xfb_info.c
index 53f12fe9dbb..962f4801a67 100644
--- a/src/compiler/nir/nir_gather_xfb_info.c
+++ b/src/compiler/nir/nir_gather_xfb_info.c
@@ -27,11 +27,15 @@
 
 static void
 add_var_xfb_varying(nir_xfb_info *xfb,
+                    nir_xfb_varyings_info *varyings,
                     nir_variable *var,
                     unsigned offset,
                     const struct glsl_type *type)
 {
-   nir_xfb_varying_info *varying = &xfb->varyings[xfb->varying_count++];
+   if (varyings == NULL)
+      return;
+
+   nir_xfb_varying_info *varying = &varyings->varyings[varyings->varying_count++];
 
    varying->type = type;
    varying->buffer = var->data.xfb_buffer;
@@ -41,18 +45,26 @@ add_var_xfb_varying(nir_xfb_info *xfb,
 
 
 static nir_xfb_info *
-nir_gather_xfb_info_create(void *mem_ctx, uint16_t output_count, uint16_t varying_count)
+nir_xfb_info_create(void *mem_ctx, uint16_t output_count)
 {
-   nir_xfb_info *xfb = rzalloc_size(mem_ctx, sizeof(nir_xfb_info));
+   return rzalloc_size(mem_ctx, nir_xfb_info_size(output_count));
+}
 
-   xfb->varyings = rzalloc_size(xfb, sizeof(nir_xfb_varying_info) * varying_count);
-   xfb->outputs = rzalloc_size(xfb, sizeof(nir_xfb_output_info) * output_count);
+static size_t
+nir_xfb_varyings_info_size(uint16_t varying_count)
+{
+   return sizeof(nir_xfb_info) + sizeof(nir_xfb_varying_info) * varying_count;
+}
 
-   return xfb;
+static nir_xfb_varyings_info *
+nir_xfb_varyings_info_create(void *mem_ctx, uint16_t varying_count)
+{
+   return rzalloc_size(mem_ctx, nir_xfb_varyings_info_size(varying_count));
 }
 
 static void
 add_var_xfb_outputs(nir_xfb_info *xfb,
+                    nir_xfb_varyings_info *varyings,
                     nir_variable *var,
                     unsigned buffer,
                     unsigned *location,
@@ -71,17 +83,19 @@ add_var_xfb_outputs(nir_xfb_info *xfb,
       if (!glsl_type_is_array(child_type) &&
           !glsl_type_is_struct(child_type)) {
 
-         add_var_xfb_varying(xfb, var, *offset, type);
+         add_var_xfb_varying(xfb, varyings, var, *offset, type);
          varying_added = true;
       }
 
       for (unsigned i = 0; i < length; i++)
-         add_var_xfb_outputs(xfb, var, buffer, location, offset, child_type, varying_added);
+         add_var_xfb_outputs(xfb, varyings, var, buffer, location, offset,
+                             child_type, varying_added);
    } else if (glsl_type_is_struct_or_ifc(type)) {
       unsigned length = glsl_get_length(type);
       for (unsigned i = 0; i < length; i++) {
          const struct glsl_type *child_type = glsl_get_struct_field(type, i);
-         add_var_xfb_outputs(xfb, var, buffer, location, offset, child_type, varying_added);
+         add_var_xfb_outputs(xfb, varyings, var, buffer, location, offset,
+                             child_type, varying_added);
       }
    } else {
       assert(buffer < NIR_MAX_XFB_BUFFERS);
@@ -124,7 +138,7 @@ add_var_xfb_outputs(nir_xfb_info *xfb,
       unsigned comp_offset = var->data.location_frac;
 
       if (!varying_added) {
-         add_var_xfb_varying(xfb, var, *offset, type);
+         add_var_xfb_varying(xfb, varyings, var, *offset, type);
       }
 
       while (comp_mask) {
@@ -166,6 +180,14 @@ compare_xfb_output_offsets(const void *_a, const void *_b)
 nir_xfb_info *
 nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx)
 {
+   return nir_gather_xfb_info_with_varyings(shader, mem_ctx, NULL);
+}
+
+nir_xfb_info *
+nir_gather_xfb_info_with_varyings(const nir_shader *shader,
+                                  void *mem_ctx,
+                                  nir_xfb_varyings_info **varyings_info_out)
+{
    assert(shader->info.stage == MESA_SHADER_VERTEX ||
           shader->info.stage == MESA_SHADER_TESS_EVAL ||
           shader->info.stage == MESA_SHADER_GEOMETRY);
@@ -179,6 +201,7 @@ nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx)
     */
    unsigned num_outputs = 0;
    unsigned num_varyings = 0;
+   nir_xfb_varyings_info *varyings_info = NULL;
    nir_foreach_variable(var, &shader->outputs) {
       if (var->data.explicit_xfb_buffer) {
          num_outputs += glsl_count_attribute_slots(var->type, false);
@@ -188,7 +211,11 @@ nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx)
    if (num_outputs == 0 || num_varyings == 0)
       return NULL;
 
-   nir_xfb_info *xfb = nir_gather_xfb_info_create(mem_ctx, num_outputs, num_varyings);
+   nir_xfb_info *xfb = nir_xfb_info_create(mem_ctx, num_outputs);
+   if (varyings_info_out != NULL) {
+      *varyings_info_out = nir_xfb_varyings_info_create(mem_ctx, num_varyings);
+      varyings_info = *varyings_info_out;
+   }
 
    /* Walk the list of outputs and add them to the array */
    nir_foreach_variable(var, &shader->outputs) {
@@ -208,7 +235,7 @@ nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx)
 
       if (var->data.explicit_offset && !is_array_block) {
          unsigned offset = var->data.offset;
-         add_var_xfb_outputs(xfb, var, var->data.xfb_buffer,
+         add_var_xfb_outputs(xfb, varyings_info, var, var->data.xfb_buffer,
                              &location, &offset, var->type, false);
       } else if (is_array_block) {
          assert(glsl_type_is_struct_or_ifc(var->interface_type));
@@ -226,7 +253,7 @@ nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx)
                }
 
                unsigned offset = foffset;
-               add_var_xfb_outputs(xfb, var, var->data.xfb_buffer + b,
+               add_var_xfb_outputs(xfb, varyings_info, var, var->data.xfb_buffer + b,
                                    &location, &offset, ftype, false);
             }
          }
@@ -239,8 +266,11 @@ nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx)
    qsort(xfb->outputs, xfb->output_count, sizeof(xfb->outputs[0]),
          compare_xfb_output_offsets);
 
-   qsort(xfb->varyings, xfb->varying_count, sizeof(xfb->varyings[0]),
-         compare_xfb_varying_offsets);
+   if (varyings_info != NULL) {
+      qsort(varyings_info->varyings, varyings_info->varying_count,
+            sizeof(varyings_info->varyings[0]),
+            compare_xfb_varying_offsets);
+   }
 
 #ifndef NDEBUG
    /* Finally, do a sanity check */
diff --git a/src/compiler/nir/nir_xfb_info.h b/src/compiler/nir/nir_xfb_info.h
index f0b222b325d..8bdfa808062 100644
--- a/src/compiler/nir/nir_xfb_info.h
+++ b/src/compiler/nir/nir_xfb_info.h
@@ -55,16 +55,15 @@ typedef struct nir_xfb_info {
    nir_xfb_buffer_info buffers[NIR_MAX_XFB_BUFFERS];
    uint8_t buffer_to_stream[NIR_MAX_XFB_STREAMS];
 
-   uint16_t varying_count;
-   nir_xfb_varying_info *varyings;
-
    uint16_t output_count;
-   nir_xfb_output_info *outputs;
+   nir_xfb_output_info outputs[0];
 } nir_xfb_info;
 
-/* This method doesn't take into account varyings, as it is used to compute
- * how much size is needed to copy only the outputs.
- */
+typedef struct nir_xfb_varyings_info {
+   uint16_t varying_count;
+   nir_xfb_varying_info varyings[0];
+} nir_xfb_varyings_info;
+
 static inline size_t
 nir_xfb_info_size(uint16_t output_count)
 {
@@ -74,4 +73,8 @@ nir_xfb_info_size(uint16_t output_count)
 nir_xfb_info *
 nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx);
 
+nir_xfb_info *
+nir_gather_xfb_info_with_varyings(const nir_shader *shader,
+                                  void *mem_ctx,
+                                  nir_xfb_varyings_info **varyings_info);
 #endif /* NIR_XFB_INFO_H */




More information about the mesa-commit mailing list