From: Ian Romanick <ian.d.roman...@intel.com> 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.roman...@intel.com> Cc: Kenneth Graunke <kenn...@whitecape.org> Cc: Eric Anholt <e...@anholt.net> --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 2ded14b..d19250b 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -506,8 +506,22 @@ static void brw_prepare_vertices(struct brw_context *brw) ptr = glarray->Ptr; } else if (interleaved != glarray->StrideB || - (uintptr_t)(glarray->Ptr - ptr) > interleaved) + (uintptr_t)(glarray->Ptr - ptr) + glarray->_ElementSize > interleaved) { + /* If the stride is different or if the stride doesn't cover the + * entire range of the data 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, 16, &data[4]); + * glVertexAttribPointer(1, 4, GL_FLOAT, 16, &data[0]); + */ interleaved = 0; } -- 1.8.1.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev