[PATCH 6/6] intel / DRI2: When available, use DRI2GetBuffersWithFormat
Ian Romanick
idr at freedesktop.org
Mon Apr 20 20:56:45 PDT 2009
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 at intel.com>
---
src/mesa/drivers/dri/intel/intel_buffers.c | 10 +++
src/mesa/drivers/dri/intel/intel_context.c | 105 +++++++++++++++++++++++----
2 files changed, 99 insertions(+), 16 deletions(-)
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
index 90964df..1b38d4c 100644
--- a/src/mesa/drivers/dri/intel/intel_buffers.c
+++ b/src/mesa/drivers/dri/intel/intel_buffers.c
@@ -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);
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 3436b8e..3400dbe 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -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(®ion);
+
+ 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);
--
1.6.0.6
More information about the xorg-devel
mailing list