More work on the nv30 software tcl code
authorStephane Marchesin <marchesin@icps.u-strasbg.fr>
Mon, 6 Mar 2006 01:46:24 +0000 (01:46 +0000)
committerStephane Marchesin <marchesin@icps.u-strasbg.fr>
Mon, 6 Mar 2006 01:46:24 +0000 (01:46 +0000)
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nv30_tris.c
src/mesa/drivers/dri/nouveau/nv30_tris.h

index d287439..49e22f8 100644 (file)
@@ -54,6 +54,7 @@ nouveau_fifo;
 #include "tnl_dd/t_dd_vertex.h"
 #undef TAG
 
+struct nouveau_context;
 
 typedef void (*nouveau_tri_func)( struct nouveau_context*, 
                nouveauVertex *,
@@ -81,6 +82,11 @@ typedef struct nouveau_context {
        /* The read-only regs */
        volatile unsigned char* mmio;
 
+       /* State for tris */
+       GLuint vertex_size;
+       GLuint color_offset;
+       GLuint specular_offset;
+
        /* The drawing fallbacks */
        nouveau_tri_func* draw_tri;
        nouveau_line_func* draw_line;
index 9853b6b..275536c 100644 (file)
@@ -23,7 +23,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-/* Triangles for NV30, NV40, G70 */
+/* Software TCL for NV30, NV40, G70 */
 
 #include <stdio.h>
 #include <math.h>
 #include "nouveau_tris.h"
 #include "nv30_tris.h"
 #include "nouveau_context.h"
-#include "nouveau_state.h"
 #include "nouveau_span.h"
 #include "nouveau_ioctl.h"
 #include "nouveau_reg.h"
 #include "nouveau_tex.h"
+#include "nouveau_fifo.h"
 
-/* hack for now */
+/* XXX hack for now */
 #define channel 1
 
+static void nv30RenderPrimitive( GLcontext *ctx, GLenum prim );
+static void nv30RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
+
 
 /***********************************************************************
  *                    Emit primitives as inline vertices               *
 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
 
 
-#define COPY_DWORDS(vb, vertsize, v)           \
-       do {                                    \
-               int j;                                  \
-               for (j = 0; j < vertsize; j++)          \
-               vb[j] = ((GLuint *)v)[j];               \
-               vb += vertsize;                         \
-       } while (0)
-#endif
-
 /* the free room we want before we start a vertex batch. this is a performance-tunable */
 #define NV30_MIN_PRIM_SIZE (32/4)
 
@@ -107,89 +101,90 @@ static inline void nv30ExtendPrimitive(struct nouveau_context* nmesa, int size)
        }
 }
 
-static inline void nv30_draw_quad(struct nouveau_context *nmesa,
+static inline void nv30_draw_quad(nouveauContextPtr nmesa,
                nouveauVertexPtr v0,
                nouveauVertexPtr v1,
                nouveauVertexPtr v2,
                nouveauVertexPtr v3)
 {
-       GLuint vertsize = nmesa->vertexSize;
-       GLuint *vb = nv30ExtendPrimitive(nmesa, 4 * 4 * vertsize);
+       GLuint vertsize = nmesa->vertex_size;
+       nv30ExtendPrimitive(nmesa, 4 * 4 * vertsize);
 
-       COPY_DWORDS(vb, vertsize, v0);
-       COPY_DWORDS(vb, vertsize, v1);
-       COPY_DWORDS(vb, vertsize, v2);
-       COPY_DWORDS(vb, vertsize, v3);
+       OUT_RINGp(v0,vertsize);
+       OUT_RINGp(v1,vertsize);
+       OUT_RINGp(v2,vertsize);
+       OUT_RINGp(v3,vertsize);
 }
 
-static inline void nv30_draw_triangle(struct nouveau_context *nmesa,
+static inline void nv30_draw_triangle(nouveauContextPtr nmesa,
                nouveauVertexPtr v0,
                nouveauVertexPtr v1,
                nouveauVertexPtr v2)
 {
-       GLuint vertsize = nmesa->vertexSize;
-       GLuint *vb = nv30ExtendPrimitive(nmesa, 3 * 4 * vertsize);
+       GLuint vertsize = nmesa->vertex_size;
+       nv30ExtendPrimitive(nmesa, 3 * 4 * vertsize);
 
-       COPY_DWORDS(vb, vertsize, v0);
-       COPY_DWORDS(vb, vertsize, v1);
-       COPY_DWORDS(vb, vertsize, v2);
+       OUT_RINGp(v0,vertsize);
+       OUT_RINGp(v1,vertsize);
+       OUT_RINGp(v2,vertsize);
 }
 
-static inline void nouveau_draw_line(struct nouveau_context *nmesa,
+static inline void nv30_draw_line(nouveauContextPtr nmesa,
                nouveauVertexPtr v0,
                nouveauVertexPtr v1)
 {
-       GLuint vertsize = nmesa->vertexSize;
-       GLuint *vb = nv30ExtendPrimitive(nmesa, 2 * 4 * vertsize);
-       COPY_DWORDS(vb, vertsize, v0);
-       COPY_DWORDS(vb, vertsize, v1);
+       GLuint vertsize = nmesa->vertex_size;
+       nv30ExtendPrimitive(nmesa, 2 * 4 * vertsize);
+       OUT_RINGp(v0,vertsize);
+       OUT_RINGp(v1,vertsize);
 }
 
-static inline void nouveau_draw_point(struct nouveau_context *nmesa,
+static inline void nv30_draw_point(nouveauContextPtr nmesa,
                nouveauVertexPtr v0)
 {
-       GLuint vertsize = nmesa->vertexSize;
-       GLuint *vb = nv30ExtendPrimitive(nmesa, 4 * vertsize);
-       COPY_DWORDS(vb, vertsize, v0);
+       GLuint vertsize = nmesa->vertex_size;
+       nv30ExtendPrimitive(nmesa, 1 * 4 * vertsize);
+       OUT_RINGp(v0,vertsize);
 }
 
 
+
 /***********************************************************************
  *          Macros for nouveau_dd_tritmp.h to draw basic primitives        *
  ***********************************************************************/
 
-#define TRI(a, b, c)                                \
-       do {                                            \
+#define TRI(a, b, c)                                        \
+       do {                                                \
                if (DO_FALLBACK)                            \
-               nmesa->draw_tri(nmesa, a, b, c);         \
+               nmesa->draw_tri(nmesa, a, b, c);            \
                else                                        \
-               nouveau_draw_triangle(nmesa, a, b, c);      \
+               nv30_draw_triangle(nmesa, a, b, c);         \
        } while (0)
 
-#define QUAD(a, b, c, d)                            \
-       do {                                            \
+#define QUAD(a, b, c, d)                                    \
+       do {                                                \
                if (DO_FALLBACK) {                          \
-                       nmesa->draw_tri(nmesa, a, b, d);         \
-                       nmesa->draw_tri(nmesa, b, c, d);         \
+                       nmesa->draw_tri(nmesa, a, b, d);    \
+                       nmesa->draw_tri(nmesa, b, c, d);    \
                }                                           \
                else                                        \
-               nouveau_draw_quad(nmesa, a, b, c, d);       \
+               nv30_draw_quad(nmesa, a, b, c, d);          \
        } while (0)
 
-#define LINE(v0, v1)                                \
-       do {                                            \
+#define LINE(v0, v1)                                        \
+       do {                                                \
                if (DO_FALLBACK)                            \
-               nmesa->draw_line(nmesa, v0, v1);         \
+               nmesa->draw_line(nmesa, v0, v1);            \
                else                                        \
-               nouveau_draw_line(nmesa, v0, v1);           \
+               nv30_draw_line(nmesa, v0, v1);              \
        } while (0)
 
-#define POINT(v0)                                    \
-       do {                                             \
-               if (DO_FALLBACK)                             \
-               nmesa->draw_point(nmesa, v0);             \
-               else                                         \
-               nouveau_draw_point(nmesa, v0);               \
+#define POINT(v0)                                           \
+       do {                                                \
+               if (DO_FALLBACK)                            \
+               nmesa->draw_point(nmesa, v0);               \
+               else                                        \
+               nv30_draw_point(nmesa, v0);                 \
        } while (0)
 
 
@@ -230,49 +225,39 @@ static struct {
 #define VERTEX            nouveauVertex
 #define TAB               rast_tab
 
-/* Only used to pull back colors into vertices (ie, we know color is
- * floating point).
- */
-#define NOUVEAU_COLOR(dst, src)                     \
-       do {                                        \
-               dst[0] = src[2];                        \
-               dst[1] = src[1];                        \
-               dst[2] = src[0];                        \
-               dst[3] = src[3];                        \
-       } while (0)
-
-#define NOUVEAU_SPEC(dst, src)                      \
-       do {                                        \
-               dst[0] = src[2];                        \
-               dst[1] = src[1];                        \
-               dst[2] = src[0];                        \
-       } while (0)
-
 
-#define DEPTH_SCALE nmesa->polygon_offset_scale
+#define DEPTH_SCALE 1.0
 #define UNFILLED_TRI unfilled_tri
 #define UNFILLED_QUAD unfilled_quad
 #define VERT_X(_v) _v->v.x
 #define VERT_Y(_v) _v->v.y
 #define VERT_Z(_v) _v->v.z
 #define AREA_IS_CCW(a) (a > 0)
-#define GET_VERTEX(e) (nmesa->verts + (e * nmesa->vertexSize * sizeof(int)))
+#define GET_VERTEX(e) (nmesa->verts + (e * nmesa->vertex_size * sizeof(int)))
 
 #define VERT_SET_RGBA( v, c )                                          \
        do {                                                            \
-               nouveau_color_t *color = (nouveau_color_t *)&((v)->ui[coloroffset]);    \
-               UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]);           \
-               UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]);         \
-               UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]);          \
-               UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]);         \
+               nouveau_color_t *color = (nouveau_color_t *)&((v)->f[coloroffset]);     \
+               color->red=(c)[0];                                      \
+               color->green=(c)[1];                                    \
+               color->blue=(c)[2];                                     \
+               color->alpha=(c)[3];                                    \
        } while (0)
 
-#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
-
-#define VERT_SET_SPEC( v, c )                                  \
+#define VERT_COPY_RGBA( v0, v1 )                                       \
        do {                                                            \
+               if (coloroffset) {                                      \
+                       v0->f[coloroffset][0] = v1->f[coloroffset][0];  \
+                       v0->f[coloroffset][1] = v1->f[coloroffset][1];  \
+                       v0->f[coloroffset][2] = v1->f[coloroffset][2];  \
+                       v0->f[coloroffset][3] = v1->f[coloroffset][3];  \
+               }                                                       \
+       } while (0)
+
+#define VERT_SET_SPEC( v, c )                                                  \
+       do {                                                                    \
                if (specoffset) {                                               \
-                       nouveau_color_t *color = (nouveau_color_t *)&((v)->ui[specoffset]);     \
+                       nouveau_color_t *color = (nouveau_color_t *)&((v)->f[specoffset]);      \
                        UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]);           \
                        UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]);         \
                        UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]);          \
@@ -281,24 +266,24 @@ static struct {
 #define VERT_COPY_SPEC( v0, v1 )                       \
        do {                                                    \
                if (specoffset) {                                       \
-                       v0->ub4[specoffset][0] = v1->ub4[specoffset][0];        \
-                       v0->ub4[specoffset][1] = v1->ub4[specoffset][1];        \
-                       v0->ub4[specoffset][2] = v1->ub4[specoffset][2];        \
+                       v0->f[specoffset][0] = v1->f[specoffset][0];    \
+                       v0->f[specoffset][1] = v1->f[specoffset][1];    \
+                       v0->f[specoffset][2] = v1->f[specoffset][2];    \
                }                                                       \
        } while (0)
 
 
-#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[coloroffset]
-#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
-#define VERT_SAVE_SPEC( idx )    if (specoffset) spec[idx] = v[idx]->ui[specoffset]
-#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
+#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->f[coloroffset]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->f[coloroffset] = color[idx]
+#define VERT_SAVE_SPEC( idx )    if (specoffset) spec[idx] = v[idx]->f[specoffset]
+#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[specoffset] = spec[idx]
 
 
-#define LOCAL_VARS(n)                                                   \
-       struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);                             \
-GLuint color[n], spec[n];                                           \
-GLuint coloroffset = nmesa->coloroffset;              \
-GLuint specoffset = nmesa->specoffset;                       \
+#define LOCAL_VARS(n)                                                          \
+       struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);                  \
+GLuint color[n], spec[n];                                                      \
+GLuint coloroffset = nmesa->color_offset;                                      \
+GLuint specoffset = nmesa->specular_offset;                                    \
 (void)color; (void)spec; (void)coloroffset; (void)specoffset;
 
 
@@ -306,20 +291,20 @@ GLuint specoffset = nmesa->specoffset;                       \
  *                Helpers for rendering unfilled primitives            *
  ***********************************************************************/
 
-static const GLenum hwPrim[GL_POLYGON+1] = {
-    GL_POINTS,
-    GL_LINES,
-    GL_LINES,
-    GL_LINES,
-    GL_TRIANGLES,
-    GL_TRIANGLES,
-    GL_TRIANGLES,
-    GL_TRIANGLES,
-    GL_TRIANGLES,
-    GL_TRIANGLES
+static const GLuint hw_prim[GL_POLYGON+1] = {
+       GL_POINTS+1,
+       GL_LINES+1,
+       GL_LINES+1,
+       GL_LINES+1,
+       GL_TRIANGLES+1,
+       GL_TRIANGLES+1,
+       GL_TRIANGLES+1,
+       GL_QUADS+1,
+       GL_QUADS+1,
+       GL_TRIANGLES+1
 };
 
-#define RASTERIZE(x) nv30RasterPrimitive( ctx, x, hwPrim[x] )
+#define RASTERIZE(x) nv30RasterPrimitive( ctx, x, hw_prim[x] )
 #define RENDER_PRIMITIVE nmesa->renderPrimitive
 #define TAG(x) x
 #define IND NOUVEAU_FALLBACK_BIT
@@ -447,12 +432,12 @@ static void init_rast_tab(void)
 #define RENDER_LINE(v0, v1)         LINE(V(v0), V(v1))
 #define RENDER_TRI( v0, v1, v2)     TRI( V(v0), V(v1), V(v2))
 #define RENDER_QUAD(v0, v1, v2, v3) QUAD(V(v0), V(v1), V(v2), V(v3))
-#define INIT(x) nv30RasterPrimitive(ctx, x, hwPrim[x])
+#define INIT(x) nv30RasterPrimitive(ctx, x, hw_prim[x])
 #undef LOCAL_VARS
 #define LOCAL_VARS                                              \
        struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);                     \
 GLubyte *vertptr = (GLubyte *)nmesa->verts;                 \
-const GLuint vertsize = nmesa->vertexSize;          \
+const GLuint vertsize = nmesa->vertex_size;          \
 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;       \
 const GLboolean stipple = ctx->Line.StippleFlag;               \
 (void) elt; (void) stipple;
@@ -515,16 +500,16 @@ static void nouveauFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
                GLuint n)
 {
        struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
-       GLuint vertsize = nmesa->vertexSize;
-       GLuint *vb = nouveauExtendPrimitive(nmesa, (n - 2) * 3 * 4 * vertsize);
+       GLuint vertsize = nmesa->vertex_size;
+       nv30ExtendPrimitive(nmesa, (n - 2) * 3 * 4 * vertsize);
        GLubyte *vertptr = (GLubyte *)nmesa->verts;
        const GLuint *start = (const GLuint *)V(elts[0]);
        int i;
 
        for (i = 2; i < n; i++) {
-               COPY_DWORDS(vb, vertsize, V(elts[i - 1]));
-               COPY_DWORDS(vb, vertsize, V(elts[i]));
-               COPY_DWORDS(vb, vertsize, start);       
+               OUT_RINGp(V(elts[i-1]),vertsize);
+               OUT_RINGp(V(elts[i]),vertsize);
+               OUT_RINGp(start,vertsize);
        }
 }
 
@@ -548,6 +533,13 @@ static void nouveauFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
                _DD_NEW_TRI_STIPPLE |             \
                _NEW_POLYGONSTIPPLE)
 
+#define EMIT_ATTR( ATTR, STYLE )                                       \
+do {                                                                   \
+   nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR);      \
+   nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE);     \
+   nmesa->vertex_attr_count++;                                         \
+} while (0)
+
 
 static void nv30ChooseRenderState(GLcontext *ctx)
 {
@@ -556,9 +548,9 @@ static void nv30ChooseRenderState(GLcontext *ctx)
        GLuint flags = ctx->_TriangleCaps;
        GLuint index = 0;
 
-       nmesa->draw_point = nouveau_draw_point;
-       nmesa->draw_line = nouveau_draw_line;
-       nmesa->draw_tri = nouveau_draw_triangle;
+       nmesa->draw_point = nv30_draw_point;
+       nmesa->draw_line = nv30_draw_line;
+       nmesa->draw_tri = nv30_draw_triangle;
 
        if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
                if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= NOUVEAU_TWOSIDE_BIT;
@@ -609,34 +601,84 @@ static void nv30ChooseRenderState(GLcontext *ctx)
 
 
 
-static inline void nv30OutputVertexFormat(struct nouveau_context* mesa, GLuint index)
+static inline void nv30OutputVertexFormat(struct nouveau_context* nmesa, GLuint index)
 {
-       /*
-        * Determine how many inputs we need in the vertex format.
-        * We need to find & setup the right input "slots"
-        * 
-        * The hw attribute order matches nv_vertex_program, and _TNL_BIT_* 
-        * also matches this order, so we can take shortcuts...
-        */
+       GLcontext* ctx=nmesa->glCtx;
+       TNLcontext *tnl = TNL_CONTEXT(ctx);
+       struct vertex_buffer *VB = &tnl->vb;
+       int attr_size[16];
+       int default_attr_size[8]={3,3,3,4,3,1,4,4};
        int i;
        int slots=0;
+       int total_size=0;
+
+       /*
+        * Determine attribute sizes
+        */
+       for(i=0;i<8;i++)
+       {
+               if (index&(1<<i))
+                       attr_size[i]=default_attr_size[i];
+               else
+                       attr_size[i]=0;
+       }
+       for(i=8;i<16;i++)
+       {
+               if (index&(1<<i))
+                       attr_size[i]=VB->TexCoordPtr[i];
+               else
+                       attr_size[i]=0;
+       }
+
+       /*
+        * Tell t_vertex about the vertex format
+        */
        for(i=0;i<16;i++)
+       {
                if (index&(1<<i))
+               {
                        slots=i+1;
+                       if (i==0)
+                       {
+                               /* special-case POS */
+                               EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_3F_VIEWPORT);
+                       }
+                       else
+                       {
+                               switch(attr_size[i])
+                               {
+                                       case 1:
+                                               EMIT_ATTR(i,EMIT_1F);
+                                               break;
+                                       case 2:
+                                               EMIT_ATTR(i,EMIT_2F);
+                                               break;
+                                       case 3:
+                                               EMIT_ATTR(i,EMIT_3F);
+                                               break;
+                                       case 4:
+                                               EMIT_ATTR(i,EMIT_4F);
+                                               break;
+                               }
+                       }
+                       if (i==_TNL_ATTRIB_COLOR0)
+                               nmesa->color_offset=total_size;
+                       if (i==_TNL_ATTRIB_COLOR1)
+                               nmesa->specular_offset=total_size;
+                       total_size+=attr_size[i];
+               }
+       }
+       nmesa->vertex_size=total_size;
 
+       /* 
+        * Tell the hardware about the vertex format
+        */
        BEGIN_RING_SIZE(channel,0x1740,slots);
        for(i=0;i<slots;i++)
-               if (index&(1<<i))
-               {
-                       /* XXX for now we only emit 3-sized attributes 
-                        * Where can we get the attribute size ? */
-                       int size=3;
-                       OUR_RING(0x00000002|(size*0x10));
-               }
-               else
-               {
-                       OUR_RING(0x00000002);
-               }
+       {
+               int size=attr_size[i];
+               OUT_RING(0x00000002|(size*0x10));
+       }
        BEGIN_RING_SIZE(channel,0x1718,1);
        OUT_RING(0);
        BEGIN_RING_SIZE(channel,0x1718,1);
@@ -698,12 +740,12 @@ static void nv30RenderFinish(GLcontext *ctx)
  */
 void nv30RasterPrimitive(GLcontext *ctx,
                GLenum glprim,
-               GLenum hwprim)
+               GLuint hwprim)
 {
        struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
 
        assert (!nmesa->newState);
-       
+
        if (hwprim != nmesa->current_primitive)
        {
                nmesa->current_primitive=hwprim;
@@ -715,7 +757,7 @@ void nv30RasterPrimitive(GLcontext *ctx,
  */
 static void nv30RenderPrimitive( GLcontext *ctx, GLuint prim )
 {
-       nv30RasterPrimitive( ctx, prim, hwPrim[prim] );
+       nv30RasterPrimitive( ctx, prim, hw_prim[prim] );
 }
 
 
index 92f1896..680b578 100644 (file)
@@ -26,14 +26,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 
-#ifndef __NV40_TRIS_H__
-#define __NV40_TRIS_H__
+#ifndef __NV30_TRIS_H__
+#define __NV30_TRIS_H__
 
 #include "mtypes.h"
 
-extern void nv40TriInitFunctions( GLcontext *ctx );
-extern void nv40Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
+extern void nv30TriInitFunctions( GLcontext *ctx );
+extern void nv30Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
 #define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode )
 
-#endif /* __NV40_TRIS_H__ */
+#endif /* __NV30_TRIS_H__ */