diff options
author | Kristian H. Kristensen <[email protected]> | 2019-02-01 17:15:45 -0800 |
---|---|---|
committer | Kristian H. Kristensen <[email protected]> | 2019-02-11 12:26:21 -0800 |
commit | 03a01e5d23a566cdde989cd98f6a757cb98b7154 (patch) | |
tree | 3e23d1915d24e718d3dd815bd43b5ac5115e8583 /src/gallium/drivers/freedreno/a6xx | |
parent | e9592da2b4b62318031f26d3281a1ec928b3fdb3 (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.c | 85 |
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); |