diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/gen7_sol_state.c | 23 |
1 files 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 b192d5d6c03..8ef899306a0 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; |