s/MAX_TEXTURE_LEVELS/SIS_MAX_TEXTURE_LEVELS/ and add assertion (bug 11806)
[mesa.git] / src / mesa / drivers / dri / sis / sis_context.c
index 6aa61944086835f46017dafbc76c4aac1c338c43..b21df0a61ea9212b1d6adba1040b68dfd3a4c613 100644 (file)
@@ -41,44 +41,69 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "sis_stencil.h"
 #include "sis_tex.h"
 #include "sis_tris.h"
-#include "sis_vb.h"
+#include "sis_alloc.h"
 
 #include "imports.h"
 #include "matrix.h"
 #include "extensions.h"
 #include "utils.h"
+#include "framebuffer.h"
+
+#include "drivers/common/driverfuncs.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
 
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
 
+#define need_GL_ARB_multisample
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_secondary_color
+#include "extension_helper.h"
+
+#ifndef SIS_DEBUG
+int SIS_DEBUG = 0;
+#endif
+
 int GlobalCurrentHwcx = -1;
 int GlobalHwcxCountBase = 1;
 int GlobalCmdQueueLen = 0;
 
-#include "xmlpool.h"
-
-const char __driConfigOptions[] =
-DRI_CONF_BEGIN
-       DRI_CONF_SECTION_DEBUG
-               DRI_CONF_OPT_BEGIN(agp_disable,bool,false)
-               DRI_CONF_DESC(en,"Disable AGP vertex dispatch")
-               DRI_CONF_OPT_END
-               DRI_CONF_OPT_BEGIN(fallback_force,bool,false)
-               DRI_CONF_DESC(en,"Force software fallback")
-               DRI_CONF_OPT_END
-       DRI_CONF_SECTION_END
-DRI_CONF_END;
-const GLuint __driNConfigOptions = 2;
-
-static const char * const card_extensions[] =
+struct dri_extension card_extensions[] =
 {
-   "GL_ARB_multitexture",
-   "GL_EXT_texture_lod_bias",
-   NULL
+    { "GL_ARB_multisample",                GL_ARB_multisample_functions },
+    { "GL_ARB_multitexture",               NULL },
+    { "GL_ARB_texture_border_clamp",       NULL },
+    { "GL_ARB_texture_compression",        GL_ARB_texture_compression_functions },
+    { "GL_ARB_texture_mirrored_repeat",    NULL },
+    { "GL_ARB_vertex_buffer_object",       GL_ARB_vertex_buffer_object_functions },
+    /*{ "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },*/
+    { "GL_EXT_texture_lod_bias",           NULL },
+    { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
+    { "GL_EXT_stencil_wrap",               NULL },
+    { "GL_MESA_ycbcr_texture",             NULL },
+    { "GL_NV_blend_square",                NULL },
+    { NULL,                                NULL }
+};
+
+struct dri_extension card_extensions_6326[] =
+{
+    { "GL_ARB_multisample",                GL_ARB_multisample_functions },
+    /*{ "GL_ARB_texture_border_clamp",       NULL },*/
+    { "GL_ARB_texture_compression",        GL_ARB_texture_compression_functions },
+    /*{ "GL_ARB_texture_mirrored_repeat",    NULL },*/
+    /*{ "GL_MESA_ycbcr_texture",             NULL },*/
+    { NULL,                                NULL }
+};
+
+static const struct dri_debug_control debug_control[] =
+{
+    { "fall",  DEBUG_FALLBACKS },
+    { NULL,    0 }
 };
 
 void
@@ -86,9 +111,15 @@ WaitEngIdle (sisContextPtr smesa)
 {
    GLuint engineState;
 
-   do {
-      engineState = MMIO_READ(REG_CommandQueue);
-   } while ((engineState & SiS_EngIdle) != SiS_EngIdle);
+   if (smesa->is6326) {
+      do {
+        engineState = MMIO_READ(REG_3D_EngineFire); /* XXX right reg? */
+      } while ((engineState & ENG_3DIDLEQE) != 0);
+   } else {
+      do {
+        engineState = MMIO_READ(REG_CommandQueue);
+      } while ((engineState & SiS_EngIdle) != SiS_EngIdle);
+   }
 }
 
 void
@@ -96,9 +127,15 @@ Wait2DEngIdle (sisContextPtr smesa)
 {
    GLuint engineState;
 
-   do {
-      engineState = MMIO_READ(REG_CommandQueue);
-   } while ((engineState & SiS_EngIdle2d) != SiS_EngIdle2d);
+   if (smesa->is6326) {
+      do {
+        engineState = MMIO_READ(REG_6326_BitBlt_Cmd);
+      } while ((engineState & BLT_BUSY) != 0);
+   } else {
+      do {
+        engineState = MMIO_READ(REG_CommandQueue);
+      } while ((engineState & SiS_EngIdle2d) != SiS_EngIdle2d);
+   }
 }
 
 /* To be called from mWait3DCmdQueue.  Separate function for profiling
@@ -107,12 +144,29 @@ Wait2DEngIdle (sisContextPtr smesa)
 void
 WaitingFor3dIdle(sisContextPtr smesa, int wLen)
 {
-   while (*(smesa->CurrentQueueLenPtr) < wLen) {
-      *(smesa->CurrentQueueLenPtr) =
-         (MMIO_READ(REG_CommandQueue) & MASK_QueueLen) - 20;
+   if (smesa->is6326) {
+      while (*(smesa->CurrentQueueLenPtr) < wLen) {
+        *(smesa->CurrentQueueLenPtr) =
+           ((GLuint)MMIO_READ(REG_3D_EngineFire) >> 16) * 2;
+      }
+   } else {
+      while (*(smesa->CurrentQueueLenPtr) < wLen) {
+        *(smesa->CurrentQueueLenPtr) =
+            (MMIO_READ(REG_CommandQueue) & MASK_QueueLen) - 20;
+      }
    }
 }
 
+void sisReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
+                          GLuint width, GLuint height)
+{
+   sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+   sisUpdateBufferSize(smesa);
+
+   _mesa_resize_framebuffer(ctx, drawbuffer, width, height);
+}
+
 GLboolean
 sisCreateContext( const __GLcontextModes *glVisual,
                  __DRIcontextPrivate *driContextPriv,
@@ -123,19 +177,27 @@ sisCreateContext( const __GLcontextModes *glVisual,
    sisContextPtr smesa;
    sisScreenPtr sisScreen;
    int i;
+   struct dd_function_table functions;
 
    smesa = (sisContextPtr)CALLOC( sizeof(*smesa) );
-   if ( smesa == NULL )
+   if (smesa == NULL)
       return GL_FALSE;
 
+   /* Init default driver functions then plug in our SIS-specific functions
+    * (the texture functions are especially important)
+    */
+   _mesa_init_driver_functions(&functions);
+   sisInitDriverFuncs(&functions);
+   sisInitTextureFuncs(&functions);
+
    /* Allocate the Mesa context */
    if (sharedContextPrivate)
       shareCtx = ((sisContextPtr)sharedContextPrivate)->glCtx;
    else 
       shareCtx = NULL;
-   smesa->glCtx = _mesa_create_context( glVisual, shareCtx, (void *) smesa,
-      GL_TRUE);
-   if (smesa->glCtx == NULL) {
+   smesa->glCtx = _mesa_create_context( glVisual, shareCtx,
+                                        &functions, (void *) smesa);
+   if (!smesa->glCtx) {
       FREE(smesa);
       return GL_FALSE;
    }
@@ -144,6 +206,7 @@ sisCreateContext( const __GLcontextModes *glVisual,
 
    sisScreen = smesa->sisScreen = (sisScreenPtr)(sPriv->private);
 
+   smesa->is6326 = GL_FALSE; /* XXX */
    smesa->driContext = driContextPriv;
    smesa->driScreen = sPriv;
    smesa->driDrawable = NULL;
@@ -156,19 +219,14 @@ sisCreateContext( const __GLcontextModes *glVisual,
    smesa->bytesPerPixel = sisScreen->cpp;
    smesa->IOBase = sisScreen->mmio.map;
    smesa->Chipset = sisScreen->deviceID;
-   smesa->irqEnabled = sisScreen->irqEnabled;
 
    smesa->FbBase = sPriv->pFB;
    smesa->displayWidth = sPriv->fbWidth;
-   smesa->frontPitch = sPriv->fbStride;
+   smesa->front.pitch = sPriv->fbStride;
 
    smesa->sarea = (SISSAREAPriv *)((char *)sPriv->pSAREA +
                                   sisScreen->sarea_priv_offset);
 
-#if defined(SIS_DUMP)
-   IOBase4Debug = GET_IOBase (smesa);
-#endif
-
    /* support ARGB8888 and RGB565 */
    switch (smesa->bytesPerPixel)
    {
@@ -187,13 +245,27 @@ sisCreateContext( const __GLcontextModes *glVisual,
       smesa->colorFormat = DST_FORMAT_RGB_565;
       break;
    default:
-      assert (0);
+      sis_fatal_error("Bad bytesPerPixel %d.\n", smesa->bytesPerPixel);
    }
 
+   if (smesa->is6326) {
+      ctx->Const.MaxTextureUnits = 1;
+      ctx->Const.MaxTextureLevels = 9;
+   } else {
+      ctx->Const.MaxTextureUnits = 2;
+      ctx->Const.MaxTextureLevels = 11;
+   }
+   ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
+   ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
+
    /* Parse configuration files */
    driParseConfigFiles (&smesa->optionCache, &sisScreen->optionCache,
                        sisScreen->driScreen->myNum, "sis");
 
+#if DO_DEBUG
+   SIS_DEBUG = driParseDebugString(getenv("SIS_DEBUG"), debug_control);
+#endif
+
    /* TODO: index mode */
 
    smesa->CurrentQueueLenPtr = &(smesa->sarea->QueueLength);
@@ -202,20 +274,31 @@ sisCreateContext( const __GLcontextModes *glVisual,
    /* set AGP */
    smesa->AGPSize = sisScreen->agp.size;
    smesa->AGPBase = sisScreen->agp.map;
-   smesa->AGPAddr = sisScreen->agp.handle;
+   smesa->AGPAddr = sisScreen->agpBaseOffset;
 
-   /* set AGP command buffer */
-   if (smesa->AGPSize != 0 && sisScreen->AGPCmdBufSize != 0 &&
+   /* Create AGP command buffer */
+   if (smesa->AGPSize != 0 && 
       !driQueryOptionb(&smesa->optionCache, "agp_disable"))
-   {   
-      smesa->AGPCmdBufBase = smesa->AGPBase + sisScreen->AGPCmdBufOffset;
-      smesa->AGPCmdBufAddr = smesa->AGPAddr + sisScreen->AGPCmdBufOffset;
-      smesa->AGPCmdBufSize = sisScreen->AGPCmdBufSize;
-
-      smesa->pAGPCmdBufNext = (GLint *)&(smesa->sarea->AGPCmdBufNext);
-      smesa->AGPCmdModeEnabled = GL_TRUE;
-   } else {
-      smesa->AGPCmdModeEnabled = GL_FALSE;
+   {
+      smesa->vb = sisAllocAGP(smesa, 64 * 1024, &smesa->vb_agp_handle);
+      if (smesa->vb != NULL) {
+        smesa->using_agp = GL_TRUE;
+        smesa->vb_cur = smesa->vb;
+        smesa->vb_last = smesa->vb;
+        smesa->vb_end = smesa->vb + 64 * 1024;
+        smesa->vb_agp_offset = ((long)smesa->vb - (long)smesa->AGPBase +
+           (long)smesa->AGPAddr);
+      }
+   }
+   if (!smesa->using_agp) {
+      smesa->vb = malloc(64 * 1024);
+      if (smesa->vb == NULL) {
+        FREE(smesa);
+        return GL_FALSE;
+      }
+      smesa->vb_cur = smesa->vb;
+      smesa->vb_last = smesa->vb;
+      smesa->vb_end = smesa->vb + 64 * 1024;
    }
 
    smesa->GlobalFlag = 0L;
@@ -225,33 +308,40 @@ sisCreateContext( const __GLcontextModes *glVisual,
    /* Initialize the software rasterizer and helper modules.
     */
    _swrast_CreateContext( ctx );
-   _ac_CreateContext( ctx );
+   _vbo_CreateContext( ctx );
    _tnl_CreateContext( ctx );
    _swsetup_CreateContext( ctx );
 
    _swrast_allow_pixel_fog( ctx, GL_TRUE );
    _swrast_allow_vertex_fog( ctx, GL_FALSE );
+   _tnl_allow_pixel_fog( ctx, GL_TRUE );
+   _tnl_allow_vertex_fog( ctx, GL_FALSE );
 
-   sisDDInitStateFuncs( ctx );
-   sisDDInitState( smesa );    /* Initializes smesa->zFormat, important */
-   sisInitVB( ctx );
+   /* XXX these should really go right after _mesa_init_driver_functions() */
+   if (smesa->is6326) {
+      sis6326DDInitStateFuncs( ctx );
+      sis6326DDInitState( smesa ); /* Initializes smesa->zFormat, important */
+   } else {
+      sisDDInitStateFuncs( ctx );
+      sisDDInitState( smesa ); /* Initializes smesa->zFormat, important */
+      sisDDInitStencilFuncs( ctx );
+   }
    sisInitTriFuncs( ctx );
-   sisDDInitDriverFuncs( ctx );
    sisDDInitSpanFuncs( ctx );
-   sisDDInitStencilFuncs( ctx );
-   sisDDInitTextureFuncs( ctx );
 
    driInitExtensions( ctx, card_extensions, GL_FALSE );
 
-   /* TODO */
-   /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
-   smesa->blockWrite = GL_FALSE;
-
    for (i = 0; i < SIS_MAX_TEXTURES; i++) {
       smesa->TexStates[i] = 0;
       smesa->PrevTexFormat[i] = 0;
    }
 
+   if (driQueryOptionb(&smesa->optionCache, "no_rast")) {
+      fprintf(stderr, "disabling 3D acceleration\n");
+      FALLBACK(smesa, SIS_FALLBACK_DISABLE, 1);
+   }
+   smesa->texture_depth = driQueryOptioni(&smesa->optionCache, "texture_depth");
+
    return GL_TRUE;
 }
 
@@ -265,9 +355,12 @@ sisDestroyContext ( __DRIcontextPrivate *driContextPriv )
    if ( smesa != NULL ) {
       _swsetup_DestroyContext( smesa->glCtx );
       _tnl_DestroyContext( smesa->glCtx );
-      _ac_DestroyContext( smesa->glCtx );
+      _vbo_DestroyContext( smesa->glCtx );
       _swrast_DestroyContext( smesa->glCtx );
 
+      if (smesa->using_agp)
+        sisFreeAGP(smesa, smesa->vb_agp_handle);
+
       /* free the Mesa context */
       /* XXX: Is the next line needed?  The DriverCtx (smesa) reference is
        * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
@@ -289,6 +382,7 @@ sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
       GET_CURRENT_CONTEXT(ctx);
       sisContextPtr oldSisCtx = ctx ? SIS_CONTEXT(ctx) : NULL;
       sisContextPtr newSisCtx = (sisContextPtr) driContextPriv->driverPrivate;
+      struct gl_framebuffer *drawBuffer, *readBuffer;
 
       if ( newSisCtx != oldSisCtx) {
          newSisCtx->GlobalFlag = GFLAG_ALL;
@@ -296,19 +390,15 @@ sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
 
       newSisCtx->driDrawable = driDrawPriv;
 
-      _mesa_make_current2( newSisCtx->glCtx,
-                         (GLframebuffer *) driDrawPriv->driverPrivate,
-                         (GLframebuffer *) driReadPriv->driverPrivate );
+      drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
+      readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
+
+      _mesa_make_current( newSisCtx->glCtx, drawBuffer, readBuffer );
 
       sisUpdateBufferSize( newSisCtx );
       sisUpdateClipping( newSisCtx->glCtx );
-
-      if ( newSisCtx->glCtx->Viewport.Width == 0 ) {
-         _mesa_set_viewport(newSisCtx->glCtx, 0, 0,
-                            driDrawPriv->w, driDrawPriv->h);
-      }
    } else {
-      _mesa_make_current( 0, 0 );
+      _mesa_make_current( NULL, NULL, NULL );
    }
 
    return GL_TRUE;
@@ -513,10 +603,126 @@ sis_update_texture_state (sisContextPtr smesa)
 }
 
 void
-sis_fatal_error (void)
+sis6326_update_render_state( sisContextPtr smesa )
+{
+   __GLSiSHardware *prev = &smesa->prev;
+
+   mWait3DCmdQueue (45);
+
+   if (smesa->GlobalFlag & GFLAG_ENABLESETTING) {
+      if (!smesa->clearTexCache) {
+        MMIO(REG_6326_3D_TEnable, prev->hwCapEnable);
+      } else {
+        MMIO(REG_6326_3D_TEnable, prev->hwCapEnable & ~S_ENABLE_TextureCache);
+        MMIO(REG_6326_3D_TEnable, prev->hwCapEnable);
+        smesa->clearTexCache = GL_FALSE;
+      }
+   }
+
+   /* Z Setting */
+   if (smesa->GlobalFlag & GFLAG_ZSETTING) {
+      MMIO(REG_6326_3D_ZSet, prev->hwZ);
+      MMIO(REG_6326_3D_ZAddress, prev->hwOffsetZ);
+   }
+
+   /* Alpha Setting */
+   if (smesa->GlobalFlag & GFLAG_ALPHASETTING)
+      MMIO(REG_6326_3D_AlphaSet, prev->hwAlpha);
+
+   if (smesa->GlobalFlag & GFLAG_DESTSETTING) {
+      MMIO(REG_6326_3D_DstSet, prev->hwDstSet);
+      MMIO(REG_6326_3D_DstAddress, prev->hwOffsetDest);
+   }
+
+   /* Fog Setting */
+   if (smesa->GlobalFlag & GFLAG_FOGSETTING) {
+      MMIO(REG_6326_3D_FogSet, prev->hwFog);
+   }
+
+   /* Miscellaneous Setting */
+   if (smesa->GlobalFlag & GFLAG_DSTBLEND)
+      MMIO(REG_6326_3D_DstSrcBlendMode, prev->hwDstSrcBlend);
+
+   if (smesa->GlobalFlag & GFLAG_CLIPPING) {
+      MMIO(REG_6326_3D_ClipTopBottom, prev->clipTopBottom);
+      MMIO(REG_6326_3D_ClipLeftRight, prev->clipLeftRight);
+   }
+
+  smesa->GlobalFlag &= ~GFLAG_RENDER_STATES;
+}
+
+void
+sis6326_update_texture_state (sisContextPtr smesa)
 {
-   /* free video memory, or the framebuffer device will do it automatically */
+   __GLSiSHardware *prev = &smesa->prev;
+
+   mWait3DCmdQueue (55);
+   if (smesa->clearTexCache || (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS)) {
+      MMIO(REG_6326_3D_TEnable, prev->hwCapEnable & ~S_ENABLE_TextureCache);
+      MMIO(REG_6326_3D_TEnable, prev->hwCapEnable);
+      smesa->clearTexCache = GL_FALSE;
+   }
+
+   /* Texture Setting */
+   if (smesa->GlobalFlag & CFLAG_TEXTURERESET)
+      MMIO(REG_6326_3D_TextureSet, prev->texture[0].hwTextureSet);
 
-   fprintf(stderr, "Fatal errors in sis_dri.so\n");
-   exit (-1);
+   if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP)
+      MMIO(REG_6326_3D_TextureWidthHeight, prev->texture[0].hwTexWidthHeight);
+
+  /*
+  MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
+  MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
+  */
+
+   if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR)
+      MMIO(REG_6326_3D_TextureBorderColor, prev->texture[0].hwTextureBorderColor);
+
+   if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS) {
+      switch ((prev->texture[0].hwTextureSet & MASK_6326_TextureLevel) >> 8)
+      {
+      case 9:
+         MMIO(REG_6326_3D_TextureAddress9, prev->texture[0].texOffset9);
+         /* FALLTHROUGH */
+      case 8:
+         MMIO(REG_6326_3D_TextureAddress8, prev->texture[0].texOffset8);
+         MMIO(REG_6326_3D_TexturePitch89, prev->texture[0].texPitch89);
+         /* FALLTHROUGH */
+      case 7:
+         MMIO(REG_6326_3D_TextureAddress7, prev->texture[0].texOffset7);
+         /* FALLTHROUGH */
+      case 6:
+         MMIO(REG_6326_3D_TextureAddress6, prev->texture[0].texOffset6);
+         MMIO(REG_6326_3D_TexturePitch67, prev->texture[0].texPitch67);
+         /* FALLTHROUGH */
+      case 5:
+         MMIO(REG_6326_3D_TextureAddress5, prev->texture[0].texOffset5);
+         /* FALLTHROUGH */
+      case 4:
+         MMIO(REG_6326_3D_TextureAddress4, prev->texture[0].texOffset4);
+         MMIO(REG_6326_3D_TexturePitch45, prev->texture[0].texPitch45);
+         /* FALLTHROUGH */
+      case 3:
+         MMIO(REG_6326_3D_TextureAddress3, prev->texture[0].texOffset3);
+         /* FALLTHROUGH */
+      case 2:
+         MMIO(REG_6326_3D_TextureAddress2, prev->texture[0].texOffset2);
+         MMIO(REG_6326_3D_TexturePitch23, prev->texture[0].texPitch23);
+         /* FALLTHROUGH */
+      case 1:
+         MMIO(REG_6326_3D_TextureAddress1, prev->texture[0].texOffset1);
+         /* FALLTHROUGH */
+      case 0:
+        MMIO(REG_6326_3D_TextureAddress0, prev->texture[0].texOffset0);
+        MMIO(REG_6326_3D_TexturePitch01, prev->texture[0].texPitch01);
+        break;
+      }
+   }
+
+   /* texture environment */
+   if (smesa->GlobalFlag & GFLAG_TEXTUREENV) {
+      MMIO(REG_6326_3D_TextureBlendSet, prev->hwTexBlendSet);
+   }
+
+   smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES;
 }