summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/iris/iris_program.c
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2019-01-22 23:28:39 -0800
committerKenneth Graunke <[email protected]>2019-02-21 10:26:11 -0800
commit1db394f46be02b49f05af7d31bd3cf41975d03bc (patch)
tree9aa1a43e457d92507b29f987bae51489dba84608 /src/gallium/drivers/iris/iris_program.c
parent5d3d75717878d7a93d6b122fcea297d88ebf629d (diff)
iris: Remap stream output indexes back to VARYING_SLOT_*.
Previously I had a hack in st/mesa to make it stop remapping VARYING_SLOT_* into the naively compacted slots, which aren't what we want. But that wasn't very feasible, as we'd have to update all drivers, or add capability bits, and it gets messy fast. It turns out that I can map back to VARYING_SLOT_* in about 5 LOC, so let's just do that. It removes the need for hacks, and is easy. This also fixes KHR-GL46.enhanced_layouts.xfb_capture_struct, which apparently with my hack was still getting the wrong slot info.
Diffstat (limited to 'src/gallium/drivers/iris/iris_program.c')
-rw-r--r--src/gallium/drivers/iris/iris_program.c27
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;