diff options
author | Brian Paul <[email protected]> | 2011-06-13 17:34:20 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2011-06-14 17:19:53 -0600 |
commit | ee231b30a804438c89da7987d4546f14e0d9179a (patch) | |
tree | 1645c7e838d4583bba87211c9dae7c7406ead3c6 | |
parent | 24a760e9cb7a1c905e36135534d4a9c6e93c3f2a (diff) |
st/mesa: improved is_interleaved_arrays() checking
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.
-rw-r--r-- | 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 dd26db2f678..1bb9b80298e 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 */ } } |