if (!drb &&
(srb = intel_get_renderbuffer(fb, BUFFER_STENCIL)) &&
+ !srb->mt->stencil_mt &&
srb->Base.Format == MESA_FORMAT_S8_Z24) {
drb = srb;
}
/* _NEW_BUFFERS */
struct intel_renderbuffer *depth_irb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
struct intel_renderbuffer *stencil_irb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
+ struct intel_mipmap_tree *stencil_mt = NULL;
struct intel_region *hiz_region = NULL;
unsigned int len;
+ bool separate_stencil = false;
if (depth_irb &&
depth_irb->mt &&
intel_emit_depth_stall_flushes(intel);
}
- /*
- * If either depth or stencil buffer has packed depth/stencil format,
- * then don't use separate stencil. Emit only a depth buffer.
+ /* Find the real separate stencil mt if present. */
+ if (stencil_irb) {
+ stencil_mt = stencil_irb->mt;
+ if (stencil_mt->stencil_mt)
+ stencil_mt = stencil_mt->stencil_mt;
+
+ if (stencil_mt->format == MESA_FORMAT_S8)
+ separate_stencil = true;
+ }
+
+ /* If there's a packed depth/stencil bound to stencil only, we need to
+ * emit the packed depth/stencil buffer packet.
*/
- if (depth_irb && depth_irb->Base.Format == MESA_FORMAT_S8_Z24) {
- stencil_irb = NULL;
- } else if (!depth_irb && stencil_irb
- && stencil_irb->Base.Format == MESA_FORMAT_S8_Z24) {
+ if (!depth_irb && stencil_irb && !separate_stencil)
depth_irb = stencil_irb;
- stencil_irb = NULL;
- }
if (intel->gen >= 6)
len = 7;
else
len = 5;
- if (!depth_irb && !stencil_irb) {
+ if (!depth_irb && !separate_stencil) {
BEGIN_BATCH(len);
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2));
OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) |
ADVANCE_BATCH();
- } else if (!depth_irb && stencil_irb) {
+ } else if (!depth_irb && separate_stencil) {
/*
* There exists a separate stencil buffer but no depth buffer.
*
* Section 7.5.5.1.1 3DSTATE_DEPTH_BUFFER, Bit 1.27 Tiled Surface:
* [DevGT+]: This field must be set to TRUE.
*/
- struct intel_region *region = stencil_irb->mt->region;
+ struct intel_region *region = stencil_mt->region;
assert(intel->has_separate_stencil);
- assert(stencil_irb->Base.Format == MESA_FORMAT_S8);
BEGIN_BATCH(len);
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2));
uint32_t tile_x, tile_y, offset;
/* If using separate stencil, hiz must be enabled. */
- assert(!stencil_irb || hiz_region);
+ assert(!separate_stencil || hiz_region);
offset = intel_renderbuffer_tile_offsets(depth_irb, &tile_x, &tile_y);
ADVANCE_BATCH();
}
- if (hiz_region || stencil_irb) {
+ if (hiz_region || separate_stencil) {
/*
* In the 3DSTATE_DEPTH_BUFFER batch emitted above, the 'separate
* stencil enable' and 'hiz enable' bits were set. Therefore we must
}
/* Emit stencil buffer. */
- if (stencil_irb) {
- struct intel_region *region = stencil_irb->mt->region;
+ if (separate_stencil) {
+ struct intel_region *region = stencil_mt->region;
BEGIN_BATCH(3);
OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
OUT_BATCH(region->pitch * region->cpp - 1);
/* _NEW_BUFFERS */
struct intel_renderbuffer *drb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
struct intel_renderbuffer *srb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
+ struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL;
- intel_emit_depth_stall_flushes(intel);
+ if (drb)
+ depth_mt = drb->mt;
+
+ if (srb) {
+ stencil_mt = srb->mt;
+ if (stencil_mt->stencil_mt)
+ stencil_mt = stencil_mt->stencil_mt;
+
+ assert(stencil_mt->format == MESA_FORMAT_S8);
+ }
/* Gen7 doesn't support packed depth/stencil */
- assert(srb == NULL || srb != drb);
+ assert(stencil_mt == NULL || depth_mt != stencil_mt);
+
+ intel_emit_depth_stall_flushes(intel);
- if (drb == NULL) {
+ if (depth_mt == NULL) {
uint32_t dw1 = BRW_DEPTHFORMAT_D32_FLOAT << 18;
uint32_t dw3 = 0;
- if (srb == NULL) {
+ if (stencil_mt == NULL) {
dw1 |= (BRW_SURFACE_NULL << 29);
} else {
- struct intel_region *region = srb->mt->region;
+ struct intel_region *region = stencil_mt->region;
/* _NEW_STENCIL: enable stencil buffer writes */
dw1 |= ((ctx->Stencil.WriteMask != 0) << 27);
OUT_BATCH(0);
ADVANCE_BATCH();
} else {
- struct intel_region *region = drb->mt->region;
+ struct intel_region *region = depth_mt->region;
uint32_t tile_x, tile_y, offset;
offset = intel_renderbuffer_tile_offsets(drb, &tile_x, &tile_y);
OUT_BATCH(((region->pitch * region->cpp) - 1) |
(brw_depthbuffer_format(brw) << 18) |
(0 << 22) /* no HiZ buffer */ |
- ((srb != NULL && ctx->Stencil.WriteMask != 0) << 27) |
+ ((stencil_mt != NULL && ctx->Stencil.WriteMask != 0) << 27) |
((ctx->Depth.Mask != 0) << 28) |
(BRW_SURFACE_2D << 29));
OUT_RELOC(region->bo,
OUT_BATCH(0);
ADVANCE_BATCH();
- if (srb == NULL) {
+ if (stencil_mt == NULL) {
BEGIN_BATCH(3);
OUT_BATCH(GEN7_3DSTATE_STENCIL_BUFFER << 16 | (3 - 2));
OUT_BATCH(0);
} else {
BEGIN_BATCH(3);
OUT_BATCH(GEN7_3DSTATE_STENCIL_BUFFER << 16 | (3 - 2));
- OUT_BATCH(srb->mt->region->pitch * srb->mt->region->cpp - 1);
- OUT_RELOC(srb->mt->region->bo,
+ OUT_BATCH(stencil_mt->region->pitch * stencil_mt->region->cpp - 1);
+ OUT_RELOC(stencil_mt->region->bo,
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
0);
ADVANCE_BATCH();
intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
{
struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
- if (irb && irb->mt)
- return irb->mt->region;
- else
+ if (irb && irb->mt) {
+ if (attIndex == BUFFER_STENCIL && irb->mt->stencil_mt)
+ return irb->mt->stencil_mt->region;
+ else
+ return irb->mt->region;
+ } else
return NULL;
}
intel_miptree_release(&irb->mt);
_mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
- _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
free(irb);
}
if (irb->mt->stencil_mt) {
bool ok;
- struct intel_renderbuffer *depth_irb, *stencil_irb;
+ struct intel_renderbuffer *depth_irb;
/* The RB got allocated as separate stencil. Hook up our wrapped
- * renderbuffers so that consumers of intel_get_renderbuffer() end up
- * with pointers to the separate pieces.
+ * renderbuffer so that consumers of intel_get_renderbuffer(BUFFER_DEPTH)
+ * end up with pointers to the separate depth.
*/
if (!irb->wrapped_depth) {
_mesa_reference_renderbuffer(&irb->wrapped_depth,
intel_new_renderbuffer(ctx, ~0));
}
- if (!irb->wrapped_stencil) {
- _mesa_reference_renderbuffer(&irb->wrapped_stencil,
- intel_new_renderbuffer(ctx, ~0));
- }
depth_irb = intel_renderbuffer(irb->wrapped_depth);
- stencil_irb = intel_renderbuffer(irb->wrapped_stencil);
- if (!depth_irb || !stencil_irb) {
+ if (!depth_irb) {
intel_miptree_release(&irb->mt);
return false;
}
MESA_FORMAT_X8_Z24,
GL_DEPTH_COMPONENT24);
assert(ok);
-
- ok = intel_renderbuffer_update_wrapper(intel, stencil_irb,
- irb->mt->stencil_mt,
- 0, 0, /* level, layer */
- MESA_FORMAT_S8,
- GL_STENCIL_INDEX);
- assert(ok);
}
return true;
irb->mt_level = level;
irb->mt_layer = layer;
+ intel_miptree_reference(&irb->mt, mt);
if (mt->stencil_mt && _mesa_is_depthstencil_format(rb->InternalFormat)) {
- assert((irb->wrapped_depth == NULL) == (irb->wrapped_stencil == NULL));
-
struct intel_renderbuffer *depth_irb;
- struct intel_renderbuffer *stencil_irb;
if (!irb->wrapped_depth) {
depth_irb = intel_renderbuffer_wrap_miptree(intel,
mt, level, layer,
MESA_FORMAT_X8_Z24,
GL_DEPTH_COMPONENT24);
- stencil_irb = intel_renderbuffer_wrap_miptree(intel,
- mt->stencil_mt,
- level, layer,
- MESA_FORMAT_S8,
- GL_STENCIL_INDEX8);
_mesa_reference_renderbuffer(&irb->wrapped_depth, &depth_irb->Base);
- _mesa_reference_renderbuffer(&irb->wrapped_stencil, &stencil_irb->Base);
- if (!irb->wrapped_depth || !irb->wrapped_stencil)
+ if (!irb->wrapped_depth) {
+ intel_miptree_release(&irb->mt);
return false;
+ }
} else {
bool ok = true;
depth_irb = intel_renderbuffer(irb->wrapped_depth);
- stencil_irb = intel_renderbuffer(irb->wrapped_stencil);
ok &= intel_renderbuffer_update_wrapper(intel,
depth_irb,
level, layer,
MESA_FORMAT_X8_Z24,
GL_DEPTH_COMPONENT24);
- ok &= intel_renderbuffer_update_wrapper(intel,
- stencil_irb,
- mt->stencil_mt,
- level, layer,
- MESA_FORMAT_S8,
- GL_STENCIL_INDEX8);
- if (!ok)
+ if (!ok) {
+ intel_miptree_release(&irb->mt);
return false;
+ }
}
-
- intel_miptree_reference(&depth_irb->mt->stencil_mt, stencil_irb->mt);
- intel_miptree_reference(&irb->mt, depth_irb->mt);
} else {
- intel_miptree_reference(&irb->mt, mt);
intel_renderbuffer_set_draw_offset(irb);
if (mt->hiz_mt == NULL &&
if (depthRb)
depth_mt = depthRb->mt;
- if (stencilRb)
+ if (stencilRb) {
stencil_mt = stencilRb->mt;
+ if (stencil_mt->stencil_mt)
+ stencil_mt = stencil_mt->stencil_mt;
+ }
if (depth_mt && stencil_mt) {
if (depth_mt == stencil_mt) {
* are the real renderbuffers.
*/
struct gl_renderbuffer *wrapped_depth;
- struct gl_renderbuffer *wrapped_stencil;
/** \} */
GLuint draw_x, draw_y; /**< Offset of drawing within the region */
irb = intel_renderbuffer(irb->wrapped_depth);
}
break;
- case BUFFER_STENCIL:
- if (irb->wrapped_stencil) {
- irb = intel_renderbuffer(irb->wrapped_stencil);
- }
- break;
default:
break;
}
* two miptrees for storing the data. If the depthstencil texture or rb is
* MESA_FORMAT_Z32_FLOAT_X24S8, then mt->format will be
* MESA_FORMAT_Z32_FLOAT, otherwise for MESA_FORMAT_S8_Z24 objects it will be
- * MESA_FORMAT_S8_Z24 (textures) or MESA_FORMAT_X8_Z24 (renderbuffers).
- * mt->stencil_mt->format will always be MESA_FORMAT_S8.
+ * MESA_FORMAT_S8_Z24.
*/
gl_format format;