freedreno/a6xx: Allocate lrcfc when needed for direction tracking
On later GPUs this buffer is also used for direction tracking, etc. Meaning that it is not optional. Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30304>
This commit is contained in:
@@ -281,9 +281,14 @@ emit_lrz(struct fd_batch *batch, struct fd_batch_subpass *subpass)
|
||||
fd6_emit_lrz_flush(ring);
|
||||
|
||||
struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
|
||||
OUT_REG(ring, A6XX_GRAS_LRZ_BUFFER_BASE(.bo = subpass->lrz),
|
||||
A6XX_GRAS_LRZ_BUFFER_PITCH(.pitch = zsbuf->lrz_pitch),
|
||||
A6XX_GRAS_LRZ_FAST_CLEAR_BUFFER_BASE());
|
||||
OUT_REG(ring,
|
||||
A6XX_GRAS_LRZ_BUFFER_BASE(.bo = subpass->lrz),
|
||||
A6XX_GRAS_LRZ_BUFFER_PITCH(.pitch = zsbuf->lrz_pitch),
|
||||
A6XX_GRAS_LRZ_FAST_CLEAR_BUFFER_BASE(
|
||||
.bo = zsbuf->lrz_fc_offset ? subpass->lrz : NULL,
|
||||
.bo_offset = zsbuf->lrz_fc_offset
|
||||
),
|
||||
);
|
||||
fd_ringbuffer_attach_bo(ring, subpass->lrz);
|
||||
}
|
||||
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "a6xx/fd6_blitter.h"
|
||||
#include "fd6_resource.h"
|
||||
#include "fdl/fd6_format_table.h"
|
||||
#include "common/freedreno_lrz.h"
|
||||
#include "common/freedreno_ubwc.h"
|
||||
|
||||
#include "a6xx.xml.h"
|
||||
@@ -233,6 +234,7 @@ fd6_validate_format(struct fd_context *ctx, struct fd_resource *rsc,
|
||||
}
|
||||
}
|
||||
|
||||
template <chip CHIP>
|
||||
static void
|
||||
setup_lrz(struct fd_resource *rsc)
|
||||
{
|
||||
@@ -252,21 +254,43 @@ setup_lrz(struct fd_resource *rsc)
|
||||
unsigned lrz_pitch = align(DIV_ROUND_UP(width0, 8), 32);
|
||||
unsigned lrz_height = align(DIV_ROUND_UP(height0, 8), 16);
|
||||
|
||||
unsigned size = lrz_pitch * lrz_height * 2;
|
||||
|
||||
rsc->lrz_height = lrz_height;
|
||||
rsc->lrz_width = lrz_pitch;
|
||||
rsc->lrz_pitch = lrz_pitch;
|
||||
rsc->lrz = fd_bo_new(screen->dev, size, FD_BO_NOMAP, "lrz");
|
||||
|
||||
unsigned lrz_size = lrz_pitch * lrz_height * 2;
|
||||
|
||||
unsigned nblocksx = DIV_ROUND_UP(DIV_ROUND_UP(width0, 8), 16);
|
||||
unsigned nblocksy = DIV_ROUND_UP(DIV_ROUND_UP(height0, 8), 4);
|
||||
|
||||
/* Fast-clear buffer is 1bit/block */
|
||||
unsigned lrz_fc_size = DIV_ROUND_UP(nblocksx * nblocksy, 8);
|
||||
|
||||
/* Fast-clear buffer cannot be larger than 512 bytes on A6XX and 1024 bytes
|
||||
* on A7XX (HW limitation)
|
||||
*/
|
||||
bool has_lrz_fc = screen->info->a6xx.enable_lrz_fast_clear &&
|
||||
lrz_fc_size <= fd_lrzfc_layout<CHIP>::FC_SIZE;
|
||||
|
||||
/* Allocate a LRZ fast-clear buffer even if we aren't using FC, if the
|
||||
* hw is re-using this buffer for direction tracking
|
||||
*/
|
||||
if (has_lrz_fc || screen->info->a6xx.has_lrz_dir_tracking) {
|
||||
rsc->lrz_fc_offset = lrz_size;
|
||||
lrz_size += sizeof(fd_lrzfc_layout<CHIP>);
|
||||
}
|
||||
|
||||
rsc->lrz = fd_bo_new(screen->dev, lrz_size, FD_BO_NOMAP, "lrz");
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
fd6_setup_slices(struct fd_resource *rsc)
|
||||
{
|
||||
struct pipe_resource *prsc = &rsc->b.b;
|
||||
struct fd_screen *screen = fd_screen(prsc->screen);
|
||||
|
||||
if (!FD_DBG(NOLRZ) && has_depth(prsc->format) && !is_z32(prsc->format))
|
||||
setup_lrz(rsc);
|
||||
FD_CALLX(screen->info, setup_lrz)(rsc);
|
||||
|
||||
if (rsc->layout.ubwc && !ok_ubwc_format(prsc->screen, prsc->format))
|
||||
rsc->layout.ubwc = false;
|
||||
|
@@ -168,6 +168,7 @@ struct fd_resource {
|
||||
uint16_t lrz_width; // for lrz clear, does this differ from lrz_pitch?
|
||||
uint16_t lrz_height;
|
||||
uint16_t lrz_pitch;
|
||||
uint16_t lrz_fc_offset;
|
||||
struct fd_bo *lrz;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user