freedreno/a6xx: UBWC support

Universal bandwidth compression(UBWC) reduces memory bandwidth
by compressing buffers. This compression takes the form of
a full sized image buffer as well as a smaller metadata buffer.
This commit is contained in:
Fritz Koenig 2019-01-07 11:58:53 -08:00 committed by Rob Clark
parent 41082446db
commit 3e6758a4e7
7 changed files with 160 additions and 44 deletions

View file

@ -276,13 +276,15 @@ emit_blit_buffer(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
/* /*
* Emit source: * Emit source:
*/ */
OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 13); OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
OUT_RING(ring, A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(RB6_R8_UNORM) | OUT_RING(ring, A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(RB6_R8_UNORM) |
A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(TILE6_LINEAR) | A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(src->tile_mode) |
A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(WZYX) | 0x500000); A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(WZYX) |
COND(fd6_ubwc_enabled(src, src->tile_mode), A6XX_SP_PS_2D_SRC_INFO_FLAGS) |
0x500000);
OUT_RING(ring, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(sshift + w) | OUT_RING(ring, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(sshift + w) |
A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(1)); /* SP_PS_2D_SRC_SIZE */ A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(1)); /* SP_PS_2D_SRC_SIZE */
OUT_RELOC(ring, src->bo, soff, 0, 0); /* SP_PS_2D_SRC_LO/HI */ OUT_RELOC(ring, src->bo, soff + src->offset, 0, 0); /* SP_PS_2D_SRC_LO/HI */
OUT_RING(ring, A6XX_SP_PS_2D_SRC_PITCH_PITCH(p)); OUT_RING(ring, A6XX_SP_PS_2D_SRC_PITCH_PITCH(p));
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
@ -291,18 +293,25 @@ emit_blit_buffer(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); if (fd6_ubwc_enabled(src, src->tile_mode)) {
OUT_RING(ring, 0x00000000); OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 6);
OUT_RING(ring, 0x00000000); OUT_RELOC(ring, src->bo, soff + src->ubwc_offset, 0, 0);
OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(src->ubwc_pitch) |
A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(src->ubwc_size));
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
}
/* /*
* Emit destination: * Emit destination:
*/ */
OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9); OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9);
OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(RB6_R8_UNORM) | OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(RB6_R8_UNORM) |
A6XX_RB_2D_DST_INFO_TILE_MODE(TILE6_LINEAR) | A6XX_RB_2D_DST_INFO_TILE_MODE(dst->tile_mode) |
A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX)); A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX) |
OUT_RELOC(ring, dst->bo, doff, 0, 0); /* RB_2D_DST_LO/HI */ COND(fd6_ubwc_enabled(dst, dst->tile_mode), A6XX_RB_2D_DST_INFO_FLAGS));
OUT_RELOC(ring, dst->bo, doff + dst->offset, 0, 0); /* RB_2D_DST_LO/HI */
OUT_RING(ring, A6XX_RB_2D_DST_SIZE_PITCH(p)); OUT_RING(ring, A6XX_RB_2D_DST_SIZE_PITCH(p));
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
@ -310,6 +319,15 @@ emit_blit_buffer(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
if (fd6_ubwc_enabled(dst, dst->tile_mode)) {
OUT_PKT4(ring, REG_A6XX_RB_2D_DST_FLAGS_LO, 6);
OUT_RELOC(ring, dst->bo, doff + dst->ubwc_offset, 0, 0);
OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(dst->ubwc_pitch) |
A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(dst->ubwc_size));
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
}
/* /*
* Blit command: * Blit command:
*/ */
@ -453,25 +471,33 @@ emit_blit_texture(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
enum a3xx_msaa_samples samples = fd_msaa_samples(src->base.nr_samples); enum a3xx_msaa_samples samples = fd_msaa_samples(src->base.nr_samples);
OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 13); OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
OUT_RING(ring, A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(sfmt) | OUT_RING(ring, A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(sfmt) |
A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(stile) | A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(stile) |
A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(sswap) | A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(sswap) |
A6XX_SP_PS_2D_SRC_INFO_SAMPLES(samples) | A6XX_SP_PS_2D_SRC_INFO_SAMPLES(samples) |
COND(fd6_ubwc_enabled(src, stile), A6XX_SP_PS_2D_SRC_INFO_FLAGS) |
0x500000 | filter); 0x500000 | filter);
OUT_RING(ring, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(width) | OUT_RING(ring, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(width) |
A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(height)); /* SP_PS_2D_SRC_SIZE */ A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(height)); /* SP_PS_2D_SRC_SIZE */
OUT_RELOC(ring, src->bo, soff, 0, 0); /* SP_PS_2D_SRC_LO/HI */ OUT_RELOC(ring, src->bo, soff + src->offset, 0, 0); /* SP_PS_2D_SRC_LO/HI */
OUT_RING(ring, A6XX_SP_PS_2D_SRC_PITCH_PITCH(spitch)); OUT_RING(ring, A6XX_SP_PS_2D_SRC_PITCH_PITCH(spitch));
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); if (fd6_ubwc_enabled(src, stile)) {
OUT_RING(ring, 0x00000000); OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 6);
OUT_RING(ring, 0x00000000); OUT_RELOC(ring, src->bo, soff + src->ubwc_offset, 0, 0);
OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(src->ubwc_pitch) |
A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(src->ubwc_size));
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
}
/* /*
* Emit destination: * Emit destination:
@ -479,8 +505,9 @@ emit_blit_texture(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9); OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9);
OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(dfmt) | OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(dfmt) |
A6XX_RB_2D_DST_INFO_TILE_MODE(dtile) | A6XX_RB_2D_DST_INFO_TILE_MODE(dtile) |
A6XX_RB_2D_DST_INFO_COLOR_SWAP(dswap)); A6XX_RB_2D_DST_INFO_COLOR_SWAP(dswap) |
OUT_RELOCW(ring, dst->bo, doff, 0, 0); /* RB_2D_DST_LO/HI */ COND(fd6_ubwc_enabled(dst, dtile), A6XX_RB_2D_DST_INFO_FLAGS));
OUT_RELOCW(ring, dst->bo, doff + dst->offset, 0, 0); /* RB_2D_DST_LO/HI */
OUT_RING(ring, A6XX_RB_2D_DST_SIZE_PITCH(dpitch)); OUT_RING(ring, A6XX_RB_2D_DST_SIZE_PITCH(dpitch));
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
@ -488,6 +515,15 @@ emit_blit_texture(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
if (fd6_ubwc_enabled(dst, dtile)) {
OUT_PKT4(ring, REG_A6XX_RB_2D_DST_FLAGS_LO, 6);
OUT_RELOC(ring, dst->bo, doff + dst->ubwc_offset, 0, 0);
OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(dst->ubwc_pitch) |
A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(dst->ubwc_size));
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);
}
/* /*
* Blit command: * Blit command:
*/ */

View file

@ -411,17 +411,22 @@ fd6_emit_textures(struct fd_pipe *pipe, struct fd_ringbuffer *ring,
static const struct fd6_pipe_sampler_view dummy_view = {}; static const struct fd6_pipe_sampler_view dummy_view = {};
const struct fd6_pipe_sampler_view *view = tex->textures[i] ? const struct fd6_pipe_sampler_view *view = tex->textures[i] ?
fd6_pipe_sampler_view(tex->textures[i]) : &dummy_view; fd6_pipe_sampler_view(tex->textures[i]) : &dummy_view;
struct fd_resource *rsc = NULL;
if (view->base.texture)
rsc = fd_resource(view->base.texture);
OUT_RING(state, view->texconst0); OUT_RING(state, view->texconst0);
OUT_RING(state, view->texconst1); OUT_RING(state, view->texconst1);
OUT_RING(state, view->texconst2); OUT_RING(state, view->texconst2);
OUT_RING(state, view->texconst3); OUT_RING(state, view->texconst3 |
COND(rsc && view->ubwc_enabled,
A6XX_TEX_CONST_3_FLAG | A6XX_TEX_CONST_3_UNK27));
if (view->base.texture) { if (rsc) {
struct fd_resource *rsc = fd_resource(view->base.texture);
if (view->base.format == PIPE_FORMAT_X32_S8X24_UINT) if (view->base.format == PIPE_FORMAT_X32_S8X24_UINT)
rsc = rsc->stencil; rsc = rsc->stencil;
OUT_RELOC(state, rsc->bo, view->offset, OUT_RELOC(state, rsc->bo, view->offset + rsc->offset,
(uint64_t)view->texconst5 << 32, 0); (uint64_t)view->texconst5 << 32, 0);
} else { } else {
OUT_RING(state, 0x00000000); OUT_RING(state, 0x00000000);
@ -429,8 +434,14 @@ fd6_emit_textures(struct fd_pipe *pipe, struct fd_ringbuffer *ring,
} }
OUT_RING(state, view->texconst6); OUT_RING(state, view->texconst6);
OUT_RING(state, view->texconst7);
OUT_RING(state, view->texconst8); if (rsc && view->ubwc_enabled) {
OUT_RELOC(state, rsc->bo, view->offset + rsc->ubwc_offset, 0, 0);
} else {
OUT_RING(state, 0);
OUT_RING(state, 0);
}
OUT_RING(state, view->texconst9); OUT_RING(state, view->texconst9);
OUT_RING(state, view->texconst10); OUT_RING(state, view->texconst10);
OUT_RING(state, view->texconst11); OUT_RING(state, view->texconst11);

View file

@ -28,6 +28,7 @@
#ifndef FD6_UTIL_H_ #ifndef FD6_UTIL_H_
#define FD6_UTIL_H_ #define FD6_UTIL_H_
#include "freedreno_resource.h"
#include "freedreno_util.h" #include "freedreno_util.h"
#include "a6xx.xml.h" #include "a6xx.xml.h"
@ -113,4 +114,10 @@ fd6_ifmt(enum a6xx_color_fmt fmt)
} }
} }
static inline bool
fd6_ubwc_enabled(struct fd_resource *rsc, enum a6xx_tile_mode tile_mode)
{
return rsc->ubwc_size && tile_mode == TILE6_3;
}
#endif /* FD6_UTIL_H_ */ #endif /* FD6_UTIL_H_ */

View file

@ -92,6 +92,12 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
stride = slice->pitch * rsc->cpp * pfb->samples; stride = slice->pitch * rsc->cpp * pfb->samples;
swap = rsc->tile_mode ? WZYX : fd6_pipe2swap(pformat); swap = rsc->tile_mode ? WZYX : fd6_pipe2swap(pformat);
if (rsc->tile_mode &&
fd_resource_level_linear(psurf->texture, psurf->u.tex.level))
tile_mode = TILE6_LINEAR;
else
tile_mode = rsc->tile_mode;
if (rsc->tile_mode && if (rsc->tile_mode &&
fd_resource_level_linear(psurf->texture, psurf->u.tex.level)) fd_resource_level_linear(psurf->texture, psurf->u.tex.level))
tile_mode = TILE6_LINEAR; tile_mode = TILE6_LINEAR;
@ -107,23 +113,23 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap)); A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap));
OUT_RING(ring, A6XX_RB_MRT_PITCH(stride)); OUT_RING(ring, A6XX_RB_MRT_PITCH(stride));
OUT_RING(ring, A6XX_RB_MRT_ARRAY_PITCH(slice->size0)); OUT_RING(ring, A6XX_RB_MRT_ARRAY_PITCH(slice->size0));
OUT_RELOCW(ring, rsc->bo, offset, 0, 0); /* BASE_LO/HI */ OUT_RELOCW(ring, rsc->bo, offset + rsc->offset, 0, 0); /* BASE_LO/HI */
OUT_RING(ring, base); /* RB_MRT[i].BASE_GMEM */ OUT_RING(ring, base); /* RB_MRT[i].BASE_GMEM */
OUT_PKT4(ring, REG_A6XX_SP_FS_MRT_REG(i), 1); OUT_PKT4(ring, REG_A6XX_SP_FS_MRT_REG(i), 1);
OUT_RING(ring, A6XX_SP_FS_MRT_REG_COLOR_FORMAT(format) | OUT_RING(ring, A6XX_SP_FS_MRT_REG_COLOR_FORMAT(format) |
COND(sint, A6XX_SP_FS_MRT_REG_COLOR_SINT) | COND(sint, A6XX_SP_FS_MRT_REG_COLOR_SINT) |
COND(uint, A6XX_SP_FS_MRT_REG_COLOR_UINT)); COND(uint, A6XX_SP_FS_MRT_REG_COLOR_UINT));
#if 0 OUT_PKT4(ring, REG_A6XX_RB_MRT_FLAG_BUFFER(i), 3);
/* when we support UBWC, these would be the system memory if (fd6_ubwc_enabled(rsc, tile_mode)) {
* addr/pitch/etc: OUT_RELOCW(ring, rsc->bo, offset + rsc->ubwc_offset, 0, 0); /* BASE_LO/HI */
*/ OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(rsc->ubwc_pitch) |
OUT_PKT4(ring, REG_A6XX_RB_MRT_FLAG_BUFFER(i), 4); A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc->ubwc_size));
OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */ } else {
OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_HI */ OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */
OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH(0)); OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_HI */
OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_ARRAY_PITCH(0)); OUT_RING(ring, 0x00000000);
#endif }
} }
OUT_PKT4(ring, REG_A6XX_RB_SRGB_CNTL, 1); OUT_PKT4(ring, REG_A6XX_RB_SRGB_CNTL, 1);
@ -166,20 +172,29 @@ emit_zs(struct fd_ringbuffer *ring, struct pipe_surface *zsbuf,
uint32_t size = slice->size0; uint32_t size = slice->size0;
uint32_t base = gmem ? gmem->zsbuf_base[0] : 0; uint32_t base = gmem ? gmem->zsbuf_base[0] : 0;
bool ubwc_enabled =
!fd_resource_level_linear(zsbuf->texture, zsbuf->u.tex.level) && rsc->ubwc_size;
OUT_PKT4(ring, REG_A6XX_RB_DEPTH_BUFFER_INFO, 6); OUT_PKT4(ring, REG_A6XX_RB_DEPTH_BUFFER_INFO, 6);
OUT_RING(ring, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt)); OUT_RING(ring, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt));
OUT_RING(ring, A6XX_RB_DEPTH_BUFFER_PITCH(stride)); OUT_RING(ring, A6XX_RB_DEPTH_BUFFER_PITCH(stride));
OUT_RING(ring, A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(size)); OUT_RING(ring, A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(size));
OUT_RELOCW(ring, rsc->bo, 0, 0, 0); /* RB_DEPTH_BUFFER_BASE_LO/HI */ OUT_RELOCW(ring, rsc->bo, rsc->offset, 0, 0); /* RB_DEPTH_BUFFER_BASE_LO/HI */
OUT_RING(ring, base); /* RB_DEPTH_BUFFER_BASE_GMEM */ OUT_RING(ring, base); /* RB_DEPTH_BUFFER_BASE_GMEM */
OUT_PKT4(ring, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO, 1); OUT_PKT4(ring, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO, 1);
OUT_RING(ring, A6XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt)); OUT_RING(ring, A6XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt));
OUT_PKT4(ring, REG_A6XX_RB_DEPTH_FLAG_BUFFER_BASE_LO, 3); OUT_PKT4(ring, REG_A6XX_RB_DEPTH_FLAG_BUFFER_BASE_LO, 3);
OUT_RING(ring, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_LO */ if (ubwc_enabled) {
OUT_RING(ring, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_HI */ OUT_RELOCW(ring, rsc->bo, rsc->ubwc_offset, 0, 0); /* BASE_LO/HI */
OUT_RING(ring, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_PITCH */ OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(rsc->ubwc_pitch) |
A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc->ubwc_size));
} else {
OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */
OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_HI */
OUT_RING(ring, 0x00000000);
}
if (rsc->lrz) { if (rsc->lrz) {
OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO, 5); OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO, 5);
@ -261,10 +276,32 @@ patch_draws(struct fd_batch *batch, enum pc_di_vis_cull_mode vismode)
} }
static void static void
update_render_cntl(struct fd_batch *batch, bool binning) update_render_cntl(struct fd_batch *batch, struct pipe_framebuffer_state *pfb, bool binning)
{ {
struct fd_ringbuffer *ring = batch->gmem; struct fd_ringbuffer *ring = batch->gmem;
uint32_t cntl = 0; uint32_t cntl = 0;
bool depth_ubwc_enable = false;
uint32_t mrts_ubwc_enable = 0;
int i;
if (pfb->zsbuf) {
struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
depth_ubwc_enable =
!fd_resource_level_linear(pfb->zsbuf->texture, pfb->zsbuf->u.tex.level) && rsc->ubwc_size;
}
for (i = 0; i < pfb->nr_cbufs; i++) {
if (!pfb->cbufs[i])
continue;
struct pipe_surface *psurf = pfb->cbufs[i];
struct fd_resource *rsc = fd_resource(psurf->texture);
if (!rsc->bo)
continue;
if (fd6_ubwc_enabled(rsc, rsc->tile_mode))
mrts_ubwc_enable |= 1 << i;
}
cntl |= A6XX_RB_RENDER_CNTL_UNK4; cntl |= A6XX_RB_RENDER_CNTL_UNK4;
if (binning) if (binning)
@ -273,7 +310,9 @@ update_render_cntl(struct fd_batch *batch, bool binning)
OUT_PKT7(ring, CP_REG_WRITE, 3); OUT_PKT7(ring, CP_REG_WRITE, 3);
OUT_RING(ring, 0x2); OUT_RING(ring, 0x2);
OUT_RING(ring, REG_A6XX_RB_RENDER_CNTL); OUT_RING(ring, REG_A6XX_RB_RENDER_CNTL);
OUT_RING(ring, cntl); OUT_RING(ring, cntl |
COND(depth_ubwc_enable, A6XX_RB_RENDER_CNTL_FLAG_DEPTH) |
A6XX_RB_RENDER_CNTL_FLAG_MRTS(mrts_ubwc_enable));
} }
static void static void
@ -483,7 +522,7 @@ fd6_emit_tile_init(struct fd_batch *batch)
if (use_hw_binning(batch)) { if (use_hw_binning(batch)) {
set_bin_size(ring, gmem->bin_w, gmem->bin_h, set_bin_size(ring, gmem->bin_w, gmem->bin_h,
A6XX_RB_BIN_CONTROL_BINNING_PASS | 0x6000000); A6XX_RB_BIN_CONTROL_BINNING_PASS | 0x6000000);
update_render_cntl(batch, true); update_render_cntl(batch, pfb, true);
emit_binning_pass(batch); emit_binning_pass(batch);
patch_draws(batch, USE_VISIBILITY); patch_draws(batch, USE_VISIBILITY);
@ -497,7 +536,7 @@ fd6_emit_tile_init(struct fd_batch *batch)
patch_draws(batch, IGNORE_VISIBILITY); patch_draws(batch, IGNORE_VISIBILITY);
} }
update_render_cntl(batch, false); update_render_cntl(batch, pfb, false);
} }
static void static void
@ -640,14 +679,22 @@ emit_blit(struct fd_batch *batch,
A6XX_RB_BLIT_DST_INFO_TILE_MODE(tile_mode) | A6XX_RB_BLIT_DST_INFO_TILE_MODE(tile_mode) |
A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) | A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) |
A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format) | A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format) |
A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap)); A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap) |
OUT_RELOCW(ring, rsc->bo, offset, 0, 0); /* RB_BLIT_DST_LO/HI */ COND(fd6_ubwc_enabled(rsc, tile_mode), A6XX_RB_BLIT_DST_INFO_FLAGS));
OUT_RELOCW(ring, rsc->bo, offset + rsc->offset, 0, 0); /* RB_BLIT_DST_LO/HI */
OUT_RING(ring, A6XX_RB_BLIT_DST_PITCH(stride)); OUT_RING(ring, A6XX_RB_BLIT_DST_PITCH(stride));
OUT_RING(ring, A6XX_RB_BLIT_DST_ARRAY_PITCH(size)); OUT_RING(ring, A6XX_RB_BLIT_DST_ARRAY_PITCH(size));
OUT_PKT4(ring, REG_A6XX_RB_BLIT_BASE_GMEM, 1); OUT_PKT4(ring, REG_A6XX_RB_BLIT_BASE_GMEM, 1);
OUT_RING(ring, base); OUT_RING(ring, base);
if (fd6_ubwc_enabled(rsc, tile_mode)) {
OUT_PKT4(ring, REG_A6XX_RB_BLIT_FLAG_DST_LO, 3);
OUT_RELOCW(ring, rsc->bo, offset + rsc->ubwc_offset, 0, 0);
OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(rsc->ubwc_pitch) |
A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc->ubwc_size));
}
fd6_emit_blit(batch, ring); fd6_emit_blit(batch, ring);
} }
@ -1076,6 +1123,8 @@ fd6_emit_sysmem_prep(struct fd_batch *batch)
emit_zs(ring, pfb->zsbuf, NULL); emit_zs(ring, pfb->zsbuf, NULL);
emit_mrt(ring, pfb, NULL); emit_mrt(ring, pfb, NULL);
emit_msaa(ring, pfb->samples); emit_msaa(ring, pfb->samples);
update_render_cntl(batch, pfb, false);
} }
static void static void

View file

@ -288,6 +288,13 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
util_format_get_nblocksx( util_format_get_nblocksx(
format, rsc->slices[lvl].pitch) * rsc->cpp); format, rsc->slices[lvl].pitch) * rsc->cpp);
so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer); so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer);
so->ubwc_enabled = rsc->ubwc_size && u_minify(prsc->width0, lvl) >= 16;
}
if (so->ubwc_enabled) {
so->texconst9 |= A6XX_TEX_CONST_9_FLAG_BUFFER_PITCH(rsc->ubwc_size);
so->texconst10 |= A6XX_TEX_CONST_10_FLAG_BUFFER_ARRAY_PITCH(rsc->ubwc_pitch);
} }
so->texconst2 |= A6XX_TEX_CONST_2_TYPE(fd6_tex_type(cso->target)); so->texconst2 |= A6XX_TEX_CONST_2_TYPE(fd6_tex_type(cso->target));

View file

@ -57,6 +57,7 @@ struct fd6_pipe_sampler_view {
uint32_t offset; uint32_t offset;
bool astc_srgb; bool astc_srgb;
uint16_t seqno; uint16_t seqno;
bool ubwc_enabled;
}; };
static inline struct fd6_pipe_sampler_view * static inline struct fd6_pipe_sampler_view *

View file

@ -78,6 +78,11 @@ struct fd_resource {
/* TODO rename to secondary or auxiliary? */ /* TODO rename to secondary or auxiliary? */
struct fd_resource *stencil; struct fd_resource *stencil;
uint32_t offset;
uint32_t ubwc_offset;
uint32_t ubwc_pitch;
uint32_t ubwc_size;
/* bitmask of in-flight batches which reference this resource. Note /* bitmask of in-flight batches which reference this resource. Note
* that the batch doesn't hold reference to resources (but instead * that the batch doesn't hold reference to resources (but instead
* the fd_ringbuffer holds refs to the underlying fd_bo), but in case * the fd_ringbuffer holds refs to the underlying fd_bo), but in case