[Mesa-dev] [PATCH v2 18/23] i965: Implement GL_PRIMITIVES_GENERATED with non-zero streams.

Iago Toral itoral at igalia.com
Wed Jun 25 01:26:53 PDT 2014


Hi Chris,

On Tue, 2014-06-24 at 22:12 +1200, Chris Forbes wrote:
> Continuing from this, I think you need a test to ensure that the
> points emitted in nonzero streams are not accidentally rendered when
> SO isn't active.
> 
> According to that same section of the Haswell PRM, if SO Function
> Enable is 0, it appears the StreamID bits are ignored entirely, rather
> than filtered by dw1.27-28 Render Stream Select.

Right... and this behavior seems to be specific to Haswell. IvyBridge
says that Render Stream Select is used even if SO Function Enable is 0,
so it should not be a problem there.

Since your suggestion to implement GL_PRIMITIVES_GENERATED (which I
already confirmed works well on Ivy) means that we will always enable SO
the above shouldn't really ever happen but adding that piglit test to
avoid regressions if we change that configuration in the future makes
sense. We will add that test to the batch we sent for review to piglit.

Iago

> On Tue, Jun 24, 2014 at 9:53 PM, Chris Forbes <chrisf at ijw.co.nz> wrote:
> > It looks like you can have the SOL stage increment that counter even
> > when not doing any actual streamout, which should give you the correct
> > semantics.
> >
> > See the definition of 3DSTATE_STREAMOUT in the Haswell PRM, Volume 2b. You want:
> >
> > - dw1.31 SO Function Enable = 1
> > - dw1.25 SO Statistics Enable = 1
> > - dw1.8-11 SO Buffer Enable [n] = 0
> >
> > This should behave just like having the unit disabled, except the
> > SO_PRIMITIVE_STORAGE_NEEDED registers will increment.
> >
> > -- Chris
> >
> >
> > On Wed, Jun 18, 2014 at 9:51 PM, Iago Toral Quiroga <itoral at igalia.com> wrote:
> >> So far we have been using CL_INVOCATION_COUNT to resolve this query but this
> >> is no good with streams, as only stream 0 reaches the clipping stage.
> >>
> >> From ARB_transform_feedback3:
> >>
> >> "When a generated primitive query for a vertex stream is active, the
> >>  primitives-generated count is incremented every time a primitive emitted to
> >>  that stream reaches the Discarding Rasterization stage (see Section 3.x)
> >>  right before rasterization. This counter is incremented whether or not
> >>  transform feedback is active."
> >>
> >> Unfortunately, I don't see any registers that provide the number of primitives
> >> written to a specific stream other than the ones that track the number of
> >> primitives written to transform feedback in the SOL stage, so I think we can't
> >> implement this exactly as specified. This should not be a major issue though,
> >> since non-zero streams are pointless unless they are bound to transform feedback
> >> buffers anyway.
> >>
> >> Also in ARB_transform_feedback3:
> >>
> >> "These two types of queries can be used together to determine if all
> >>  primitives in a given vertex stream have been written to the bound
> >>  feedback buffers; if both queries are run simultaneously and the query
> >>  results are equal, all primitives have been written to the buffer(s).  If
> >>  the number of primitives written is less than the number of primitives
> >>  generated, one or more buffers overflowed.
> >>
> >> This refers to GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN and
> >> GL_PRIMITIVES_GENERATED. This behavior is achieved by implementing primitives
> >> generated queries through GEN7_SO_PRIM_STORAGE_NEEDED for non-zero streams.
> >> ---
> >>  src/mesa/drivers/dri/i965/gen6_queryobj.c | 13 +++++++++----
> >>  1 file changed, 9 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/src/mesa/drivers/dri/i965/gen6_queryobj.c b/src/mesa/drivers/dri/i965/gen6_queryobj.c
> >> index 0cb64ca..ee33e1d 100644
> >> --- a/src/mesa/drivers/dri/i965/gen6_queryobj.c
> >> +++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c
> >> @@ -84,11 +84,16 @@ brw_store_register_mem64(struct brw_context *brw,
> >>
> >>  static void
> >>  write_primitives_generated(struct brw_context *brw,
> >> -                           drm_intel_bo *query_bo, int idx)
> >> +                           drm_intel_bo *query_bo, int stream, int idx)
> >>  {
> >>     intel_batchbuffer_emit_mi_flush(brw);
> >>
> >> -   brw_store_register_mem64(brw, query_bo, CL_INVOCATION_COUNT, idx);
> >> +   if (brw->gen >= 7 && stream > 0) {
> >> +      brw_store_register_mem64(brw, query_bo,
> >> +                               GEN7_SO_PRIM_STORAGE_NEEDED(stream), idx);
> >> +   } else {
> >> +      brw_store_register_mem64(brw, query_bo, CL_INVOCATION_COUNT, idx);
> >> +   }
> >>  }
> >>
> >>  static void
> >> @@ -240,7 +245,7 @@ gen6_begin_query(struct gl_context *ctx, struct gl_query_object *q)
> >>        break;
> >>
> >>     case GL_PRIMITIVES_GENERATED:
> >> -      write_primitives_generated(brw, query->bo, 0);
> >> +      write_primitives_generated(brw, query->bo, query->Base.Stream, 0);
> >>        break;
> >>
> >>     case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
> >> @@ -279,7 +284,7 @@ gen6_end_query(struct gl_context *ctx, struct gl_query_object *q)
> >>        break;
> >>
> >>     case GL_PRIMITIVES_GENERATED:
> >> -      write_primitives_generated(brw, query->bo, 1);
> >> +      write_primitives_generated(brw, query->bo, query->Base.Stream, 1);
> >>        break;
> >>
> >>     case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
> >> --
> >> 1.9.1
> >>
> >> _______________________________________________
> >> mesa-dev mailing list
> >> mesa-dev at lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 




More information about the mesa-dev mailing list