raedon/r200/r300: mega-FBO commits.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_screen.c
index 46a946b1c9463a134906238e23971be05bc41410..4725f38ae83c8882f3facb52f58af74f52c70b39 100644 (file)
@@ -335,6 +335,11 @@ static const __DRItexOffsetExtension radeonTexOffsetExtension = {
     { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
     radeonSetTexOffset,
 };
+
+static const __DRItexBufferExtension radeonTexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+   radeonSetTexBuffer,
+};
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
@@ -349,6 +354,11 @@ static const __DRItexOffsetExtension r200texOffsetExtension = {
     { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
    r200SetTexOffset,
 };
+
+static const __DRItexBufferExtension r200TexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+   r200SetTexBuffer,
+};
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
@@ -570,6 +580,12 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
       screen->chip_family = CHIP_FAMILY_RS400;
       break;
 
+   case PCI_CHIP_RS600_793F:
+   case PCI_CHIP_RS600_7941:
+   case PCI_CHIP_RS600_7942:
+      screen->chip_family = CHIP_FAMILY_RS600;
+      break;
+
    case PCI_CHIP_RS690_791E:
    case PCI_CHIP_RS690_791F:
       screen->chip_family = CHIP_FAMILY_RS690;
@@ -716,7 +732,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
    unsigned char *RADEONMMIO = NULL;
    int i;
    int ret;
-   uint32_t temp;
+   uint32_t temp = 0;
 
    if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) {
       fprintf(stderr,"\nERROR!  sizeof(RADEONDRIRec) does not match passed size from device driver\n");
@@ -881,7 +897,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
    ret = radeonGetParam( sPriv->fd, RADEON_PARAM_FB_LOCATION,
                          &temp);
    if (ret) {
-       if (screen->chip_family < CHIP_FAMILY_RS690 && !screen->kernel_mm)
+       if (screen->chip_family < CHIP_FAMILY_RS600 && !screen->kernel_mm)
           screen->fbLocation      = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff) << 16;
        else {
            FREE( screen );
@@ -892,7 +908,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
        screen->fbLocation = (temp & 0xffff) << 16;
    }
 
-   if (screen->chip_family >= CHIP_FAMILY_RV515) {
+   if (screen->chip_family >= CHIP_FAMILY_R300) {
        ret = radeonGetParam( sPriv->fd, RADEON_PARAM_NUM_GB_PIPES,
                             &temp);
        if (ret) {
@@ -1070,6 +1086,9 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
    else
       screen->chip_flags |= RADEON_CLASS_R300;
 
+   if (getenv("R300_NO_TCL"))
+     screen->chip_flags &= ~RADEON_CHIPSET_TCL;
+
    i = 0;
    screen->extensions[i++] = &driCopySubBufferExtension.base;
    screen->extensions[i++] = &driFrameTrackingExtension.base;
@@ -1081,18 +1100,17 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
    }
 
 #if !RADEON_COMMON
-   screen->extensions[i++] = &radeonTexOffsetExtension.base;
+   screen->extensions[i++] = &radeonTexBufferExtension.base;
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
    if (IS_R200_CLASS(screen))
        screen->extensions[i++] = &r200AllocateExtension.base;
 
-   screen->extensions[i++] = &r200texOffsetExtension.base;
+   screen->extensions[i++] = &r200TexBufferExtension.base;
 #endif
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
-   //screen->extensions[i++] = &r300texOffsetExtension.base;
    screen->extensions[i++] = &r300TexBufferExtension.base;
 #endif
 
@@ -1160,89 +1178,7 @@ radeonInitDriver( __DRIscreenPrivate *sPriv )
     return GL_TRUE;
 }
 
-static GLboolean
-radeon_alloc_window_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
-                           GLenum intFormat, GLuint w, GLuint h)
-{
-    rb->Width = w;
-    rb->Height = h;
-    rb->_ActualFormat = intFormat;
-
-    return GL_TRUE;
-}
-
 
-static struct radeon_renderbuffer *
-radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
-{
-    struct radeon_renderbuffer *ret;
-
-    ret = CALLOC_STRUCT(radeon_renderbuffer);
-    if (!ret)
-       return NULL;
-
-    _mesa_init_renderbuffer(&ret->base, 0);
-
-    /* XXX format junk */
-    switch (format) {
-       case GL_RGB5:
-           ret->base._ActualFormat = GL_RGB5;
-           ret->base._BaseFormat = GL_RGBA;
-           ret->base.RedBits = 5;
-           ret->base.GreenBits = 6;
-           ret->base.BlueBits = 5;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_RGBA8:
-           ret->base._ActualFormat = GL_RGBA8;
-           ret->base._BaseFormat = GL_RGBA;
-           ret->base.RedBits = 8;
-           ret->base.GreenBits = 8;
-           ret->base.BlueBits = 8;
-           ret->base.AlphaBits = 8;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_STENCIL_INDEX8_EXT:
-           ret->base._ActualFormat = GL_STENCIL_INDEX8_EXT;
-           ret->base._BaseFormat = GL_STENCIL_INDEX;
-           ret->base.StencilBits = 8;
-           ret->base.DataType = GL_UNSIGNED_BYTE;
-           break;
-       case GL_DEPTH_COMPONENT16:
-           ret->base._ActualFormat = GL_DEPTH_COMPONENT16;
-           ret->base._BaseFormat = GL_DEPTH_COMPONENT;
-           ret->base.DepthBits = 16;
-           ret->base.DataType = GL_UNSIGNED_SHORT;
-           break;
-       case GL_DEPTH_COMPONENT24:
-           ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-           ret->base._BaseFormat = GL_DEPTH_COMPONENT;
-           ret->base.DepthBits = 24;
-           ret->base.DataType = GL_UNSIGNED_INT;
-           break;
-       case GL_DEPTH24_STENCIL8_EXT:
-           ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
-           ret->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
-           ret->base.DepthBits = 24;
-           ret->base.StencilBits = 8;
-           ret->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
-           break;
-       default:
-           fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format);
-           _mesa_delete_renderbuffer(&ret->base);
-           return NULL;
-    }
-
-    ret->dPriv = driDrawPriv;
-    ret->base.InternalFormat = format;
-
-    ret->base.AllocStorage = radeon_alloc_window_storage;
-
-    radeonSetSpanFunctions(ret);
-
-    ret->bo = NULL;
-    return ret;
-}
 
 /**
  * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
@@ -1256,7 +1192,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
                     const __GLcontextModes *mesaVis,
                     GLboolean isPixmap )
 {
-   radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
+    radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
 
     const GLboolean swDepth = GL_FALSE;
     const GLboolean swAlpha = GL_FALSE;
@@ -1264,54 +1200,56 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
     const GLboolean swStencil = mesaVis->stencilBits > 0 &&
        mesaVis->depthBits != 24;
     GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8);
-    GLenum depthFormat = GL_NONE;
-    struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
+    struct radeon_framebuffer *rfb;
 
-    if (mesaVis->depthBits == 16)
-       depthFormat = GL_DEPTH_COMPONENT16;
-    else if (mesaVis->depthBits == 24)
-       depthFormat = GL_DEPTH_COMPONENT24;
+    if (isPixmap)
+      return GL_FALSE; /* not implemented */
+
+    rfb = CALLOC_STRUCT(radeon_framebuffer);
+    if (!rfb)
+      return GL_FALSE;
+
+    _mesa_initialize_framebuffer(&rfb->base, mesaVis);
 
     /* front color renderbuffer */
-    {
-       struct radeon_renderbuffer *front =
-           radeon_create_renderbuffer(rgbFormat, driDrawPriv);
-       _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &front->base);
-       front->has_surface = 1;
-    }
+    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
+    _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
+    rfb->color_rb[0]->has_surface = 1;
 
     /* back color renderbuffer */
     if (mesaVis->doubleBufferMode) {
-       struct radeon_renderbuffer *back =
-           radeon_create_renderbuffer(rgbFormat, driDrawPriv);
-       _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &back->base);
-       back->has_surface = 1;
+      rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
+       rfb->color_rb[1]->has_surface = 1;
     }
 
-    /* depth renderbuffer */
-    if (depthFormat != GL_NONE) {
-       struct radeon_renderbuffer *depth =
-           radeon_create_renderbuffer(depthFormat, driDrawPriv);
-       _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth->base);
+    if (mesaVis->depthBits == 24) {
+      if (mesaVis->stencilBits == 8) {
+       struct radeon_renderbuffer *depthStencilRb = radeon_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base);
+       depthStencilRb->has_surface = screen->depthHasSurface;
+      } else {
+       /* depth renderbuffer */
+       struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT24, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
+       depth->has_surface = screen->depthHasSurface;
+      }
+    } else if (mesaVis->depthBits == 16) {
+      /* just 16-bit depth buffer, no hw stencil */
+       struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT16, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
        depth->has_surface = screen->depthHasSurface;
     }
 
-    /* stencil renderbuffer */
-    if (mesaVis->stencilBits > 0 && !swStencil) {
-       struct radeon_renderbuffer *stencil =
-           radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv);
-       _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencil->base);
-       stencil->has_surface = screen->depthHasSurface;
-    }
-
-    _mesa_add_soft_renderbuffers(fb,
+    _mesa_add_soft_renderbuffers(&rfb->base,
            GL_FALSE, /* color */
            swDepth,
            swStencil,
            swAccum,
            swAlpha,
            GL_FALSE /* aux */);
-    driDrawPriv->driverPrivate = (void *) fb;
+    driDrawPriv->driverPrivate = (void *) rfb;
 
     return (driDrawPriv->driverPrivate != NULL);
 }
@@ -1319,26 +1257,26 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
 static void
 radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
 {
-       struct radeon_renderbuffer *rb;
-       GLframebuffer *fb;
+    struct radeon_renderbuffer *rb;
+    struct radeon_framebuffer *rfb;
     
-    fb = (void*)driDrawPriv->driverPrivate;
-    rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+    rfb = (void*)driDrawPriv->driverPrivate;
+    rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
     if (rb && rb->bo) {
         radeon_bo_unref(rb->bo);
         rb->bo = NULL;
     }
-    rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+    rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
     if (rb && rb->bo) {
         radeon_bo_unref(rb->bo);
         rb->bo = NULL;
     }
-    rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+    rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
     if (rb && rb->bo) {
         radeon_bo_unref(rb->bo);
         rb->bo = NULL;
     }
-   _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
+    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
 
 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
@@ -1438,6 +1376,7 @@ radeonInitScreen(__DRIscreenPrivate *psp)
                             (dri_priv->bpp == 16) ? 16 : 24,
                             (dri_priv->bpp == 16) ? 0  : 8, 1);
 }
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
 /**
  * This is the driver specific part of the createNewScreen entry point.
@@ -1448,6 +1387,18 @@ radeonInitScreen(__DRIscreenPrivate *psp)
 static const
 __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
 {
+   GLenum fb_format[3];
+   GLenum fb_type[3];
+   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
+    * support pageflipping at all.
+    */
+   static const GLenum back_buffer_modes[] = {
+     GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
+   };
+   uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
+   int color;
+   __DRIconfig **configs = NULL;
+
    /* 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
@@ -1470,9 +1421,50 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
    if (!radeonInitDriver(psp)) {
        return NULL;
     }
+   depth_bits[0] = 0;
+   stencil_bits[0] = 0;
+   depth_bits[1] = 16;
+   stencil_bits[1] = 0;
+   depth_bits[2] = 24;
+   stencil_bits[2] = 0;
+   depth_bits[3] = 24;
+   stencil_bits[3] = 8;
+
+   msaa_samples_array[0] = 0;
+
+   fb_format[0] = GL_RGB;
+   fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
+
+   fb_format[1] = GL_BGR;
+   fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
+
+   fb_format[2] = GL_BGRA;
+   fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
+
+   for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
+      __DRIconfig **new_configs;
+
+      new_configs = driCreateConfigs(fb_format[color], fb_type[color],
+                                    depth_bits,
+                                    stencil_bits,
+                                    ARRAY_SIZE(depth_bits),
+                                    back_buffer_modes,
+                                    ARRAY_SIZE(back_buffer_modes),
+                                    msaa_samples_array,
+                                    ARRAY_SIZE(msaa_samples_array));
+      if (configs == NULL)
+        configs = new_configs;
+      else
+        configs = driConcatConfigs(configs, new_configs);
+   }
 
-   /* for now fill in all modes */
-   return radeonFillInModes( psp, 24, 24, 8, 1);
+   if (configs == NULL) {
+      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+              __LINE__);
+      return NULL;
+   }
+
+   return (const __DRIconfig **)configs;
 }
 
 /**
@@ -1481,21 +1473,21 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
 static int
 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
 {
-   radeonContextPtr  rmesa;
+    struct radeon_framebuffer *rfb;
 
-   if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
-       || (dPriv->driContextPriv->driverPrivate == NULL)
-       || (sInfo == NULL) ) {
-      return -1;
+    if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
+        || (dPriv->driContextPriv->driverPrivate == NULL)
+        || (sInfo == NULL) ) {
+       return -1;
    }
 
-   rmesa = dPriv->driContextPriv->driverPrivate;
-   sInfo->swap_count = rmesa->swap_count;
-   sInfo->swap_ust = rmesa->swap_ust;
-   sInfo->swap_missed_count = rmesa->swap_missed_count;
+    rfb = dPriv->driverPrivate;
+    sInfo->swap_count = rfb->swap_count;
+    sInfo->swap_ust = rfb->swap_ust;
+    sInfo->swap_missed_count = rfb->swap_missed_count;
 
    sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
-       ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
+       ? driCalculateSwapUsage( dPriv, 0, rfb->swap_missed_ust )
        : 0.0;
 
    return 0;