Mesa (master): i965: Be more careful with the interleaved user array upload optimization

Ian Romanick idr at kemper.freedesktop.org
Wed Jun 26 19:27:34 UTC 2013


Module: Mesa
Branch: master
Commit: 329cd6a9b145d5b3b5a2acca1b6c2019d01c9355
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=329cd6a9b145d5b3b5a2acca1b6c2019d01c9355

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Thu Jun 20 05:43:32 2013 -0700

i965: Be more careful with the interleaved user array upload optimization

The checks to determine when the data can be uploaded in an interleaved
fashion can be tricked by certain data layouts.  For example,

    float data[...];

    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 16, &data[0]);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 16, &data[4]);
    glDrawArrays(GL_POINTS, 0, 1);

will hit the interleaved path with an incorrect size (16 bytes instead
of 32 bytes).  As a result, the data for attribute 1 never gets
uploaded.  The single element draw case is the only sensible case I can
think of for non-interleaved-that-looks-like-interleaved data, but there
may be others as well.

To fix this, make sure that the end of the element in the array being
checked is within the stride "window."  Previously the code would check
that the begining of the element was within the window.

NOTE: This is a candidate for stable branches.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Eric Anholt <eric at anholt.net>
Acked-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/mesa/drivers/dri/i965/brw_draw_upload.c |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 2ded14b..74c9e2f 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -506,8 +506,24 @@ static void brw_prepare_vertices(struct brw_context *brw)
 	    ptr = glarray->Ptr;
 	 }
 	 else if (interleaved != glarray->StrideB ||
-		  (uintptr_t)(glarray->Ptr - ptr) > interleaved)
+                  glarray->Ptr < ptr ||
+                  (uintptr_t)(glarray->Ptr - ptr) + glarray->_ElementSize > interleaved)
 	 {
+            /* If our stride is different from the first attribute's stride,
+             * or if the first attribute's stride didn't cover our element,
+             * disable the interleaved upload optimization.  The second case
+             * can most commonly occur in cases where there is a single vertex
+             * and, for example, the data is stored on the application's
+             * stack.
+             *
+             * NOTE: This will also disable the optimization in cases where
+             * the data is in a different order than the array indices.
+             * Something like:
+             *
+             *     float data[...];
+             *     glVertexAttribPointer(0, 4, GL_FLOAT, 32, &data[4]);
+             *     glVertexAttribPointer(1, 4, GL_FLOAT, 32, &data[0]);
+             */
 	    interleaved = 0;
 	 }
 




More information about the mesa-commit mailing list