From 39d0e3632a4ccb10f2ce6578151e854ba52d3c0e Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Thu, 16 Jun 2011 14:12:54 -0700 Subject: [PATCH] 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 Signed-off-by: Chad Versace --- src/mesa/drivers/dri/intel/intel_buffers.c | 82 ++++++++++++---------- src/mesa/drivers/dri/intel/intel_fbo.c | 6 ++ src/mesa/drivers/dri/intel/intel_fbo.h | 54 ++++++++++++-- src/mesa/drivers/dri/intel/intel_span.c | 20 +++++- 4 files changed, 118 insertions(+), 44 deletions(-) diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 7eb50edc6b4..33f691bf5f3 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -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); } diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index e7c23f02f65..b48eac40008 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -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); } diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index 509f5887225..da0b24064df 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -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; } /** diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index fdf687a04a6..153803fba09 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -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); -- 2.30.2