[Mesa-dev] [PATCH] st/mesa: improved is_interleaved_arrays() checking
Brian Paul
brianp at vmware.com
Mon Jun 13 16:42:19 PDT 2011
Check that the difference in array pointers/offsets from the 0th
array are less than the stride, for both VBOs and user-space arrays.
Previously, we were only doing this for the later.
This tightens up the interleaved array test and fixes a problem with
the llvmpipe driver where we were creating way too many vertex fetch
variants only because the pipe_vertex_element::src_offset values were
changing frequently. This change results in a 5x speed-up for one of
the viewperf tests.
Also, clean up the function to make it easier to understand.
---
src/mesa/state_tracker/st_draw.c | 50 ++++++++++++++-----------------------
1 files changed, 19 insertions(+), 31 deletions(-)
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index dd26db2..1bb9b80 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -237,7 +237,6 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
/**
* Examine the active arrays to determine if we have interleaved
* vertex arrays all living in one VBO, or all living in user space.
- * \param userSpace returns whether the arrays are in user space.
*/
static GLboolean
is_interleaved_arrays(const struct st_vertex_program *vp,
@@ -247,8 +246,8 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
GLuint attr;
const struct gl_buffer_object *firstBufObj = NULL;
GLint firstStride = -1;
- const GLubyte *client_addr = NULL;
- GLboolean user_memory = GL_FALSE;
+ const GLubyte *firstPtr = NULL;
+ GLboolean userSpaceBuffer = GL_FALSE;
for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
@@ -256,37 +255,26 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
const struct gl_buffer_object *bufObj = array->BufferObj;
const GLsizei stride = array->StrideB; /* in bytes */
- if (firstStride < 0) {
+ if (attr == 0) {
+ /* save info about the first array */
firstStride = stride;
- user_memory = !bufObj || !bufObj->Name;
- }
- else if (firstStride != stride) {
- return GL_FALSE;
- }
-
- if (!bufObj || !bufObj->Name) {
- /* Try to detect if the client-space arrays are
- * "close" to each other.
- */
- if (!user_memory) {
- return GL_FALSE;
- }
- if (!client_addr) {
- client_addr = array->Ptr;
- }
- else if (abs(array->Ptr - client_addr) > firstStride) {
- /* arrays start too far apart */
- return GL_FALSE;
- }
- }
- else if (!firstBufObj) {
- if (user_memory) {
- return GL_FALSE;
- }
+ firstPtr = array->Ptr;
firstBufObj = bufObj;
+ userSpaceBuffer = !bufObj || !bufObj->Name;
}
- else if (bufObj != firstBufObj) {
- return GL_FALSE;
+ else {
+ /* check if other arrays interleave with the first, in same buffer */
+ if (stride != firstStride)
+ return GL_FALSE; /* strides don't match */
+
+ if (bufObj != firstBufObj)
+ return GL_FALSE; /* arrays in different VBOs */
+
+ if (abs(array->Ptr - firstPtr) > firstStride)
+ return GL_FALSE; /* arrays start too far apart */
+
+ if ((!bufObj || !_mesa_is_bufferobj(bufObj)) != userSpaceBuffer)
+ return GL_FALSE; /* mix of VBO and user-space arrays */
}
}
--
1.7.3.4
More information about the mesa-dev
mailing list