summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/freedreno_resource.c
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2016-06-27 09:44:15 -0400
committerRob Clark <[email protected]>2016-07-30 09:23:42 -0400
commit9f219c7047b51561f6f69274d445e6a6ec41c5f8 (patch)
tree9222818fd1f2d961640e0ae1752659ee58926268 /src/gallium/drivers/freedreno/freedreno_resource.c
parentf02a64dbdd2ec147167ad60357bd46d8d964290a (diff)
freedreno: add batch-cache and batch reordering
Note that I originally also had a entry-point that would construct a key and do lookup from a pipe_surface. I ended up not needing that (yet?) but it is easy-enough to re-introduce later if we need it for the blit path. For now, not enabled by default, but can be enabled (on a3xx/a4xx) with FD_MESA_DEBUG=reorder. Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/freedreno_resource.c')
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 20d68fed9d5..ae8061cba28 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -33,8 +33,10 @@
#include "util/u_transfer.h"
#include "util/u_string.h"
#include "util/u_surface.h"
+#include "util/set.h"
#include "freedreno_resource.h"
+#include "freedreno_batch_cache.h"
#include "freedreno_screen.h"
#include "freedreno_surface.h"
#include "freedreno_context.h"
@@ -47,10 +49,20 @@
#include "state_tracker/drm_driver.h"
static bool
-pending(struct fd_resource *rsc, enum fd_resource_status status)
+pending(struct fd_resource *rsc, bool write)
{
- return (rsc->status & status) ||
- (rsc->stencil && (rsc->stencil->status & status));
+ /* if we have a pending GPU write, we are busy in any case: */
+ if (rsc->write_batch)
+ return true;
+
+ /* if CPU wants to write, but we are pending a GPU read, we are busy: */
+ if (write && rsc->batch_mask)
+ return true;
+
+ if (rsc->stencil && pending(rsc->stencil, write))
+ return true;
+
+ return false;
}
static void
@@ -108,10 +120,8 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
rsc->bo = fd_bo_new(screen->dev, size, flags);
rsc->timestamp = 0;
- rsc->status = 0;
- fd_batch_reference(&rsc->pending_batch, NULL);
- list_delinit(&rsc->list);
util_range_set_empty(&rsc->valid_buffer_range);
+ fd_bc_invalidate_resource(rsc, true);
}
static unsigned
@@ -324,9 +334,18 @@ fd_resource_transfer_map(struct pipe_context *pctx,
* resource and we're trying to write to it, flush the renders.
*/
if (((ptrans->usage & PIPE_TRANSFER_WRITE) &&
- pending(rsc, FD_PENDING_READ | FD_PENDING_WRITE)) ||
- pending(rsc, FD_PENDING_WRITE))
- fd_context_render(pctx);
+ pending(rsc, true)) ||
+ pending(rsc, false)) {
+ if (usage & PIPE_TRANSFER_WRITE) {
+ struct fd_batch *batch;
+ foreach_batch(batch, &ctx->screen->batch_cache, rsc->batch_mask) {
+ fd_batch_flush(batch);
+ }
+ assert(rsc->batch_mask == 0);
+ } else {
+ fd_batch_flush(rsc->write_batch);
+ }
+ }
/* The GPU keeps track of how the various bo's are being used, and
* will wait if necessary for the proper operation to have
@@ -451,10 +470,9 @@ fd_resource_destroy(struct pipe_screen *pscreen,
struct pipe_resource *prsc)
{
struct fd_resource *rsc = fd_resource(prsc);
+ fd_bc_invalidate_resource(rsc, true);
if (rsc->bo)
fd_bo_del(rsc->bo);
- fd_batch_reference(&rsc->pending_batch, NULL);
- list_delinit(&rsc->list);
util_range_destroy(&rsc->valid_buffer_range);
FREE(rsc);
}
@@ -570,7 +588,7 @@ fd_resource_create(struct pipe_screen *pscreen,
*prsc = *tmpl;
pipe_reference_init(&prsc->reference, 1);
- list_inithead(&rsc->list);
+
prsc->screen = pscreen;
util_range_init(&rsc->valid_buffer_range);
@@ -657,7 +675,7 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
*prsc = *tmpl;
pipe_reference_init(&prsc->reference, 1);
- list_inithead(&rsc->list);
+
prsc->screen = pscreen;
util_range_init(&rsc->valid_buffer_range);
@@ -846,8 +864,10 @@ fd_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
{
struct fd_resource *rsc = fd_resource(prsc);
- if (pending(rsc, FD_PENDING_WRITE | FD_PENDING_READ))
- fd_context_render(pctx);
+ if (rsc->write_batch)
+ fd_batch_flush(rsc->write_batch);
+
+ assert(!rsc->write_batch);
}
void