Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / mesa / drivers / dri / sis / sis_screen.c
index 1d78801442d3b8fa0145e74c4e46bb58f710dacf..d90482f3d714473ddb4a9f0b8db56a16b9b18c79 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86$ */
 /**************************************************************************
 
 Copyright 2003 Eric Anholt
@@ -34,25 +33,97 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "context.h"
 #include "utils.h"
 #include "imports.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
 
 #include "sis_context.h"
 #include "sis_dri.h"
 #include "sis_lock.h"
+#include "sis_span.h"
 
 #include "xmlpool.h"
 
-const char __driConfigOptions[] =
+#include "GL/internal/dri_interface.h"
+
+#define SIS_AGP_DISABLE(def) \
+DRI_CONF_OPT_BEGIN(agp_disable,bool,def)                               \
+       DRI_CONF_DESC(en,"Disable AGP vertex dispatch")                 \
+DRI_CONF_OPT_END
+
+PUBLIC const char __driConfigOptions[] =
 DRI_CONF_BEGIN
+       DRI_CONF_SECTION_QUALITY
+               DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
+       DRI_CONF_SECTION_END
        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
+               SIS_AGP_DISABLE(true)
+               DRI_CONF_NO_RAST(false)
        DRI_CONF_SECTION_END
 DRI_CONF_END;
-static const GLuint __driNConfigOptions = 2;
+static const GLuint __driNConfigOptions = 3;
+
+extern const struct dri_extension card_extensions[];
+
+static __GLcontextModes *
+sisFillInModes(int bpp)
+{
+   __GLcontextModes *modes;
+   __GLcontextModes *m;
+   unsigned num_modes;
+   unsigned depth_buffer_factor;
+   unsigned back_buffer_factor;
+   GLenum fb_format;
+   GLenum fb_type;
+   static const GLenum back_buffer_modes[] = {
+      GLX_NONE, GLX_SWAP_UNDEFINED_OML
+   };
+   u_int8_t depth_bits_array[4];
+   u_int8_t stencil_bits_array[4];
+
+   depth_bits_array[0] = 0;
+   stencil_bits_array[0] = 0;
+   depth_bits_array[1] = 16;
+   stencil_bits_array[1] = 0;
+   depth_bits_array[2] = 24;
+   stencil_bits_array[2] = 8;
+   depth_bits_array[3] = 32;
+   stencil_bits_array[3] = 0;
+
+   depth_buffer_factor = 4;
+   back_buffer_factor = 2;
+
+   /* Last 4 is for GLX_TRUE_COLOR & GLX_DIRECT_COLOR, with/without accum */
+   num_modes = depth_buffer_factor * back_buffer_factor * 4;
+
+   if (bpp == 16) {
+      fb_format = GL_RGB;
+      fb_type = GL_UNSIGNED_SHORT_5_6_5;
+   } else {
+      fb_format = GL_BGRA;
+      fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+   }
+
+   modes = (*dri_interface->createContextModes)(num_modes, sizeof(__GLcontextModes));
+   m = modes;
+   if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array,
+                      stencil_bits_array, depth_buffer_factor,
+                      back_buffer_modes, back_buffer_factor,
+                      GLX_TRUE_COLOR)) {
+      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__);
+      return NULL;
+   }
+
+   if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array,
+                      stencil_bits_array, depth_buffer_factor,
+                      back_buffer_modes, back_buffer_factor,
+                      GLX_DIRECT_COLOR)) {
+      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__);
+      return NULL;
+   }
+
+   return modes;
+}
+
 
 /* Create the device specific screen private data struct.
  */
@@ -62,8 +133,10 @@ sisCreateScreen( __DRIscreenPrivate *sPriv )
    sisScreenPtr sisScreen;
    SISDRIPtr sisDRIPriv = (SISDRIPtr)sPriv->pDevPriv;
 
-   if ( !driCheckDriDdxDrmVersions( sPriv, "SiS", 4, 0, 0, 1, 1, 0 ) )
-      return NULL;
+   if (sPriv->devPrivSize != sizeof(SISDRIRec)) {
+      fprintf(stderr,"\nERROR!  sizeof(SISDRIRec) does not match passed size from device driver\n");
+      return GL_FALSE;
+   }
 
    /* Allocate the private area */
    sisScreen = (sisScreenPtr)CALLOC( sizeof(*sisScreen) );
@@ -73,11 +146,10 @@ sisCreateScreen( __DRIscreenPrivate *sPriv )
    sisScreen->screenX = sisDRIPriv->width;
    sisScreen->screenY = sisDRIPriv->height;
    sisScreen->cpp = sisDRIPriv->bytesPerPixel;
-   sisScreen->irqEnabled = sisDRIPriv->bytesPerPixel;
    sisScreen->deviceID = sisDRIPriv->deviceID;
    sisScreen->AGPCmdBufOffset = sisDRIPriv->AGPCmdBufOffset;
    sisScreen->AGPCmdBufSize = sisDRIPriv->AGPCmdBufSize;
-   sisScreen->sarea_priv_offset = sizeof(XF86DRISAREARec);
+   sisScreen->sarea_priv_offset = sizeof(drm_sarea_t);
 
    sisScreen->mmio.handle = sisDRIPriv->regs.handle;
    sisScreen->mmio.size   = sisDRIPriv->regs.size;
@@ -90,6 +162,7 @@ sisCreateScreen( __DRIscreenPrivate *sPriv )
 
    if (sisDRIPriv->agp.size) {
       sisScreen->agp.handle = sisDRIPriv->agp.handle;
+      sisScreen->agpBaseOffset = drmAgpBase(sPriv->fd);
       sisScreen->agp.size   = sisDRIPriv->agp.size;
       if ( drmMap( sPriv->fd, sisScreen->agp.handle, sisScreen->agp.size,
                    &sisScreen->agp.map ) )
@@ -125,6 +198,7 @@ sisDestroyScreen( __DRIscreenPrivate *sPriv )
    sPriv->private = NULL;
 }
 
+
 /* Create and initialize the Mesa and driver specific pixmap buffer
  * data.
  */
@@ -134,15 +208,23 @@ sisCreateBuffer( __DRIscreenPrivate *driScrnPriv,
                  const __GLcontextModes *mesaVis,
                  GLboolean isPixmap )
 {
+   /*sisScreenPtr screen = (sisScreenPtr) driScrnPriv->private;*/
+   struct gl_framebuffer *fb;
+
    if (isPixmap)
       return GL_FALSE; /* not implemented */
 
-   driDrawPriv->driverPrivate = (void *)_mesa_create_framebuffer(
-                                mesaVis,
-                                GL_FALSE,  /* software depth buffer? */
-                                mesaVis->stencilBits > 0,
-                                mesaVis->accumRedBits > 0,
-                                mesaVis->alphaBits > 0 ); /* XXX */
+   fb = _mesa_create_framebuffer(mesaVis);
+
+   _mesa_add_soft_renderbuffers(fb,
+                               GL_FALSE, /* color */
+                               GL_FALSE, /* depth */
+                               mesaVis->stencilBits > 0,
+                               mesaVis->accumRedBits > 0,
+                               GL_FALSE, /* alpha */
+                               GL_FALSE /* aux */);
+   driDrawPriv->driverPrivate = (void *) fb;
+
    return (driDrawPriv->driverPrivate != NULL);
 }
 
@@ -150,64 +232,33 @@ sisCreateBuffer( __DRIscreenPrivate *driScrnPriv,
 static void
 sisDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
 {
-   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
-}
-
-__inline__ static void
-sis_bitblt_copy_cmd (sisContextPtr smesa, ENGPACKET * pkt)
-{
-   GLint *lpdwDest, *lpdwSrc;
-   int i;
-
-   lpdwSrc = (GLint *) pkt;
-   lpdwDest = (GLint *) (GET_IOBase (smesa) + REG_SRC_ADDR);
-
-   mWait3DCmdQueue (10);
-
-   for (i = 0; i < 7; i++)
-      *lpdwDest++ = *lpdwSrc++;
-
-   MMIO(REG_CMD0, *(GLint *)&pkt->stdwCmd);
-   MMIO(REG_CommandQueue, -1);
+   _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
 }
 
 static void sisCopyBuffer( __DRIdrawablePrivate *dPriv )
 {
    sisContextPtr smesa = (sisContextPtr)dPriv->driContextPriv->driverPrivate;
    int i;
-   ENGPACKET stEngPacket;
-  
+
    while ((*smesa->FrameCountPtr) - MMIO_READ(0x8a2c) > SIS_MAX_FRAME_LENGTH)
       ;
 
    LOCK_HARDWARE();
 
-   stEngPacket.dwSrcBaseAddr = smesa->backOffset;
-   stEngPacket.dwSrcPitch = smesa->backPitch |
-      ((smesa->bytesPerPixel == 2) ? 0x80000000 : 0xc0000000);
-   stEngPacket.dwDestBaseAddr = 0;
-   stEngPacket.wDestPitch = smesa->frontPitch;
-   /* TODO: set maximum value? */
-   stEngPacket.wDestHeight = smesa->virtualY;
-
-   stEngPacket.stdwCmd.cRop = 0xcc;
-
-   if (smesa->blockWrite)
-      stEngPacket.stdwCmd.cCmd0 = CMD0_PAT_FG_COLOR;
-   else
-      stEngPacket.stdwCmd.cCmd0 = 0;
-   stEngPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC;
-
    for (i = 0; i < dPriv->numClipRects; i++) {
-      XF86DRIClipRectPtr box = &dPriv->pClipRects[i];
-      stEngPacket.stdwSrcPos.wY = box->y1 - dPriv->y;
-      stEngPacket.stdwSrcPos.wX = box->x1 - dPriv->x;
-      stEngPacket.stdwDestPos.wY = box->y1;
-      stEngPacket.stdwDestPos.wX = box->x1;
-
-      stEngPacket.stdwDim.wWidth = (GLshort) box->x2 - box->x1;
-      stEngPacket.stdwDim.wHeight = (GLshort) box->y2 - box->y1;
-      sis_bitblt_copy_cmd( smesa, &stEngPacket );
+      drm_clip_rect_t *box = &dPriv->pClipRects[i];
+
+      mWait3DCmdQueue(10);
+      MMIO(REG_SRC_ADDR, smesa->back.offset);
+      MMIO(REG_SRC_PITCH, smesa->back.pitch | ((smesa->bytesPerPixel == 4) ? 
+                          BLIT_DEPTH_32 : BLIT_DEPTH_16));
+      MMIO(REG_SRC_X_Y, ((box->x1 - dPriv->x) << 16) | (box->y1 - dPriv->y));
+      MMIO(REG_DST_X_Y, ((box->x1 - dPriv->x) << 16) | (box->y1 - dPriv->y));
+      MMIO(REG_DST_ADDR, smesa->front.offset);
+      MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->front.pitch);
+      MMIO(REG_WIDTH_HEIGHT, ((box->y2 - box->y1) << 16) | (box->x2 - box->x1));
+      MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_SRC);
+      MMIO(REG_CommandQueue, -1);
    }
 
    *(GLint *)(smesa->IOBase+0x8a2c) = *smesa->FrameCountPtr;
@@ -251,14 +302,6 @@ sisInitDriver( __DRIscreenPrivate *sPriv )
    return GL_TRUE;
 }
 
-/* Fullscreen mode change stub
- */
-static GLboolean
-sisOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
-{
-   return GL_TRUE;
-}
-
 static struct __DriverAPIRec sisAPI = {
    .InitDriver      = sisInitDriver,
    .DestroyScreen   = sisDestroyScreen,
@@ -269,8 +312,6 @@ static struct __DriverAPIRec sisAPI = {
    .SwapBuffers     = sisSwapBuffers,
    .MakeCurrent     = sisMakeCurrent,
    .UnbindContext   = sisUnbindContext,
-   .OpenFullScreen  = sisOpenCloseFullScreen,
-   .CloseFullScreen = sisOpenCloseFullScreen,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
    .WaitForMSC      = NULL,
@@ -279,25 +320,62 @@ static struct __DriverAPIRec sisAPI = {
 
 };
 
-/*
- * This is the bootstrap function for the driver.
- * The __driCreateScreen name is the symbol that libGL.so fetches.
- * Return:  pointer to a __DRIscreenPrivate.
+
+/**
+ * This is the bootstrap function for the driver.  libGL supplies all of the
+ * requisite information about the system, and the driver initializes itself.
+ * This routine also fills in the linked list pointed to by \c driver_modes
+ * with the \c __GLcontextModes that the driver can support for windows or
+ * pbuffers.
+ *
+ * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on 
+ *         failure.
  */
-#ifndef _SOLO
-void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
-                        int numConfigs, __GLXvisualConfig *config)
+PUBLIC
+void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn,
+                            __DRIscreen *psc,
+                            const __GLcontextModes *modes,
+                            const __DRIversion *ddx_version,
+                            const __DRIversion *dri_version,
+                            const __DRIversion *drm_version,
+                            const __DRIframebuffer *frame_buffer,
+                            drmAddress pSAREA, int fd,
+                            int internal_api_version,
+                            const __DRIinterfaceMethods * interface,
+                            __GLcontextModes **driver_modes )
+
 {
    __DRIscreenPrivate *psp;
-   psp = __driUtilCreateScreen( dpy, scrn, psc, numConfigs, config, &sisAPI );
+   static const __DRIversion ddx_expected = {0, 8, 0};
+   static const __DRIversion dri_expected = {4, 0, 0};
+   static const __DRIversion drm_expected = {1, 0, 0};
+   static const char *driver_name = "SiS";
+   dri_interface = interface;
+
+   if (!driCheckDriDdxDrmVersions2(driver_name, dri_version, &dri_expected,
+                                  ddx_version, &ddx_expected,
+                                  drm_version, &drm_expected)) {
+      return NULL;
+   }
+
+   psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
+                                 ddx_version, dri_version, drm_version,
+                                 frame_buffer, pSAREA, fd,
+                                 internal_api_version, &sisAPI);
+   if (psp != NULL) {
+      SISDRIPtr dri_priv = (SISDRIPtr)psp->pDevPriv;
+      *driver_modes = sisFillInModes(dri_priv->bytesPerPixel * 8);
+
+      /* Calling driInitExtensions here, with a NULL context pointer, does not actually
+       * enable the extensions.  It just makes sure that all the dispatch offsets for all
+       * the extensions that *might* be enables are known.  This is needed because the
+       * dispatch offsets need to be known when _mesa_context_create is called, but we can't
+       * enable the extensions until we have a context pointer.
+       *
+       * Hello chicken.  Hello egg.  How are you two today?
+       */
+      driInitExtensions( NULL, card_extensions, GL_FALSE );
+   }
+
    return (void *)psp;
 }
-#else
-void *__driCreateScreen(struct DRIDriverRec *driver,
-                        struct DRIDriverContextRec *driverContext)
-{
-   __DRIscreenPrivate *psp;
-   psp = __driUtilCreateScreen(driver, driverContext, &sisAPI);
-   return (void *) psp;
-}
-#endif