diff options
author | Christian König <[email protected]> | 2011-06-05 00:11:41 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2011-06-05 00:11:41 +0200 |
commit | 1eb957bb4108123bea95b818e0544e3b5f255e08 (patch) | |
tree | d7febd8e6cc841ab16dca53f031322ec47d5ccd9 /src/mesa/drivers/dri/intel | |
parent | a6c76c8a90dc8995feed3c61b02dbd8408149036 (diff) | |
parent | 6491e9593d5cbc5644eb02593a2f562447efdcbb (diff) |
Merge remote-tracking branch 'origin/master' into pipe-video
Diffstat (limited to 'src/mesa/drivers/dri/intel')
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_buffers.c | 28 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_context.c | 62 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_context.h | 7 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_fbo.c | 130 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_fbo.h | 27 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_span.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_format.c | 1 |
9 files changed, 227 insertions, 46 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index ee551ef60d4..7eb50edc6b4 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -93,6 +93,7 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb) struct intel_context *intel = intel_context(ctx); struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL; struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL; + bool fb_has_hiz = intel_framebuffer_has_hiz(fb); if (!fb) { /* this can happen during the initial context initialization */ @@ -166,11 +167,11 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb) /*** *** Get depth buffer region and check if we need a software fallback. - *** Note that the depth buffer is usually a DEPTH_STENCIL buffer. ***/ 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; } @@ -187,13 +188,16 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb) /*** *** Stencil buffer - *** This can only be hardware accelerated if we're using a - *** combined DEPTH_STENCIL buffer. ***/ if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped); if (irbStencil && irbStencil->region) { - ASSERT(irbStencil->Base.Format == MESA_FORMAT_S8_Z24); + 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 { @@ -208,8 +212,10 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb) /* If we have a (packed) stencil buffer attached but no depth buffer, * we still need to set up the shared depth/stencil state so we can use it. */ - if (depthRegion == NULL && irbStencil && irbStencil->region) + if (depthRegion == NULL && irbStencil && irbStencil->region + && irbStencil->Base.Format == MESA_FORMAT_S8_Z24) { depthRegion = irbStencil->region; + } /* * Update depth and stencil test state @@ -302,18 +308,6 @@ intelReadBuffer(struct gl_context * ctx, GLenum mode) if (!was_front_buffer_reading && intel->is_front_buffer_reading) dri2InvalidateDrawable(intel->driContext->driReadablePriv); } - - if (ctx->ReadBuffer == ctx->DrawBuffer) { - /* This will update FBO completeness status. - * A framebuffer will be incomplete if the GL_READ_BUFFER setting - * refers to a missing renderbuffer. Calling glReadBuffer can set - * that straight and can make the drawing buffer complete. - */ - intel_draw_buffer(ctx, ctx->DrawBuffer); - } - /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc) - * reference ctx->ReadBuffer and do appropriate state checks. - */ } diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 4516db20ffc..2ea52c26106 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -620,6 +620,53 @@ intelInitDriverFunctions(struct dd_function_table *functions) intel_init_syncobj_functions(functions); } +/** + * Override intel->has_hiz with environment variable INTEL_HIZ. + * + * Valid values for INTEL_HIZ are "0" and "1". If an invalid valid value is + * encountered, a warning is emitted and INTEL_HIZ is ignored. + */ +static void +intel_override_hiz(struct intel_context *intel) +{ + const char *s = getenv("INTEL_HIZ"); + if (!s) { + return; + } else if (!strncmp("0", s, 2)) { + intel->has_hiz = false; + } else if (!strncmp("1", s, 2)) { + intel->has_hiz = true; + } else { + _mesa_warning(&intel->ctx, + "env variable INTEL_HIZ=\"%s\" has invalid value and " + "is ignored", s); + } +} + +/** + * Override intel->has_separate_stencil with environment variable + * INTEL_SEPARATE_STENCIL. + * + * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid + * value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL is + * ignored. + */ +static void +intel_override_separate_stencil(struct intel_context *intel) +{ + const char *s = getenv("INTEL_SEPARATE_STENCIL"); + if (!s) { + return; + } else if (!strncmp("0", s, 2)) { + intel->has_separate_stencil = false; + } else if (!strncmp("1", s, 2)) { + intel->has_separate_stencil = true; + } else { + _mesa_warning(&intel->ctx, + "env variable INTEL_SEPARATE_STENCIL=\"%s\" has invalid " + "value and is ignored", s); + } +} GLboolean intelInitContext(struct intel_context *intel, @@ -667,9 +714,14 @@ intelInitContext(struct intel_context *intel, if (IS_GEN7(intel->intelScreen->deviceID)) { intel->needs_ff_sync = GL_TRUE; intel->has_luminance_srgb = GL_TRUE; + /* FINISHME: Enable intel->has_separate_stencil on Gen7. */ + /* FINISHME: Enable intel->must_use_separate_stencil on Gen7. */ + /* FINISHME: Enable intel->has_hiz on Gen7. */ } else if (IS_GEN6(intel->intelScreen->deviceID)) { intel->needs_ff_sync = GL_TRUE; intel->has_luminance_srgb = GL_TRUE; + /* FINISHME: Enable intel->has_separate_stencil on Gen6. */ + /* FINISHME: Enable intel->has_hiz on Gen6. */ } else if (IS_GEN5(intel->intelScreen->deviceID)) { intel->needs_ff_sync = GL_TRUE; intel->has_luminance_srgb = GL_TRUE; @@ -689,6 +741,9 @@ intelInitContext(struct intel_context *intel, } } + intel_override_hiz(intel); + intel_override_separate_stencil(intel); + memset(&ctx->TextureFormatSupported, 0, sizeof(ctx->TextureFormatSupported)); ctx->TextureFormatSupported[MESA_FORMAT_ARGB8888] = GL_TRUE; @@ -703,7 +758,12 @@ intelInitContext(struct intel_context *intel, ctx->TextureFormatSupported[MESA_FORMAT_AL88] = GL_TRUE; if (intel->gen >= 4) ctx->TextureFormatSupported[MESA_FORMAT_AL1616] = GL_TRUE; - ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = GL_TRUE; + + /* Depth and stencil */ + ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = !intel->must_use_separate_stencil; + ctx->TextureFormatSupported[MESA_FORMAT_X8_Z24] = intel->has_separate_stencil; + ctx->TextureFormatSupported[MESA_FORMAT_S8] = intel->has_separate_stencil; + /* * This was disabled in initial FBO enabling to avoid combinations * of depth+stencil that wouldn't work together. We since decided diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index d3a8a659caa..f599861cba8 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -149,6 +149,10 @@ struct intel_context void (*debug_batch)(struct intel_context *intel); bool (*render_target_supported)(gl_format format); + + /** Can HiZ be enabled on a depthbuffer of the given format? */ + bool (*is_hiz_depth_format)(struct intel_context *intel, + gl_format format); } vtbl; GLbitfield Fallback; /**< mask of INTEL_FALLBACK_x bits */ @@ -166,6 +170,9 @@ struct intel_context GLboolean is_945; GLboolean has_luminance_srgb; GLboolean has_xrgb_textures; + GLboolean has_separate_stencil; + GLboolean must_use_separate_stencil; + GLboolean has_hiz; int urb_size; diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index ad2468a3237..7434e0efff6 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -79,6 +79,9 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) if (intel && irb->region) { intel_region_release(&irb->region); } + if (intel && irb->hiz_region) { + intel_region_release(&irb->hiz_region); + } free(irb); } @@ -129,7 +132,12 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer case GL_STENCIL_INDEX8_EXT: case GL_STENCIL_INDEX16_EXT: /* These aren't actual texture formats, so force them here. */ - rb->Format = MESA_FORMAT_S8_Z24; + if (intel->has_separate_stencil) { + rb->Format = MESA_FORMAT_S8; + } else { + assert(!intel->must_use_separate_stencil); + rb->Format = MESA_FORMAT_S8_Z24; + } break; } @@ -143,6 +151,9 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer if (irb->region) { intel_region_release(&irb->region); } + if (irb->hiz_region) { + intel_region_release(&irb->hiz_region); + } /* allocate new memory region/renderbuffer */ @@ -154,19 +165,54 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer GLenum base_format = _mesa_get_format_base_format(rb->Format); if (intel->gen >= 4 && (base_format == GL_DEPTH_COMPONENT || + base_format == GL_STENCIL_INDEX || base_format == GL_DEPTH_STENCIL)) tiling = I915_TILING_Y; else tiling = I915_TILING_X; } - irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp, - width, height, GL_TRUE); + if (irb->Base.Format == MESA_FORMAT_S8) { + /* + * The stencil buffer has quirky pitch requirements. From Vol 2a, + * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch": + * The pitch must be set to 2x the value computed based on width, as + * the stencil buffer is stored with two rows interleaved. + * To accomplish this, we resort to the nasty hack of doubling the drm + * region's cpp and halving its height. + * + * If we neglect to double the pitch, then drm_intel_gem_bo_map_gtt() + * maps the memory incorrectly. + */ + irb->region = intel_region_alloc(intel->intelScreen, + I915_TILING_Y, + cpp * 2, + width, + height / 2, + GL_TRUE); + } else { + irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp, + width, height, GL_TRUE); + } + if (!irb->region) return GL_FALSE; /* out of memory? */ ASSERT(irb->region->buffer); + if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) { + irb->hiz_region = intel_region_alloc(intel->intelScreen, + I915_TILING_Y, + irb->region->cpp, + irb->region->width, + irb->region->height, + GL_TRUE); + if (!irb->hiz_region) { + intel_region_release(&irb->region); + return GL_FALSE; + } + } + rb->Width = width; rb->Height = height; @@ -374,6 +420,9 @@ static GLboolean intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb, struct gl_texture_image *texImage) { + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intel_image = intel_texture_image(texImage); + if (!intel_span_supports_format(texImage->TexFormat)) { DBG("Render to texture BAD FORMAT %s\n", _mesa_get_format_name(texImage->TexFormat)); @@ -392,6 +441,32 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb, irb->Base.Delete = intel_delete_renderbuffer; irb->Base.AllocStorage = intel_nop_alloc_storage; + /* Point the renderbuffer's region to the texture's region. */ + if (irb->region != intel_image->mt->region) { + intel_region_release(&irb->region); + intel_region_reference(&irb->region, intel_image->mt->region); + } + + /* Allocate the texture's hiz region if necessary. */ + if (intel->vtbl.is_hiz_depth_format(intel, texImage->TexFormat) + && !intel_image->mt->hiz_region) { + intel_image->mt->hiz_region = + intel_region_alloc(intel->intelScreen, + I915_TILING_Y, + _mesa_get_format_bytes(texImage->TexFormat), + texImage->Width, + texImage->Height, + GL_TRUE); + if (!intel_image->mt->hiz_region) + return GL_FALSE; + } + + /* Point the renderbuffer's hiz region to the texture's hiz region. */ + if (irb->hiz_region != intel_image->mt->hiz_region) { + intel_region_release(&irb->hiz_region); + intel_region_reference(&irb->hiz_region, intel_image->mt->hiz_region); + } + return GL_TRUE; } @@ -497,13 +572,6 @@ intel_render_texture(struct gl_context * ctx, att->Texture->Name, newImage->Width, newImage->Height, irb->Base.RefCount); - /* point the renderbufer's region to the texture image region */ - if (irb->region != intel_image->mt->region) { - if (irb->region) - intel_region_release(&irb->region); - intel_region_reference(&irb->region, intel_image->mt->region); - } - intel_set_draw_offset_for_image(intel_image, att->Zoffset); intel_image->used_as_render_target = GL_TRUE; @@ -597,21 +665,33 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) intel_get_renderbuffer(fb, BUFFER_STENCIL); int i; - if (depthRb && stencilRb && stencilRb != depthRb) { - if (fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE && - fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE && - (fb->Attachment[BUFFER_DEPTH].Texture->Name == - fb->Attachment[BUFFER_STENCIL].Texture->Name)) { - /* OK */ - } else { - /* we only support combined depth/stencil buffers, not separate - * stencil buffers. - */ - DBG("Only supports combined depth/stencil (found %s, %s)\n", - depthRb ? _mesa_get_format_name(depthRb->Base.Format): "NULL", - stencilRb ? _mesa_get_format_name(stencilRb->Base.Format): "NULL"); - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - } + /* + * The depth and stencil renderbuffers are the same renderbuffer or wrap + * the same texture. + */ + bool depth_stencil_are_same; + if (depthRb && stencilRb && depthRb == stencilRb) + depth_stencil_are_same = true; + else if (depthRb && stencilRb && depthRb != stencilRb + && (fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) + && (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE) + && (fb->Attachment[BUFFER_DEPTH].Texture->Name + == fb->Attachment[BUFFER_STENCIL].Texture->Name)) + depth_stencil_are_same = true; + else + depth_stencil_are_same = false; + + bool fb_has_combined_depth_stencil_format = + (depthRb && depthRb->Base.Format == MESA_FORMAT_S8_Z24) || + (stencilRb && stencilRb->Base.Format == MESA_FORMAT_S8_Z24); + + bool fb_has_hiz = intel_framebuffer_has_hiz(fb); + + if ((intel->must_use_separate_stencil || fb_has_hiz) + && (depth_stencil_are_same || fb_has_combined_depth_stencil_format)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + } else if (!intel->has_separate_stencil && depthRb && stencilRb && !depth_stencil_are_same) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; } for (i = 0; i < Elements(fb->Attachment); i++) { diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index 028f657d12d..212dd9aadc8 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -28,6 +28,7 @@ #ifndef INTEL_FBO_H #define INTEL_FBO_H +#include <stdbool.h> #include "main/formats.h" #include "intel_screen.h" @@ -40,6 +41,9 @@ struct intel_renderbuffer { struct gl_renderbuffer Base; struct intel_region *region; + + /** Only used by depth renderbuffers for which HiZ is enabled. */ + struct intel_region *hiz_region; }; @@ -80,6 +84,29 @@ intel_get_renderbuffer(struct gl_framebuffer *fb, int attIndex) return NULL; } +/** + * If the framebuffer has a depth buffer attached, then return its HiZ region. + * The HiZ region may be null. + */ +static INLINE struct intel_region* +intel_framebuffer_get_hiz_region(struct gl_framebuffer *fb) +{ + struct intel_renderbuffer *rb = NULL; + if (fb) + rb = intel_get_renderbuffer(fb, BUFFER_DEPTH); + + if (rb) + return rb->hiz_region; + else + return NULL; +} + +static INLINE bool +intel_framebuffer_has_hiz(struct gl_framebuffer *fb) +{ + return intel_framebuffer_get_hiz_region(fb) != NULL; +} + extern void intel_renderbuffer_set_region(struct intel_context *intel, diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index a3409274fb7..e62905de7c3 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -200,6 +200,7 @@ intel_miptree_release(struct intel_context *intel, DBG("%s deleting %p\n", __FUNCTION__, *mt); intel_region_release(&((*mt)->region)); + intel_region_release(&((*mt)->hiz_region)); for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { free((*mt)->level[i].x_offset); diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 760a8bce601..325e3916981 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -113,6 +113,20 @@ struct intel_mipmap_tree */ struct intel_region *region; + /** + * This points to an auxillary hiz region if all of the following hold: + * 1. The texture has been attached to an FBO as a depthbuffer. + * 2. The texture format is hiz compatible. + * 3. The intel context supports hiz. + * + * When a texture is attached to multiple FBO's, a separate renderbuffer + * wrapper is created for each attachment. This necessitates storing the + * hiz region in the texture itself instead of the renderbuffer wrapper. + * + * \see intel_fbo.c:intel_wrap_texture() + */ + struct intel_region *hiz_region; + /* These are also refcounted: */ GLuint refcount; diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index 16bce20317e..5290342c3e1 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -70,9 +70,6 @@ intel_set_span_functions(struct intel_context *intel, #define HW_UNLOCK() -/* Convenience macros to avoid typing the address argument over and over */ -#define NO_TILE(_X, _Y) (((_Y) * irb->region->pitch + (_X)) * irb->region->cpp) - /* r5g6b5 color span and pixel functions */ #define SPANTMP_PIXEL_FMT GL_RGB #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c index befa615d1e6..6890a690ab1 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_format.c +++ b/src/mesa/drivers/dri/intel/intel_tex_format.c @@ -22,6 +22,7 @@ intel_mesa_format_to_rb_datatype(gl_format format) case MESA_FORMAT_RGB565: case MESA_FORMAT_ARGB1555: case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_S8: return GL_UNSIGNED_BYTE; case MESA_FORMAT_R16: case MESA_FORMAT_RG1616: |