summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel/intel_context.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2012-07-04 10:52:32 -0700
committerChad Versace <chad.versace@linux.intel.com>2012-07-17 08:17:56 -0700
commitbce58e155db7202a98642c10e6132dee4e08162b (patch)
tree3d0bb60da3279927743e56312e2db7f5a88033b4 /src/mesa/drivers/dri/intel/intel_context.c
parent433ff3e16e8e090fd3a1bf427e61f3e5971a5740 (diff)
intel: Convert to using private depth/stencil buffers (v2)
This means that GLX buffer sharing of these no longer works. On the other hand, just *look* at this code reduction. v2: - [chad] Fix intelCreateBuffer for gen < 6. When the branch for !screen->hw_has_separate_stencil was taken, intel_create_private_renderbuffer was incorrectly not used. - [chad] Remove all code in intel_process_dri2_buffer for processing depth, stencil, and hiz buffers. That code is now dead. CC: Eric Anholt <eric@anholt.net> Signed-off-by: Chad Versace <chad.versace@linux.intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'src/mesa/drivers/dri/intel/intel_context.c')
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c616
1 files changed, 34 insertions, 582 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index c2f7d2956ef..60e93f0dc3e 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -239,37 +239,17 @@ intel_bits_per_pixel(const struct intel_renderbuffer *rb)
}
static void
-intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer **buffers,
- int *count);
+intel_query_dri2_buffers(struct intel_context *intel,
+ __DRIdrawable *drawable,
+ __DRIbuffer **buffers,
+ int *count);
static void
-intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer *buffer,
- struct intel_renderbuffer *rb,
- const char *buffer_name);
-
-static void
-intel_query_dri2_buffers_with_separate_stencil(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer **buffers,
- unsigned **attachments,
- int *count);
-
-static void
-intel_process_dri2_buffer_with_separate_stencil(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer *buffer,
- struct intel_renderbuffer *rb,
- const char *buffer_name);
-static void
-intel_verify_dri2_has_hiz(struct intel_context *intel,
+intel_process_dri2_buffer(struct intel_context *intel,
__DRIdrawable *drawable,
- __DRIbuffer **buffers,
- unsigned **attachments,
- int *count);
+ __DRIbuffer *buffer,
+ struct intel_renderbuffer *rb,
+ const char *buffer_name);
void
intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
@@ -278,19 +258,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
struct intel_renderbuffer *rb;
struct intel_context *intel = context->driverPrivate;
__DRIbuffer *buffers = NULL;
- unsigned *attachments = NULL;
int i, count;
const char *region_name;
- bool try_separate_stencil =
- intel->has_separate_stencil &&
- intel->intelScreen->dri2_has_hiz != INTEL_DRI2_HAS_HIZ_FALSE &&
- intel->intelScreen->driScrnPriv->dri2.loader != NULL &&
- intel->intelScreen->driScrnPriv->dri2.loader->base.version > 2 &&
- intel->intelScreen->driScrnPriv->dri2.loader->getBuffersWithFormat != NULL;
-
- assert(!intel->must_use_separate_stencil || try_separate_stencil);
-
/* If we're rendering to the fake front buffer, make sure all the
* pending drawing has landed on the real front buffer. Otherwise
* when we eventually get to DRI2GetBuffersWithFormat the stale
@@ -310,13 +280,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
if (unlikely(INTEL_DEBUG & DEBUG_DRI))
fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
- if (try_separate_stencil) {
- intel_query_dri2_buffers_with_separate_stencil(intel, drawable, &buffers,
- &attachments, &count);
- } else {
- intel_query_dri2_buffers_no_separate_stencil(intel, drawable, &buffers,
- &count);
- }
+ intel_query_dri2_buffers(intel, drawable, &buffers, &count);
if (buffers == NULL)
return;
@@ -339,26 +303,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
break;
case __DRI_BUFFER_DEPTH:
- rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
- region_name = "dri2 depth buffer";
- break;
-
case __DRI_BUFFER_HIZ:
- /* The hiz region resides in the depth renderbuffer. */
- rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
- region_name = "dri2 hiz buffer";
- break;
-
case __DRI_BUFFER_DEPTH_STENCIL:
- rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
- region_name = "dri2 depth / stencil buffer";
- break;
-
case __DRI_BUFFER_STENCIL:
- rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
- region_name = "dri2 stencil buffer";
- break;
-
case __DRI_BUFFER_ACCUM:
default:
fprintf(stderr,
@@ -367,26 +314,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
return;
}
- if (try_separate_stencil) {
- intel_process_dri2_buffer_with_separate_stencil(intel, drawable,
- &buffers[i], rb,
- region_name);
- } else {
- intel_process_dri2_buffer_no_separate_stencil(intel, drawable,
- &buffers[i], rb,
- region_name);
- }
+ intel_process_dri2_buffer(intel, drawable, &buffers[i], rb, region_name);
}
- if (try_separate_stencil
- && intel->intelScreen->dri2_has_hiz == INTEL_DRI2_HAS_HIZ_UNKNOWN) {
- intel_verify_dri2_has_hiz(intel, drawable, &buffers, &attachments,
- &count);
- }
-
- if (attachments)
- free(attachments);
-
driUpdateFramebufferSize(&intel->ctx, drawable);
}
@@ -887,8 +817,7 @@ intelMakeCurrent(__DRIcontext * driContextPriv,
* attached to the drawable's framebuffer. Then request the buffers with
* DRI2GetBuffers() or DRI2GetBuffersWithFormat().
*
- * This is called from intel_update_renderbuffers(). It is used only if either
- * the hardware or the X driver lacks separate stencil support.
+ * This is called from intel_update_renderbuffers().
*
* \param drawable Drawable whose buffers are queried.
* \param buffers [out] List of buffers returned by DRI2 query.
@@ -899,13 +828,11 @@ intelMakeCurrent(__DRIcontext * driContextPriv,
* \see DRI2GetBuffersWithFormat()
*/
static void
-intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer **buffers,
- int *buffer_count)
+intel_query_dri2_buffers(struct intel_context *intel,
+ __DRIdrawable *drawable,
+ __DRIbuffer **buffers,
+ int *buffer_count)
{
- assert(!intel->must_use_separate_stencil);
-
__DRIscreen *screen = intel->intelScreen->driScrnPriv;
struct gl_framebuffer *fb = drawable->driverPrivate;
@@ -919,13 +846,9 @@ intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
struct intel_renderbuffer *front_rb;
struct intel_renderbuffer *back_rb;
- struct intel_renderbuffer *depth_rb;
- struct intel_renderbuffer *stencil_rb;
front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
- depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
- stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
if ((intel->is_front_buffer_rendering ||
intel->is_front_buffer_reading ||
@@ -939,17 +862,6 @@ intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
attachments[i++] = intel_bits_per_pixel(back_rb);
}
- if (depth_rb && stencil_rb) {
- attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
- attachments[i++] = intel_bits_per_pixel(depth_rb);
- } else if (depth_rb) {
- attachments[i++] = __DRI_BUFFER_DEPTH;
- attachments[i++] = intel_bits_per_pixel(depth_rb);
- } else if (stencil_rb) {
- attachments[i++] = __DRI_BUFFER_STENCIL;
- attachments[i++] = intel_bits_per_pixel(stencil_rb);
- }
-
assert(i <= 2 * max_attachments);
*buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
@@ -970,10 +882,6 @@ intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
if (intel_get_renderbuffer(fb, BUFFER_BACK_LEFT))
attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- if (intel_get_renderbuffer(fb, BUFFER_DEPTH))
- attachments[i++] = __DRI_BUFFER_DEPTH;
- if (intel_get_renderbuffer(fb, BUFFER_STENCIL))
- attachments[i++] = __DRI_BUFFER_STENCIL;
assert(i <= max_attachments);
@@ -994,8 +902,7 @@ intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
/**
* \brief Assign a DRI buffer's DRM region to a renderbuffer.
*
- * This is called from intel_update_renderbuffers(). It is used only if
- * either the hardware or the X driver lacks separate stencil support.
+ * This is called from intel_update_renderbuffers().
*
* \par Note:
* DRI buffers whose attachment point is DRI2BufferStencil or
@@ -1008,16 +915,13 @@ intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
* \see intel_region_alloc_for_handle()
*/
static void
-intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer *buffer,
- struct intel_renderbuffer *rb,
- const char *buffer_name)
+intel_process_dri2_buffer(struct intel_context *intel,
+ __DRIdrawable *drawable,
+ __DRIbuffer *buffer,
+ struct intel_renderbuffer *rb,
+ const char *buffer_name)
{
- assert(!intel->must_use_separate_stencil);
-
- struct gl_framebuffer *fb = drawable->driverPrivate;
- struct intel_renderbuffer *depth_rb = NULL;
+ struct intel_region *region = NULL;
if (!rb)
return;
@@ -1034,472 +938,20 @@ intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
buffer->cpp, buffer->pitch);
}
- bool identify_depth_and_stencil = false;
- if (buffer->attachment == __DRI_BUFFER_STENCIL) {
- struct intel_renderbuffer *depth_rb =
- intel_get_renderbuffer(fb, BUFFER_DEPTH);
- identify_depth_and_stencil = depth_rb && depth_rb->mt;
- }
-
- if (identify_depth_and_stencil) {
- if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
- fprintf(stderr, "(reusing depth buffer as stencil)\n");
- }
- intel_miptree_reference(&rb->mt, depth_rb->mt);
- } else {
- intel_miptree_release(&rb->mt);
- struct intel_region *region =
- intel_region_alloc_for_handle(intel->intelScreen,
- buffer->cpp,
- drawable->w,
- drawable->h,
- buffer->pitch / buffer->cpp,
- buffer->name,
- buffer_name);
- if (!region)
- return;
-
- rb->mt = intel_miptree_create_for_region(intel,
- GL_TEXTURE_2D,
- intel_rb_format(rb),
- region);
- intel_region_release(&region);
- if (!rb->mt)
- return;
- }
-
- if (buffer->attachment == __DRI_BUFFER_DEPTH_STENCIL) {
- struct intel_renderbuffer *stencil_rb =
- intel_get_renderbuffer(fb, BUFFER_STENCIL);
-
- if (!stencil_rb)
- return;
-
- /* The rb passed in is the BUFFER_DEPTH attachment, and we need
- * to associate this region to BUFFER_STENCIL as well.
- */
- intel_miptree_reference(&stencil_rb->mt, rb->mt);
- }
-}
-
-/**
- * \brief Query DRI2 to obtain a DRIdrawable's buffers.
- *
- * To determine which DRI buffers to request, examine the renderbuffers
- * attached to the drawable's framebuffer. Then request the buffers with
- * DRI2GetBuffersWithFormat().
- *
- * This is called from intel_update_renderbuffers(). It is used when 1) the
- * hardware supports separate stencil and 2) the X driver's separate stencil
- * support has been verified to work or is still unknown.
- *
- * \param drawable Drawable whose buffers are queried.
- * \param buffers [out] List of buffers returned by DRI2 query.
- * \param buffer_count [out] Number of buffers returned.
- * \param attachments [out] List of pairs (attachment_point, bits_per_pixel)
- * that were submitted in the DRI2 query. Number of pairs
- * is same as buffer_count.
- *
- * \see intel_update_renderbuffers()
- * \see DRI2GetBuffersWithFormat()
- * \see enum intel_dri2_has_hiz
- */
-static void
-intel_query_dri2_buffers_with_separate_stencil(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer **buffers,
- unsigned **attachments,
- int *count)
-{
- assert(intel->has_separate_stencil);
-
- __DRIscreen *screen = intel->intelScreen->driScrnPriv;
- struct gl_framebuffer *fb = drawable->driverPrivate;
-
- const int max_attachments = 5;
- int i = 0;
-
- *attachments = calloc(2 * max_attachments, sizeof(unsigned));
- if (!*attachments) {
- *buffers = NULL;
- *count = 0;
- return;
- }
-
- struct intel_renderbuffer *front_rb;
- struct intel_renderbuffer *back_rb;
- struct intel_renderbuffer *depth_rb;
- struct intel_renderbuffer *stencil_rb;
-
- front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
- back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
- depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
- stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
-
- if ((intel->is_front_buffer_rendering ||
- intel->is_front_buffer_reading ||
- !back_rb) && front_rb) {
- (*attachments)[i++] = __DRI_BUFFER_FRONT_LEFT;
- (*attachments)[i++] = intel_bits_per_pixel(front_rb);
- }
-
- if (back_rb) {
- (*attachments)[i++] = __DRI_BUFFER_BACK_LEFT;
- (*attachments)[i++] = intel_bits_per_pixel(back_rb);
- }
-
- /*
- * We request a separate stencil buffer, and perhaps a hiz buffer too, even
- * if we do not yet know if the X driver supports it. See the comments for
- * 'enum intel_dri2_has_hiz'.
- */
-
- if (depth_rb) {
- (*attachments)[i++] = __DRI_BUFFER_DEPTH;
- (*attachments)[i++] = intel_bits_per_pixel(depth_rb);
-
- if (intel->vtbl.is_hiz_depth_format(intel, intel_rb_format(depth_rb))) {
- /* Depth and hiz buffer have same bpp. */
- (*attachments)[i++] = __DRI_BUFFER_HIZ;
- (*attachments)[i++] = intel_bits_per_pixel(depth_rb);
- }
- }
-
- if (stencil_rb) {
- assert(intel_rb_format(stencil_rb) == MESA_FORMAT_S8);
- (*attachments)[i++] = __DRI_BUFFER_STENCIL;
- (*attachments)[i++] = intel_bits_per_pixel(stencil_rb);
- }
-
- assert(i <= 2 * max_attachments);
-
- *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
- &drawable->w,
- &drawable->h,
- *attachments, i / 2,
- count,
- drawable->loaderPrivate);
-
- if (!*buffers) {
- free(*attachments);
- *attachments = NULL;
- *count = 0;
- }
-}
-
-/**
- * \brief Assign a DRI buffer's DRM region to a renderbuffer.
- *
- * This is called from intel_update_renderbuffers(). It is used when 1) the
- * hardware supports separate stencil and 2) the X driver's separate stencil
- * support has been verified to work or is still unknown.
- *
- * \par Note:
- * DRI buffers whose attachment point is DRI2BufferStencil or DRI2BufferHiz
- * are handled as special cases.
- *
- * \param buffer_name is a human readable name, such as "dri2 front buffer",
- * that is passed to intel_region_alloc_for_handle().
- *
- * \see intel_update_renderbuffers()
- * \see intel_region_alloc_for_handle()
- * \see enum intel_dri2_has_hiz
- */
-static void
-intel_process_dri2_buffer_with_separate_stencil(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer *buffer,
- struct intel_renderbuffer *rb,
- const char *buffer_name)
-{
- assert(intel->has_separate_stencil);
- assert(buffer->attachment != __DRI_BUFFER_DEPTH_STENCIL);
-
- if (!rb)
- return;
-
- /* Check if we failed to allocate the depth miptree earlier. */
- if (buffer->attachment == __DRI_BUFFER_HIZ && rb->mt == NULL)
- return;
-
- /* If the renderbuffer's and DRIbuffer's regions match, then continue. */
- if ((buffer->attachment != __DRI_BUFFER_HIZ &&
- rb->mt &&
- rb->mt->region &&
- rb->mt->region->name == buffer->name) ||
- (buffer->attachment == __DRI_BUFFER_HIZ &&
- rb->mt &&
- rb->mt->hiz_mt &&
- rb->mt->hiz_mt->region->name == buffer->name)) {
- return;
- }
-
- if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
- fprintf(stderr,
- "attaching buffer %d, at %d, cpp %d, pitch %d\n",
- buffer->name, buffer->attachment,
- buffer->cpp, buffer->pitch);
- }
-
- int buffer_width;
- int buffer_height;
- int buffer_cpp = buffer->cpp;
- int buffer_pitch = buffer->pitch;
- if (buffer->attachment == __DRI_BUFFER_STENCIL) {
- /* Stencil buffers use W tiling, a tiling format that the DRM functions
- * don't properly account for. Therefore, when we allocate a stencil
- * buffer that is private to Mesa (see intel_miptree_create), we round
- * the height and width up to the next multiple of the tile size (64x64)
- * and then ask DRM to allocate an untiled buffer. Consequently, the
- * height and the width stored in the stencil buffer's region structure
- * are always multiples of 64, even if the stencil buffer itself is
- * smaller.
- *
- * To avoid inconsistencies between how we represent private buffers and
- * buffers shared with the window system, round up the height and width
- * for window system buffers too.
- */
- buffer_width = ALIGN(drawable->w, 64);
- buffer_height = ALIGN(drawable->h, 64);
-
- /* Versions 2.17.0 and earlier of xf86-video-intel (a.k.a. the DDX) lie
- * and send cpp and pitch values that are two times too large for
- * stencil buffers. Hopefully this will be fixed in a future version
- * of xf86-video-intel, but for now detect the bug by checking if cpp
- * is 2, and fixing cpp and pitch if it is.
- */
- if (buffer_cpp == 2) {
- buffer_cpp = 1;
- buffer_pitch /= 2;
- }
- } else {
- buffer_width = drawable->w;
- buffer_height = drawable->h;
- }
-
- /* Release the buffer storage now in case we have to return early
- * due to failure to allocate new storage.
- */
- if (buffer->attachment == __DRI_BUFFER_HIZ) {
- assert(rb->mt);
- intel_miptree_release(&rb->mt->hiz_mt);
- } else {
- intel_miptree_release(&rb->mt);
- }
-
- struct intel_region *region =
- intel_region_alloc_for_handle(intel->intelScreen,
- buffer_cpp,
- buffer_width,
- buffer_height,
- buffer_pitch / buffer_cpp,
- buffer->name,
- buffer_name);
+ intel_miptree_release(&rb->mt);
+ region = intel_region_alloc_for_handle(intel->intelScreen,
+ buffer->cpp,
+ drawable->w,
+ drawable->h,
+ buffer->pitch / buffer->cpp,
+ buffer->name,
+ buffer_name);
if (!region)
return;
- struct intel_mipmap_tree *mt =
- intel_miptree_create_for_region(intel,
- GL_TEXTURE_2D,
- intel_rb_format(rb),
- region);
+ rb->mt = intel_miptree_create_for_region(intel,
+ GL_TEXTURE_2D,
+ intel_rb_format(rb),
+ region);
intel_region_release(&region);
-
- /* Associate buffer with new storage. */
- if (buffer->attachment == __DRI_BUFFER_HIZ) {
- assert(rb->mt);
- rb->mt->hiz_mt = mt;
- } else {
- rb->mt = mt;
- }
-}
-
-/**
- * \brief Verify that the X driver supports hiz and separate stencil.
- *
- * This implements the cleanup stage of the handshake described in the
- * comments for 'enum intel_dri2_has_hiz'.
- *
- * This should be called from intel_update_renderbuffers() after 1) the
- * DRIdrawable has been queried for its buffers via DRI2GetBuffersWithFormat()
- * and 2) the DRM region of each returned DRIbuffer has been assigned to the
- * appropriate intel_renderbuffer. Furthermore, this should be called *only*
- * when 1) intel_update_renderbuffers() tried to used the X driver's separate
- * stencil functionality and 2) it has not yet been determined if the X driver
- * supports separate stencil.
- *
- * If we determine that the X driver does have support, then we set
- * intel_screen.dri2_has_hiz to true and return.
- *
- * If we determine that the X driver lacks support, and we requested
- * a DRI2BufferDepth and DRI2BufferStencil, then we must remedy the mistake by
- * taking the following actions:
- * 1. Discard the framebuffer's stencil and depth renderbuffers.
- * 2. Create a combined depth/stencil renderbuffer and attach
- * it to the framebuffer's depth and stencil attachment points.
- * 3. Query the drawable for a new set of buffers, which consists of the
- * originally requested set plus DRI2BufferDepthStencil.
- * 4. Assign the DRI2BufferDepthStencil's DRM region to the new
- * depth/stencil renderbuffer.
- *
- * \pre intel->intelScreen->dri2_has_hiz == INTEL_DRI2_HAS_HIZ_UNKNOWN
- *
- * \param drawable Drawable whose buffers were queried.
- *
- * \param buffers [in/out] As input, the buffer list returned by the
- * original DRI2 query. As output, the current buffer
- * list, which may have been altered by a new DRI2 query.
- *
- * \param attachments [in/out] As input, the attachment list submitted
- * in the original DRI2 query. As output, the attachment
- * list that was submitted in the DRI2 query that
- * obtained the current buffer list, as returned in the
- * output parameter \c buffers. (Note: If no new query
- * was made, then the list remains unaltered).
- *
- * \param count [out] Number of buffers in the current buffer list, as
- * returned in the output parameter \c buffers.
- *
- * \see enum intel_dri2_has_hiz
- * \see struct intel_screen::dri2_has_hiz
- * \see intel_update_renderbuffers
- */
-static void
-intel_verify_dri2_has_hiz(struct intel_context *intel,
- __DRIdrawable *drawable,
- __DRIbuffer **buffers,
- unsigned **attachments,
- int *count)
-{
- assert(intel->intelScreen->dri2_has_hiz == INTEL_DRI2_HAS_HIZ_UNKNOWN);
-
- struct gl_framebuffer *fb = drawable->driverPrivate;
- struct intel_renderbuffer *stencil_rb =
- intel_get_renderbuffer(fb, BUFFER_STENCIL);
-
- if (stencil_rb) {
- /*
- * We requested a DRI2BufferStencil without knowing if the X driver
- * supports it. Now, check if X handled the request correctly and clean
- * up if it did not. (See comments for 'enum intel_dri2_has_hiz').
- */
- struct intel_renderbuffer *depth_rb =
- intel_get_renderbuffer(fb, BUFFER_DEPTH);
- assert(intel_rb_format(stencil_rb) == MESA_FORMAT_S8);
- assert(depth_rb && intel_rb_format(depth_rb) == MESA_FORMAT_X8_Z24);
-
- if (stencil_rb->mt->region->tiling == I915_TILING_NONE) {
- /*
- * The stencil buffer is actually W tiled. The region's tiling is
- * I915_TILING_NONE, however, because the GTT is incapable of W
- * fencing.
- */
- intel->intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_TRUE;
- return;
- } else {
- /*
- * Oops... the screen doesn't support separate stencil. Discard the
- * separate depth and stencil buffers and replace them with
- * a combined depth/stencil buffer. Discard the hiz buffer too.
- */
- intel->intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_FALSE;
- if (intel->must_use_separate_stencil) {
- _mesa_problem(&intel->ctx,
- "intel_context requires separate stencil, but the "
- "DRIscreen does not support it. You may need to "
- "upgrade the Intel X driver to 2.16.0");
- abort();
- }
-
- /* 1. Discard depth and stencil renderbuffers. */
- _mesa_remove_renderbuffer(fb, BUFFER_DEPTH);
- depth_rb = NULL;
- _mesa_remove_renderbuffer(fb, BUFFER_STENCIL);
- stencil_rb = NULL;
-
- /* 2. Create new depth/stencil renderbuffer. */
- struct intel_renderbuffer *depth_stencil_rb =
- intel_create_renderbuffer(MESA_FORMAT_S8_Z24);
- _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth_stencil_rb->Base.Base);
- _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &depth_stencil_rb->Base.Base);
-
- /* 3. Append DRI2BufferDepthStencil to attachment list. */
- int old_count = *count;
- unsigned int *old_attachments = *attachments;
- *count = old_count + 1;
- *attachments = malloc(2 * (*count) * sizeof(unsigned));
- memcpy(*attachments, old_attachments, 2 * old_count * sizeof(unsigned));
- free(old_attachments);
- (*attachments)[2 * old_count + 0] = __DRI_BUFFER_DEPTH_STENCIL;
- (*attachments)[2 * old_count + 1] = intel_bits_per_pixel(depth_stencil_rb);
-
- /* 4. Request new set of DRI2 attachments. */
- __DRIscreen *screen = intel->intelScreen->driScrnPriv;
- *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
- &drawable->w,
- &drawable->h,
- *attachments,
- *count,
- count,
- drawable->loaderPrivate);
- if (!*buffers)
- return;
-
- /*
- * I don't know how to recover from the failure assertion below.
- * Rather than fail gradually and unexpectedly, we should just die
- * now.
- */
- assert(*count == old_count + 1);
-
- /* 5. Assign the DRI buffer's DRM region to the its renderbuffers. */
- __DRIbuffer *depth_stencil_buffer = NULL;
- for (int i = 0; i < *count; ++i) {
- if ((*buffers)[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
- depth_stencil_buffer = &(*buffers)[i];
- break;
- }
- }
- struct intel_region *region =
- intel_region_alloc_for_handle(intel->intelScreen,
- depth_stencil_buffer->cpp,
- drawable->w,
- drawable->h,
- depth_stencil_buffer->pitch
- / depth_stencil_buffer->cpp,
- depth_stencil_buffer->name,
- "dri2 depth / stencil buffer");
- if (!region)
- return;
-
- struct intel_mipmap_tree *mt =
- intel_miptree_create_for_region(intel,
- GL_TEXTURE_2D,
- intel_rb_format(depth_stencil_rb),
- region);
- intel_region_release(&region);
- if (!mt)
- return;
-
- intel_miptree_reference(&intel_get_renderbuffer(fb, BUFFER_DEPTH)->mt, mt);
- intel_miptree_reference(&intel_get_renderbuffer(fb, BUFFER_STENCIL)->mt, mt);
- intel_miptree_release(&mt);
- }
- }
-
- if (intel_framebuffer_has_hiz(fb)) {
- /*
- * In the future, the driver may advertise a GL config with hiz
- * compatible depth bits and 0 stencil bits (for example, when the
- * driver gains support for float32 depth buffers). When that day comes,
- * here we need to verify that the X driver does in fact support hiz and
- * clean up if it doesn't.
- *
- * Presently, however, no verification or clean up is necessary, and
- * execution should not reach here. If the framebuffer still has a hiz
- * region, then we have already set dri2_has_hiz to true after
- * confirming above that the stencil buffer is W tiled.
- */
- assert(0);
- }
}