return true;
}
-static bool is_z32(enum pipe_format format)
-{
- switch (format) {
- case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
- case PIPE_FORMAT_Z32_UNORM:
- case PIPE_FORMAT_Z32_FLOAT:
- return true;
- default:
- return false;
- }
-}
-
static void
fd6_clear_lrz(struct fd_batch *batch, struct fd_resource *zsbuf, double depth)
{
struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
struct fd_ringbuffer *ring = ctx->batch->draw;
- if ((buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
- is_z32(pfb->zsbuf->format))
- return false;
-
OUT_PKT4(ring, REG_A6XX_RB_BLIT_SCISSOR_TL, 2);
OUT_RING(ring, A6XX_RB_BLIT_SCISSOR_TL_X(scissor->minx) |
A6XX_RB_BLIT_SCISSOR_TL_Y(scissor->miny));
}
}
- if (pfb->zsbuf && (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
+ const bool has_depth = pfb->zsbuf;
+ const bool has_separate_stencil =
+ has_depth && fd_resource(pfb->zsbuf->texture)->stencil;
+
+ /* First clear depth or combined depth/stencil. */
+ if ((has_depth && (buffers & PIPE_CLEAR_DEPTH)) ||
+ (!has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL))) {
enum pipe_format pfmt = pfb->zsbuf->format;
- uint32_t clear = util_pack_z_stencil(pfmt, depth, stencil);
+ uint32_t clear_value;
uint32_t mask = 0;
+ if (has_separate_stencil) {
+ pfmt = util_format_get_depth_only(pfb->zsbuf->format);
+ clear_value = util_pack_z(pfmt, depth);
+ } else {
+ pfmt = pfb->zsbuf->format;
+ clear_value = util_pack_z_stencil(pfmt, depth, stencil);
+ }
+
if (buffers & PIPE_CLEAR_DEPTH)
mask |= 0x1;
- if (buffers & PIPE_CLEAR_STENCIL)
+ if (!has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL))
mask |= 0x2;
OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1);
OUT_RING(ring, 0);
OUT_PKT4(ring, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 1);
- OUT_RING(ring, clear);
+ OUT_RING(ring, clear_value);
fd6_emit_blit(ctx->batch, ring);
+ }
- if (pfb->zsbuf && (buffers & PIPE_CLEAR_DEPTH)) {
- struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
- if (zsbuf->lrz) {
- zsbuf->lrz_valid = true;
- fd6_clear_lrz(ctx->batch, zsbuf, depth);
- }
+ /* Then clear the separate stencil buffer in case of 32 bit depth
+ * formats with separate stencil. */
+ if (has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL)) {
+ OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1);
+ OUT_RING(ring, A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) |
+ A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(RB6_R8_UINT));
+
+ OUT_PKT4(ring, REG_A6XX_RB_BLIT_INFO, 1);
+ OUT_RING(ring, A6XX_RB_BLIT_INFO_GMEM |
+ //A6XX_RB_BLIT_INFO_UNK0 |
+ A6XX_RB_BLIT_INFO_DEPTH |
+ A6XX_RB_BLIT_INFO_CLEAR_MASK(0x1));
+
+ OUT_PKT4(ring, REG_A6XX_RB_BLIT_BASE_GMEM, 1);
+ OUT_RINGP(ring, MAX_RENDER_TARGETS + 1, &ctx->batch->gmem_patches);
+
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_88D0, 1);
+ OUT_RING(ring, 0);
+
+ OUT_PKT4(ring, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 1);
+ OUT_RING(ring, stencil & 0xff);
+
+ fd6_emit_blit(ctx->batch, ring);
+ }
+
+ if (has_depth && (buffers & PIPE_CLEAR_DEPTH)) {
+ struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
+ if (zsbuf->lrz) {
+ zsbuf->lrz_valid = true;
+ fd6_clear_lrz(ctx->batch, zsbuf, depth);
}
}