[Mesa-dev] [RFC PATCH 11/13] nir: adding varyings on nir_xfb_info and gather_info
Alejandro PiƱeiro
apinheiro at igalia.com
Sat Dec 8 11:48:19 UTC 2018
In order to be used for OpenGL (right now for ARB_gl_spirv).
This commit adds two new structures:
* nir_xfb_varying_info: that identifies each individual varying. For
each one, we need to know the type, buffer and xfb_offset
* nir_xfb_buffer_info: as now for each buffer, in addition to the
stride, we need to know how many varyings are assigned to it.
At this point, the only case where num_outputs != num_varyings is with
the case of doubles, that for dvec3/4 could require more than one
output. There are more cases though, that will be handled on following
patches.
As it is somewhat more complex to know the number of varyings needed
that the number of outputs, and num_varyings will be always less that
num_outputs, we are using num_outputs as an approximation when
allocating memory. This is debatable though. One alternative would be
to allocate as needed, as the original ARB_gl_spirv custom xfb
gathering pass was doing.
---
src/compiler/nir/nir_gather_xfb_info.c | 27 +++++++++++++++++++++++---
src/compiler/nir/nir_xfb_info.h | 24 +++++++++++++++--------
2 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/src/compiler/nir/nir_gather_xfb_info.c b/src/compiler/nir/nir_gather_xfb_info.c
index c46af311b20..e3c3376fb34 100644
--- a/src/compiler/nir/nir_gather_xfb_info.c
+++ b/src/compiler/nir/nir_gather_xfb_info.c
@@ -25,6 +25,17 @@
#include <util/u_math.h>
+static nir_xfb_info *
+nir_gather_xfb_info_create(void *mem_ctx, uint16_t output_count, uint16_t varying_count)
+{
+ nir_xfb_info *xfb = rzalloc_size(mem_ctx, sizeof(nir_xfb_info));
+
+ xfb->varyings = rzalloc_size(mem_ctx, sizeof(nir_xfb_varying_info) * varying_count);
+ xfb->outputs = rzalloc_size(mem_ctx, sizeof(nir_xfb_output_info) * output_count);
+
+ return xfb;
+}
+
static void
add_var_xfb_outputs(nir_xfb_info *xfb,
nir_variable *var,
@@ -48,11 +59,11 @@ add_var_xfb_outputs(nir_xfb_info *xfb,
} else {
assert(buffer < NIR_MAX_XFB_BUFFERS);
if (xfb->buffers_written & (1 << buffer)) {
- assert(xfb->strides[buffer] == var->data.xfb_stride);
+ assert(xfb->buffers[buffer].stride == var->data.xfb_stride);
assert(xfb->buffer_to_stream[buffer] == var->data.stream);
} else {
xfb->buffers_written |= (1 << buffer);
- xfb->strides[buffer] = var->data.xfb_stride;
+ xfb->buffers[buffer].stride = var->data.xfb_stride;
xfb->buffer_to_stream[buffer] = var->data.stream;
}
@@ -74,6 +85,12 @@ add_var_xfb_outputs(nir_xfb_info *xfb,
uint8_t comp_mask = ((1 << comp_slots) - 1) << var->data.location_frac;
unsigned location_frac = var->data.location_frac;
+ nir_xfb_varying_info *varying = &xfb->varyings[xfb->varying_count++];
+ varying->type = type;
+ varying->buffer = var->data.xfb_buffer;
+ varying->offset = *offset;
+ xfb->buffers[var->data.xfb_buffer].varying_count++;
+
assert(attrib_slots <= 2);
for (unsigned s = 0; s < attrib_slots; s++) {
nir_xfb_output_info *output = &xfb->outputs[xfb->output_count++];
@@ -149,7 +166,11 @@ nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx)
if (num_outputs == 0)
return NULL;
- nir_xfb_info *xfb = rzalloc_size(mem_ctx, nir_xfb_info_size(num_outputs));
+ /* It is complex to know how many varyings do we have beforehand. We use
+ * num_outputs as an approximation, as num_outputs should be bigger that
+ * num_varyings.
+ */
+ nir_xfb_info *xfb = nir_gather_xfb_info_create(mem_ctx, num_outputs, num_outputs);
/* Walk the list of outputs and add them to the array */
nir_foreach_variable(var, &shader->outputs) {
diff --git a/src/compiler/nir/nir_xfb_info.h b/src/compiler/nir/nir_xfb_info.h
index fef52ba96d8..71f4e87018c 100644
--- a/src/compiler/nir/nir_xfb_info.h
+++ b/src/compiler/nir/nir_xfb_info.h
@@ -29,6 +29,11 @@
#define NIR_MAX_XFB_BUFFERS 4
#define NIR_MAX_XFB_STREAMS 4
+typedef struct {
+ uint16_t stride;
+ uint16_t varying_count;
+} nir_xfb_buffer_info;
+
typedef struct {
uint8_t buffer;
uint16_t offset;
@@ -37,23 +42,26 @@ typedef struct {
uint8_t component_offset;
} nir_xfb_output_info;
+typedef struct {
+ const struct glsl_type *type;
+ uint8_t buffer;
+ uint16_t offset;
+} nir_xfb_varying_info;
+
typedef struct {
uint8_t buffers_written;
uint8_t streams_written;
- uint16_t strides[NIR_MAX_XFB_BUFFERS];
+ 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[0];
+ nir_xfb_output_info *outputs;
} nir_xfb_info;
-static inline size_t
-nir_xfb_info_size(uint16_t output_count)
-{
- return sizeof(nir_xfb_info) + sizeof(nir_xfb_output_info) * output_count;
-}
-
nir_xfb_info *
nir_gather_xfb_info(const nir_shader *shader, void *mem_ctx);
--
2.19.1
More information about the mesa-dev
mailing list