a4xx: add noperspective interpolation support
[mesa.git] / src / gallium / drivers / freedreno / freedreno_batch_cache.c
index 1bf656cf2087af2fb25005d7203e20f29e2318b6..448e701bbc6276c81d2edd155c466ad0b2f60c6a 100644 (file)
@@ -28,6 +28,8 @@
 #include "util/set.h"
 #include "util/list.h"
 #include "util/u_string.h"
+#define XXH_INLINE_ALL
+#include "util/xxhash.h"
 
 #include "freedreno_batch.h"
 #include "freedreno_batch_cache.h"
@@ -81,7 +83,8 @@ struct key {
        struct {
                struct pipe_resource *texture;
                union pipe_surface_desc u;
-               uint16_t pos, format;
+               uint8_t pos, samples;
+               uint16_t format;
        } surf[0];
 };
 
@@ -97,9 +100,9 @@ static uint32_t
 key_hash(const void *_key)
 {
        const struct key *key = _key;
-       uint32_t hash = _mesa_fnv32_1a_offset_bias;
-       hash = _mesa_fnv32_1a_accumulate_block(hash, key, offsetof(struct key, surf[0]));
-       hash = _mesa_fnv32_1a_accumulate_block(hash, key->surf, sizeof(key->surf[0]) * key->num_surfs);
+       uint32_t hash = 0;
+       hash = XXH32(key, offsetof(struct key, surf[0]), hash);
+       hash = XXH32(key->surf, sizeof(key->surf[0]) * key->num_surfs , hash);
        return hash;
 }
 
@@ -144,10 +147,11 @@ bc_flush(struct fd_batch_cache *cache, struct fd_context *ctx, bool deferred)
        }
 
        if (deferred) {
-               struct fd_batch *current_batch = ctx->batch;
+               struct fd_batch *current_batch = fd_context_batch(ctx);
 
                for (unsigned i = 0; i < n; i++) {
-                       if (batches[i] != current_batch) {
+                       if (batches[i] && (batches[i]->ctx == ctx) &&
+                                       (batches[i] != current_batch)) {
                                fd_batch_add_dep(current_batch, batches[i]);
                        }
                }
@@ -157,7 +161,7 @@ bc_flush(struct fd_batch_cache *cache, struct fd_context *ctx, bool deferred)
                fd_context_unlock(ctx);
 
                for (unsigned i = 0; i < n; i++) {
-                       fd_batch_flush(batches[i], false, false);
+                       fd_batch_flush(batches[i]);
                }
        }
 
@@ -183,20 +187,59 @@ fd_bc_flush_deferred(struct fd_batch_cache *cache, struct fd_context *ctx)
        bc_flush(cache, ctx, true);
 }
 
+static bool
+batch_in_cache(struct fd_batch_cache *cache, struct fd_batch *batch)
+{
+       struct fd_batch *b;
+
+       foreach_batch (b, cache, cache->batch_mask)
+               if (b == batch)
+                       return true;
+
+       return false;
+}
+
+void
+fd_bc_dump(struct fd_screen *screen, const char *fmt, ...)
+{
+       struct fd_batch_cache *cache = &screen->batch_cache;
+
+       if (!BATCH_DEBUG)
+               return;
+
+       fd_screen_lock(screen);
+
+       va_list ap;
+       va_start(ap, fmt);
+       vprintf(fmt, ap);
+       va_end(ap);
+
+       set_foreach (screen->live_batches, entry) {
+               struct fd_batch *batch = (struct fd_batch *)entry->key;
+               printf("  %p<%u>%s%s\n", batch, batch->seqno,
+                               batch->needs_flush ? ", NEEDS FLUSH" : "",
+                               batch_in_cache(cache, batch) ? "" : ", ORPHAN");
+       }
+
+       printf("----\n");
+
+       fd_screen_unlock(screen);
+}
+
 void
 fd_bc_invalidate_context(struct fd_context *ctx)
 {
        struct fd_batch_cache *cache = &ctx->screen->batch_cache;
        struct fd_batch *batch;
 
-       mtx_lock(&ctx->screen->lock);
+       fd_screen_lock(ctx->screen);
 
        foreach_batch(batch, cache, cache->batch_mask) {
                if (batch->ctx == ctx)
                        fd_bc_invalidate_batch(batch, true);
        }
 
-       mtx_unlock(&ctx->screen->lock);
+       fd_screen_unlock(ctx->screen);
 }
 
 /**
@@ -248,7 +291,7 @@ fd_bc_invalidate_resource(struct fd_resource *rsc, bool destroy)
        struct fd_screen *screen = fd_screen(rsc->base.screen);
        struct fd_batch *batch;
 
-       mtx_lock(&screen->lock);
+       fd_screen_lock(screen);
 
        if (destroy) {
                foreach_batch(batch, &screen->batch_cache, rsc->batch_mask) {
@@ -265,23 +308,22 @@ fd_bc_invalidate_resource(struct fd_resource *rsc, bool destroy)
 
        rsc->bc_batch_mask = 0;
 
-       mtx_unlock(&screen->lock);
+       fd_screen_unlock(screen);
 }
 
 struct fd_batch *
-fd_bc_alloc_batch(struct fd_batch_cache *cache, struct fd_context *ctx)
+fd_bc_alloc_batch(struct fd_batch_cache *cache, struct fd_context *ctx, bool nondraw)
 {
        struct fd_batch *batch;
        uint32_t idx;
 
-       mtx_lock(&ctx->screen->lock);
+       fd_screen_lock(ctx->screen);
 
        while ((idx = ffs(~cache->batch_mask)) == 0) {
 #if 0
                for (unsigned i = 0; i < ARRAY_SIZE(cache->batches); i++) {
                        batch = cache->batches[i];
                        debug_printf("%d: needs_flush=%d, depends:", batch->idx, batch->needs_flush);
-                       struct set_entry *entry;
                        set_foreach(batch->dependencies, entry) {
                                struct fd_batch *dep = (struct fd_batch *)entry->key;
                                debug_printf(" %d", dep->idx);
@@ -294,9 +336,6 @@ fd_bc_alloc_batch(struct fd_batch_cache *cache, struct fd_context *ctx)
                 */
                struct fd_batch *flush_batch = NULL;
                for (unsigned i = 0; i < ARRAY_SIZE(cache->batches); i++) {
-                       if ((cache->batches[i] == ctx->batch) ||
-                                       !cache->batches[i]->needs_flush)
-                               continue;
                        if (!flush_batch || (cache->batches[i]->seqno < flush_batch->seqno))
                                fd_batch_reference_locked(&flush_batch, cache->batches[i]);
                }
@@ -304,10 +343,10 @@ fd_bc_alloc_batch(struct fd_batch_cache *cache, struct fd_context *ctx)
                /* we can drop lock temporarily here, since we hold a ref,
                 * flush_batch won't disappear under us.
                 */
-               mtx_unlock(&ctx->screen->lock);
+               fd_screen_unlock(ctx->screen);
                DBG("%p: too many batches!  flush forced!", flush_batch);
-               fd_batch_flush(flush_batch, true, false);
-               mtx_lock(&ctx->screen->lock);
+               fd_batch_flush(flush_batch);
+               fd_screen_lock(ctx->screen);
 
                /* While the resources get cleaned up automatically, the flush_batch
                 * doesn't get removed from the dependencies of other batches, so
@@ -332,7 +371,7 @@ fd_bc_alloc_batch(struct fd_batch_cache *cache, struct fd_context *ctx)
 
        idx--;              /* bit zero returns 1 for ffs() */
 
-       batch = fd_batch_create(ctx, false);
+       batch = fd_batch_create(ctx, nondraw);
        if (!batch)
                goto out;
 
@@ -344,7 +383,7 @@ fd_bc_alloc_batch(struct fd_batch_cache *cache, struct fd_context *ctx)
        cache->batches[idx] = batch;
 
 out:
-       mtx_unlock(&ctx->screen->lock);
+       fd_screen_unlock(ctx->screen);
 
        return batch;
 }
@@ -364,7 +403,7 @@ batch_from_key(struct fd_batch_cache *cache, struct key *key,
                return batch;
        }
 
-       batch = fd_bc_alloc_batch(cache, ctx);
+       batch = fd_bc_alloc_batch(cache, ctx, false);
 #ifdef DEBUG
        DBG("%p: hash=0x%08x, %ux%u, %u layers, %u samples", batch, hash,
                        key->width, key->height, key->layers, key->samples);
@@ -379,7 +418,15 @@ batch_from_key(struct fd_batch_cache *cache, struct key *key,
        if (!batch)
                return NULL;
 
-       mtx_lock(&ctx->screen->lock);
+       /* reset max_scissor, which will be adjusted on draws
+        * according to the actual scissor.
+        */
+       batch->max_scissor.minx = ~0;
+       batch->max_scissor.miny = ~0;
+       batch->max_scissor.maxx = 0;
+       batch->max_scissor.maxy = 0;
+
+       fd_screen_lock(ctx->screen);
 
        _mesa_hash_table_insert_pre_hashed(cache->ht, hash, key, batch);
        batch->key = key;
@@ -390,7 +437,7 @@ batch_from_key(struct fd_batch_cache *cache, struct key *key,
                rsc->bc_batch_mask = (1 << batch->idx);
        }
 
-       mtx_unlock(&ctx->screen->lock);
+       fd_screen_unlock(ctx->screen);
 
        return batch;
 }
@@ -401,6 +448,7 @@ key_surf(struct key *key, unsigned idx, unsigned pos, struct pipe_surface *psurf
        key->surf[idx].texture = psurf->texture;
        key->surf[idx].u = psurf->u;
        key->surf[idx].pos = pos;
+       key->surf[idx].samples = MAX2(1, psurf->nr_samples);
        key->surf[idx].format = psurf->format;
 }