intel: Add fields to intel_renderbuffer for unwrapping packed depth/stencil buffers

Add the following fields:
    intel_renderbuffer.wrapped_depth;
    intel_renderbuffer.wrapped_stencil

If the intel_context is using separate stencil and the renderbuffer has
a packed depth/stencil format, then wrapped_depth and wrapped_stencil are
the real renderbuffers.

Alter the following functions to accomodate the wrapped buffers:
    intel_delete_renderbuffer
    intel_draw_buffer
    intel_get_renderbuffer
    intel_renderbuffer_map
    intel_renderbuffer_unmap

Subsequent commits allocate renderbuffer storage for wrapped_depth and
wrapped_stencil.

Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Chad Versace <chad@chad-versace.us>
This commit is contained in:
Chad Versace 2011-06-16 14:12:54 -07:00
parent 23ed3b90c7
commit 39d0e3632a
4 changed files with 118 additions and 44 deletions

View file

@ -28,7 +28,9 @@
#include "intel_context.h"
#include "intel_buffers.h"
#include "intel_fbo.h"
#include "main/framebuffer.h"
#include "main/renderbuffer.h"
/**
* Return pointer to current color drawing region, or NULL.
@ -100,6 +102,26 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb)
return;
}
/*
* If intel_context is using separate stencil, but the depth attachment
* (gl_framebuffer.Attachment[BUFFER_DEPTH]) has a packed depth/stencil
* format, then we must install the real depth buffer at
* gl_framebuffer._DepthBuffer before calling _mesa_update_framebuffer.
* Otherwise, _mesa_update_framebuffer will create and install a swrast
* depth wrapper instead.
*
* Ditto for stencil.
*/
irbDepth = intel_get_renderbuffer(fb, BUFFER_DEPTH);
if (irbDepth && irbDepth->Base.Format == MESA_FORMAT_X8_Z24) {
_mesa_reference_renderbuffer(&fb->_DepthBuffer, &irbDepth->Base);
}
irbStencil = intel_get_renderbuffer(fb, BUFFER_STENCIL);
if (irbStencil && irbStencil->Base.Format == MESA_FORMAT_S8) {
_mesa_reference_renderbuffer(&fb->_StencilBuffer, &irbStencil->Base);
}
/* Do this here, not core Mesa, since this function is called from
* many places within the driver.
*/
@ -165,47 +187,33 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb)
FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
}
/***
*** Get depth buffer region and check if we need a software fallback.
***/
if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped);
if (irbDepth && irbDepth->region) {
assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24);
FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
depthRegion = irbDepth->region;
}
else {
FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
depthRegion = NULL;
}
}
else {
/* not using depth buffer */
/* Check for depth fallback. */
if (irbDepth && irbDepth->region) {
assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24);
FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
depthRegion = irbDepth->region;
} else if (irbDepth && !irbDepth->region) {
FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
depthRegion = NULL;
} else { /* !irbDepth */
/* No fallback is needed because there is no depth buffer. */
FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
depthRegion = NULL;
}
/***
*** Stencil buffer
***/
if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped);
if (irbStencil && irbStencil->region) {
if (!intel->has_separate_stencil)
assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24);
if (fb_has_hiz || intel->must_use_separate_stencil)
assert(irbStencil->Base.Format == MESA_FORMAT_S8);
if (irbStencil->Base.Format == MESA_FORMAT_S8)
assert(intel->has_separate_stencil);
FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
}
else {
FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
}
}
else {
/* XXX FBO: instead of FALSE, pass ctx->Stencil._Enabled ??? */
/* Check for stencil fallback. */
if (irbStencil && irbStencil->region) {
if (!intel->has_separate_stencil)
assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24);
if (fb_has_hiz || intel->must_use_separate_stencil)
assert(irbStencil->Base.Format == MESA_FORMAT_S8);
if (irbStencil->Base.Format == MESA_FORMAT_S8)
assert(intel->has_separate_stencil);
FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
} else if (irbStencil && !irbStencil->region) {
FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
} else { /* !irbStencil */
/* No fallback is needed because there is no stencil buffer. */
FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
}

View file

@ -82,6 +82,12 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb)
if (intel && irb->hiz_region) {
intel_region_release(&irb->hiz_region);
}
if (intel && irb->wrapped_depth) {
_mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
}
if (intel && irb->wrapped_stencil) {
_mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
}
free(irb);
}

View file

@ -45,6 +45,18 @@ struct intel_renderbuffer
/** Only used by depth renderbuffers for which HiZ is enabled. */
struct intel_region *hiz_region;
/**
* \name Packed depth/stencil unwrappers
*
* If the intel_context is using separate stencil and this renderbuffer has
* a a packed depth/stencil format, then wrapped_depth and wrapped_stencil
* are the real renderbuffers.
*/
struct gl_renderbuffer *wrapped_depth;
struct gl_renderbuffer *wrapped_stencil;
/** \} */
GLuint draw_offset; /**< Offset of drawing address within the region */
GLuint draw_x, draw_y; /**< Offset of drawing within the region */
};
@ -76,15 +88,47 @@ intel_renderbuffer(struct gl_renderbuffer *rb)
/**
* Return a framebuffer's renderbuffer, named by a BUFFER_x index.
* \brief Return the framebuffer attachment specified by attIndex.
*
* If the framebuffer lacks the specified attachment, then return null.
*
* If the attached renderbuffer is a wrapper, then return wrapped
* renderbuffer.
*/
static INLINE struct intel_renderbuffer *
intel_get_renderbuffer(struct gl_framebuffer *fb, int attIndex)
intel_get_renderbuffer(struct gl_framebuffer *fb, gl_buffer_index attIndex)
{
if (attIndex >= 0)
return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
else
struct gl_renderbuffer *rb;
struct intel_renderbuffer *irb;
/* XXX: Who passes -1 to intel_get_renderbuffer? */
if (attIndex < 0)
return NULL;
rb = fb->Attachment[attIndex].Renderbuffer;
if (!rb)
return NULL;
irb = intel_renderbuffer(rb);
if (!irb)
return NULL;
switch (attIndex) {
case BUFFER_DEPTH:
if (irb->wrapped_depth) {
irb = intel_renderbuffer(irb->wrapped_depth);
}
break;
case BUFFER_STENCIL:
if (irb->wrapped_stencil) {
irb = intel_renderbuffer(irb->wrapped_stencil);
}
break;
default:
break;
}
return irb;
}
/**

View file

@ -177,7 +177,15 @@ intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb)
{
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
if (irb == NULL || irb->region == NULL)
if (!irb)
return;
if (irb->wrapped_depth)
intel_renderbuffer_map(intel, irb->wrapped_depth);
if (irb->wrapped_stencil)
intel_renderbuffer_map(intel, irb->wrapped_stencil);
if (!irb->region)
return;
drm_intel_gem_bo_map_gtt(irb->region->buffer);
@ -206,7 +214,15 @@ intel_renderbuffer_unmap(struct intel_context *intel,
{
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
if (irb == NULL || irb->region == NULL)
if (!irb)
return;
if (irb->wrapped_depth)
intel_renderbuffer_unmap(intel, irb->wrapped_depth);
if (irb->wrapped_stencil)
intel_renderbuffer_unmap(intel, irb->wrapped_stencil);
if (!irb->region)
return;
drm_intel_gem_bo_unmap_gtt(irb->region->buffer);