[Mesa-dev] [PATCH] i965: Fix an off-by-1 error in the draw upload code's size calculation.
Kenneth Graunke
kenneth at whitecape.org
Wed Oct 15 10:04:17 PDT 2014
On Wednesday, October 15, 2014 09:50:42 AM Jason Ekstrand wrote:
> On Tue, Oct 14, 2014 at 4:42 PM, Kenneth Graunke <kenneth at whitecape.org>
> wrote:
>
> > According to INTEL_DEBUG=perf, "Borderlands: The Pre-Sequel" was
> > stalling on nearly every glBufferSubData call, with very slightly
> > overlapping busy ranges.
> >
> > It turns out the draw upload code was accidentally including an extra
> > stride's worth of data in the vertex buffer size due to a simple
> > off-by-one error. We considered this extra bit of buffer space to be
> > busy (in use by the GPU), when it was actually idle.
> >
>
> Nice Catch!
>
>
> >
> > The new diagram should make it easier to understand the formula. It's
> > basically what I drew on paper when working through an actual
> > glDrawRangeElements call.
> >
> > Eliminates all glBufferSubData stalls in "Borderlands: The Pre-Sequel."
> >
> > Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> > Cc: mesa-stable at lists.freedesktop.org
> > ---
> > src/mesa/drivers/dri/i965/brw_draw_upload.c | 22 +++++++++++++++++++++-
> > 1 file changed, 21 insertions(+), 1 deletion(-)
> >
> > No Piglit regressions on Haswell. This might help Dota 2 and Serious Sam 3
> > as well, but I haven't checked.
> >
> > diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c
> > b/src/mesa/drivers/dri/i965/brw_draw_upload.c
> > index 5a12439..6cb653c 100644
> > --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
> > +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
> > @@ -486,8 +486,28 @@ brw_prepare_vertices(struct brw_context *brw)
> > offset = 0;
> > size = intel_buffer->Base.Size;
> > } else {
> > + /* Compute the size/amount of data referenced by the
> > GPU.
> > + * If the data is interleaved, StrideB may be larger
> > than
> > + * _ElementSize. As an example, assume we have 2
> > interleaved
> > + * attributes A and B. The data is organized like this:
> > + *
> > + * Stride EltSize
> > + * _,,_ ,
> > + * / \ / \
> > + * A: --- --- --- --- --- ---
> > + * B: --- --- --- --- --- ---
> > + *
> > + * |===== 4 elts ======| (4-1) * Stride + EltSize
> > + *
> > + * max_index - min_index gives the number of elements
> > that
> > + * will be referenced. Say we're drawing 4 elements.
> > On
> > + * the first three, we need the full stride in order to
> > get
> > + * to the next element. But on the last, we only want
> > the
> > + * element size, since we don't actually read the other
> > + * interleaved vertex attributes stored beyond that.
> > + */
> > offset = buffer->offset + min_index * buffer->stride;
> > - size = (buffer->stride * (max_index - min_index) +
> > + size = (buffer->stride * MAX2(max_index - min_index -
> > 1, 0) +
> > glarray->_ElementSize);
> >
>
> I'm not so sure about this new formula. Looking at the docs on
> glDrawRangeElements, the index range is inclusive on both ends meaning that
> the number of elements drawn is max_index - min_index + 1. If that's the
> case, then the old formula was correct. Are we using a half-open interval
> in mesa?
Yes, you're both right...I got tripped up by seeing (max_index - min_index) instead of (elements = max_index - min_index + 1) and then (elements - 1).
Looking over the code, everything sure looks correct.
Which leaves the question of why both Borderlands: TPS and Serious Sam 3 have all kinds of stalling with the current code, and work fine with no stalls with the patch.
I wonder if the games are incorrectly translating DirectX's DrawIndexedPrimitive call, which takes MinIndex and NumVertices, where NumVertices is apparently supposed to be (Max-Min+1). I suppose I could ask...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20141015/23f880e0/attachment.sig>
More information about the mesa-dev
mailing list