/*
 * Copyright (C) 2019 Alyssa Rosenzweig
 * Copyright (C) 2014-2017 Broadcom
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include <assert.h>

#include "drm-uapi/panfrost_drm.h"

#include "pan_bo.h"
#include "pan_context.h"
#include "util/hash_table.h"
#include "util/ralloc.h"
#include "util/format/u_format.h"
#include "util/u_pack_color.h"
#include "util/rounding.h"
#include "pan_util.h"
#include "pan_blending.h"
#include "decode.h"
#include "panfrost-quirks.h"

/* panfrost_bo_access is here to help us keep track of batch accesses to BOs
 * and build a proper dependency graph such that batches can be pipelined for
 * better GPU utilization.
 *
 * Each accessed BO has a corresponding entry in the ->accessed_bos hash table.
 * A BO is either being written or read at any time (see if writer != NULL).
 * When the last access is a write, the batch writing the BO might have read
 * dependencies (readers that have not been executed yet and want to read the
 * previous BO content), and when the last access is a read, all readers might
 * depend on another batch to push its results to memory. That's what the
 * readers/writers keep track off.
 * There can only be one writer at any given time, if a new batch wants to
 * write to the same BO, a dependency will be added between the new writer and
 * the old writer (at the batch level), and panfrost_bo_access->writer will be
 * updated to point to the new writer.
 */
struct panfrost_bo_access {
        struct util_dynarray readers;
        struct panfrost_batch_fence *writer;
};

static struct panfrost_batch_fence *
panfrost_create_batch_fence(struct panfrost_batch *batch)
{
        struct panfrost_batch_fence *fence;

        fence = rzalloc(NULL, struct panfrost_batch_fence);
        assert(fence);
        pipe_reference_init(&fence->reference, 1);
        fence->batch = batch;

        return fence;
}

static void
panfrost_free_batch_fence(struct panfrost_batch_fence *fence)
{
        ralloc_free(fence);
}

void
panfrost_batch_fence_unreference(struct panfrost_batch_fence *fence)
{
        if (pipe_reference(&fence->reference, NULL))
                 panfrost_free_batch_fence(fence);
}

void
panfrost_batch_fence_reference(struct panfrost_batch_fence *fence)
{
        pipe_reference(NULL, &fence->reference);
}

static void
panfrost_batch_add_fbo_bos(struct panfrost_batch *batch);

static struct panfrost_batch *
panfrost_create_batch(struct panfrost_context *ctx,
                      const struct pipe_framebuffer_state *key)
{
        struct panfrost_batch *batch = rzalloc(ctx, struct panfrost_batch);
        struct panfrost_device *dev = pan_device(ctx->base.screen);

        batch->ctx = ctx;

        batch->bos = _mesa_hash_table_create(batch, _mesa_hash_pointer,
                        _mesa_key_pointer_equal);

        batch->minx = batch->miny = ~0;
        batch->maxx = batch->maxy = 0;

        batch->out_sync = panfrost_create_batch_fence(batch);
        util_copy_framebuffer_state(&batch->key, key);

        /* Preallocate the main pool, since every batch has at least one job
         * structure so it will be used */
        panfrost_pool_init(&batch->pool, batch, dev, 0, true);

        /* Don't preallocate the invisible pool, since not every batch will use
         * the pre-allocation, particularly if the varyings are larger than the
         * preallocation and a reallocation is needed after anyway. */
        panfrost_pool_init(&batch->invisible_pool, batch, dev, PAN_BO_INVISIBLE, false);

        panfrost_batch_add_fbo_bos(batch);

        return batch;
}

static void
panfrost_freeze_batch(struct panfrost_batch *batch)
{
        struct panfrost_context *ctx = batch->ctx;
        struct hash_entry *entry;

        /* Remove the entry in the FBO -> batch hash table if the batch
         * matches and drop the context reference. This way, next draws/clears
         * targeting this FBO will trigger the creation of a new batch.
         */
        entry = _mesa_hash_table_search(ctx->batches, &batch->key);
        if (entry && entry->data == batch)
                _mesa_hash_table_remove(ctx->batches, entry);

        if (ctx->batch == batch)
                ctx->batch = NULL;
}

#ifdef PAN_BATCH_DEBUG
static bool panfrost_batch_is_frozen(struct panfrost_batch *batch)
{
        struct panfrost_context *ctx = batch->ctx;
        struct hash_entry *entry;

        entry = _mesa_hash_table_search(ctx->batches, &batch->key);
        if (entry && entry->data == batch)
                return false;

        if (ctx->batch == batch)
                return false;

        return true;
}
#endif

static void
panfrost_free_batch(struct panfrost_batch *batch)
{
        if (!batch)
                return;

#ifdef PAN_BATCH_DEBUG
        assert(panfrost_batch_is_frozen(batch));
#endif

        hash_table_foreach(batch->bos, entry)
                panfrost_bo_unreference((struct panfrost_bo *)entry->key);

        panfrost_pool_cleanup(&batch->pool);
        panfrost_pool_cleanup(&batch->invisible_pool);

        util_dynarray_foreach(&batch->dependencies,
                              struct panfrost_batch_fence *, dep) {
                panfrost_batch_fence_unreference(*dep);
        }

        util_dynarray_fini(&batch->dependencies);

        /* The out_sync fence lifetime is different from the the batch one
         * since other batches might want to wait on a fence of already
         * submitted/signaled batch. All we need to do here is make sure the
         * fence does not point to an invalid batch, which the core will
         * interpret as 'batch is already submitted'.
         */
        batch->out_sync->batch = NULL;
        panfrost_batch_fence_unreference(batch->out_sync);

        util_unreference_framebuffer_state(&batch->key);
        ralloc_free(batch);
}

#ifdef PAN_BATCH_DEBUG
static bool
panfrost_dep_graph_contains_batch(struct panfrost_batch *root,
                                  struct panfrost_batch *batch)
{
        if (!root)
                return false;

        util_dynarray_foreach(&root->dependencies,
                              struct panfrost_batch_fence *, dep) {
                if ((*dep)->batch == batch ||
                    panfrost_dep_graph_contains_batch((*dep)->batch, batch))
                        return true;
        }

        return false;
}
#endif

static void
panfrost_batch_add_dep(struct panfrost_batch *batch,
                       struct panfrost_batch_fence *newdep)
{
        if (batch == newdep->batch)
                return;

        /* We might want to turn ->dependencies into a set if the number of
         * deps turns out to be big enough to make this 'is dep already there'
         * search inefficient.
         */
        util_dynarray_foreach(&batch->dependencies,
                              struct panfrost_batch_fence *, dep) {
                if (*dep == newdep)
                        return;
        }

#ifdef PAN_BATCH_DEBUG
        /* Make sure the dependency graph is acyclic. */
        assert(!panfrost_dep_graph_contains_batch(newdep->batch, batch));
#endif

        panfrost_batch_fence_reference(newdep);
        util_dynarray_append(&batch->dependencies,
                             struct panfrost_batch_fence *, newdep);

        /* We now have a batch depending on us, let's make sure new draw/clear
         * calls targeting the same FBO use a new batch object.
         */
        if (newdep->batch)
                panfrost_freeze_batch(newdep->batch);
}

static struct panfrost_batch *
panfrost_get_batch(struct panfrost_context *ctx,
                   const struct pipe_framebuffer_state *key)
{
        /* Lookup the job first */
        struct hash_entry *entry = _mesa_hash_table_search(ctx->batches, key);

        if (entry)
                return entry->data;

        /* Otherwise, let's create a job */

        struct panfrost_batch *batch = panfrost_create_batch(ctx, key);

        /* Save the created job */
        _mesa_hash_table_insert(ctx->batches, &batch->key, batch);

        return batch;
}

/* Get the job corresponding to the FBO we're currently rendering into */

struct panfrost_batch *
panfrost_get_batch_for_fbo(struct panfrost_context *ctx)
{
        /* If we're wallpapering, we special case to workaround
         * u_blitter abuse */

        if (ctx->wallpaper_batch)
                return ctx->wallpaper_batch;

        /* If we already began rendering, use that */

        if (ctx->batch) {
                assert(util_framebuffer_state_equal(&ctx->batch->key,
                                                    &ctx->pipe_framebuffer));
                return ctx->batch;
        }

        /* If not, look up the job */
        struct panfrost_batch *batch = panfrost_get_batch(ctx,
                                                          &ctx->pipe_framebuffer);

        /* Set this job as the current FBO job. Will be reset when updating the
         * FB state and when submitting or releasing a job.
         */
        ctx->batch = batch;
        return batch;
}

struct panfrost_batch *
panfrost_get_fresh_batch_for_fbo(struct panfrost_context *ctx)
{
        struct panfrost_batch *batch;

        batch = panfrost_get_batch(ctx, &ctx->pipe_framebuffer);

        /* The batch has no draw/clear queued, let's return it directly.
         * Note that it's perfectly fine to re-use a batch with an
         * existing clear, we'll just update it with the new clear request.
         */
        if (!batch->scoreboard.first_job)
                return batch;

        /* Otherwise, we need to freeze the existing one and instantiate a new
         * one.
         */
        panfrost_freeze_batch(batch);
        return panfrost_get_batch(ctx, &ctx->pipe_framebuffer);
}

static void
panfrost_bo_access_gc_fences(struct panfrost_context *ctx,
                             struct panfrost_bo_access *access,
			     const struct panfrost_bo *bo)
{
        if (access->writer) {
                panfrost_batch_fence_unreference(access->writer);
                access->writer = NULL;
        }

        struct panfrost_batch_fence **readers_array = util_dynarray_begin(&access->readers);
        struct panfrost_batch_fence **new_readers = readers_array;

        util_dynarray_foreach(&access->readers, struct panfrost_batch_fence *,
                              reader) {
                if (!(*reader))
                        continue;

                panfrost_batch_fence_unreference(*reader);
                *reader = NULL;
        }

        if (!util_dynarray_resize(&access->readers, struct panfrost_batch_fence *,
                                  new_readers - readers_array) &&
            new_readers != readers_array)
                unreachable("Invalid dynarray access->readers");
}

/* Collect signaled fences to keep the kernel-side syncobj-map small. The
 * idea is to collect those signaled fences at the end of each flush_all
 * call. This function is likely to collect only fences from previous
 * batch flushes not the one that have just have just been submitted and
 * are probably still in flight when we trigger the garbage collection.
 * Anyway, we need to do this garbage collection at some point if we don't
 * want the BO access map to keep invalid entries around and retain
 * syncobjs forever.
 */
static void
panfrost_gc_fences(struct panfrost_context *ctx)
{
        hash_table_foreach(ctx->accessed_bos, entry) {
                struct panfrost_bo_access *access = entry->data;

                assert(access);
                panfrost_bo_access_gc_fences(ctx, access, entry->key);
                if (!util_dynarray_num_elements(&access->readers,
                                                struct panfrost_batch_fence *) &&
                    !access->writer) {
                        ralloc_free(access);
                        _mesa_hash_table_remove(ctx->accessed_bos, entry);
                }
        }
}

#ifdef PAN_BATCH_DEBUG
static bool
panfrost_batch_in_readers(struct panfrost_batch *batch,
                          struct panfrost_bo_access *access)
{
        util_dynarray_foreach(&access->readers, struct panfrost_batch_fence *,
                              reader) {
                if (*reader && (*reader)->batch == batch)
                        return true;
        }

        return false;
}
#endif

static void
panfrost_batch_update_bo_access(struct panfrost_batch *batch,
                                struct panfrost_bo *bo, bool writes,
                                bool already_accessed)
{
        struct panfrost_context *ctx = batch->ctx;
        struct panfrost_bo_access *access;
        bool old_writes = false;
        struct hash_entry *entry;

        entry = _mesa_hash_table_search(ctx->accessed_bos, bo);
        access = entry ? entry->data : NULL;
        if (access) {
                old_writes = access->writer != NULL;
        } else {
                access = rzalloc(ctx, struct panfrost_bo_access);
                util_dynarray_init(&access->readers, access);
                _mesa_hash_table_insert(ctx->accessed_bos, bo, access);
                /* We are the first to access this BO, let's initialize
                 * old_writes to our own access type in that case.
                 */
                old_writes = writes;
        }

        assert(access);

        if (writes && !old_writes) {
                /* Previous access was a read and we want to write this BO.
                 * We first need to add explicit deps between our batch and
                 * the previous readers.
                 */
                util_dynarray_foreach(&access->readers,
                                      struct panfrost_batch_fence *, reader) {
                        /* We were already reading the BO, no need to add a dep
                         * on ourself (the acyclic check would complain about
                         * that).
                         */
                        if (!(*reader) || (*reader)->batch == batch)
                                continue;

                        panfrost_batch_add_dep(batch, *reader);
                }
                panfrost_batch_fence_reference(batch->out_sync);

                if (access->writer)
                        panfrost_batch_fence_unreference(access->writer);

                /* We now are the new writer. */
                access->writer = batch->out_sync;

                /* Release the previous readers and reset the readers array. */
                util_dynarray_foreach(&access->readers,
                                      struct panfrost_batch_fence *,
                                      reader) {
                        if (!*reader)
                                continue;
                        panfrost_batch_fence_unreference(*reader);
                }

                util_dynarray_clear(&access->readers);
        } else if (writes && old_writes) {
                /* First check if we were the previous writer, in that case
                 * there's nothing to do. Otherwise we need to add a
                 * dependency between the new writer and the old one.
                 */
		if (access->writer != batch->out_sync) {
                        if (access->writer) {
                                panfrost_batch_add_dep(batch, access->writer);
                                panfrost_batch_fence_unreference(access->writer);
                        }
                        panfrost_batch_fence_reference(batch->out_sync);
                        access->writer = batch->out_sync;
                }
        } else if (!writes && old_writes) {
                /* First check if we were the previous writer, in that case
                 * we want to keep the access type unchanged, as a write is
                 * more constraining than a read.
                 */
                if (access->writer != batch->out_sync) {
                        /* Add a dependency on the previous writer. */
                        panfrost_batch_add_dep(batch, access->writer);

                        /* The previous access was a write, there's no reason
                         * to have entries in the readers array.
                         */
                        assert(!util_dynarray_num_elements(&access->readers,
                                                           struct panfrost_batch_fence *));

                        /* Add ourselves to the readers array. */
                        panfrost_batch_fence_reference(batch->out_sync);
                        util_dynarray_append(&access->readers,
                                             struct panfrost_batch_fence *,
                                             batch->out_sync);
                        access->writer = NULL;
                }
        } else {
                /* We already accessed this BO before, so we should already be
                 * in the reader array.
                 */
#ifdef PAN_BATCH_DEBUG
                if (already_accessed) {
                        assert(panfrost_batch_in_readers(batch, access));
                        return;
                }
#endif

                /* Previous access was a read and we want to read this BO.
                 * Add ourselves to the readers array and add a dependency on
                 * the previous writer if any.
                 */
                panfrost_batch_fence_reference(batch->out_sync);
                util_dynarray_append(&access->readers,
                                     struct panfrost_batch_fence *,
                                     batch->out_sync);

                if (access->writer)
                        panfrost_batch_add_dep(batch, access->writer);
        }
}

void
panfrost_batch_add_bo(struct panfrost_batch *batch, struct panfrost_bo *bo,
                      uint32_t flags)
{
        if (!bo)
                return;

        struct hash_entry *entry;
        uint32_t old_flags = 0;

        entry = _mesa_hash_table_search(batch->bos, bo);
        if (!entry) {
                entry = _mesa_hash_table_insert(batch->bos, bo,
                                                (void *)(uintptr_t)flags);
                panfrost_bo_reference(bo);
	} else {
                old_flags = (uintptr_t)entry->data;

                /* All batches have to agree on the shared flag. */
                assert((old_flags & PAN_BO_ACCESS_SHARED) ==
                       (flags & PAN_BO_ACCESS_SHARED));
        }

        assert(entry);

        if (old_flags == flags)
                return;

        flags |= old_flags;
        entry->data = (void *)(uintptr_t)flags;

        /* If this is not a shared BO, we don't really care about dependency
         * tracking.
         */
        if (!(flags & PAN_BO_ACCESS_SHARED))
                return;

        /* All dependencies should have been flushed before we execute the
         * wallpaper draw, so it should be harmless to skip the
         * update_bo_access() call.
         */
        if (batch == batch->ctx->wallpaper_batch)
                return;

        assert(flags & PAN_BO_ACCESS_RW);
        panfrost_batch_update_bo_access(batch, bo, flags & PAN_BO_ACCESS_WRITE,
                        old_flags != 0);
}

static void
panfrost_batch_add_resource_bos(struct panfrost_batch *batch,
                                struct panfrost_resource *rsrc,
                                uint32_t flags)
{
        panfrost_batch_add_bo(batch, rsrc->bo, flags);

        for (unsigned i = 0; i < MAX_MIP_LEVELS; i++)
                if (rsrc->slices[i].checksum_bo)
                        panfrost_batch_add_bo(batch, rsrc->slices[i].checksum_bo, flags);

        if (rsrc->separate_stencil)
                panfrost_batch_add_bo(batch, rsrc->separate_stencil->bo, flags);
}

static void
panfrost_batch_add_fbo_bos(struct panfrost_batch *batch)
{
        uint32_t flags = PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_WRITE |
                         PAN_BO_ACCESS_VERTEX_TILER |
                         PAN_BO_ACCESS_FRAGMENT;

        for (unsigned i = 0; i < batch->key.nr_cbufs; ++i) {
                struct panfrost_resource *rsrc = pan_resource(batch->key.cbufs[i]->texture);
                panfrost_batch_add_resource_bos(batch, rsrc, flags);
        }

        if (batch->key.zsbuf) {
                struct panfrost_resource *rsrc = pan_resource(batch->key.zsbuf->texture);
                panfrost_batch_add_resource_bos(batch, rsrc, flags);
        }
}

struct panfrost_bo *
panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
                         uint32_t create_flags, uint32_t access_flags)
{
        struct panfrost_bo *bo;

        bo = panfrost_bo_create(pan_device(batch->ctx->base.screen), size,
                                create_flags);
        panfrost_batch_add_bo(batch, bo, access_flags);

        /* panfrost_batch_add_bo() has retained a reference and
         * panfrost_bo_create() initialize the refcnt to 1, so let's
         * unreference the BO here so it gets released when the batch is
         * destroyed (unless it's retained by someone else in the meantime).
         */
        panfrost_bo_unreference(bo);
        return bo;
}

/* Returns the polygon list's GPU address if available, or otherwise allocates
 * the polygon list.  It's perfectly fast to use allocate/free BO directly,
 * since we'll hit the BO cache and this is one-per-batch anyway. */

mali_ptr
panfrost_batch_get_polygon_list(struct panfrost_batch *batch, unsigned size)
{
        if (batch->polygon_list) {
                assert(batch->polygon_list->size >= size);
        } else {
                /* Create the BO as invisible, as there's no reason to map */
                size = util_next_power_of_two(size);

                batch->polygon_list = panfrost_batch_create_bo(batch, size,
                                                               PAN_BO_INVISIBLE,
                                                               PAN_BO_ACCESS_PRIVATE |
                                                               PAN_BO_ACCESS_RW |
                                                               PAN_BO_ACCESS_VERTEX_TILER |
                                                               PAN_BO_ACCESS_FRAGMENT);
        }

        return batch->polygon_list->gpu;
}

struct panfrost_bo *
panfrost_batch_get_scratchpad(struct panfrost_batch *batch,
                unsigned size_per_thread,
                unsigned thread_tls_alloc,
                unsigned core_count)
{
        unsigned size = panfrost_get_total_stack_size(size_per_thread,
                        thread_tls_alloc,
                        core_count);

        if (batch->scratchpad) {
                assert(batch->scratchpad->size >= size);
        } else {
                batch->scratchpad = panfrost_batch_create_bo(batch, size,
                                             PAN_BO_INVISIBLE,
                                             PAN_BO_ACCESS_PRIVATE |
                                             PAN_BO_ACCESS_RW |
                                             PAN_BO_ACCESS_VERTEX_TILER |
                                             PAN_BO_ACCESS_FRAGMENT);
        }

        return batch->scratchpad;
}

struct panfrost_bo *
panfrost_batch_get_shared_memory(struct panfrost_batch *batch,
                unsigned size,
                unsigned workgroup_count)
{
        if (batch->shared_memory) {
                assert(batch->shared_memory->size >= size);
        } else {
                batch->shared_memory = panfrost_batch_create_bo(batch, size,
                                             PAN_BO_INVISIBLE,
                                             PAN_BO_ACCESS_PRIVATE |
                                             PAN_BO_ACCESS_RW |
                                             PAN_BO_ACCESS_VERTEX_TILER);
        }

        return batch->shared_memory;
}

mali_ptr
panfrost_batch_get_bifrost_tiler(struct panfrost_batch *batch, unsigned vertex_count)
{
        if (!vertex_count)
                return 0;

        if (batch->tiler_meta)
                return batch->tiler_meta;

        struct panfrost_device *dev = pan_device(batch->ctx->base.screen);
        struct panfrost_transfer t =
                panfrost_pool_alloc_aligned(&batch->pool, MALI_BIFROST_TILER_HEAP_LENGTH, 64);

        pan_pack(t.cpu, BIFROST_TILER_HEAP, heap) {
                heap.size = dev->tiler_heap->size;
                heap.base = dev->tiler_heap->gpu;
                heap.bottom = dev->tiler_heap->gpu;
                heap.top = dev->tiler_heap->gpu + dev->tiler_heap->size;
        }

        mali_ptr heap = t.gpu;

        t = panfrost_pool_alloc_aligned(&batch->pool, MALI_BIFROST_TILER_LENGTH, 64);
        pan_pack(t.cpu, BIFROST_TILER, tiler) {
                tiler.hierarchy_mask = 0x28;
                tiler.fb_width = batch->key.width;
                tiler.fb_height = batch->key.height;
                tiler.heap = heap;
        }

        batch->tiler_meta = t.gpu;
        return batch->tiler_meta;
}

struct panfrost_bo *
panfrost_batch_get_tiler_dummy(struct panfrost_batch *batch)
{
        struct panfrost_device *dev = pan_device(batch->ctx->base.screen);

        uint32_t create_flags = 0;

        if (batch->tiler_dummy)
                return batch->tiler_dummy;

        if (!(dev->quirks & MIDGARD_NO_HIER_TILING))
                create_flags = PAN_BO_INVISIBLE;

        batch->tiler_dummy = panfrost_batch_create_bo(batch, 4096,
                                                      create_flags,
                                                      PAN_BO_ACCESS_PRIVATE |
                                                      PAN_BO_ACCESS_RW |
                                                      PAN_BO_ACCESS_VERTEX_TILER |
                                                      PAN_BO_ACCESS_FRAGMENT);
        assert(batch->tiler_dummy);
        return batch->tiler_dummy;
}

mali_ptr
panfrost_batch_reserve_framebuffer(struct panfrost_batch *batch)
{
        struct panfrost_device *dev = pan_device(batch->ctx->base.screen);

        /* If we haven't, reserve space for the framebuffer */

        if (!batch->framebuffer.gpu) {
                unsigned size = (dev->quirks & MIDGARD_SFBD) ?
                        MALI_SINGLE_TARGET_FRAMEBUFFER_LENGTH :
                        sizeof(struct mali_framebuffer);

                batch->framebuffer = panfrost_pool_alloc_aligned(&batch->pool, size, 64);

                /* Tag the pointer */
                if (!(dev->quirks & MIDGARD_SFBD))
                        batch->framebuffer.gpu |= MALI_MFBD;
        }

        return batch->framebuffer.gpu;
}



static void
panfrost_load_surface(struct panfrost_batch *batch, struct pipe_surface *surf, unsigned loc)
{
        if (!surf)
                return;

        struct panfrost_resource *rsrc = pan_resource(surf->texture);
        unsigned level = surf->u.tex.level;

        if (!rsrc->slices[level].initialized)
                return;

        if (!rsrc->damage.inverted_len)
                return;

        /* Clamp the rendering area to the damage extent. The
         * KHR_partial_update() spec states that trying to render outside of
         * the damage region is "undefined behavior", so we should be safe.
         */
        unsigned damage_width = (rsrc->damage.extent.maxx - rsrc->damage.extent.minx);
        unsigned damage_height = (rsrc->damage.extent.maxy - rsrc->damage.extent.miny);

        if (damage_width && damage_height) {
                panfrost_batch_intersection_scissor(batch,
                                                    rsrc->damage.extent.minx,
                                                    rsrc->damage.extent.miny,
                                                    rsrc->damage.extent.maxx,
                                                    rsrc->damage.extent.maxy);
        }

        /* XXX: Native blits on Bifrost */
        if (batch->pool.dev->quirks & IS_BIFROST) {
                if (loc != FRAG_RESULT_DATA0)
                        return;

                /* XXX: why align on *twice* the tile length? */
                batch->minx = batch->minx & ~((MALI_TILE_LENGTH * 2) - 1);
                batch->miny = batch->miny & ~((MALI_TILE_LENGTH * 2) - 1);
                batch->maxx = MIN2(ALIGN_POT(batch->maxx, MALI_TILE_LENGTH * 2),
                                rsrc->base.width0);
                batch->maxy = MIN2(ALIGN_POT(batch->maxy, MALI_TILE_LENGTH * 2),
                                rsrc->base.height0);

                struct pipe_box rect;
                batch->ctx->wallpaper_batch = batch;
                u_box_2d(batch->minx, batch->miny, batch->maxx - batch->minx,
                                batch->maxy - batch->miny, &rect);
                panfrost_blit_wallpaper(batch->ctx, &rect);
                batch->ctx->wallpaper_batch = NULL;
                return;
        }

        enum pipe_format format = rsrc->base.format;

        if (loc == FRAG_RESULT_DEPTH) {
                if (!util_format_has_depth(util_format_description(format)))
                        return;

                format = util_format_get_depth_only(format);
        } else if (loc == FRAG_RESULT_STENCIL) {
                if (!util_format_has_stencil(util_format_description(format)))
                        return;

                if (rsrc->separate_stencil) {
                        rsrc = rsrc->separate_stencil;
                        format = rsrc->base.format;
                }

                format = util_format_stencil_only(format);
        }

        enum mali_texture_dimension dim =
                panfrost_translate_texture_dimension(rsrc->base.target);

        struct pan_image img = {
                .width0 = rsrc->base.width0,
                .height0 = rsrc->base.height0,
                .depth0 = rsrc->base.depth0,
                .format = format,
                .dim = dim,
                .modifier = rsrc->modifier,
                .array_size = rsrc->base.array_size,
                .first_level = level,
                .last_level = level,
                .first_layer = surf->u.tex.first_layer,
                .last_layer = surf->u.tex.last_layer,
                .nr_samples = rsrc->base.nr_samples,
                .cubemap_stride = rsrc->cubemap_stride,
                .bo = rsrc->bo,
                .slices = rsrc->slices
        };

        mali_ptr blend_shader = 0;

        if (loc >= FRAG_RESULT_DATA0 && !panfrost_can_fixed_blend(rsrc->base.format)) {
                struct panfrost_blend_shader *b =
                        panfrost_get_blend_shader(batch->ctx, &batch->ctx->blit_blend, rsrc->base.format, loc - FRAG_RESULT_DATA0);

                struct panfrost_bo *bo = panfrost_batch_create_bo(batch, b->size,
                   PAN_BO_EXECUTE,
                   PAN_BO_ACCESS_PRIVATE |
                   PAN_BO_ACCESS_READ |
                   PAN_BO_ACCESS_FRAGMENT);

                memcpy(bo->cpu, b->buffer, b->size);
                assert(b->work_count <= 4);

                blend_shader = bo->gpu | b->first_tag;
        }

        struct panfrost_transfer transfer = panfrost_pool_alloc_aligned(&batch->pool,
                        4 * 4 * 6 * rsrc->damage.inverted_len, 64);

        for (unsigned i = 0; i < rsrc->damage.inverted_len; ++i) {
                float *o = (float *) (transfer.cpu + (4 * 4 * 6 * i));
                struct pan_rect r = rsrc->damage.inverted_rects[i];

                float rect[] = {
                        r.minx, rsrc->base.height0 - r.miny, 0.0, 1.0,
                        r.maxx, rsrc->base.height0 - r.miny, 0.0, 1.0,
                        r.minx, rsrc->base.height0 - r.maxy, 0.0, 1.0,

                        r.maxx, rsrc->base.height0 - r.miny, 0.0, 1.0,
                        r.minx, rsrc->base.height0 - r.maxy, 0.0, 1.0,
                        r.maxx, rsrc->base.height0 - r.maxy, 0.0, 1.0,
                };

                assert(sizeof(rect) == 4 * 4 * 6);
                memcpy(o, rect, sizeof(rect));
        }

        panfrost_load_midg(&batch->pool, &batch->scoreboard,
                blend_shader,
                batch->framebuffer.gpu, transfer.gpu,
                rsrc->damage.inverted_len * 6,
                &img, loc);

        panfrost_batch_add_bo(batch, batch->pool.dev->blit_shaders.bo,
                        PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_READ | PAN_BO_ACCESS_FRAGMENT);
}

static void
panfrost_batch_draw_wallpaper(struct panfrost_batch *batch)
{
        panfrost_batch_reserve_framebuffer(batch);

        /* Assume combined. If either depth or stencil is written, they will
         * both be written so we need to be careful for reloading */

        unsigned draws = batch->draws;

        if (draws & PIPE_CLEAR_DEPTHSTENCIL)
                draws |= PIPE_CLEAR_DEPTHSTENCIL;

        /* Mask of buffers which need reload since they are not cleared and
         * they are drawn. (If they are cleared, reload is useless; if they are
         * not drawn and also not cleared, we can generally omit the attachment
         * at the framebuffer descriptor level */

        unsigned reload = ~batch->clear & draws;

        for (unsigned i = 0; i < batch->key.nr_cbufs; ++i) {
                if (reload & (PIPE_CLEAR_COLOR0 << i)) 
                        panfrost_load_surface(batch, batch->key.cbufs[i], FRAG_RESULT_DATA0 + i);
        }

        if (reload & PIPE_CLEAR_DEPTH)
                panfrost_load_surface(batch, batch->key.zsbuf, FRAG_RESULT_DEPTH);

        if (reload & PIPE_CLEAR_STENCIL)
                panfrost_load_surface(batch, batch->key.zsbuf, FRAG_RESULT_STENCIL);
}

static void
panfrost_batch_record_bo(struct hash_entry *entry, unsigned *bo_handles, unsigned idx)
{
        struct panfrost_bo *bo = (struct panfrost_bo *)entry->key;
        uint32_t flags = (uintptr_t)entry->data;

        assert(bo->gem_handle > 0);
        bo_handles[idx] = bo->gem_handle;

        /* Update the BO access flags so that panfrost_bo_wait() knows
         * about all pending accesses.
         * We only keep the READ/WRITE info since this is all the BO
         * wait logic cares about.
         * We also preserve existing flags as this batch might not
         * be the first one to access the BO.
         */
        bo->gpu_access |= flags & (PAN_BO_ACCESS_RW);
}

static int
panfrost_batch_submit_ioctl(struct panfrost_batch *batch,
                            mali_ptr first_job_desc,
                            uint32_t reqs,
                            uint32_t out_sync)
{
        struct panfrost_context *ctx = batch->ctx;
        struct pipe_context *gallium = (struct pipe_context *) ctx;
        struct panfrost_device *dev = pan_device(gallium->screen);
        struct drm_panfrost_submit submit = {0,};
        uint32_t *bo_handles;
        int ret;

        /* If we trace, we always need a syncobj, so make one of our own if we
         * weren't given one to use. Remember that we did so, so we can free it
         * after we're done but preventing double-frees if we were given a
         * syncobj */

        bool our_sync = false;

        if (!out_sync && dev->debug & (PAN_DBG_TRACE | PAN_DBG_SYNC)) {
                drmSyncobjCreate(dev->fd, 0, &out_sync);
                our_sync = true;
        }

        submit.out_sync = out_sync;
        submit.jc = first_job_desc;
        submit.requirements = reqs;

        bo_handles = calloc(panfrost_pool_num_bos(&batch->pool) +
                            panfrost_pool_num_bos(&batch->invisible_pool) +
                            batch->bos->entries + 1,
                            sizeof(*bo_handles));
        assert(bo_handles);

        hash_table_foreach(batch->bos, entry)
                panfrost_batch_record_bo(entry, bo_handles, submit.bo_handle_count++);

        panfrost_pool_get_bo_handles(&batch->pool, bo_handles + submit.bo_handle_count);
        submit.bo_handle_count += panfrost_pool_num_bos(&batch->pool);
        panfrost_pool_get_bo_handles(&batch->invisible_pool, bo_handles + submit.bo_handle_count);
        submit.bo_handle_count += panfrost_pool_num_bos(&batch->invisible_pool);

        /* Used by all tiler jobs (XXX: skip for compute-only) */
        if (!(reqs & PANFROST_JD_REQ_FS))
                bo_handles[submit.bo_handle_count++] = dev->tiler_heap->gem_handle;

        submit.bo_handles = (u64) (uintptr_t) bo_handles;
        ret = drmIoctl(dev->fd, DRM_IOCTL_PANFROST_SUBMIT, &submit);
        free(bo_handles);

        if (ret) {
                if (dev->debug & PAN_DBG_MSGS)
                        fprintf(stderr, "Error submitting: %m\n");

                if (our_sync)
                        drmSyncobjDestroy(dev->fd, out_sync);

                return errno;
        }

        /* Trace the job if we're doing that */
        if (dev->debug & (PAN_DBG_TRACE | PAN_DBG_SYNC)) {
                /* Wait so we can get errors reported back */
                drmSyncobjWait(dev->fd, &out_sync, 1,
                               INT64_MAX, 0, NULL);

                /* Trace gets priority over sync */
                bool minimal = !(dev->debug & PAN_DBG_TRACE);
                pandecode_jc(submit.jc, dev->quirks & IS_BIFROST, dev->gpu_id, minimal);
        }

        /* Cleanup if we created the syncobj */
        if (our_sync)
                drmSyncobjDestroy(dev->fd, out_sync);

        return 0;
}

/* Submit both vertex/tiler and fragment jobs for a batch, possibly with an
 * outsync corresponding to the later of the two (since there will be an
 * implicit dep between them) */

static int
panfrost_batch_submit_jobs(struct panfrost_batch *batch, uint32_t out_sync)
{
        bool has_draws = batch->scoreboard.first_job;
        bool has_frag = batch->scoreboard.tiler_dep || batch->clear;
        int ret = 0;

        if (has_draws) {
                ret = panfrost_batch_submit_ioctl(batch, batch->scoreboard.first_job,
                                0, has_frag ? 0 : out_sync);
                assert(!ret);
        }

        if (has_frag) {
                /* Whether we program the fragment job for draws or not depends
                 * on whether there is any *tiler* activity (so fragment
                 * shaders). If there are draws but entirely RASTERIZER_DISCARD
                 * (say, for transform feedback), we want a fragment job that
                 * *only* clears, since otherwise the tiler structures will be
                 * uninitialized leading to faults (or state leaks) */

                mali_ptr fragjob = panfrost_fragment_job(batch,
                                batch->scoreboard.tiler_dep != 0);
                ret = panfrost_batch_submit_ioctl(batch, fragjob,
                                PANFROST_JD_REQ_FS, out_sync);
                assert(!ret);
        }

        return ret;
}

static void
panfrost_batch_submit(struct panfrost_batch *batch, uint32_t out_sync)
{
        assert(batch);
        struct panfrost_device *dev = pan_device(batch->ctx->base.screen);

        /* Submit the dependencies first. Don't pass along the out_sync since
         * they are guaranteed to terminate sooner */
        util_dynarray_foreach(&batch->dependencies,
                              struct panfrost_batch_fence *, dep) {
                if ((*dep)->batch)
                        panfrost_batch_submit((*dep)->batch, 0);
        }

        int ret;

        /* Nothing to do! */
        if (!batch->scoreboard.first_job && !batch->clear) {
                if (out_sync)
                        drmSyncobjSignal(dev->fd, &out_sync, 1);
                goto out;
	}

        panfrost_batch_draw_wallpaper(batch);

        /* Now that all draws are in, we can finally prepare the
         * FBD for the batch */

        if (batch->framebuffer.gpu && batch->scoreboard.first_job) {
                struct panfrost_context *ctx = batch->ctx;
                struct pipe_context *gallium = (struct pipe_context *) ctx;
                struct panfrost_device *dev = pan_device(gallium->screen);

                if (dev->quirks & MIDGARD_SFBD)
                        panfrost_attach_sfbd(batch, ~0);
                else
                        panfrost_attach_mfbd(batch, ~0);
        }

        mali_ptr polygon_list = panfrost_batch_get_polygon_list(batch,
                MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE);

        panfrost_scoreboard_initialize_tiler(&batch->pool, &batch->scoreboard, polygon_list);

        ret = panfrost_batch_submit_jobs(batch, out_sync);

        if (ret && dev->debug & PAN_DBG_MSGS)
                fprintf(stderr, "panfrost_batch_submit failed: %d\n", ret);

        /* We must reset the damage info of our render targets here even
         * though a damage reset normally happens when the DRI layer swaps
         * buffers. That's because there can be implicit flushes the GL
         * app is not aware of, and those might impact the damage region: if
         * part of the damaged portion is drawn during those implicit flushes,
         * you have to reload those areas before next draws are pushed, and
         * since the driver can't easily know what's been modified by the draws
         * it flushed, the easiest solution is to reload everything.
         */
        for (unsigned i = 0; i < batch->key.nr_cbufs; i++) {
                if (!batch->key.cbufs[i])
                        continue;

                panfrost_resource_set_damage_region(NULL,
                                batch->key.cbufs[i]->texture, 0, NULL);
        }

out:
        panfrost_freeze_batch(batch);
        panfrost_free_batch(batch);
}

/* Submit all batches, applying the out_sync to the currently bound batch */

void
panfrost_flush_all_batches(struct panfrost_context *ctx, uint32_t out_sync)
{
        struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
        panfrost_batch_submit(batch, out_sync);

        hash_table_foreach(ctx->batches, hentry) {
                struct panfrost_batch *batch = hentry->data;
                assert(batch);

                panfrost_batch_submit(batch, 0);
        }

        assert(!ctx->batches->entries);

        /* Collect batch fences before returning */
        panfrost_gc_fences(ctx);
}

bool
panfrost_pending_batches_access_bo(struct panfrost_context *ctx,
                                   const struct panfrost_bo *bo)
{
        struct panfrost_bo_access *access;
        struct hash_entry *hentry;

        hentry = _mesa_hash_table_search(ctx->accessed_bos, bo);
        access = hentry ? hentry->data : NULL;
        if (!access)
                return false;

        if (access->writer && access->writer->batch)
                return true;

        util_dynarray_foreach(&access->readers, struct panfrost_batch_fence *,
                              reader) {
                if (*reader && (*reader)->batch)
                        return true;
        }

        return false;
}

/* We always flush writers. We might also need to flush readers */

void
panfrost_flush_batches_accessing_bo(struct panfrost_context *ctx,
                                    struct panfrost_bo *bo,
                                    bool flush_readers)
{
        struct panfrost_bo_access *access;
        struct hash_entry *hentry;

        hentry = _mesa_hash_table_search(ctx->accessed_bos, bo);
        access = hentry ? hentry->data : NULL;
        if (!access)
                return;

        if (access->writer && access->writer->batch)
                panfrost_batch_submit(access->writer->batch, 0);

        if (!flush_readers)
                return;

        util_dynarray_foreach(&access->readers, struct panfrost_batch_fence *,
                              reader) {
                if (*reader && (*reader)->batch)
                        panfrost_batch_submit((*reader)->batch, 0);
        }
}

void
panfrost_batch_set_requirements(struct panfrost_batch *batch)
{
        struct panfrost_context *ctx = batch->ctx;

        if (ctx->rasterizer->base.multisample)
                batch->requirements |= PAN_REQ_MSAA;

        if (ctx->depth_stencil && ctx->depth_stencil->base.depth.writemask) {
                batch->requirements |= PAN_REQ_DEPTH_WRITE;
                batch->draws |= PIPE_CLEAR_DEPTH;
        }

        if (ctx->depth_stencil && ctx->depth_stencil->base.stencil[0].enabled)
                batch->draws |= PIPE_CLEAR_STENCIL;
}

void
panfrost_batch_adjust_stack_size(struct panfrost_batch *batch)
{
        struct panfrost_context *ctx = batch->ctx;

        for (unsigned i = 0; i < PIPE_SHADER_TYPES; ++i) {
                struct panfrost_shader_state *ss;

                ss = panfrost_get_shader_state(ctx, i);
                if (!ss)
                        continue;

                batch->stack_size = MAX2(batch->stack_size, ss->stack_size);
        }
}

/* Helper to smear a 32-bit color across 128-bit components */

static void
pan_pack_color_32(uint32_t *packed, uint32_t v)
{
        for (unsigned i = 0; i < 4; ++i)
                packed[i] = v;
}

static void
pan_pack_color_64(uint32_t *packed, uint32_t lo, uint32_t hi)
{
        for (unsigned i = 0; i < 4; i += 2) {
                packed[i + 0] = lo;
                packed[i + 1] = hi;
        }
}

static void
pan_pack_color(uint32_t *packed, const union pipe_color_union *color, enum pipe_format format)
{
        /* Alpha magicked to 1.0 if there is no alpha */

        bool has_alpha = util_format_has_alpha(format);
        float clear_alpha = has_alpha ? color->f[3] : 1.0f;

        /* Packed color depends on the framebuffer format */

        const struct util_format_description *desc =
                util_format_description(format);

        if (util_format_is_rgba8_variant(desc) && desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
                pan_pack_color_32(packed,
                                  ((uint32_t) float_to_ubyte(clear_alpha) << 24) |
                                  ((uint32_t) float_to_ubyte(color->f[2]) << 16) |
                                  ((uint32_t) float_to_ubyte(color->f[1]) <<  8) |
                                  ((uint32_t) float_to_ubyte(color->f[0]) <<  0));
        } else if (format == PIPE_FORMAT_B5G6R5_UNORM) {
                /* First, we convert the components to R5, G6, B5 separately */
                unsigned r5 = _mesa_roundevenf(SATURATE(color->f[0]) * 31.0);
                unsigned g6 = _mesa_roundevenf(SATURATE(color->f[1]) * 63.0);
                unsigned b5 = _mesa_roundevenf(SATURATE(color->f[2]) * 31.0);

                /* Then we pack into a sparse u32. TODO: Why these shifts? */
                pan_pack_color_32(packed, (b5 << 25) | (g6 << 14) | (r5 << 5));
        } else if (format == PIPE_FORMAT_B4G4R4A4_UNORM) {
                /* Convert to 4-bits */
                unsigned r4 = _mesa_roundevenf(SATURATE(color->f[0]) * 15.0);
                unsigned g4 = _mesa_roundevenf(SATURATE(color->f[1]) * 15.0);
                unsigned b4 = _mesa_roundevenf(SATURATE(color->f[2]) * 15.0);
                unsigned a4 = _mesa_roundevenf(SATURATE(clear_alpha) * 15.0);

                /* Pack on *byte* intervals */
                pan_pack_color_32(packed, (a4 << 28) | (b4 << 20) | (g4 << 12) | (r4 << 4));
        } else if (format == PIPE_FORMAT_B5G5R5A1_UNORM) {
                /* Scale as expected but shift oddly */
                unsigned r5 = _mesa_roundevenf(SATURATE(color->f[0]) * 31.0);
                unsigned g5 = _mesa_roundevenf(SATURATE(color->f[1]) * 31.0);
                unsigned b5 = _mesa_roundevenf(SATURATE(color->f[2]) * 31.0);
                unsigned a1 = _mesa_roundevenf(SATURATE(clear_alpha) * 1.0);

                pan_pack_color_32(packed, (a1 << 31) | (b5 << 25) | (g5 << 15) | (r5 << 5));
        } else {
                /* Otherwise, it's generic subject to replication */

                union util_color out = { 0 };
                unsigned size = util_format_get_blocksize(format);

                util_pack_color(color->f, format, &out);

                if (size == 1) {
                        unsigned b = out.ui[0];
                        unsigned s = b | (b << 8);
                        pan_pack_color_32(packed, s | (s << 16));
                } else if (size == 2)
                        pan_pack_color_32(packed, out.ui[0] | (out.ui[0] << 16));
                else if (size == 3 || size == 4)
                        pan_pack_color_32(packed, out.ui[0]);
                else if (size == 6)
                        pan_pack_color_64(packed, out.ui[0], out.ui[1] | (out.ui[1] << 16)); /* RGB16F -- RGBB */
                else if (size == 8)
                        pan_pack_color_64(packed, out.ui[0], out.ui[1]);
                else if (size == 16)
                        memcpy(packed, out.ui, 16);
                else
                        unreachable("Unknown generic format size packing clear colour");
        }
}

void
panfrost_batch_clear(struct panfrost_batch *batch,
                     unsigned buffers,
                     const union pipe_color_union *color,
                     double depth, unsigned stencil)
{
        struct panfrost_context *ctx = batch->ctx;

        if (buffers & PIPE_CLEAR_COLOR) {
                for (unsigned i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
                        if (!(buffers & (PIPE_CLEAR_COLOR0 << i)))
                                continue;

                        enum pipe_format format = ctx->pipe_framebuffer.cbufs[i]->format;
                        pan_pack_color(batch->clear_color[i], color, format);
                }
        }

        if (buffers & PIPE_CLEAR_DEPTH) {
                batch->clear_depth = depth;
        }

        if (buffers & PIPE_CLEAR_STENCIL) {
                batch->clear_stencil = stencil;
        }

        batch->clear |= buffers;

        /* Clearing affects the entire framebuffer (by definition -- this is
         * the Gallium clear callback, which clears the whole framebuffer. If
         * the scissor test were enabled from the GL side, the gallium frontend
         * would emit a quad instead and we wouldn't go down this code path) */

        panfrost_batch_union_scissor(batch, 0, 0,
                                     ctx->pipe_framebuffer.width,
                                     ctx->pipe_framebuffer.height);
}

static bool
panfrost_batch_compare(const void *a, const void *b)
{
        return util_framebuffer_state_equal(a, b);
}

static uint32_t
panfrost_batch_hash(const void *key)
{
        return _mesa_hash_data(key, sizeof(struct pipe_framebuffer_state));
}

/* Given a new bounding rectangle (scissor), let the job cover the union of the
 * new and old bounding rectangles */

void
panfrost_batch_union_scissor(struct panfrost_batch *batch,
                             unsigned minx, unsigned miny,
                             unsigned maxx, unsigned maxy)
{
        batch->minx = MIN2(batch->minx, minx);
        batch->miny = MIN2(batch->miny, miny);
        batch->maxx = MAX2(batch->maxx, maxx);
        batch->maxy = MAX2(batch->maxy, maxy);
}

void
panfrost_batch_intersection_scissor(struct panfrost_batch *batch,
                                  unsigned minx, unsigned miny,
                                  unsigned maxx, unsigned maxy)
{
        batch->minx = MAX2(batch->minx, minx);
        batch->miny = MAX2(batch->miny, miny);
        batch->maxx = MIN2(batch->maxx, maxx);
        batch->maxy = MIN2(batch->maxy, maxy);
}

/* Are we currently rendering to the dev (rather than an FBO)? */

bool
panfrost_batch_is_scanout(struct panfrost_batch *batch)
{
        /* If there is no color buffer, it's an FBO */
        if (batch->key.nr_cbufs != 1)
                return false;

        /* If we're too early that no framebuffer was sent, it's scanout */
        if (!batch->key.cbufs[0])
                return true;

        return batch->key.cbufs[0]->texture->bind & PIPE_BIND_DISPLAY_TARGET ||
               batch->key.cbufs[0]->texture->bind & PIPE_BIND_SCANOUT ||
               batch->key.cbufs[0]->texture->bind & PIPE_BIND_SHARED;
}

void
panfrost_batch_init(struct panfrost_context *ctx)
{
        ctx->batches = _mesa_hash_table_create(ctx,
                                               panfrost_batch_hash,
                                               panfrost_batch_compare);
        ctx->accessed_bos = _mesa_hash_table_create(ctx, _mesa_hash_pointer,
                                                    _mesa_key_pointer_equal);
}
