intel / DRI2: When available, use DRI2GetBuffersWithFormat
authorIan Romanick <idr@freedesktop.org>
Tue, 21 Apr 2009 03:56:45 +0000 (20:56 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 24 Apr 2009 19:48:20 +0000 (12:48 -0700)
This interface gives the driver two important features.  First, it can
allocate the (fake) front-buffer only when needed.  Second, it can
tell the buffer allocator the format of buffers being allocated.  This
enables support for back-buffer and depth-buffer with different bits
per pixel.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kristian Høgsberg <krh@redhat.com>
src/mesa/drivers/dri/intel/intel_buffers.c
src/mesa/drivers/dri/intel/intel_context.c

index 90964df35530c4823172ab6743320b37c01dc86d..ecac5bf0207944428dff92c97260d428991f6ed2 100644 (file)
@@ -323,8 +323,18 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode)
 {
    if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
       struct intel_context *const intel = intel_context(ctx);
+      const GLboolean was_front_buffer_rendering =
+       intel->is_front_buffer_rendering;
 
       intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT);
+
+      /* If we weren't front-buffer rendering before but we are now, make sure
+       * that the front-buffer has actually been allocated.
+       */
+      if (!was_front_buffer_rendering && intel->is_front_buffer_rendering) {
+        intel_update_renderbuffers(intel->driContext,
+                                   intel->driContext->driDrawablePriv);
+      }
    }
 
    intel_draw_buffer(ctx, ctx->DrawBuffer);
index 9b628dbc8e37f1cb5ebbca4e3bfa13b3be965267..7fda7933733708fbc1bd4881ccb67a3fe670bef5 100644 (file)
@@ -173,6 +173,24 @@ intelGetString(GLcontext * ctx, GLenum name)
    }
 }
 
+static unsigned
+intel_bits_per_pixel(const struct intel_renderbuffer *rb)
+{
+   switch (rb->Base._ActualFormat) {
+   case GL_RGB5:
+   case GL_DEPTH_COMPONENT16:
+      return 16;
+   case GL_RGB8:
+   case GL_RGBA8:
+   case GL_DEPTH_COMPONENT24:
+   case GL_DEPTH24_STENCIL8_EXT:
+   case GL_STENCIL_INDEX8_EXT:
+      return 32;
+   default:
+      return 0;
+   }
+}
+
 void
 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 {
@@ -192,22 +210,62 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 
    screen = intel->intelScreen->driScrnPriv;
 
-   i = 0;
-   if (intel_fb->color_rb[0])
-      attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-   if (intel_fb->color_rb[1])
-      attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-   if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH))
-      attachments[i++] = __DRI_BUFFER_DEPTH;
-   if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL))
-      attachments[i++] = __DRI_BUFFER_STENCIL;
-
-   buffers = (*screen->dri2.loader->getBuffers)(drawable,
-                                               &drawable->w,
-                                               &drawable->h,
-                                               attachments, i,
-                                               &count,
-                                               drawable->loaderPrivate);
+   if ((screen->dri2.loader->base.version > 2)
+       && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
+      struct intel_renderbuffer *depth_rb;
+      struct intel_renderbuffer *stencil_rb;
+
+      i = 0;
+      if ((intel->is_front_buffer_rendering || !intel_fb->color_rb[1])
+          && intel_fb->color_rb[0]) {
+        attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+        attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]);
+      }
+
+      if (intel_fb->color_rb[1]) {
+        attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+        attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[1]);
+      }
+
+      depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+      stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+
+      if ((depth_rb != NULL) && (stencil_rb != NULL)) {
+        attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+        attachments[i++] = intel_bits_per_pixel(depth_rb);
+      } else if (depth_rb != NULL) {
+        attachments[i++] = __DRI_BUFFER_DEPTH;
+        attachments[i++] = intel_bits_per_pixel(depth_rb);
+      } else if (stencil_rb != NULL) {
+        attachments[i++] = __DRI_BUFFER_STENCIL;
+        attachments[i++] = intel_bits_per_pixel(stencil_rb);
+      }
+
+      buffers =
+        (*screen->dri2.loader->getBuffersWithFormat)(drawable,
+                                                     &drawable->w,
+                                                     &drawable->h,
+                                                     attachments, i / 2,
+                                                     &count,
+                                                     drawable->loaderPrivate);
+   } else {
+      i = 0;
+      if (intel_fb->color_rb[0])
+        attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+      if (intel_fb->color_rb[1])
+        attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+      if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH))
+        attachments[i++] = __DRI_BUFFER_DEPTH;
+      if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL))
+        attachments[i++] = __DRI_BUFFER_STENCIL;
+
+      buffers = (*screen->dri2.loader->getBuffers)(drawable,
+                                                  &drawable->w,
+                                                  &drawable->h,
+                                                  attachments, i,
+                                                  &count,
+                                                  drawable->loaderPrivate);
+   }
 
    if (buffers == NULL)
       return;
@@ -250,6 +308,11 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
           region_name = "dri2 depth buffer";
           break;
 
+       case __DRI_BUFFER_DEPTH_STENCIL:
+          rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+          region_name = "dri2 depth / stencil buffer";
+          break;
+
        case __DRI_BUFFER_STENCIL:
           rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
           region_name = "dri2 stencil buffer";
@@ -296,6 +359,16 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 
        intel_renderbuffer_set_region(rb, region);
        intel_region_release(&region);
+
+       if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
+         struct intel_region *stencil_region;
+
+         intel_region_reference(&stencil_region, region);
+
+         rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+         intel_renderbuffer_set_region(rb, stencil_region);
+         intel_region_release(&stencil_region);
+       }
    }
 
    driUpdateFramebufferSize(&intel->ctx, drawable);