mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 14:40:10 +01:00
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:
parent
23ed3b90c7
commit
39d0e3632a
4 changed files with 118 additions and 44 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue