st/dri, st/xorg: fix buffers that have attachements of different depth
authorZack Rusin <zackr@vmware.com>
Thu, 11 Feb 2010 00:00:35 +0000 (19:00 -0500)
committerZack Rusin <zack@kde.org>
Fri, 12 Feb 2010 21:00:22 +0000 (16:00 -0500)
we actually need to specify the formats for different attachements, otherwise
if the color buffer is 24bpp and the app asks for 16bpp depth buffer than
we end up fetching the depth from the drawable which is 24bpp and end up
creating the wrong depth buffer. use the new getBuffersWithFormat extension
to pass the depth correctly.

src/gallium/state_trackers/dri/dri_drawable.c
src/gallium/state_trackers/xorg/xorg_dri2.c

index ff21f2f9580ff59bc30dd5431504a40b5d389d5f..97277c05072dc8145af38530ffac7a15f407bf33 100644 (file)
@@ -132,14 +132,22 @@ dri_get_buffers(__DRIdrawable * dPriv)
    boolean have_depth = FALSE;
    int i, count;
 
-   buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
-                                                    &dri_drawable->w,
-                                                    &dri_drawable->h,
-                                                    drawable->attachments,
-                                                    drawable->
-                                                    num_attachments, &count,
-                                                    dri_drawable->
-                                                    loaderPrivate);
+   if ((dri_screen->dri2.loader
+        && (dri_screen->dri2.loader->base.version > 2)
+        && (dri_screen->dri2.loader->getBuffersWithFormat != NULL)))
+      buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
+                (dri_drawable, &dri_drawable->w, &dri_drawable->h,
+                 drawable->attachments, drawable->num_attachments,
+                 &count, dri_drawable->loaderPrivate);
+   else
+      buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
+                                                        &dri_drawable->w,
+                                                        &dri_drawable->h,
+                                                        drawable->attachments,
+                                                        drawable->
+                                                        num_attachments, &count,
+                                                        dri_drawable->
+                                                        loaderPrivate);
 
    if (buffers == NULL) {
       return;
@@ -346,12 +354,12 @@ dri_create_buffer(__DRIscreen * sPriv,
    case 24:
       if (visual->stencilBits == 0) {
         drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
-           PIPE_FORMAT_X8Z24_UNORM:
-           PIPE_FORMAT_Z24X8_UNORM;
+                                          PIPE_FORMAT_X8Z24_UNORM:
+                                          PIPE_FORMAT_Z24X8_UNORM;
       } else {
         drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
-           PIPE_FORMAT_S8Z24_UNORM:
-           PIPE_FORMAT_Z24S8_UNORM;
+                                          PIPE_FORMAT_S8Z24_UNORM:
+                                          PIPE_FORMAT_Z24S8_UNORM;
       }
       break;
    case 32:
@@ -375,23 +383,49 @@ dri_create_buffer(__DRIscreen * sPriv,
    /* setup dri2 buffers information */
    /* TODO incase of double buffer visual, delay fake creation */
    i = 0;
-   drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-   if (!screen->auto_fake_front)
-      drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
-   if (visual->doubleBufferMode)
-      drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-   if (visual->depthBits && visual->stencilBits)
-      drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
-   else if (visual->depthBits)
-      drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
-   else if (visual->stencilBits)
-      drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
-   drawable->num_attachments = i;
+   if (sPriv->dri2.loader
+       && (sPriv->dri2.loader->base.version > 2)
+       && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
+      drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+      drawable->attachments[i++] = visual->rgbBits;
+      if (!screen->auto_fake_front)  {
+         drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
+         drawable->attachments[i++] = visual->rgbBits;
+      }
+      if (visual->doubleBufferMode) {
+         drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+         drawable->attachments[i++] = visual->rgbBits;
+      }
+      if (visual->depthBits && visual->stencilBits) {
+         drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+         drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
+      } else if (visual->depthBits) {
+         drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
+         drawable->attachments[i++] = visual->depthBits;
+      } else if (visual->stencilBits) {
+         drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
+         drawable->attachments[i++] = visual->stencilBits;
+      }
+      drawable->num_attachments = i / 2;
+   } else {
+      drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+      if (!screen->auto_fake_front)
+         drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
+      if (visual->doubleBufferMode)
+         drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+      if (visual->depthBits && visual->stencilBits)
+         drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+      else if (visual->depthBits)
+         drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
+      else if (visual->stencilBits)
+         drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
+      drawable->num_attachments = i;
+   }
 
    drawable->desired_fences = 2;
 
    return GL_TRUE;
- fail:
+fail:
    FREE(drawable);
    return GL_FALSE;
 }
index 7457fe1c6d68da138e38f4aac5bc5196ee06026b..5b6739243508947cb4f4883b4e1871b36a869218 100644 (file)
@@ -103,14 +103,26 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
            pipe_texture_reference(&tex, exa_priv->depth_stencil_tex);
         else {
            struct pipe_texture template;
+            unsigned depthBits = (format != 0) ? format : pDraw->depth;
            memset(&template, 0, sizeof(template));
            template.target = PIPE_TEXTURE_2D;
-           if (buffer->attachment == DRI2BufferDepth)
-               template.format = ms->ds_depth_bits_last ?
-                   PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
-           else
-               template.format = ms->ds_depth_bits_last ?
-                   PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
+           if (buffer->attachment == DRI2BufferDepth) {
+               switch(depthBits) {
+               case 16:
+                  template.format = PIPE_FORMAT_Z16_UNORM;
+                  break;
+               case 32:
+                  template.format = PIPE_FORMAT_Z32_UNORM;
+                  break;
+               default:
+                  template.format = ms->ds_depth_bits_last ?
+                                    PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
+                  break;
+               }
+            } else {
+               template.format = ms->ds_depth_bits_last ?
+                                 PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
+            }
            template.width0 = pDraw->width;
            template.height0 = pDraw->height;
            template.depth0 = 1;