Keith Whitwell wrote:
OK, the first round of work on the VBO branch seems to have gone quite smoothly. It'd be great if a couple of the key r200/r300 people could check the branch out and verify whether I've broken those drivers or not.It'd be particularly interesting to see if someone (Aapo?) can take a look at the disabled vtxfmt_a code and see if it is easy to port that over to the new archiecture. I've got a feeling it should be fairly straight-forward, as it's simple to fallback to the tnl/ module for any unexpected or non-handled situations.
I took a quick look at this and it seems doable. I sketched out a simplified approach that just attempts to hook the existing code into a _radeon_draw_prims() callback. It looks like it might work, but it would be better to try for a deeper integration.
I'm pretty bullish about the vbo code & would like to see an early merge, so please take a look at this.
Keith
? diff ? server Index: radeon_vtxfmt_a.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c,v retrieving revision 1.22 diff -u -r1.22 radeon_vtxfmt_a.c --- radeon_vtxfmt_a.c 23 Aug 2006 23:18:39 -0000 1.22 +++ radeon_vtxfmt_a.c 2 Nov 2006 10:20:28 -0000 @@ -46,6 +46,8 @@ #include "state.h" #include "image.h" +#include "vbo/vbo_context.h" + #define CONV_VB(a, b) rvb->AttribPtr[(a)].size = vb->b->size, \ rvb->AttribPtr[(a)].type = GL_FLOAT, \ rvb->AttribPtr[(a)].stride = vb->b->stride, \ @@ -129,15 +131,7 @@ CONV(i, VertexAttrib[i]); for (i=0; i < VERT_ATTRIB_MAX; i++) { - if (enabled & (1 << i)) { - rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start; - } else { - def.data = ctx->Current.Attrib[i]; - memcpy(&rmesa->state.VB.AttribPtr[i], &def, sizeof(struct dt)); - } - - /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i]) - fprintf(stderr, "%d is default coord\n", i);*/ + rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start; } for(i=0; i < VERT_ATTRIB_MAX; i++){ @@ -177,177 +171,11 @@ void radeon_init_vtxfmt_a(r300ContextPtr rmesa); -static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *c_indices ) -{ - GET_CURRENT_CONTEXT(ctx); - r300ContextPtr rmesa = R300_CONTEXT(ctx); - int elt_size; - int i; - unsigned int min = ~0, max = 0; - struct tnl_prim prim; - static void *ptr = NULL; - struct r300_dma_region rvb; - const GLvoid *indices = c_indices; - - if (count > 65535) { - WARN_ONCE("Too many verts!\n"); - goto fallback; - } - - if (ctx->Array.ElementArrayBufferObj->Name) { - /* use indices in the buffer object */ - if (!ctx->Array.ElementArrayBufferObj->Data) { - _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!"); - return; - } - /* actual address is the sum of pointers */ - indices = (GLvoid *) - ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices); - } - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - memset(&rvb, 0, sizeof(rvb)); - switch (type) { - case GL_UNSIGNED_BYTE: - for (i=0; i < count; i++) { - if(((unsigned char *)indices)[i] < min) - min = ((unsigned char *)indices)[i]; - if(((unsigned char *)indices)[i] > max) - max = ((unsigned char *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - elt_size = 2; -#endif - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - -#ifdef FORCE_32BITS_ELTS - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min; -#else - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min; -#endif - break; - - case GL_UNSIGNED_SHORT: - for (i=0; i < count; i++) { - if(((unsigned short int *)indices)[i] < min) - min = ((unsigned short int *)indices)[i]; - if(((unsigned short int *)indices)[i] > max) - max = ((unsigned short int *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - elt_size = 2; -#endif - - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - -#ifdef FORCE_32BITS_ELTS - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min; -#else - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min; -#endif - break; - - case GL_UNSIGNED_INT: - for (i=0; i < count; i++) { - if(((unsigned int *)indices)[i] < min) - min = ((unsigned int *)indices)[i]; - if(((unsigned int *)indices)[i] > max) - max = ((unsigned int *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - if (max - min <= 65535) - elt_size = 2; - else - elt_size = 4; -#endif - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - - - if (elt_size == 2) - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min; - else - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min; - break; - - default: - WARN_ONCE("Unknown elt type!\n"); - goto fallback; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - r300UpdateShaders(rmesa); - - if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) { - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; - } - - rmesa->state.VB.Count = max - min + 1; - - r300UpdateShaderStates(rmesa); - - rmesa->state.VB.Primitive = &prim; - rmesa->state.VB.PrimitiveCount = 1; - - prim.mode = mode | PRIM_BEGIN | PRIM_END; - if (rmesa->state.VB.LockCount) - prim.start = min - rmesa->state.VB.LockFirst; - else - prim.start = 0; - prim.count = count; - - rmesa->state.VB.Elts = ptr; - rmesa->state.VB.elt_size = elt_size; - - if (r300_run_vb_render(ctx, NULL)) { - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; - } - - if(rvb.buf) - radeon_mm_use(rmesa, rvb.buf->id); - - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - return; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawElements(GET_DISPATCH(), (mode, count, type, c_indices)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); -} -static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei count, GLenum type, const GLvoid *c_indices) +static void radeonDrawRangeElements(GLcontext *ctx, + GLenum mode, GLuint min, GLuint max, GLsizei count, + GLenum type, const GLvoid *c_indices) { - GET_CURRENT_CONTEXT(ctx); r300ContextPtr rmesa = R300_CONTEXT(ctx); struct tnl_prim prim; int elt_size; @@ -371,26 +199,23 @@ indices += i * _mesa_sizeof_type(type); count -= i; } - return ; + return GL_TRUE; } WARN_ONCE("Too many verts!\n"); - goto fallback; + return GL_FALSE; } if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ if (!ctx->Array.ElementArrayBufferObj->Data) { _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!"); - return; + return GL_TRUE; } /* actual address is the sum of pointers */ indices = (GLvoid *) ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices); } - if (!_mesa_validate_DrawRangeElements( ctx, mode, min, max, count, type, indices )) - return; - FLUSH_CURRENT( ctx, 0 ); #ifdef OPTIMIZE_ELTS min = 0; @@ -465,7 +290,7 @@ default: WARN_ONCE("Unknown elt type!\n"); - goto fallback; + return GL_FALSE; } /* XXX: setup_arrays before state update? */ @@ -477,7 +302,7 @@ if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) { r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; + return GL_FALSE; } rmesa->state.VB.Count = max - min + 1; @@ -501,37 +326,30 @@ if (r300_run_vb_render(ctx, NULL)) { r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; + return GL_FALSE; } if(rvb.buf) radeon_mm_use(rmesa, rvb.buf->id); r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - return ; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawRangeElements(GET_DISPATCH(), (mode, min, max, count, type, c_indices)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); + return GL_TRUE; } -static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) +static GLboolean radeonDrawArrays( GLcontext *ctx, + GLenum mode, GLint start, GLsizei count ) { GET_CURRENT_CONTEXT(ctx); r300ContextPtr rmesa = R300_CONTEXT(ctx); struct tnl_prim prim; if (count > 65535) { + /* TODO: split into multiple draws. + */ WARN_ONCE("Too many verts!\n"); - goto fallback; + return GL_FALSE; } - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - FLUSH_CURRENT( ctx, 0 ); if (ctx->NewState) @@ -542,7 +360,7 @@ r300UpdateShaders(rmesa); if (setup_arrays(rmesa, start) >= R300_FALLBACK_TCL) - goto fallback; + return GL_FALSE; rmesa->state.VB.Count = count; @@ -564,31 +382,49 @@ rmesa->state.VB.elt_max = 0; if (r300_run_vb_render(ctx, NULL)) - goto fallback; + return GL_FALSE; - return ; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawArrays(GET_DISPATCH(), (mode, start, count)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); + return GL_TRUE; } +static void radeon_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index) +{ + if (ib == NULL) { + for (i = 0; i < nr_prims; i++) { + if (!radeonDrawArrays(...)) { + /* Fallback + */ + _tnl_draw_prims(ctx, arrays, prim + i, nr_prims - i, ib, + min_index, max_index); + return; + } + } + } + else { + for (i = 0; i < nr_prims; i++) { + if (!radeonDrawRangeElements(...)) { + _tnl_draw_prims(ctx, arrays, prim + i, nr_prims - i, ib, + min_index, max_index); + return; + } + } + } +} + void radeon_init_vtxfmt_a(r300ContextPtr rmesa) { GLcontext *ctx; - GLvertexformat *vfmt; - - ctx = rmesa->radeon.glCtx; - vfmt = (GLvertexformat *)ctx->TnlModule.Current; - - vfmt->DrawElements = radeonDrawElements; - vfmt->DrawArrays = radeonDrawArrays; - vfmt->DrawRangeElements = radeonDrawRangeElements; + struct vbo_context *vbo = vbo_context(ctx); + vbo->draw_prims = radeon_draw_prims; } + #endif #ifdef HW_VBOS
------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mesa3d-dev