Buffer vertices and emit them in batches. Still using conventional drawing

commands, no vertex DMA.
This commit is contained in:
Felix Kuehling
2004-03-24 16:15:28 +00:00
parent fda7215db3
commit 67d0343377
7 changed files with 229 additions and 144 deletions
+59
View File
@@ -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;
}
+5
View File
@@ -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
+31 -6
View File
@@ -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))
+28 -1
View File
@@ -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
+4 -2
View File
@@ -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 );
+2 -2
View File
@@ -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, "*");
+100 -133
View File
@@ -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;
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;
EMIT_VERT (j, vb, vertsize, 0, v0);
EMIT_VERT (j, vb, vertsize, 0, v1);
EMIT_VERT (j, vb, vertsize, 0, v2);
}
(*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);
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;
WRITE_CMD(vb, x - sz, GLfloat);
WRITE_CMD(vb, y - sz, GLfloat);
vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize);
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);
}
WRITE_CMD(vb, x + sz, GLfloat);
WRITE_CMD(vb, y - sz, GLfloat);
vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize);
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;
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);
*(float *)&vb[0] = x - sz;
*(float *)&vb[1] = y - sz;
EMIT_VERT (j, vb, vertsize, 2, tmp);
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;
*(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);
}
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;
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);
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);
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] = 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, (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);
savageDMACommit (imesa, vb);
*(float *)&vb[0] = v1->v.x - ix;
*(float *)&vb[1] = v1->v.y - iy;
EMIT_VERT (j, vb, vertsize, 2, v1);
*(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;
}