From 67d03433772867abc23272c9cf323b15285dde47 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 24 Mar 2004 16:15:28 +0000 Subject: [PATCH] Buffer vertices and emit them in batches. Still using conventional drawing commands, no vertex DMA. --- src/mesa/drivers/dri/savage/savagedma.c | 59 ++++++ src/mesa/drivers/dri/savage/savagedma.h | 5 + src/mesa/drivers/dri/savage/savageioctl.c | 37 +++- src/mesa/drivers/dri/savage/savageioctl.h | 29 ++- src/mesa/drivers/dri/savage/savagestate.c | 6 +- src/mesa/drivers/dri/savage/savagetex.c | 4 +- src/mesa/drivers/dri/savage/savagetris.c | 241 ++++++++++------------ 7 files changed, 233 insertions(+), 148 deletions(-) diff --git a/src/mesa/drivers/dri/savage/savagedma.c b/src/mesa/drivers/dri/savage/savagedma.c index fb0ec879036..caaeeaa104e 100644 --- a/src/mesa/drivers/dri/savage/savagedma.c +++ b/src/mesa/drivers/dri/savage/savagedma.c @@ -296,3 +296,62 @@ int savageDMAClose (savageContextPtr imesa) { } #endif + +/* Faked vertex buffers + * + * This is a dirty hack, knowing that it will go away soon when real + * vertex DMA is implemented and eventually moved to the DRM. + */ + +static uint32_t vertex_data[16384]; /* 64KB */ +static drmBuf vertex_buffer = { + 0, /* idx */ + 65536, /* total = 64KB */ + 0, /* used */ + (drmAddress)vertex_data /* address */ +}; + +void savageFakeVertices (savageContextPtr imesa, drmBufPtr buffer) { + GLuint vertexStride = imesa->vertex_size; /* stride in dwords */ + GLuint vertexSize = imesa->vertex_size; /* the real vertex size in dwords */ + GLuint nVertices = buffer->used / (vertexStride*4); + uint32_t *data = (uint32_t*)buffer->address; + uint32_t vertexFormat = imesa->DrawPrimitiveCmd & SAVAGE_HW_SKIPFLAGS; + GLuint i, j, left; + + /* we have the monopoly on vertex buffers ;-) */ + assert (buffer == &vertex_buffer); + assert (buffer->used % (vertexStride*4) == 0); /* whole vertices */ + assert (nVertices % 3 == 0); /* triangle lists */ + + /* Flush (pseodo) DMA before accessing the BCI directly. */ + savageDMAFlush(imesa); + + left = nVertices; + while (left != 0) { + /* Can emit up to 255 vertices (85 triangles) with one command. */ + GLuint count = left > 255 ? 255 : left; + /* Don't go through another buffering mechanism, copy to BCI + * directly. */ + volatile uint32_t *vb = SAVAGE_GET_BCI_POINTER(imesa, + count*vertexSize + 1); + + WRITE_CMD (vb, SAVAGE_DRAW_PRIMITIVE( + count, SAVAGE_HW_TRIANGLE_LIST | vertexFormat, 0), + uint32_t); + for (i = 0; i < count; ++i) { + for (j = 0; j < vertexSize; ++j) + WRITE_CMD (vb, data[j], uint32_t); + data += vertexStride; + } + left -= count; + } + + /* clear the vertex buffer for the next set of vertices */ + vertex_buffer.used = 0; +} + +drmBufPtr savageFakeGetBuffer (savageContextPtr imesa) { + assert (vertex_buffer.used == 0); /* has been flushed */ + return &vertex_buffer; +} diff --git a/src/mesa/drivers/dri/savage/savagedma.h b/src/mesa/drivers/dri/savage/savagedma.h index 29456858464..ad8e2c771b3 100644 --- a/src/mesa/drivers/dri/savage/savagedma.h +++ b/src/mesa/drivers/dri/savage/savagedma.h @@ -47,4 +47,9 @@ void savageDMACommit (savageContextPtr imesa, void *end); void savageDMAFlush (savageContextPtr imesa); int savageDMAInit (savageContextPtr imesa); int savageDMAClose (savageContextPtr); + +/* faked implementation of vertex buffers */ +void savageFakeVertices (savageContextPtr imesa, drmBufPtr buffer); +drmBufPtr savageFakeGetBuffer (savageContextPtr imesa); + #endif diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c index 95cbeecbfa2..8b946195c3b 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.c +++ b/src/mesa/drivers/dri/savage/savageioctl.c @@ -244,9 +244,9 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_16); else clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_24); -#if 0 + FLUSH_BATCH( imesa ); -#endif + if ((mask & DD_FRONT_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ){ clear.flags |= SAVAGE_FRONT; mask &= ~DD_FRONT_LEFT_BIT; @@ -346,6 +346,8 @@ void savageSwapBuffers( __DRIdrawablePrivate *dPriv ) if (imesa->IsDouble) _mesa_notifySwapBuffers( imesa->glCtx ); + FLUSH_BATCH(imesa); + LOCK_HARDWARE( imesa ); PAGE_PENDING(pending); @@ -397,15 +399,29 @@ void savageWaitAge( savageContextPtr imesa, int age ) -void savageFlushVertices( savageContextPtr imesa ) +void savageFlushVerticesLocked( savageContextPtr imesa ) { + drmBufPtr buffer = imesa->vertex_dma_buffer; + + if (!buffer) + return; + + imesa->vertex_dma_buffer = NULL; + /* Lot's of stuff to do here. For now there is a fake DMA implementation + * in savagedma.c that emits drawing commands. Cliprects are not handled + * yet. */ + if (buffer->used) { + savageFakeVertices (imesa, buffer); + } } -void savageFlushVerticesLocked( savageContextPtr imesa ) +void savageFlushVertices( savageContextPtr imesa ) { - + LOCK_HARDWARE(imesa); + savageFlushVerticesLocked (imesa); + UNLOCK_HARDWARE(imesa); } @@ -416,11 +432,20 @@ int savage_check_copy(int fd) static void savageDDFlush( GLcontext *ctx ) { - + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + LOCK_HARDWARE(imesa); + savageFlushVerticesLocked (imesa); + savageDMAFlush (imesa); + UNLOCK_HARDWARE(imesa); } static void savageDDFinish( GLcontext *ctx ) { + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + LOCK_HARDWARE(imesa); + savageFlushVerticesLocked (imesa); + savageDmaFinish (imesa); + UNLOCK_HARDWARE(imesa); } #define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60)) diff --git a/src/mesa/drivers/dri/savage/savageioctl.h b/src/mesa/drivers/dri/savage/savageioctl.h index 94b02e33197..92f42950e13 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.h +++ b/src/mesa/drivers/dri/savage/savageioctl.h @@ -68,5 +68,32 @@ GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer); int savageFreeDMABuffer(savageContextPtr, drm_savage_alloc_cont_mem_t*); #endif -#define FLUSH_BATCH(imesa) savageDMAFlush(imesa) +#define FLUSH_BATCH(imesa) do { \ + if (imesa->vertex_dma_buffer) savageFlushVertices(imesa); \ +} while (0) + +static __inline +uint32_t *savageAllocDmaLow( savageContextPtr imesa, GLuint bytes ) +{ + uint32_t *head; + + if (!imesa->vertex_dma_buffer) { + LOCK_HARDWARE(imesa); + imesa->vertex_dma_buffer = savageFakeGetBuffer (imesa); + UNLOCK_HARDWARE(imesa); + } else if (imesa->vertex_dma_buffer->used + bytes > + imesa->vertex_dma_buffer->total) { + LOCK_HARDWARE(imesa); + savageFlushVerticesLocked( imesa ); + imesa->vertex_dma_buffer = savageFakeGetBuffer (imesa); + UNLOCK_HARDWARE(imesa); + } + + head = (uint32_t *)((uint8_t *)imesa->vertex_dma_buffer->address + + imesa->vertex_dma_buffer->used); + + imesa->vertex_dma_buffer->used += bytes; + return head; +} + #endif diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index b32b58ab878..2542b1d29d1 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -1327,6 +1327,8 @@ void savageDDUpdateHwState( GLcontext *ctx ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + /*FLUSH_BATCH(imesa);*/ + if(imesa->driDrawable) { LOCK_HARDWARE(imesa); @@ -1837,7 +1839,6 @@ void savageDDRenderStart(GLcontext *ctx) { /*ctx->VB->CopyStart = ctx->VB->Count;*/ } - LOCK_HARDWARE(SAVAGE_CONTEXT(ctx)); } @@ -1845,7 +1846,6 @@ void savageDDRenderEnd(GLcontext *ctx) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); - UNLOCK_HARDWARE(SAVAGE_CONTEXT(ctx)); if(!imesa->IsDouble) { savageSwapBuffers(imesa->driDrawable); @@ -1855,6 +1855,8 @@ void savageDDRenderEnd(GLcontext *ctx) static void savageDDInvalidateState( GLcontext *ctx, GLuint new_state ) { + FLUSH_BATCH(SAVAGE_CONTEXT(ctx)); + _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); _ac_InvalidateState( ctx, new_state ); diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c index 541de5bf865..69cb5b88664 100644 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -791,8 +791,8 @@ int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t ) savageUpdateTexLRU( imesa, t ); if (t->dirty_images) { - FLUSH_BATCH( imesa ); - WAIT_IDLE_EMPTY; + savageFlushVerticesLocked (imesa); + savageDmaFinish (imesa); if (SAVAGE_DEBUG & DEBUG_VERBOSE_LRU) fprintf(stderr, "*"); diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c index 8347580e860..c8bd5762ea3 100644 --- a/src/mesa/drivers/dri/savage/savagetris.c +++ b/src/mesa/drivers/dri/savage/savagetris.c @@ -61,109 +61,97 @@ static void savageRenderPrimitive( GLcontext *ctx, GLenum prim ); * Emit primitives * ***********************************************************************/ -static __inline__ GLuint * savage_send_one_vertex(savageContextPtr imesa, savageVertexPtr v, uint32_t * vb, GLuint start, GLuint size) -{ - GLuint j; - for (j = start ; j < size ; j++) - { - WRITE_CMD(vb, v->ui[j],uint32_t); - } - return vb; -} - -static void __inline__ savage_draw_triangle( savageContextPtr imesa, - savageVertexPtr v0, - savageVertexPtr v1, - savageVertexPtr v2 ) -{ - GLuint vertsize = imesa->vertex_size; -#if SAVAGEDEBUG - uint32_t *vb = savageDMAAlloc (imesa, 3 * vertsize + 1 + 8); +#if defined (USE_X86_ASM) +#define EMIT_VERT( j, vb, vertex_size, start, v ) \ +do { int __tmp; \ + vb += start; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertex_size-start), \ + "D" ((long)vb), \ + "S" ((long)&v->ui[start])); \ +} while (0) #else - uint32_t *vb = savageDMAAlloc (imesa, 4 * vertsize + 1); +#define EMIT_VERT( j, vb, vertex_size, start, v ) \ +do { \ + for ( j = start ; j < vertex_size ; j++ ) \ + vb[j] = (v)->ui[j]; \ + vb += vertex_size; \ +} while (0) #endif - imesa->DrawPrimitiveCmd &= - ~(SAVAGE_HW_TRIANGLE_TYPE| SAVAGE_HW_TRIANGLE_CONT); - WRITE_CMD(vb,SAVAGE_DRAW_PRIMITIVE(3, imesa->DrawPrimitiveCmd, 0),uint32_t); +static void __inline__ savage_draw_triangle (savageContextPtr imesa, + savageVertexPtr v0, + savageVertexPtr v1, + savageVertexPtr v2) { + GLuint vertsize = imesa->vertex_size; + uint32_t *vb = savageAllocDmaLow (imesa, 3*4*vertsize); + GLuint j; + + EMIT_VERT (j, vb, vertsize, 0, v0); + EMIT_VERT (j, vb, vertsize, 0, v1); + EMIT_VERT (j, vb, vertsize, 0, v2); +} - vb = savage_send_one_vertex(imesa, v0, vb, 0, vertsize); - vb = savage_send_one_vertex(imesa, v1, vb, 0, vertsize); - vb = savage_send_one_vertex(imesa, v2, vb, 0, vertsize); - -#if SAVAGEDEBUG - { - GLuint x0,y0,w,h; - x0 = (GLuint)imesa->drawX; - y0 = (GLuint)imesa->drawY; - w = (GLuint)imesa->driDrawable->w; - h = (GLuint)imesa->driDrawable->h; - - (*vb) = 0x4BCC00C0; - vb++; - (*vb) = imesa->savageScreen->backOffset; - vb++; - (*vb) = imesa->savageScreen->backBitmapDesc; - vb++; - (*vb) = (y0<<16)|x0; - vb++; - (*vb) = 0x0; - vb++; - (*vb) = (h<<16)|w; - vb++; - } -#endif - savageDMACommit (imesa, vb); -} - -static __inline__ void savage_draw_point( savageContextPtr imesa, - savageVertexPtr tmp ) -{ - GLfloat sz = imesa->glCtx->Point._Size * .5; - GLuint vertsize = imesa->vertex_size; - uint32_t *vb = savageDMAAlloc (imesa, 4 * vertsize + 1); - const GLfloat x = tmp->v.x; - const GLfloat y = tmp->v.y; - - imesa->DrawPrimitiveCmd &= - ~(SAVAGE_HW_TRIANGLE_TYPE | SAVAGE_HW_TRIANGLE_CONT); - imesa->DrawPrimitiveCmd |= SAVAGE_HW_TRIANGLE_FAN; - - WRITE_CMD(vb, SAVAGE_DRAW_PRIMITIVE(4, imesa->DrawPrimitiveCmd, 0),uint32_t); - - WRITE_CMD(vb, x - sz, GLfloat); - WRITE_CMD(vb, y - sz, GLfloat); - vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize); - - WRITE_CMD(vb, x + sz, GLfloat); - WRITE_CMD(vb, y - sz, GLfloat); - vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize); - - WRITE_CMD(vb, x + sz, GLfloat); - WRITE_CMD(vb, y + sz, GLfloat); - vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize); - - WRITE_CMD(vb, x - sz, GLfloat); - WRITE_CMD(vb, y + sz, GLfloat); - vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize); +static void __inline__ savage_draw_quad (savageContextPtr imesa, + savageVertexPtr v0, + savageVertexPtr v1, + savageVertexPtr v2, + savageVertexPtr v3) { + GLuint vertsize = imesa->vertex_size; + uint32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); + GLuint j; + + EMIT_VERT (j, vb, vertsize, 0, v0); + EMIT_VERT (j, vb, vertsize, 0, v1); + EMIT_VERT (j, vb, vertsize, 0, v3); + EMIT_VERT (j, vb, vertsize, 0, v1); + EMIT_VERT (j, vb, vertsize, 0, v2); + EMIT_VERT (j, vb, vertsize, 0, v3); +} - savageDMACommit (imesa, vb); -} - - -static __inline__ void savage_draw_line( savageContextPtr imesa, - savageVertexPtr v0, - savageVertexPtr v1 ) -{ - GLuint vertsize = imesa->vertex_size; - uint32_t *vb = savageDMAAlloc (imesa, 4 * vertsize + 1); - GLfloat dx, dy, ix, iy; - GLfloat width = imesa->glCtx->Line._Width; +static __inline__ void savage_draw_point (savageContextPtr imesa, + savageVertexPtr tmp) { + GLuint vertsize = imesa->vertex_size; + uint32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); + const GLfloat x = tmp->v.x; + const GLfloat y = tmp->v.y; + const GLfloat sz = imesa->glCtx->Point._Size * .5; + GLuint j; + + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y - sz; + EMIT_VERT (j, vb, vertsize, 2, tmp); + + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y - sz; + EMIT_VERT (j, vb, vertsize, 2, tmp); + + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y + sz; + EMIT_VERT (j, vb, vertsize, 2, tmp); + + *(float *)&vb[0] = x + sz; + *(float *)&vb[1] = y + sz; + EMIT_VERT (j, vb, vertsize, 2, tmp); + + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y + sz; + EMIT_VERT (j, vb, vertsize, 2, tmp); + + *(float *)&vb[0] = x - sz; + *(float *)&vb[1] = y - sz; + EMIT_VERT (j, vb, vertsize, 2, tmp); +} - imesa->DrawPrimitiveCmd &= - ~(SAVAGE_HW_TRIANGLE_TYPE | SAVAGE_HW_TRIANGLE_CONT); - imesa->DrawPrimitiveCmd |= SAVAGE_HW_TRIANGLE_FAN; - WRITE_CMD(vb, SAVAGE_DRAW_PRIMITIVE(4, imesa->DrawPrimitiveCmd, 0),uint32_t); +static __inline__ void savage_draw_line (savageContextPtr imesa, + savageVertexPtr v0, + savageVertexPtr v1 ) { + GLuint vertsize = imesa->vertex_size; + uint32_t *vb = savageAllocDmaLow (imesa, 6*4*vertsize); + GLfloat width = imesa->glCtx->Line._Width; + GLfloat dx, dy, ix, iy; + GLuint j; dx = v0->v.x - v1->v.x; dy = v0->v.y - v1->v.y; @@ -173,48 +161,31 @@ static __inline__ void savage_draw_line( savageContextPtr imesa, iy = ix; ix = 0; } - WRITE_CMD(vb, (v0->v.x - ix), GLfloat); - WRITE_CMD(vb, (v0->v.y - iy), GLfloat); - vb = savage_send_one_vertex(imesa, v0, vb, 2, vertsize); + *(float *)&vb[0] = v0->v.x - ix; + *(float *)&vb[1] = v0->v.y - iy; + EMIT_VERT (j, vb, vertsize, 2, v0); + + *(float *)&vb[0] = v1->v.x + ix; + *(float *)&vb[1] = v1->v.y + iy; + EMIT_VERT (j, vb, vertsize, 2, v1); - WRITE_CMD(vb, (v1->v.x - ix), GLfloat); - WRITE_CMD(vb, (v1->v.y - iy), GLfloat); - vb = savage_send_one_vertex(imesa, v1, vb, 2, vertsize); + *(float *)&vb[0] = v0->v.x + ix; + *(float *)&vb[1] = v0->v.y + iy; + EMIT_VERT (j, vb, vertsize, 2, v0); - WRITE_CMD(vb, (v1->v.x + ix), GLfloat); - WRITE_CMD(vb, (v1->v.y + iy), GLfloat); - vb = savage_send_one_vertex(imesa, v1, vb, 2, vertsize); + *(float *)&vb[0] = v0->v.x - ix; + *(float *)&vb[1] = v0->v.y - iy; + EMIT_VERT (j, vb, vertsize, 2, v0); - WRITE_CMD(vb, (v0->v.x + ix), GLfloat); - WRITE_CMD(vb, (v0->v.y + iy), GLfloat); - vb = savage_send_one_vertex(imesa, v0, vb, 2, vertsize); + *(float *)&vb[0] = v1->v.x - ix; + *(float *)&vb[1] = v1->v.y - iy; + EMIT_VERT (j, vb, vertsize, 2, v1); - savageDMACommit (imesa, vb); + *(float *)&vb[0] = v1->v.x + ix; + *(float *)&vb[1] = v1->v.y + iy; + EMIT_VERT (j, vb, vertsize, 2, v1); } -static void __inline__ savage_draw_quad( savageContextPtr imesa, - savageVertexPtr v0, - savageVertexPtr v1, - savageVertexPtr v2, - savageVertexPtr v3 ) -{ - GLuint vertsize = imesa->vertex_size; - uint32_t *vb = savageDMAAlloc (imesa, 6 * vertsize + 1); - - imesa->DrawPrimitiveCmd &= - ~(SAVAGE_HW_TRIANGLE_TYPE | SAVAGE_HW_TRIANGLE_CONT); - WRITE_CMD(vb, SAVAGE_DRAW_PRIMITIVE(6, imesa->DrawPrimitiveCmd, 0),uint32_t); - - vb = savage_send_one_vertex(imesa, v0, vb, 0, vertsize); - vb = savage_send_one_vertex(imesa, v1, vb, 0, vertsize); - vb = savage_send_one_vertex(imesa, v3, vb, 0, vertsize); - vb = savage_send_one_vertex(imesa, v1, vb, 0, vertsize); - vb = savage_send_one_vertex(imesa, v2, vb, 0, vertsize); - vb = savage_send_one_vertex(imesa, v3, vb, 0, vertsize); - - savageDMACommit (imesa, vb); -} - /*********************************************************************** * Macros for t_dd_tritmp.h to draw basic primitives * ***********************************************************************/ @@ -699,8 +670,6 @@ static void savageRasterPrimitive( GLcontext *ctx, GLuint prim ) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); - FLUSH_BATCH( imesa ); - /* Update culling */ if (imesa->raster_primitive != prim) imesa->dirty |= SAVAGE_UPLOAD_CTX; @@ -845,9 +814,7 @@ void savageFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) imesa->Fallback |= bit; if (oldfallback == 0) { /* the first fallback */ - LOCK_HARDWARE(SAVAGE_CONTEXT(ctx)); FLUSH_BATCH( imesa ); - UNLOCK_HARDWARE(SAVAGE_CONTEXT(ctx)); _swsetup_Wakeup( ctx ); imesa->RenderIndex = ~0; } -- 2.30.2