summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-03-29 20:54:42 -0400
committerIlia Mirkin <[email protected]>2015-04-02 00:09:14 -0400
commitd9992ab35a51c574dcfa8049859c0887956ecdf6 (patch)
tree537f89e1e1da4e99679c8b80a1f2d34cae524ef0
parent602bc6c88dbfa34083aa9d229fb6396b008e23eb (diff)
freedreno: add support for laying out MRTs in gmem
Signed-off-by: Ilia Mirkin <[email protected]>
-rw-r--r--src/gallium/drivers/freedreno/freedreno_gmem.c53
-rw-r--r--src/gallium/drivers/freedreno/freedreno_gmem.h6
2 files changed, 43 insertions, 16 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c
index afe088ac261..6bdd7704b86 100644
--- a/src/gallium/drivers/freedreno/freedreno_gmem.c
+++ b/src/gallium/drivers/freedreno/freedreno_gmem.c
@@ -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,26 +108,27 @@ 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 (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 ((gmem->cpp == cpp) && (gmem->has_zs == has_zs) &&
- !memcmp(&gmem->scissor, scissor, sizeof(gmem->scissor))) {
+ 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 have depth/stencil, we need to leave room: */
- if (has_zs) {
- gmem_size /= 2;
- max_width /= 2;
- }
-
if (fd_mesa_debug & FD_DBG_NOSCIS) {
minx = 0;
miny = 0;
@@ -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;
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.h b/src/gallium/drivers/freedreno/freedreno_gmem.h
index ff322df3c2f..81f9b6abe98 100644
--- a/src/gallium/drivers/freedreno/freedreno_gmem.h
+++ b/src/gallium/drivers/freedreno/freedreno_gmem.h
@@ -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;