Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / sis / sis_tris.c
index 04c750e5509e338fb0a684c5e215d35bbe73cbfe..4690274c3c05f8d7f43921ff6a012bdd4e7e5629 100644 (file)
@@ -32,10 +32,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Eric Anholt <anholt@FreeBSD.org>
  */
 
-#include "glheader.h"
-#include "mtypes.h"
-#include "colormac.h"
-#include "macros.h"
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "main/colormac.h"
+#include "main/macros.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
@@ -50,6 +50,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "sis_alloc.h"
 #include "sis_tex.h"
 
+/* 6326 and 300-series shared */
 static const GLuint hw_prim[GL_POLYGON+1] = {
    OP_3D_POINT_DRAW,           /* GL_POINTS */
    OP_3D_LINE_DRAW,            /* GL_LINES */
@@ -68,6 +69,11 @@ static const GLuint hw_prim_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = {
    OP_3D_FIRE_TSARGBb,
    OP_3D_FIRE_TSARGBc
 };
+static const GLuint hw_prim_6326_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = {
+   OP_6326_3D_FIRE_TSARGBa,
+   OP_6326_3D_FIRE_TSARGBb,
+   OP_6326_3D_FIRE_TSARGBc
+};
 
 static const GLuint hw_prim_mmio_shade[OP_3D_TRIANGLE_DRAW+1] = {
    SHADE_FLAT_VertexA,
@@ -98,7 +104,6 @@ static void sisRenderPrimitive( GLcontext *ctx, GLenum prim );
 #define HAVE_LINES 1
 #define HAVE_POINTS 1
 #define CTX_ARG sisContextPtr smesa
-#define CTX_ARG2 smesa
 #define GET_VERTEX_DWORDS() smesa->vertex_size
 #define ALLOC_VERTS( n, size ) sisAllocDmaLow( smesa, n * size * sizeof(int) )
 #undef LOCAL_VARS
@@ -143,6 +148,25 @@ do {                                                               \
       MMIO(REG_3D_TSARGBa+(i)*0x30, __color);                  \
 } while (0)
 
+#define SIS6326_MMIO_WRITE_VERTEX(_v, i, lastvert)             \
+do {                                                           \
+   GLuint __color, __i = 0;                                    \
+   MMIO(REG_6326_3D_TSXa+(i)*0x20, _v->ui[__i++]);             \
+   MMIO(REG_6326_3D_TSYa+(i)*0x20, _v->ui[__i++]);             \
+   MMIO(REG_6326_3D_TSZa+(i)*0x20, _v->ui[__i++]);             \
+   if (SIS_STATES & VERT_W)                                    \
+      MMIO(REG_6326_3D_TSWa+(i)*0x20, _v->ui[__i++]);          \
+   __color = _v->ui[__i++];                                    \
+   if (SIS_STATES & VERT_SPEC)                                 \
+      MMIO(REG_6326_3D_TSFSa+(i)*0x20, _v->ui[__i++]);         \
+   if (SIS_STATES & VERT_UV0) {                                        \
+      MMIO(REG_6326_3D_TSUa+(i)*0x20, _v->ui[__i++]);          \
+      MMIO(REG_6326_3D_TSVa+(i)*0x20, _v->ui[__i++]);          \
+   }                                                           \
+   if (lastvert || (SIS_STATES & VERT_SMOOTH))                 \
+      MMIO(REG_6326_3D_TSARGBa+(i)*0x30, __color);             \
+} while (0)
+
 #define MMIO_VERT_REG_COUNT 10
 
 #define VERT_SMOOTH    0x01
@@ -150,11 +174,12 @@ do {                                                              \
 #define VERT_SPEC      0x04
 #define VERT_UV0       0x08
 #define VERT_UV1       0x10
+#define VERT_6326      0x20    /* Right after UV1, but won't have a UV1 set */
 
 typedef void (*mmio_draw_func)(sisContextPtr smesa, char *verts);
-static mmio_draw_func sis_tri_func_mmio[32];
-static mmio_draw_func sis_line_func_mmio[32];
-static mmio_draw_func sis_point_func_mmio[32];
+static mmio_draw_func sis_tri_func_mmio[48];
+static mmio_draw_func sis_line_func_mmio[48];
+static mmio_draw_func sis_point_func_mmio[48];
 
 #define SIS_STATES (0)
 #define TAG(x) x##_none
@@ -378,34 +403,38 @@ do {                                                              \
 
 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
 
-#define VERT_SET_SPEC( v0, c )                                 \
+#define VERT_SET_SPEC( v, c )                                  \
 do {                                                           \
-   if (havespec) {                                             \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]);    \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]);  \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]);   \
+   if (specoffset != 0) {                                      \
+      sis_color_t *spec = (sis_color_t *)&((v)->ui[specoffset]); \
+      UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]);             \
+      UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]);           \
+      UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]);            \
    }                                                           \
 } while (0)
-#define VERT_COPY_SPEC( v0, v1 )                       \
-do {                                                   \
-   if (havespec) {                                     \
-      v0->v.specular.red   = v1->v.specular.red;       \
-      v0->v.specular.green = v1->v.specular.green;     \
-      v0->v.specular.blue  = v1->v.specular.blue;      \
-   }                                                   \
+#define VERT_COPY_SPEC( v0, v1 )                               \
+do {                                                           \
+   if (specoffset != 0) {                                      \
+      sis_color_t *spec0 = (sis_color_t *)&((v0)->ui[specoffset]); \
+      sis_color_t *spec1 = (sis_color_t *)&((v1)->ui[specoffset]); \
+      spec0->red   = spec1->red;                               \
+      spec0->green = spec1->green;                             \
+      spec0->blue  = spec1->blue;                              \
+   }                                                           \
 } 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 (havespec) spec[idx] = v[idx]->ui[5]
-#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
+#define VERT_SAVE_SPEC( idx )    if (specoffset != 0) spec[idx] = v[idx]->ui[specoffset]
+#define VERT_RESTORE_SPEC( idx ) if (specoffset != 0) v[idx]->ui[specoffset] = spec[idx]
 
 #define LOCAL_VARS(n)                                          \
    sisContextPtr smesa = SIS_CONTEXT(ctx);                     \
-   GLuint color[n], spec[n];                                   \
-   GLuint coloroffset = (smesa->vertex_size == 4 ? 3 : 4);     \
-   GLboolean havespec = (smesa->vertex_size == 4 ? 0 : 1);     \
-   (void) color; (void) spec; (void) coloroffset; (void) havespec;
+   GLuint color[n] = { 0 };                                    \
+   GLuint spec[n] = { 0 };                                     \
+   GLuint coloroffset = smesa->coloroffset;                    \
+   GLuint specoffset = smesa->specoffset;                      \
+   (void) color; (void) spec; (void) coloroffset; (void) specoffset;
 
 /***********************************************************************
  *                Helpers for rendering unfilled primitives            *
@@ -623,6 +652,9 @@ static void sisChooseRenderState(GLcontext *ctx)
    GLuint flags = ctx->_TriangleCaps;
    GLuint index = 0;
 
+   if (smesa->Fallback)
+      return;
+
    if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) {
 
       if (flags & ANY_RASTER_FLAGS) {
@@ -717,9 +749,9 @@ static void sisRunPipeline( GLcontext *ctx )
 {
    sisContextPtr smesa = SIS_CONTEXT( ctx );
 
-   if (!smesa->Fallback && smesa->NewGLState) {
+   if (smesa->NewGLState) {
+      SIS_FIREVERTICES(smesa);
       if (smesa->NewGLState & _NEW_TEXTURE) {
-        SIS_FIREVERTICES(smesa);
         sisUpdateTextureState(ctx);
       }
 
@@ -752,17 +784,30 @@ static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim )
    if (smesa->hw_primitive != hwprim) {
       SIS_FIREVERTICES(smesa);
       smesa->hw_primitive = hwprim;
+
       smesa->AGPParseSet &= ~(MASK_PsDataType | MASK_PsShadingMode);
-      smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand |
-        MASK_SetFirePosition | MASK_ShadingMode);
       smesa->AGPParseSet |= hw_prim_agp_type[hwprim];
-      smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim];
+
+      if (smesa->is6326) {
+        smesa->dwPrimitiveSet &= ~(MASK_6326_DrawPrimitiveCommand |
+           MASK_6326_SetFirePosition | MASK_6326_ShadingMode);
+        smesa->dwPrimitiveSet |= hwprim | hw_prim_6326_mmio_fire[hwprim];
+      } else {
+        smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand |
+           MASK_SetFirePosition | MASK_ShadingMode);
+        smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim];
+      }
+
       if (ctx->Light.ShadeModel == GL_FLAT) {
         smesa->AGPParseSet |= hw_prim_agp_shade[hwprim];
         smesa->dwPrimitiveSet |= hw_prim_mmio_shade[hwprim];
       } else {
         smesa->AGPParseSet |= MASK_PsShadingSmooth;
-        smesa->dwPrimitiveSet |= SHADE_GOURAUD;
+        if (smesa->is6326) {
+           smesa->dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_GOURAUD;
+        } else {
+           smesa->dwPrimitiveSet |= SHADE_GOURAUD;
+        }
       }
    }
 }
@@ -792,20 +837,19 @@ do {                                                                      \
    smesa->vertex_attrs[smesa->vertex_attr_count].offset = (N);         \
    smesa->vertex_attr_count++;                                         \
 } while (0)
-
-#define SIS_TCL_STATE_BITS \
-       (_TNL_BITS_TEX_ANY | _TNL_BIT_COLOR1 | _TNL_BIT_FOG)
                                
 static void sisRenderStart( GLcontext *ctx )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    sisContextPtr smesa = SIS_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   GLuint index = tnl->render_inputs;
+   DECLARE_RENDERINPUTS(index_bitset);
    GLuint AGPParseSet = smesa->AGPParseSet;
    GLboolean tex_fallback = GL_FALSE;
 
-   if (ctx->Color._DrawDestMask == DD_FRONT_LEFT_BIT && 
+   RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+
+   if (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT && 
       smesa->driDrawable->numClipRects != 0)
    {
       multipass_cliprect(ctx, 0);
@@ -828,46 +872,53 @@ static void sisRenderStart( GLcontext *ctx )
 
    AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat);
    AGPParseSet |= SiS_PS_HAS_XYZ | SiS_PS_HAS_DIFFUSE;
-   if (index & _TNL_BITS_TEX_ANY) {
+   if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
       EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT);
       AGPParseSet |= SiS_PS_HAS_W;
+      smesa->coloroffset = 4;
    } else {
       EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT);
+      smesa->coloroffset = 3;
    }
 
    EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA);
 
-   if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
+   smesa->specoffset = 0;
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
+       RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
       AGPParseSet |= SiS_PS_HAS_SPECULAR;
 
-      if (index & _TNL_BIT_COLOR1) {
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
         EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR);
+        smesa->specoffset = smesa->coloroffset + 1;
       } else {
         EMIT_PAD(3);
       }
 
-      if (index & _TNL_BIT_FOG)
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
         EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F);
-      else 
+      } else {
         EMIT_PAD(1);
+      }
    }
 
    /* projective textures are not supported by the hardware */
-   if (index & _TNL_BIT_TEX(0)) {
-      if (VB->TexCoordPtr[0]->size > 2)
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX0]->size > 2)
         tex_fallback = GL_TRUE;
       EMIT_ATTR(_TNL_ATTRIB_TEX0, EMIT_2F);
       AGPParseSet |= SiS_PS_HAS_UV0;
    }
-   if (index & _TNL_BIT_TEX(1)) {
-      if (VB->TexCoordPtr[1]->size > 2)
+   /* Will only hit tex1 on SiS300 */
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX1]->size > 2)
         tex_fallback = GL_TRUE;
       EMIT_ATTR(_TNL_ATTRIB_TEX1, EMIT_2F);
       AGPParseSet |= SiS_PS_HAS_UV1;
    }
    FALLBACK(smesa, SIS_FALLBACK_TEXTURE, tex_fallback);
 
-   if (smesa->last_tcl_state != index) {
+   if (!RENDERINPUTS_EQUAL( smesa->last_tcl_state_bitset, index_bitset )) {
       smesa->AGPParseSet = AGPParseSet;
 
       smesa->vertex_size =  _tnl_install_attrs( ctx, smesa->vertex_attrs, 
@@ -892,7 +943,10 @@ sisFlushPrimsLocked(sisContextPtr smesa)
    if (smesa->vb_cur == smesa->vb_last)
       return;
 
-   sisUpdateHWState(smesa->glCtx);
+   if (smesa->is6326)
+      sis6326UpdateHWState(smesa->glCtx);
+   else
+      sisUpdateHWState(smesa->glCtx);
 
    if (smesa->using_agp) {
       mWait3DCmdQueue(8);
@@ -918,6 +972,8 @@ sisFlushPrimsLocked(sisContextPtr smesa)
         mmio_index |= VERT_UV0;
       if (smesa->AGPParseSet & SiS_PS_HAS_UV1)
         mmio_index |= VERT_UV1;
+      if (smesa->is6326)
+        mmio_index |= VERT_6326;
 
       switch (smesa->AGPParseSet & MASK_PsDataType) {
       case MASK_PsPointList:
@@ -933,11 +989,13 @@ sisFlushPrimsLocked(sisContextPtr smesa)
         sis_emit_func = sis_tri_func_mmio[mmio_index];
         break;
       }
-      
-      mWait3DCmdQueue(1);
-      MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet);
+
+      if (!smesa->is6326) {
+        mWait3DCmdQueue(1);
+        MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet);
+      }
       while (smesa->vb_last < smesa->vb_cur) {
-        sis_emit_func(smesa, smesa->vb_last);
+        sis_emit_func(smesa, (char *)smesa->vb_last);
         smesa->vb_last += incr;
       }
       mWait3DCmdQueue(1);
@@ -960,6 +1018,28 @@ void sisFlushPrims(sisContextPtr smesa)
 /*           Transition to/from hardware rasterization.               */
 /**********************************************************************/
 
+static const char * const fallbackStrings[] = {
+   "Texture mode",
+   "Texture 0 mode",
+   "Texture 1 mode",
+   "Texture 0 env",    /* Note: unused */
+   "Texture 1 env",    /* Note: unused */
+   "glDrawBuffer(GL_FRONT_AND_BACK)",
+   "glEnable(GL_STENCIL) without hw stencil buffer",
+   "write mask",
+   "no_rast",
+};
+
+static const char *getFallbackString(GLuint bit)
+{
+   int i = 0;
+   while (bit > 1) {
+      i++;
+      bit >>= 1;
+   }
+   return fallbackStrings[i];
+}
+
 void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
@@ -972,6 +1052,10 @@ void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
         SIS_FIREVERTICES(smesa);
         _swsetup_Wakeup( ctx );
         smesa->RenderIndex = ~0;
+         if (SIS_DEBUG & DEBUG_FALLBACKS) {
+            fprintf(stderr, "SiS begin rasterization fallback: 0x%x %s\n",
+                    bit, getFallbackString(bit));
+         }
       }
    }
    else {
@@ -994,6 +1078,10 @@ void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
                             smesa->hw_viewport, 0 ); 
 
         smesa->NewGLState |= _SIS_NEW_RENDER_STATE;
+         if (SIS_DEBUG & DEBUG_FALLBACKS) {
+            fprintf(stderr, "SiS end rasterization fallback: 0x%x %s\n",
+                    bit, getFallbackString(bit));
+         }
       }
    }
 }
@@ -1047,11 +1135,6 @@ void sisInitTriFuncs( GLcontext *ctx )
       sis_vert_init_gwst0t1();
    }
 
-   if (driQueryOptionb(&smesa->optionCache, "fallback_force"))
-      sisFallback(ctx, SIS_FALLBACK_FORCE, 1);
-   else
-      sisFallback(ctx, SIS_FALLBACK_FORCE, 0);
-
    smesa->RenderIndex = ~0;
    smesa->NewGLState |= _SIS_NEW_RENDER_STATE;