nir/lower_samplers: split out _legacy version for deref chains
[mesa.git] / src / gallium / drivers / freedreno / freedreno_batch.h
index 047044a9538bcdfcf6929a8a3fe16a36a14ddf03..b113c0713604a254963aa0c25d63ada3089d3110 100644 (file)
@@ -50,19 +50,12 @@ enum fd_render_stage {
        FD_STAGE_NULL     = 0x01,
        FD_STAGE_DRAW     = 0x02,
        FD_STAGE_CLEAR    = 0x04,
-       /* TODO before queries which include MEM2GMEM or GMEM2MEM will
-        * work we will need to call fd_hw_query_prepare() from somewhere
-        * appropriate so that queries in the tiling IB get backed with
-        * memory to write results to.
-        */
-       FD_STAGE_MEM2GMEM = 0x08,
-       FD_STAGE_GMEM2MEM = 0x10,
        /* used for driver internal draws (ie. util_blitter_blit()): */
-       FD_STAGE_BLIT     = 0x20,
+       FD_STAGE_BLIT     = 0x08,
        FD_STAGE_ALL      = 0xff,
 };
 
-#define MAX_HW_SAMPLE_PROVIDERS 4
+#define MAX_HW_SAMPLE_PROVIDERS 5
 struct fd_hw_sample_provider;
 struct fd_hw_sample;
 
@@ -73,7 +66,11 @@ struct fd_hw_sample;
 struct fd_batch {
        struct pipe_reference reference;
        unsigned seqno;
-       unsigned idx;
+       unsigned idx;       /* index into cache->batches[] */
+
+       int in_fence_fd;
+       bool needs_out_fence_fd;
+       struct pipe_fence_handle *fence;
 
        struct fd_context *ctx;
 
@@ -96,10 +93,17 @@ struct fd_batch {
                FD_BUFFER_ALL     = FD_BUFFER_COLOR | FD_BUFFER_DEPTH | FD_BUFFER_STENCIL,
        } cleared, partial_cleared, restore, resolve;
 
+       /* is this a non-draw batch (ie compute/blit which has no pfb state)? */
+       bool nondraw : 1;
        bool needs_flush : 1;
        bool blit : 1;
        bool back_blit : 1;      /* only blit so far is resource shadowing back-blit */
 
+       /* Keep track if WAIT_FOR_IDLE is needed for registers we need
+        * to update via RMW:
+        */
+       bool needs_wfi : 1;
+
        /* To decide whether to render to system memory, keep track of the
         * number of draws, and whether any of them require multisample,
         * depth_test (or depth write), stencil_test, blending, and
@@ -111,7 +115,6 @@ struct fd_batch {
                FD_GMEM_DEPTH_ENABLED        = 0x02,
                FD_GMEM_STENCIL_ENABLED      = 0x04,
 
-               FD_GMEM_MSAA_ENABLED         = 0x08,
                FD_GMEM_BLEND_ENABLED        = 0x10,
                FD_GMEM_LOGICOP_ENABLED      = 0x20,
        } gmem_reason;
@@ -153,6 +156,9 @@ struct fd_batch {
        /** tiling/gmem (IB0) cmdstream: */
        struct fd_ringbuffer *gmem;
 
+       // TODO maybe more generically split out clear and clear_binning rings?
+       struct fd_ringbuffer *lrz_clear;
+
        /**
         * hw query related state:
         */
@@ -197,11 +203,12 @@ struct fd_batch {
        uint32_t dependents_mask;
 };
 
-struct fd_batch * fd_batch_create(struct fd_context *ctx);
+struct fd_batch * fd_batch_create(struct fd_context *ctx, bool nondraw);
 
 void fd_batch_reset(struct fd_batch *batch);
 void fd_batch_sync(struct fd_batch *batch);
-void fd_batch_flush(struct fd_batch *batch, bool sync);
+void fd_batch_flush(struct fd_batch *batch, bool sync, bool force);
+void fd_batch_add_dep(struct fd_batch *batch, struct fd_batch *dep);
 void fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc, bool write);
 void fd_batch_check_size(struct fd_batch *batch);
 
@@ -209,6 +216,17 @@ void fd_batch_check_size(struct fd_batch *batch);
 void __fd_batch_describe(char* buf, const struct fd_batch *batch);
 void __fd_batch_destroy(struct fd_batch *batch);
 
+/*
+ * NOTE the rule is, you need to hold the screen->lock when destroying
+ * a batch..  so either use fd_batch_reference() (which grabs the lock
+ * for you) if you don't hold the lock, or fd_batch_reference_locked()
+ * if you do hold the lock.
+ *
+ * WARNING the _locked() version can briefly drop the lock.  Without
+ * recursive mutexes, I'm not sure there is much else we can do (since
+ * __fd_batch_destroy() needs to unref resources)
+ */
+
 static inline void
 fd_batch_reference(struct fd_batch **ptr, struct fd_batch *batch)
 {
@@ -219,4 +237,50 @@ fd_batch_reference(struct fd_batch **ptr, struct fd_batch *batch)
        *ptr = batch;
 }
 
+/* fwd-decl prototypes to untangle header dependency :-/ */
+static inline void fd_context_assert_locked(struct fd_context *ctx);
+static inline void fd_context_lock(struct fd_context *ctx);
+static inline void fd_context_unlock(struct fd_context *ctx);
+
+static inline void
+fd_batch_reference_locked(struct fd_batch **ptr, struct fd_batch *batch)
+{
+       struct fd_batch *old_batch = *ptr;
+
+       if (old_batch)
+               fd_context_assert_locked(old_batch->ctx);
+       else if (batch)
+               fd_context_assert_locked(batch->ctx);
+
+       if (pipe_reference_described(&(*ptr)->reference, &batch->reference,
+                       (debug_reference_descriptor)__fd_batch_describe)) {
+               struct fd_context *ctx = old_batch->ctx;
+               fd_context_unlock(ctx);
+               __fd_batch_destroy(old_batch);
+               fd_context_lock(ctx);
+       }
+       *ptr = batch;
+}
+
+#include "freedreno_context.h"
+
+static inline void
+fd_reset_wfi(struct fd_batch *batch)
+{
+       batch->needs_wfi = true;
+}
+
+void fd_wfi(struct fd_batch *batch, struct fd_ringbuffer *ring);
+
+/* emit a CP_EVENT_WRITE:
+ */
+static inline void
+fd_event_write(struct fd_batch *batch, struct fd_ringbuffer *ring,
+               enum vgt_event_type evt)
+{
+       OUT_PKT3(ring, CP_EVENT_WRITE, 1);
+       OUT_RING(ring, evt);
+       fd_reset_wfi(batch);
+}
+
 #endif /* FREEDRENO_BATCH_H_ */