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. RFC: Also, 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. --- 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 cd3afa32661..948b802a815 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, @@ -46,11 +57,11 @@ add_var_xfb_outputs(nir_xfb_info *xfb, } else { assert(var->data.xfb_buffer < NIR_MAX_XFB_BUFFERS); if (xfb->buffers_written & (1 << var->data.xfb_buffer)) { - assert(xfb->strides[var->data.xfb_buffer] == var->data.xfb_stride); + assert(xfb->buffers[var->data.xfb_buffer].stride == var->data.xfb_stride); assert(xfb->buffer_to_stream[var->data.xfb_buffer] == var->data.stream); } else { xfb->buffers_written |= (1 << var->data.xfb_buffer); - xfb->strides[var->data.xfb_buffer] = var->data.xfb_stride; + xfb->buffers[var->data.xfb_buffer].stride = var->data.xfb_stride; xfb->buffer_to_stream[var->data.xfb_buffer] = var->data.stream; } @@ -72,6 +83,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++]; @@ -132,7 +149,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.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev