There were only two places it was really used at this point, which was in the batchbuffer emit of the separate stencil packets for gen6/7. Just write in the ->stencil_mt reference in those two places and ditch all this flailing around with allocation and refcounts. v2: Fix separate stencil on gen7. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>tags/mesa-8.0-rc1
@@ -208,6 +208,7 @@ brw_depthbuffer_format(struct brw_context *brw) | |||
if (!drb && | |||
(srb = intel_get_renderbuffer(fb, BUFFER_STENCIL)) && | |||
!srb->mt->stencil_mt && | |||
srb->Base.Format == MESA_FORMAT_S8_Z24) { | |||
drb = srb; | |||
} | |||
@@ -239,8 +240,10 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
/* _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 && | |||
@@ -256,17 +259,21 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
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; | |||
@@ -275,7 +282,7 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
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) | | |||
@@ -292,7 +299,7 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
ADVANCE_BATCH(); | |||
} else if (!depth_irb && stencil_irb) { | |||
} else if (!depth_irb && separate_stencil) { | |||
/* | |||
* There exists a separate stencil buffer but no depth buffer. | |||
* | |||
@@ -317,10 +324,9 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
* 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)); | |||
@@ -346,7 +352,7 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
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); | |||
@@ -381,7 +387,7 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
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 | |||
@@ -408,8 +414,8 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
} | |||
/* 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); |
@@ -38,20 +38,32 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
/* _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); | |||
@@ -71,7 +83,7 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
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); | |||
@@ -84,7 +96,7 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
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, | |||
@@ -104,7 +116,7 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
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); | |||
@@ -113,8 +125,8 @@ static void emit_depthbuffer(struct brw_context *brw) | |||
} 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(); |
@@ -81,9 +81,12 @@ struct intel_region* | |||
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; | |||
} | |||
@@ -111,7 +114,6 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) | |||
intel_miptree_release(&irb->mt); | |||
_mesa_reference_renderbuffer(&irb->wrapped_depth, NULL); | |||
_mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL); | |||
free(irb); | |||
} | |||
@@ -260,24 +262,19 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer | |||
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; | |||
} | |||
@@ -288,13 +285,6 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer | |||
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; | |||
@@ -541,32 +531,25 @@ intel_renderbuffer_update_wrapper(struct intel_context *intel, | |||
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, | |||
@@ -574,20 +557,12 @@ intel_renderbuffer_update_wrapper(struct intel_context *intel, | |||
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 && | |||
@@ -857,8 +832,11 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) | |||
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) { |
@@ -72,7 +72,6 @@ struct intel_renderbuffer | |||
* 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 */ | |||
@@ -134,11 +133,6 @@ intel_get_renderbuffer(struct gl_framebuffer *fb, gl_buffer_index attIndex) | |||
irb = intel_renderbuffer(irb->wrapped_depth); | |||
} | |||
break; | |||
case BUFFER_STENCIL: | |||
if (irb->wrapped_stencil) { | |||
irb = intel_renderbuffer(irb->wrapped_stencil); | |||
} | |||
break; | |||
default: | |||
break; | |||
} |
@@ -149,8 +149,7 @@ struct intel_mipmap_tree | |||
* 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; | |||