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);
|
fd6_emit_lrz_flush(ring);
|
||||||
|
|
||||||
struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
|
struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
|
||||||
OUT_REG(ring, A6XX_GRAS_LRZ_BUFFER_BASE(.bo = subpass->lrz),
|
OUT_REG(ring,
|
||||||
A6XX_GRAS_LRZ_BUFFER_PITCH(.pitch = zsbuf->lrz_pitch),
|
A6XX_GRAS_LRZ_BUFFER_BASE(.bo = subpass->lrz),
|
||||||
A6XX_GRAS_LRZ_FAST_CLEAR_BUFFER_BASE());
|
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);
|
fd_ringbuffer_attach_bo(ring, subpass->lrz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "a6xx/fd6_blitter.h"
|
#include "a6xx/fd6_blitter.h"
|
||||||
#include "fd6_resource.h"
|
#include "fd6_resource.h"
|
||||||
#include "fdl/fd6_format_table.h"
|
#include "fdl/fd6_format_table.h"
|
||||||
|
#include "common/freedreno_lrz.h"
|
||||||
#include "common/freedreno_ubwc.h"
|
#include "common/freedreno_ubwc.h"
|
||||||
|
|
||||||
#include "a6xx.xml.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
|
static void
|
||||||
setup_lrz(struct fd_resource *rsc)
|
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_pitch = align(DIV_ROUND_UP(width0, 8), 32);
|
||||||
unsigned lrz_height = align(DIV_ROUND_UP(height0, 8), 16);
|
unsigned lrz_height = align(DIV_ROUND_UP(height0, 8), 16);
|
||||||
|
|
||||||
unsigned size = lrz_pitch * lrz_height * 2;
|
|
||||||
|
|
||||||
rsc->lrz_height = lrz_height;
|
rsc->lrz_height = lrz_height;
|
||||||
rsc->lrz_width = lrz_pitch;
|
rsc->lrz_width = lrz_pitch;
|
||||||
rsc->lrz_pitch = 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
|
static uint32_t
|
||||||
fd6_setup_slices(struct fd_resource *rsc)
|
fd6_setup_slices(struct fd_resource *rsc)
|
||||||
{
|
{
|
||||||
struct pipe_resource *prsc = &rsc->b.b;
|
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))
|
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))
|
if (rsc->layout.ubwc && !ok_ubwc_format(prsc->screen, prsc->format))
|
||||||
rsc->layout.ubwc = false;
|
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_width; // for lrz clear, does this differ from lrz_pitch?
|
||||||
uint16_t lrz_height;
|
uint16_t lrz_height;
|
||||||
uint16_t lrz_pitch;
|
uint16_t lrz_pitch;
|
||||||
|
uint16_t lrz_fc_offset;
|
||||||
struct fd_bo *lrz;
|
struct fd_bo *lrz;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user