From 3e6758a4e774d2906aba31410462346bd00a79cf Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Mon, 7 Jan 2019 11:58:53 -0800 Subject: 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. --- src/gallium/drivers/freedreno/a6xx/fd6_blitter.c | 70 +++++++++++++---- src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 23 ++++-- src/gallium/drivers/freedreno/a6xx/fd6_format.h | 7 ++ src/gallium/drivers/freedreno/a6xx/fd6_gmem.c | 91 +++++++++++++++++----- src/gallium/drivers/freedreno/a6xx/fd6_texture.c | 7 ++ src/gallium/drivers/freedreno/a6xx/fd6_texture.h | 1 + src/gallium/drivers/freedreno/freedreno_resource.h | 5 ++ 7 files changed, 160 insertions(+), 44 deletions(-) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c index b9118699dc0..f16eda74456 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c @@ -276,13 +276,15 @@ emit_blit_buffer(struct fd_ringbuffer *ring, const struct pipe_blit_info *info) /* * 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) | - A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(TILE6_LINEAR) | - A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(WZYX) | 0x500000); + A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(src->tile_mode) | + 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) | 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, 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_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 6); + 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: */ OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9); 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_COLOR_SWAP(WZYX)); - OUT_RELOC(ring, dst->bo, doff, 0, 0); /* RB_2D_DST_LO/HI */ + A6XX_RB_2D_DST_INFO_TILE_MODE(dst->tile_mode) | + A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX) | + 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, 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); + 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: */ @@ -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); - 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) | A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(stile) | A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(sswap) | A6XX_SP_PS_2D_SRC_INFO_SAMPLES(samples) | + COND(fd6_ubwc_enabled(src, stile), A6XX_SP_PS_2D_SRC_INFO_FLAGS) | 0x500000 | filter); OUT_RING(ring, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(width) | 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, 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_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 6); + 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: @@ -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_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(dfmt) | A6XX_RB_2D_DST_INFO_TILE_MODE(dtile) | - A6XX_RB_2D_DST_INFO_COLOR_SWAP(dswap)); - OUT_RELOCW(ring, dst->bo, doff, 0, 0); /* RB_2D_DST_LO/HI */ + A6XX_RB_2D_DST_INFO_COLOR_SWAP(dswap) | + 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, 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); + 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: */ diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 9fdc352c699..6115fda3b1a 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -411,17 +411,22 @@ fd6_emit_textures(struct fd_pipe *pipe, struct fd_ringbuffer *ring, static const struct fd6_pipe_sampler_view dummy_view = {}; const struct fd6_pipe_sampler_view *view = tex->textures[i] ? 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->texconst1); 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) { - struct fd_resource *rsc = fd_resource(view->base.texture); + if (rsc) { if (view->base.format == PIPE_FORMAT_X32_S8X24_UINT) 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); } else { 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->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->texconst10); OUT_RING(state, view->texconst11); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_format.h b/src/gallium/drivers/freedreno/a6xx/fd6_format.h index 321794771b3..a1ed03d60f4 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_format.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_format.h @@ -28,6 +28,7 @@ #ifndef FD6_UTIL_H_ #define FD6_UTIL_H_ +#include "freedreno_resource.h" #include "freedreno_util.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_ */ diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c index fa1090d0eaf..1c1ca65598c 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c @@ -92,6 +92,12 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb, stride = slice->pitch * rsc->cpp * pfb->samples; 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 && fd_resource_level_linear(psurf->texture, psurf->u.tex.level)) 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)); OUT_RING(ring, A6XX_RB_MRT_PITCH(stride)); 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_PKT4(ring, REG_A6XX_SP_FS_MRT_REG(i), 1); OUT_RING(ring, A6XX_SP_FS_MRT_REG_COLOR_FORMAT(format) | COND(sint, A6XX_SP_FS_MRT_REG_COLOR_SINT) | COND(uint, A6XX_SP_FS_MRT_REG_COLOR_UINT)); -#if 0 - /* when we support UBWC, these would be the system memory - * addr/pitch/etc: - */ - OUT_PKT4(ring, REG_A6XX_RB_MRT_FLAG_BUFFER(i), 4); - 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, A6XX_RB_MRT_FLAG_BUFFER_PITCH(0)); - OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_ARRAY_PITCH(0)); -#endif + OUT_PKT4(ring, REG_A6XX_RB_MRT_FLAG_BUFFER(i), 3); + if (fd6_ubwc_enabled(rsc, tile_mode)) { + 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) | + 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); + } } 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 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_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_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_PKT4(ring, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO, 1); 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_RING(ring, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_LO */ - OUT_RING(ring, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_HI */ - OUT_RING(ring, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_PITCH */ + if (ubwc_enabled) { + OUT_RELOCW(ring, rsc->bo, rsc->ubwc_offset, 0, 0); /* BASE_LO/HI */ + 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) { 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 -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; 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; if (binning) @@ -273,7 +310,9 @@ update_render_cntl(struct fd_batch *batch, bool binning) OUT_PKT7(ring, CP_REG_WRITE, 3); OUT_RING(ring, 0x2); 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 @@ -483,7 +522,7 @@ fd6_emit_tile_init(struct fd_batch *batch) if (use_hw_binning(batch)) { set_bin_size(ring, gmem->bin_w, gmem->bin_h, A6XX_RB_BIN_CONTROL_BINNING_PASS | 0x6000000); - update_render_cntl(batch, true); + update_render_cntl(batch, pfb, true); emit_binning_pass(batch); patch_draws(batch, USE_VISIBILITY); @@ -497,7 +536,7 @@ fd6_emit_tile_init(struct fd_batch *batch) patch_draws(batch, IGNORE_VISIBILITY); } - update_render_cntl(batch, false); + update_render_cntl(batch, pfb, false); } 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_SAMPLES(samples) | A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format) | - A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap)); - OUT_RELOCW(ring, rsc->bo, offset, 0, 0); /* RB_BLIT_DST_LO/HI */ + A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap) | + 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_ARRAY_PITCH(size)); OUT_PKT4(ring, REG_A6XX_RB_BLIT_BASE_GMEM, 1); 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); } @@ -1076,6 +1123,8 @@ fd6_emit_sysmem_prep(struct fd_batch *batch) emit_zs(ring, pfb->zsbuf, NULL); emit_mrt(ring, pfb, NULL); emit_msaa(ring, pfb->samples); + + update_render_cntl(batch, pfb, false); } static void diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c index 0d6bec72b14..6f61f4ed3da 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c @@ -288,6 +288,13 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, util_format_get_nblocksx( format, rsc->slices[lvl].pitch) * rsc->cpp); 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)); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h index 417aa72b9ae..122f60bba27 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h @@ -57,6 +57,7 @@ struct fd6_pipe_sampler_view { uint32_t offset; bool astc_srgb; uint16_t seqno; + bool ubwc_enabled; }; static inline struct fd6_pipe_sampler_view * diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h index 9cdeea863bc..6a207fe2dc2 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.h +++ b/src/gallium/drivers/freedreno/freedreno_resource.h @@ -78,6 +78,11 @@ struct fd_resource { /* TODO rename to secondary or auxiliary? */ 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 * that the batch doesn't hold reference to resources (but instead * the fd_ringbuffer holds refs to the underlying fd_bo), but in case -- cgit v1.2.3