intel / DRI2: When available, use DRI2GetBuffersWithFormat

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>
This commit is contained in:
Ian Romanick
2009-04-20 20:56:45 -07:00
committed by Ian Romanick
parent dbf87f2312
commit f2272b5b2f
2 changed files with 98 additions and 15 deletions

View File

@@ -323,8 +323,18 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode)
{ {
if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
struct intel_context *const intel = intel_context(ctx); 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); 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); intel_draw_buffer(ctx, ctx->DrawBuffer);

View 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 void
intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
{ {
@@ -192,22 +210,62 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
screen = intel->intelScreen->driScrnPriv; screen = intel->intelScreen->driScrnPriv;
i = 0; if ((screen->dri2.loader->base.version > 2)
if (intel_fb->color_rb[0]) && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
attachments[i++] = __DRI_BUFFER_FRONT_LEFT; struct intel_renderbuffer *depth_rb;
if (intel_fb->color_rb[1]) struct intel_renderbuffer *stencil_rb;
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, i = 0;
&drawable->w, if ((intel->is_front_buffer_rendering || !intel_fb->color_rb[1])
&drawable->h, && intel_fb->color_rb[0]) {
attachments, i, attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
&count, attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]);
drawable->loaderPrivate); }
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) if (buffers == NULL)
return; return;
@@ -250,6 +308,11 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
region_name = "dri2 depth buffer"; region_name = "dri2 depth buffer";
break; 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: case __DRI_BUFFER_STENCIL:
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
region_name = "dri2 stencil buffer"; region_name = "dri2 stencil buffer";
@@ -296,6 +359,16 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
intel_renderbuffer_set_region(rb, region); intel_renderbuffer_set_region(rb, region);
intel_region_release(&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); driUpdateFramebufferSize(&intel->ctx, drawable);