Added support for ELTS to the _savage_render_stage. Requires at least
authorFelix Kuehling <fxkuehl@gmx.de>
Thu, 20 Jan 2005 13:59:49 +0000 (13:59 +0000)
committerFelix Kuehling <fxkuehl@gmx.de>
Thu, 20 Jan 2005 13:59:49 +0000 (13:59 +0000)
Savage DRM version 2.2.0. Otherwise the render stage is disabled.

src/mesa/drivers/dri/savage/savage_xmesa.c
src/mesa/drivers/dri/savage/savagecontext.h
src/mesa/drivers/dri/savage/savageioctl.c
src/mesa/drivers/dri/savage/savageioctl.h
src/mesa/drivers/dri/savage/savagerender.c

index 9a8e090ab5164a5946edad315a0fb56864753588..742c6e89a9f1cc95fd67c4dfd4d8ea27cac2c422 100644 (file)
@@ -109,8 +109,8 @@ static const char *const card_extensions[] =
     NULL
 };
 
-extern const struct tnl_pipeline_stage _savage_texnorm_stage;
-extern const struct tnl_pipeline_stage _savage_render_stage;
+extern struct tnl_pipeline_stage _savage_texnorm_stage;
+extern struct tnl_pipeline_stage _savage_render_stage;
 
 static const struct tnl_pipeline_stage *savage_pipeline[] = {
 
@@ -435,6 +435,8 @@ savageCreateContext( const __GLcontextModes *mesaVis,
 
    imesa->vtxBuf = &imesa->clientVtxBuf;
 
+   imesa->firstElt = -1;
+
    /* Uninitialized vertex format. Force setting the vertex state in
     * savageRenderStart.
     */
@@ -463,10 +465,18 @@ savageCreateContext( const __GLcontextModes *mesaVis,
 
    /* Install the customized pipeline:
     */
-#if 1
    _tnl_destroy_pipeline( ctx );
    _tnl_install_pipeline( ctx, savage_pipeline );
-#endif
+   /* DRM versions before 2.1.3 would only render triangle lists. ELTS
+    * support was added in 2.2.0. */
+   if (sPriv->drmMinor < 2) {
+      _savage_render_stage.active = GL_FALSE;
+      fprintf (stderr,
+              "*** Disabling fast path because your DRM version is buggy "
+              "or doesn't\n*** support ELTS. You need at least Savage DRM "
+              "version 2.2.\n");
+   }
+
 
    /* Configure swrast to match hardware characteristics:
     */
@@ -508,6 +518,7 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv)
       savageTextureObjectPtr next_t, t;
 
       savageFlushVertices(imesa);
+      savageReleaseIndexedVerts(imesa);
       savageFlushCmdBuf(imesa, GL_TRUE); /* release DMA buffer */
 
       /* update for multi-tex*/ 
index 5a66bdfa4ef24d2f002834d3ef9e43cdc0e9d3a5..37aa7d33489795e0def8b172e09992e315614743 100644 (file)
@@ -141,6 +141,11 @@ struct savage_cmdbuf_t {
     drm_savage_cmd_header_t *write; /* append stuff here */
 };
 
+struct savage_elt_t {
+    GLuint n;                          /* number of elts currently allocated */
+    drm_savage_cmd_header_t *cmd;      /* the indexed drawing command */
+};
+
 
 struct savage_context_t {
     GLint refcount;
@@ -173,6 +178,10 @@ struct savage_context_t {
     /* Command buffer */
     struct savage_cmdbuf_t cmdBuf;
 
+    /* Elt book-keeping */
+    struct savage_elt_t elts;
+    GLint firstElt;
+
     /* Vertex buffers */
     struct savage_vtxbuf_t dmaVtxBuf, clientVtxBuf;
     struct savage_vtxbuf_t *vtxBuf;
index 62e7142d24623c426b802b2000a6ef495c2405bb..27747c3cd89894a734310f0b6811108b434a178d 100644 (file)
@@ -559,6 +559,9 @@ void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard )
     drm_savage_cmd_header_t *start;
     int ret;
 
+    /* complete indexed drawing commands */
+    savageFlushElts(imesa);
+
     /* If we lost the context we must restore the initial state (at
      * the start of the command buffer). */
     if (imesa->lostContext) {
@@ -609,13 +612,15 @@ void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard )
     }
 
     if (discard) {
+       assert (!savageHaveIndexedVerts(imesa));
        imesa->dmaVtxBuf.total = 0;
        imesa->dmaVtxBuf.used = 0;
        imesa->dmaVtxBuf.flushed = 0;
     }
-    imesa->clientVtxBuf.used = 0;
-    imesa->clientVtxBuf.flushed = 0;
-
+    if (!savageHaveIndexedVerts(imesa)) {
+       imesa->clientVtxBuf.used = 0;
+       imesa->clientVtxBuf.flushed = 0;
+    }
     imesa->cmdBuf.write = imesa->cmdBuf.base;
 
     /* Save the current state at the start of the command buffer. That
index 941e74e56b5b37a7a26b02749f166a71f47b2009..8f50324c3f71cfa15d9dfb07fd572f2ce939fdad 100644 (file)
@@ -65,6 +65,18 @@ void savageSwapBuffers( __DRIdrawablePrivate *dPriv );
 
 extern void savageGetDMABuffer( savageContextPtr imesa );
 
+static __inline
+void savageReleaseIndexedVerts( savageContextPtr imesa )
+{
+    imesa->firstElt = -1;
+}
+
+static __inline
+GLboolean savageHaveIndexedVerts( savageContextPtr imesa )
+{
+    return (imesa->firstElt != -1);
+}
+
 static __inline
 u_int32_t *savageAllocVtxBuf( savageContextPtr imesa, GLuint words )
 {
@@ -80,7 +92,8 @@ u_int32_t *savageAllocVtxBuf( savageContextPtr imesa, GLuint words )
           if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
               fprintf (stderr, "... flushing DMA buffer in %s\n",
                        __FUNCTION__);
-          savageFlushVertices( imesa );
+          savageReleaseIndexedVerts(imesa);
+          savageFlushVertices(imesa);
           LOCK_HARDWARE(imesa);
           savageFlushCmdBufLocked(imesa, GL_TRUE); /* discard DMA buffer */
           savageGetDMABuffer(imesa);
@@ -90,7 +103,8 @@ u_int32_t *savageAllocVtxBuf( savageContextPtr imesa, GLuint words )
        if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
           fprintf (stderr, "... flushing client vertex buffer in %s\n",
                    __FUNCTION__);
-       savageFlushVertices( imesa );
+       savageReleaseIndexedVerts(imesa);
+       savageFlushVertices(imesa);
        LOCK_HARDWARE(imesa);
        savageFlushCmdBufLocked(imesa, GL_FALSE); /* free clientVtxBuf */
        UNLOCK_HARDWARE(imesa);
@@ -102,18 +116,89 @@ u_int32_t *savageAllocVtxBuf( savageContextPtr imesa, GLuint words )
    return head;
 }
 
+static __inline
+u_int32_t *savageAllocIndexedVerts( savageContextPtr imesa, GLuint n )
+{
+    u_int32_t *ret;
+    savageFlushVertices(imesa);
+    ret = savageAllocVtxBuf(imesa, n*imesa->HwVertexSize);
+    imesa->firstElt = imesa->vtxBuf->flushed / imesa->HwVertexSize;
+    imesa->vtxBuf->flushed = imesa->vtxBuf->used;
+    return ret;
+}
+
+/* Flush Elts:
+ * - Complete the drawing command with the correct number of indices.
+ * - Actually allocate entries for the indices in the command buffer.
+ *   (This allocation must succeed without wrapping the cmd buffer!)
+ */
+static __inline
+void savageFlushElts( savageContextPtr imesa )
+{
+    if (imesa->elts.cmd) {
+       GLuint qwords = (imesa->elts.n + 3) >> 2;
+       assert(imesa->cmdBuf.write - imesa->cmdBuf.base + qwords
+              <= imesa->cmdBuf.size);
+       imesa->cmdBuf.write += qwords;
+
+       imesa->elts.cmd->idx.count = imesa->elts.n;
+       imesa->elts.cmd = NULL;
+    }
+}
+
+/* Allocate a command buffer entry with <bytes> bytes of arguments:
+ * - implies savageFlushElts
+ */
 static __inline
 drm_savage_cmd_header_t *savageAllocCmdBuf( savageContextPtr imesa, GLuint bytes )
 {
     drm_savage_cmd_header_t *ret;
     GLuint qwords = ((bytes + 7) >> 3) + 1; /* round up */
     assert (qwords < imesa->cmdBuf.size);
-    if (imesa->cmdBuf.write - imesa->cmdBuf.base + qwords > imesa->cmdBuf.size) {
+
+    savageFlushElts(imesa);
+
+    if (imesa->cmdBuf.write - imesa->cmdBuf.base + qwords > imesa->cmdBuf.size)
        savageFlushCmdBuf(imesa, GL_FALSE);
-    }
+
     ret = (drm_savage_cmd_header_t *)imesa->cmdBuf.write;
     imesa->cmdBuf.write += qwords;
     return ret;
 }
 
+/* Allocate Elts:
+ * - if it doesn't fit, flush the cmd buffer first
+ * - allocates the drawing command on the cmd buffer if there is no
+ *   incomplete indexed drawing command yet
+ * - increments the number of elts. Final allocation is done in savageFlushElts
+ */
+static __inline
+u_int16_t *savageAllocElts( savageContextPtr imesa, GLuint n )
+{
+    u_int16_t *ret;
+    GLuint qwords;
+    assert (savageHaveIndexedVerts(imesa));
+
+    if (imesa->elts.cmd)
+       qwords = (imesa->elts.n + n + 3) >> 2;
+    else
+       qwords = ((n + 3) >> 2) + 1;
+    if (imesa->cmdBuf.write - imesa->cmdBuf.base + qwords > imesa->cmdBuf.size)
+       savageFlushCmdBuf(imesa, GL_FALSE); /* implies savageFlushElts */
+
+    if (!imesa->elts.cmd) {
+       savageFlushVertices(imesa);
+       imesa->elts.cmd = savageAllocCmdBuf(imesa, 0);
+       imesa->elts.cmd->idx.cmd = (imesa->vtxBuf == &imesa->dmaVtxBuf) ?
+           SAVAGE_CMD_DMA_IDX : SAVAGE_CMD_VB_IDX;
+       imesa->elts.cmd->idx.prim = imesa->HwPrim;
+       imesa->elts.cmd->idx.skip = imesa->skip;
+       imesa->elts.n = 0;
+    }
+
+    ret = (u_int16_t *)(imesa->elts.cmd+1) + imesa->elts.n;
+    imesa->elts.n += n;
+    return ret;
+}
+
 #endif
index 50ec9eac68530037847f1c7b0cd299ae16e2a048..cdc82c7be8ca9efa2bd0e64bff22371b7726ef66 100644 (file)
@@ -54,7 +54,7 @@
 #define HAVE_QUADS       0
 #define HAVE_QUAD_STRIPS 0
 
-#define HAVE_ELTS        0     /* for now */
+#define HAVE_ELTS        1
 
 #define LOCAL_VARS savageContextPtr imesa = SAVAGE_CONTEXT(ctx) 
 #define INIT( prim ) do {                                              \
@@ -66,7 +66,8 @@
    case GL_TRIANGLE_FAN:   imesa->HwPrim = SAVAGE_PRIM_TRIFAN; break;  \
    }                                                                   \
 } while (0)
-#define FLUSH()                savageFlushVertices(imesa)
+#define FLUSH()                savageFlushElts(imesa), savageFlushVertices(imesa)
+
 #define GET_CURRENT_VB_MAX_VERTS() \
    ((imesa->bufferSize/4 - imesa->vtxBuf->used) / imesa->HwVertexSize)
 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
 #define EMIT_VERTS( ctx, j, nr, buf ) \
        _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf )
 
+#define ELTS_VARS( buf ) GLushort *dest = buf, firstElt = imesa->firstElt
+#define ELT_INIT( prim ) INIT(prim)
+
+/* (size - used - 1 qword for drawing command) * 4 elts per qword */
+#define GET_CURRENT_VB_MAX_ELTS() \
+   ((imesa->cmdBuf.size - (imesa->cmdBuf.write - imesa->cmdBuf.base) - 1)*4)
+/* (size - space for initial state - 1 qword for drawing command) * 4 elts
+ * imesa is not defined in validate_render :( */
+#define GET_SUBSEQUENT_VB_MAX_ELTS()                                   \
+   ((SAVAGE_CONTEXT(ctx)->cmdBuf.size -                                \
+     (SAVAGE_CONTEXT(ctx)->cmdBuf.start -                              \
+      SAVAGE_CONTEXT(ctx)->cmdBuf.base) - 1)*4)
+
+#define ALLOC_ELTS(nr) savageAllocElts(imesa, nr)
+#define EMIT_ELT(offset, x) do {                                       \
+   (dest)[offset] = (GLushort) ((x)+firstElt);                         \
+} while (0)
+#define EMIT_TWO_ELTS(offset, x, y) do {                               \
+   *(GLuint *)(dest + offset) = (((y)+firstElt) << 16) |               \
+                               ((x)+firstElt);                         \
+} while (0)
+
+#define INCR_ELTS( nr ) dest += nr
+#define ELTPTR dest
+#define RELEASE_ELT_VERTS() \
+   savageReleaseIndexedVerts(imesa)
+
+#define EMIT_INDEXED_VERTS( ctx, start, count ) do {                   \
+   GLuint *buf = savageAllocIndexedVerts(imesa, count-start);          \
+   EMIT_VERTS(ctx, start, count-start, buf);                           \
+} while (0)
+
 #define TAG(x) savage_##x
 #include "tnl_dd/t_dd_dmatmp.h"
 
@@ -114,20 +147,25 @@ static GLboolean savage_run_render( GLcontext *ctx,
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb; 
-   tnl_render_func *tab;
+   tnl_render_func *tab, *tab_elts;
    GLboolean valid;
    GLuint i;
 
+   if (savageHaveIndexedVerts(imesa) && (!VB->Elts || stage->changed_inputs))
+      savageReleaseIndexedVerts(imesa);
+
    if (imesa->savageScreen->chipset < S3_SAVAGE4 &&
        (ctx->_TriangleCaps & DD_FLATSHADE)) {
       tab = savage_flat_render_tab_verts_s3d;
+      tab_elts = savage_flat_render_tab_elts_s3d;
       valid = savage_flat_validate_render_s3d( ctx, VB );
    } else {
       tab = savage_render_tab_verts;
+      tab_elts = savage_render_tab_elts;
       valid = savage_validate_render( ctx, VB );
    }
 
-   /* Don't handle clipping or indexed vertices or vertex manipulations.
+   /* Don't handle clipping or vertex manipulations.
     */
    if (imesa->RenderIndex != 0 || !valid) {
       return GL_TRUE;
@@ -135,7 +173,7 @@ static GLboolean savage_run_render( GLcontext *ctx,
    
    tnl->Driver.Render.Start( ctx );
    /* Check RenderIndex again. The ptexHack is detected late in RenderStart.
-    * Also check for fallbacks detected late.
+    * Also check for ptex fallbacks detected late.
     */
    if (imesa->RenderIndex != 0 || imesa->Fallback != 0) {
       return GL_TRUE;
@@ -144,7 +182,19 @@ static GLboolean savage_run_render( GLcontext *ctx,
    /* setup for hardware culling */
    imesa->raster_primitive = GL_TRIANGLES;
    imesa->new_state |= SAVAGE_NEW_CULL;
+
+   /* update and emit state */
    savageDDUpdateHwState(ctx);
+   savageEmitChangedState(imesa);
+
+   if (VB->Elts) {
+      tab = tab_elts;
+      if (!savageHaveIndexedVerts(imesa)) {
+        if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS())
+           return GL_TRUE;
+        EMIT_INDEXED_VERTS(ctx, 0, VB->Count);
+      }
+   }
 
    for (i = 0 ; i < VB->PrimitiveCount ; i++)
    {
@@ -164,20 +214,7 @@ static GLboolean savage_run_render( GLcontext *ctx,
 static void savage_check_render( GLcontext *ctx,
                                 struct tnl_pipeline_stage *stage )
 {
-   __DRIscreenPrivate *driScrnPriv =
-      SAVAGE_CONTEXT(ctx)->savageScreen->driScrnPriv;
    stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
-   /* This hack will go away when we depend on 2.2.x for ELTS. */
-   if (driScrnPriv->drmMinor <= 1 && driScrnPriv->drmPatch < 3) {
-      static GLboolean firstTime = GL_TRUE;
-      stage->active = GL_FALSE;
-      if (firstTime) {
-        fprintf (stderr,
-                 "*** Disabling fast path because your DRM version is buggy.\n"
-                 "*** You need at least Savage DRM version 2.1.3.\n");
-        firstTime = GL_FALSE;
-      }
-   }
 }
 
 static void dtr( struct tnl_pipeline_stage *stage )
@@ -185,7 +222,7 @@ static void dtr( struct tnl_pipeline_stage *stage )
    (void)stage;
 }
 
-const struct tnl_pipeline_stage _savage_render_stage = 
+struct tnl_pipeline_stage _savage_render_stage = 
 { 
    "savage render",
    (_DD_NEW_SEPARATE_SPECULAR |
@@ -340,7 +377,7 @@ static void free_texnorm_data( struct tnl_pipeline_stage *stage )
    }
 }
 
-const struct tnl_pipeline_stage _savage_texnorm_stage =
+struct tnl_pipeline_stage _savage_texnorm_stage =
 {
    "savage texture coordinate normalization stage", /* name */
    _NEW_TEXTURE,       /* check_state */