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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev