freedreno: add support for laying out MRTs in gmem

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Ilia Mirkin
2015-03-29 20:54:42 -04:00
parent 602bc6c88d
commit d9992ab35a
2 changed files with 44 additions and 17 deletions
+40 -15
View File
@@ -76,6 +76,27 @@ static uint32_t bin_width(struct fd_context *ctx)
return 512;
}
static uint32_t
total_size(uint8_t cbuf_cpp[], uint8_t zsbuf_cpp,
uint32_t bin_w, uint32_t bin_h, struct fd_gmem_stateobj *gmem)
{
uint32_t total = 0, i;
for (i = 0; i < 4; i++) {
if (cbuf_cpp[i]) {
gmem->cbuf_base[i] = align(total, 0x4000);
total = gmem->cbuf_base[i] + cbuf_cpp[i] * bin_w * bin_h;
}
}
if (zsbuf_cpp) {
gmem->zsbuf_base = align(total, 0x4000);
total = gmem->zsbuf_base + zsbuf_cpp * bin_w * bin_h;
}
return total;
}
static void
calculate_tiles(struct fd_context *ctx)
{
@@ -87,24 +108,25 @@ calculate_tiles(struct fd_context *ctx)
uint32_t nbins_x = 1, nbins_y = 1;
uint32_t bin_w, bin_h;
uint32_t max_width = bin_width(ctx);
uint32_t cpp = 4;
uint8_t cbuf_cpp[4] = {0}, zsbuf_cpp = 0;
uint32_t i, j, t, xoff, yoff;
uint32_t tpp_x, tpp_y;
bool has_zs = !!(ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL));
if (pfb->cbufs[0])
cpp = util_format_get_blocksize(pfb->cbufs[0]->format);
if ((gmem->cpp == cpp) && (gmem->has_zs == has_zs) &&
!memcmp(&gmem->scissor, scissor, sizeof(gmem->scissor))) {
/* everything is up-to-date */
return;
if (has_zs)
zsbuf_cpp = util_format_get_blocksize(pfb->zsbuf->format);
for (i = 0; i < pfb->nr_cbufs; i++) {
if (pfb->cbufs[i])
cbuf_cpp[i] = util_format_get_blocksize(pfb->cbufs[i]->format);
else
cbuf_cpp[i] = 4;
}
/* if have depth/stencil, we need to leave room: */
if (has_zs) {
gmem_size /= 2;
max_width /= 2;
if (gmem->zsbuf_cpp == zsbuf_cpp &&
!memcmp(gmem->cbuf_cpp, cbuf_cpp, sizeof(cbuf_cpp)) &&
!memcmp(&gmem->scissor, scissor, sizeof(gmem->scissor))) {
/* everything is up-to-date */
return;
}
if (fd_mesa_debug & FD_DBG_NOSCIS) {
@@ -133,7 +155,10 @@ calculate_tiles(struct fd_context *ctx)
/* then find a bin width/height that satisfies the memory
* constraints:
*/
while ((bin_w * bin_h * cpp) > gmem_size) {
DBG("binning input: cbuf cpp: %d %d %d %d, zsbuf cpp: %d; %dx%d",
cbuf_cpp[0], cbuf_cpp[1], cbuf_cpp[2], cbuf_cpp[3], zsbuf_cpp,
width, height);
while (total_size(cbuf_cpp, zsbuf_cpp, bin_w, bin_h, gmem) > gmem_size) {
if (bin_w > bin_h) {
nbins_x++;
bin_w = align(width / nbins_x, 32);
@@ -146,8 +171,8 @@ calculate_tiles(struct fd_context *ctx)
DBG("using %d bins of size %dx%d", nbins_x*nbins_y, bin_w, bin_h);
gmem->scissor = *scissor;
gmem->cpp = cpp;
gmem->has_zs = has_zs;
memcpy(gmem->cbuf_cpp, cbuf_cpp, sizeof(cbuf_cpp));
gmem->zsbuf_cpp = zsbuf_cpp;
gmem->bin_h = bin_h;
gmem->bin_w = bin_w;
gmem->nbins_x = nbins_x;
@@ -47,12 +47,14 @@ struct fd_tile {
struct fd_gmem_stateobj {
struct pipe_scissor_state scissor;
uint cpp;
uint32_t cbuf_base[4];
uint32_t zsbuf_base;
uint8_t cbuf_cpp[4];
uint8_t zsbuf_cpp;
uint16_t bin_h, nbins_y;
uint16_t bin_w, nbins_x;
uint16_t minx, miny;
uint16_t width, height;
bool has_zs; /* gmem config using depth/stencil? */
};
struct fd_context;