summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/a6xx
diff options
context:
space:
mode:
authorKristian H. Kristensen <[email protected]>2019-02-01 17:15:45 -0800
committerKristian H. Kristensen <[email protected]>2019-02-11 12:26:21 -0800
commit03a01e5d23a566cdde989cd98f6a757cb98b7154 (patch)
tree3e23d1915d24e718d3dd815bd43b5ac5115e8583 /src/gallium/drivers/freedreno/a6xx
parente9592da2b4b62318031f26d3281a1ec928b3fdb3 (diff)
freedreno/a6xx: Support some depth/stencil blits on blitter
We can rewrite almost all depth stencil blits to various red-only blits. The exception is depth-only or stencil-only blits into z24s8 combined depth stencil buffer. We can fall back for depth-only, but stencil-only remains broken. Fixes dEQP-GLES3.functional.fbo.blit.depth_stencil.depth24_stencil8_basic dEQP-GLES3.functional.fbo.blit.depth_stencil.depth24_stencil8_scale dEQP-GLES3.functional.fbo.blit.depth_stencil.depth32f_stencil8_basic dEQP-GLES3.functional.fbo.blit.depth_stencil.depth32f_stencil8_scale dEQP-GLES3.functional.fbo.blit.depth_stencil.depth32f_stencil8_stencil_only Reviewed-by: Rob Clark <[email protected]> Signed-off-by: Kristian H. Kristensen <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/a6xx')
-rw-r--r--src/gallium/drivers/freedreno/a6xx/fd6_blitter.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c
index b107d484050..0a741acf1d8 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c
@@ -56,6 +56,18 @@ static bool
ok_format(enum pipe_format pfmt)
{
enum a6xx_color_fmt fmt = fd6_pipe2color(pfmt);
+
+ switch (pfmt) {
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_Z32_UNORM:
+ case PIPE_FORMAT_Z32_FLOAT:
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ case PIPE_FORMAT_S8_UINT:
+ return true;
+ }
+
if (fmt == ~0)
return false;
@@ -138,6 +150,11 @@ can_do_blit(const struct pipe_blit_info *info)
fail_if(info->alpha_blend);
+ /* We can blit depth and stencil in most cases, except for depth only or
+ * stencil only to combined zs. */
+ fail_if(info->dst.format == PIPE_FORMAT_Z24_UNORM_S8_UINT &&
+ info->mask != PIPE_MASK_ZS);
+
return true;
}
@@ -505,6 +522,67 @@ emit_blit_texture(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
}
}
+static void
+rewrite_zs_blit(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
+{
+ struct pipe_blit_info separate = *info;
+
+ switch (info->src.format) {
+ case PIPE_FORMAT_S8_UINT:
+ debug_assert(info->mask == PIPE_MASK_S);
+ separate.mask = PIPE_MASK_R;
+ separate.src.format = PIPE_FORMAT_R8_UNORM;
+ separate.dst.format = PIPE_FORMAT_R8_UNORM;
+ emit_blit_texture(ring, &separate);
+ break;
+
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ if (info->mask & PIPE_MASK_Z) {
+ separate.mask = PIPE_MASK_R;
+ separate.src.format = PIPE_FORMAT_R32_FLOAT;
+ separate.dst.format = PIPE_FORMAT_R32_FLOAT;
+ emit_blit_texture(ring, &separate);
+ }
+ if (info->mask & PIPE_MASK_S) {
+ separate.mask = PIPE_MASK_R;
+ separate.src.format = PIPE_FORMAT_R8_UNORM;
+ separate.dst.format = PIPE_FORMAT_R8_UNORM;
+ separate.src.resource = &fd_resource(info->src.resource)->stencil->base;
+ separate.dst.resource = &fd_resource(info->dst.resource)->stencil->base;
+ emit_blit_texture(ring, &separate);
+ }
+ break;
+
+ case PIPE_FORMAT_Z16_UNORM:
+ separate.mask = PIPE_MASK_R;
+ separate.src.format = PIPE_FORMAT_R16_UNORM;
+ separate.dst.format = PIPE_FORMAT_R16_UNORM;
+ emit_blit_texture(ring, &separate);
+ break;
+
+ case PIPE_FORMAT_Z32_UNORM:
+ case PIPE_FORMAT_Z32_FLOAT:
+ debug_assert(info->mask == PIPE_MASK_Z);
+ separate.mask = PIPE_MASK_R;
+ separate.src.format = PIPE_FORMAT_R32_UINT;
+ separate.dst.format = PIPE_FORMAT_R32_UINT;
+ emit_blit_texture(ring, &separate);
+ break;
+
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ separate.mask = PIPE_MASK_R;
+ separate.src.format = PIPE_FORMAT_R32_UINT;
+ separate.dst.format = PIPE_FORMAT_R32_UINT;
+ emit_blit_texture(ring, &separate);
+ break;
+
+ default:
+ unreachable("");
+ }
+}
+
static bool
fd6_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
{
@@ -538,7 +616,12 @@ fd6_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
/* I don't *think* we need to handle blits between buffer <-> !buffer */
debug_assert(info->src.resource->target != PIPE_BUFFER);
debug_assert(info->dst.resource->target != PIPE_BUFFER);
- emit_blit_texture(batch->draw, info);
+
+ if (info->mask & (PIPE_MASK_ZS)) {
+ rewrite_zs_blit(batch->draw, info);
+ } else {
+ emit_blit_texture(batch->draw, info);
+ }
}
fd6_event_write(batch, batch->draw, 0x1d, true);