summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-10-10 18:00:12 -0600
committerBrian <[email protected]>2007-10-10 18:00:12 -0600
commit453ac4b1ebc70aeabb182f2b336c6abb3324323e (patch)
tree2ad4912c0157e736a5df303cd9a4256d66ef949e
parent66ab569590f3bb9232eb7a04988ed477fe7fe2c5 (diff)
Use winsys->user_buffer_create() to wrap user-space vertex arrays and element buffers.
Now client-side vertex arrays and glDrawElements work. More testing/debug/clean-up to come...
-rw-r--r--src/mesa/state_tracker/st_draw.c72
1 files changed, 50 insertions, 22 deletions
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 7c836ba2c13..22f09c7a982 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -31,6 +31,7 @@
*/
#include "main/imports.h"
+#include "main/image.h"
#include "vbo/vbo.h"
#include "vbo/vbo_context.h"
@@ -61,6 +62,12 @@ pipe_vertex_format(GLenum format, GLuint size)
PIPE_FORMAT_R32G32B32_FLOAT,
PIPE_FORMAT_R32G32B32A32_FLOAT,
};
+ static const GLuint int_fmts[4] = {
+ PIPE_FORMAT_R32_SSCALED,
+ PIPE_FORMAT_R32G32_SSCALED,
+ PIPE_FORMAT_R32G32B32_SSCALED,
+ PIPE_FORMAT_R32G32B32A32_SSCALED,
+ };
assert(format >= GL_BYTE);
assert(format <= GL_DOUBLE);
@@ -70,6 +77,8 @@ pipe_vertex_format(GLenum format, GLuint size)
switch (format) {
case GL_FLOAT:
return float_fmts[size - 1];
+ case GL_INT:
+ return int_fmts[size - 1];
default:
assert(0);
}
@@ -215,6 +224,7 @@ st_draw_vbo(GLcontext *ctx,
velement.src_format = 0;
if (bufobj && bufobj->Name) {
+ /* attribute data is in a VBO */
struct st_buffer_object *stobj = st_buffer_object(bufobj);
/* Recall that for VBOs, the gl_client_array->Ptr field is
* really an offset from the start of the VBO, not a pointer.
@@ -236,23 +246,30 @@ st_draw_vbo(GLcontext *ctx,
assert(velement.src_format);
}
else {
- /* use the default attribute buffer */
- needDefaultAttribs = GL_TRUE;
+ /* attribute data is in user-space memory, not a VBO */
+ uint bytes = (arrays[mesaAttr]->Size
+ * _mesa_sizeof_type(arrays[mesaAttr]->Type)
+ * (max_index + 1));
+
+ /* wrap user data */
+ vbuffer.buffer
+ = pipe->winsys->user_buffer_create(pipe->winsys,
+ (void *) arrays[mesaAttr]->Ptr,
+ bytes);
+
+ /* XXX need to deref/free this buffer.vbuffer after drawing! */
- vbuffer.buffer = ctx->st->default_attrib_buffer;
vbuffer.buffer_offset = 0;
- vbuffer.pitch = 0; /* must be zero! */
- vbuffer.max_index = 1;
+ vbuffer.pitch = arrays[mesaAttr]->StrideB; /* in bytes */
+ vbuffer.max_index = 0; /* need this? */
- velement.src_offset = mesaAttr * 4 * sizeof(GLfloat);
+ velement.src_offset = 0;
velement.vertex_buffer_index = attr;
- velement.dst_offset = 0;
- velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ velement.dst_offset = 0; /* need this? */
+ velement.src_format = pipe_vertex_format(arrays[mesaAttr]->Type,
+ arrays[mesaAttr]->Size);
}
- if (attr == 0)
- assert(vbuffer.buffer);
-
pipe->set_vertex_buffer(pipe, attr, &vbuffer);
pipe->set_vertex_element(pipe, attr, &velement);
}
@@ -268,30 +285,41 @@ st_draw_vbo(GLcontext *ctx,
struct gl_buffer_object *bufobj = ib->obj;
struct pipe_buffer_handle *bh = NULL;
unsigned indexSize, i;
+ GLboolean userBuffer = GL_FALSE;
+
+ switch (ib->type) {
+ case GL_UNSIGNED_INT:
+ indexSize = 4;
+ break;
+ case GL_UNSIGNED_SHORT:
+ indexSize = 2;
+ break;
+ default:
+ assert(0);
+ }
if (bufobj && bufobj->Name) {
/* elements/indexes are in a real VBO */
struct st_buffer_object *stobj = st_buffer_object(bufobj);
bh = stobj->buffer;
- switch (ib->type) {
- case GL_UNSIGNED_INT:
- indexSize = 4;
- break;
- case GL_UNSIGNED_SHORT:
- indexSize = 2;
- break;
- default:
- assert(0);
- }
+ /* XXX reference buffer here, don't special case userBuffer below */
}
else {
- assert(0);
+ /* element/indicies are in user space memory */
+ bh = pipe->winsys->user_buffer_create(pipe->winsys,
+ (void *) ib->ptr,
+ ib->count * indexSize);
+ userBuffer = GL_TRUE;
}
for (i = 0; i < nr_prims; i++) {
pipe->draw_elements(pipe, bh, indexSize,
prims[i].mode, prims[i].start, prims[i].count);
}
+
+ if (userBuffer) {
+ pipe->winsys->buffer_reference(pipe->winsys, &bh, NULL);
+ }
}
else {
/* non-indexed */