[Mesa-dev] [PATCH 3/5] i965: Add support for gl_SkipComponents[1234].

Kenneth Graunke kenneth at whitecape.org
Sat Oct 26 22:33:27 CEST 2013


ARB_transform_feedback3 allows applications to insert blank space
between interleaved varyings by adding fake 1, 2, 3, or 4-component
varyings named gl_SkipComponents[1234].

Mesa's core data structures don't explicitly track these, instead simply
tracking the buffer offset for each real varying.  If there is padding
due to gl_SkipComponents, these will not be contiguous.

Our hardware takes the specification quite literally.  Instead of
specifying offsets for each varying, it assumes they're all contiguous
and requires you to program fake varyings for each "hole".

This patch adds support for emitting SO_DECL structures for these holes.
Although we've lost the information about exactly how the application
specified their padding (i.e. gl_SkipComponents2, gl_SkipComponents2
vs. a single gl_SkipComponents4), it shouldn't matter.  We just need to
emit the right amount of space.  This patch emits the minimal number of
hole SO_DECL structures.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/gen7_sol_state.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/gen7_sol_state.c b/src/mesa/drivers/dri/i965/gen7_sol_state.c
index b9debdb..6be658f 100644
--- a/src/mesa/drivers/dri/i965/gen7_sol_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_sol_state.c
@@ -140,9 +140,28 @@ gen7_upload_3dstate_so_decl_list(struct brw_context *brw,
 	 SO_DECL_REGISTER_INDEX_SHIFT;
       decl |= component_mask << SO_DECL_COMPONENT_MASK_SHIFT;
 
-      /* This assert should be true until GL_ARB_transform_feedback_instanced
-       * is added and we start using the hole flag.
+      /* Mesa doesn't store entries for gl_SkipComponents in the Outputs[]
+       * array.  Instead, it simply increments DstOffset for the following
+       * input by the number of components that should be skipped.
+       *
+       * Our hardware is unusual in that it requires us to program SO_DECLs
+       * for fake "hole" components, rather than simply taking the offset
+       * for each real varying.  Each hole can have size 1, 2, 3, or 4; we
+       * program as many size = 4 holes as we can, then a final hole to
+       * accomodate the final 1, 2, or 3 remaining.
        */
+      int skip_components =
+         linked_xfb_info->Outputs[i].DstOffset - next_offset[buffer];
+
+      next_offset[buffer] += skip_components;
+
+      while (skip_components >= 4) {
+         so_decl[decls++] = SO_DECL_HOLE_FLAG | 0xf;
+         skip_components -= 4;
+      }
+      if (skip_components > 0)
+         so_decl[decls++] = SO_DECL_HOLE_FLAG | ((1 << skip_components) - 1);
+
       assert(linked_xfb_info->Outputs[i].DstOffset == next_offset[buffer]);
 
       next_offset[buffer] += components;
-- 
1.8.3.2



More information about the mesa-dev mailing list