diff options
Diffstat (limited to 'src/gallium/drivers/iris/iris_program.c')
-rw-r--r-- | src/gallium/drivers/iris/iris_program.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index b7d626df7d3..b50ac9d74c4 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -175,12 +175,35 @@ iris_lower_storage_image_derefs(nir_shader *nir) // XXX: need unify_interfaces() at link time... +/** + * Fix an uncompiled shader's stream output info. + * + * Core Gallium stores output->register_index as a "slot" number, where + * slots are assigned consecutively to all outputs in info->outputs_written. + * This naive packing of outputs doesn't work for us - we too have slots, + * but the layout is defined by the VUE map, which we won't have until we + * compile a specific shader variant. So, we remap these and simply store + * VARYING_SLOT_* in our copy's output->register_index fields. + * + * We also fix up VARYING_SLOT_{LAYER,VIEWPORT,PSIZ} to select the Y/Z/W + * components of our VUE header. See brw_vue_map.c for the layout. + */ static void -update_so_info(struct pipe_stream_output_info *so_info) +update_so_info(struct pipe_stream_output_info *so_info, + uint64_t outputs_written) { + uint8_t reverse_map[64] = {}; + unsigned slot = 0; + while (outputs_written) { + reverse_map[slot++] = u_bit_scan64(&outputs_written); + } + for (unsigned i = 0; i < so_info->num_outputs; i++) { struct pipe_stream_output *output = &so_info->output[i]; + /* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */ + output->register_index = reverse_map[output->register_index]; + /* The VUE header contains three scalar fields packed together: * - gl_PointSize is stored in VARYING_SLOT_PSIZ.w * - gl_Layer is stored in VARYING_SLOT_PSIZ.y @@ -237,7 +260,7 @@ iris_create_uncompiled_shader(struct pipe_context *ctx, ish->nir = nir; if (so_info) { memcpy(&ish->stream_output, so_info, sizeof(*so_info)); - update_so_info(&ish->stream_output); + update_so_info(&ish->stream_output, nir->info.outputs_written); } return ish; |