"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/freedreno/freedreno_batch.h" (16 Sep 2020, 10609 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "freedreno_batch.h" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    1 /*
    2  * Copyright (C) 2016 Rob Clark <robclark@freedesktop.org>
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice (including the next
   12  * paragraph) shall be included in all copies or substantial portions of the
   13  * Software.
   14  *
   15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   21  * SOFTWARE.
   22  *
   23  * Authors:
   24  *    Rob Clark <robclark@freedesktop.org>
   25  */
   26 
   27 #ifndef FREEDRENO_BATCH_H_
   28 #define FREEDRENO_BATCH_H_
   29 
   30 #include "util/u_inlines.h"
   31 #include "util/u_queue.h"
   32 #include "util/list.h"
   33 
   34 #include "freedreno_util.h"
   35 
   36 struct fd_context;
   37 struct fd_resource;
   38 enum fd_resource_status;
   39 
   40 /* Bitmask of stages in rendering that a particular query query is
   41  * active.  Queries will be automatically started/stopped (generating
   42  * additional fd_hw_sample_period's) on entrance/exit from stages that
   43  * are applicable to the query.
   44  *
   45  * NOTE: set the stage to NULL at end of IB to ensure no query is still
   46  * active.  Things aren't going to work out the way you want if a query
   47  * is active across IB's (or between tile IB and draw IB)
   48  */
   49 enum fd_render_stage {
   50     FD_STAGE_NULL     = 0x00,
   51     FD_STAGE_DRAW     = 0x01,
   52     FD_STAGE_CLEAR    = 0x02,
   53     /* used for driver internal draws (ie. util_blitter_blit()): */
   54     FD_STAGE_BLIT     = 0x04,
   55     FD_STAGE_ALL      = 0xff,
   56 };
   57 
   58 #define MAX_HW_SAMPLE_PROVIDERS 7
   59 struct fd_hw_sample_provider;
   60 struct fd_hw_sample;
   61 
   62 /* A batch tracks everything about a cmdstream batch/submit, including the
   63  * ringbuffers used for binning, draw, and gmem cmds, list of associated
   64  * fd_resource-s, etc.
   65  */
   66 struct fd_batch {
   67     struct pipe_reference reference;
   68     unsigned seqno;
   69     unsigned idx;       /* index into cache->batches[] */
   70 
   71     int in_fence_fd;
   72     bool needs_out_fence_fd;
   73     struct pipe_fence_handle *fence;
   74 
   75     struct fd_context *ctx;
   76 
   77     /* do we need to mem2gmem before rendering.  We don't, if for example,
   78      * there was a glClear() that invalidated the entire previous buffer
   79      * contents.  Keep track of which buffer(s) are cleared, or needs
   80      * restore.  Masks of PIPE_CLEAR_*
   81      *
   82      * The 'cleared' bits will be set for buffers which are *entirely*
   83      * cleared, and 'partial_cleared' bits will be set if you must
   84      * check cleared_scissor.
   85      *
   86      * The 'invalidated' bits are set for cleared buffers, and buffers
   87      * where the contents are undefined, ie. what we don't need to restore
   88      * to gmem.
   89      */
   90     enum {
   91         /* align bitmask values w/ PIPE_CLEAR_*.. since that is convenient.. */
   92         FD_BUFFER_COLOR   = PIPE_CLEAR_COLOR,
   93         FD_BUFFER_DEPTH   = PIPE_CLEAR_DEPTH,
   94         FD_BUFFER_STENCIL = PIPE_CLEAR_STENCIL,
   95         FD_BUFFER_ALL     = FD_BUFFER_COLOR | FD_BUFFER_DEPTH | FD_BUFFER_STENCIL,
   96     } invalidated, cleared, fast_cleared, restore, resolve;
   97 
   98     /* is this a non-draw batch (ie compute/blit which has no pfb state)? */
   99     bool nondraw : 1;
  100     bool needs_flush : 1;
  101     bool flushed : 1;
  102     bool blit : 1;
  103     bool back_blit : 1;      /* only blit so far is resource shadowing back-blit */
  104     bool tessellation : 1;      /* tessellation used in batch */
  105 
  106     /* Keep track if WAIT_FOR_IDLE is needed for registers we need
  107      * to update via RMW:
  108      */
  109     bool needs_wfi : 1;
  110 
  111     /* To decide whether to render to system memory, keep track of the
  112      * number of draws, and whether any of them require multisample,
  113      * depth_test (or depth write), stencil_test, blending, and
  114      * color_logic_Op (since those functions are disabled when by-
  115      * passing GMEM.
  116      */
  117     enum {
  118         FD_GMEM_CLEARS_DEPTH_STENCIL = 0x01,
  119         FD_GMEM_DEPTH_ENABLED        = 0x02,
  120         FD_GMEM_STENCIL_ENABLED      = 0x04,
  121 
  122         FD_GMEM_BLEND_ENABLED        = 0x10,
  123         FD_GMEM_LOGICOP_ENABLED      = 0x20,
  124         FD_GMEM_FB_READ              = 0x40,
  125     } gmem_reason;
  126 
  127     /* At submit time, once we've decided that this batch will use GMEM
  128      * rendering, the appropriate gmem state is looked up:
  129      */
  130     const struct fd_gmem_stateobj *gmem_state;
  131 
  132     unsigned num_draws;      /* number of draws in current batch */
  133     unsigned num_vertices;   /* number of vertices in current batch */
  134 
  135     /* Currently only used on a6xx, to calculate vsc prim/draw stream
  136      * sizes:
  137      */
  138     unsigned num_bins_per_pipe;
  139     unsigned prim_strm_bits;
  140     unsigned draw_strm_bits;
  141 
  142     /* Track the maximal bounds of the scissor of all the draws within a
  143      * batch.  Used at the tile rendering step (fd_gmem_render_tiles(),
  144      * mem2gmem/gmem2mem) to avoid needlessly moving data in/out of gmem.
  145      */
  146     struct pipe_scissor_state max_scissor;
  147 
  148     /* Keep track of DRAW initiators that need to be patched up depending
  149      * on whether we using binning or not:
  150      */
  151     struct util_dynarray draw_patches;
  152 
  153     /* texture state that needs patching for fb_read: */
  154     struct util_dynarray fb_read_patches;
  155 
  156     /* Keep track of writes to RB_RENDER_CONTROL which need to be patched
  157      * once we know whether or not to use GMEM, and GMEM tile pitch.
  158      *
  159      * (only for a3xx.. but having gen specific subclasses of fd_batch
  160      * seemed overkill for now)
  161      */
  162     struct util_dynarray rbrc_patches;
  163 
  164     /* Keep track of GMEM related values that need to be patched up once we
  165      * know the gmem layout:
  166      */
  167     struct util_dynarray gmem_patches;
  168 
  169     /* Keep track of pointer to start of MEM exports for a20x binning shaders
  170      *
  171      * this is so the end of the shader can be cut off at the right point
  172      * depending on the GMEM configuration
  173      */
  174     struct util_dynarray shader_patches;
  175 
  176     struct pipe_framebuffer_state framebuffer;
  177 
  178     struct fd_submit *submit;
  179 
  180     /** draw pass cmdstream: */
  181     struct fd_ringbuffer *draw;
  182     /** binning pass cmdstream: */
  183     struct fd_ringbuffer *binning;
  184     /** tiling/gmem (IB0) cmdstream: */
  185     struct fd_ringbuffer *gmem;
  186 
  187     // TODO maybe more generically split out clear and clear_binning rings?
  188     struct fd_ringbuffer *lrz_clear;
  189     struct fd_ringbuffer *tile_setup;
  190     struct fd_ringbuffer *tile_fini;
  191 
  192     union pipe_color_union clear_color[MAX_RENDER_TARGETS];
  193     double clear_depth;
  194     unsigned clear_stencil;
  195 
  196     /**
  197      * hw query related state:
  198      */
  199     /*@{*/
  200     /* next sample offset.. incremented for each sample in the batch/
  201      * submit, reset to zero on next submit.
  202      */
  203     uint32_t next_sample_offset;
  204 
  205     /* cached samples (in case multiple queries need to reference
  206      * the same sample snapshot)
  207      */
  208     struct fd_hw_sample *sample_cache[MAX_HW_SAMPLE_PROVIDERS];
  209 
  210     /* which sample providers were active in the current batch: */
  211     uint32_t active_providers;
  212 
  213     /* tracking for current stage, to know when to start/stop
  214      * any active queries:
  215      */
  216     enum fd_render_stage stage;
  217 
  218     /* list of samples in current batch: */
  219     struct util_dynarray samples;
  220 
  221     /* current query result bo and tile stride: */
  222     struct pipe_resource *query_buf;
  223     uint32_t query_tile_stride;
  224     /*@}*/
  225 
  226 
  227     /* Set of resources used by currently-unsubmitted batch (read or
  228      * write).. does not hold a reference to the resource.
  229      */
  230     struct set *resources;
  231 
  232     /** key in batch-cache (if not null): */
  233     const void *key;
  234     uint32_t hash;
  235 
  236     /** set of dependent batches.. holds refs to dependent batches: */
  237     uint32_t dependents_mask;
  238 
  239     /* Buffer for tessellation engine input
  240      */
  241     struct fd_bo *tessfactor_bo;
  242     uint32_t tessfactor_size;
  243 
  244     /* Buffer for passing parameters between TCS and TES
  245      */
  246     struct fd_bo *tessparam_bo;
  247     uint32_t tessparam_size;
  248 
  249     struct fd_ringbuffer *tess_addrs_constobj;
  250 
  251     struct list_head log_chunks;  /* list of unflushed log chunks in fifo order */
  252 };
  253 
  254 struct fd_batch * fd_batch_create(struct fd_context *ctx, bool nondraw);
  255 
  256 void fd_batch_reset(struct fd_batch *batch);
  257 void fd_batch_flush(struct fd_batch *batch);
  258 void fd_batch_add_dep(struct fd_batch *batch, struct fd_batch *dep);
  259 void fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc, bool write);
  260 void fd_batch_check_size(struct fd_batch *batch);
  261 
  262 /* not called directly: */
  263 void __fd_batch_describe(char* buf, const struct fd_batch *batch);
  264 void __fd_batch_destroy(struct fd_batch *batch);
  265 
  266 /*
  267  * NOTE the rule is, you need to hold the screen->lock when destroying
  268  * a batch..  so either use fd_batch_reference() (which grabs the lock
  269  * for you) if you don't hold the lock, or fd_batch_reference_locked()
  270  * if you do hold the lock.
  271  *
  272  * WARNING the _locked() version can briefly drop the lock.  Without
  273  * recursive mutexes, I'm not sure there is much else we can do (since
  274  * __fd_batch_destroy() needs to unref resources)
  275  *
  276  * WARNING you must acquire the screen->lock and use the _locked()
  277  * version in case that the batch being ref'd can disappear under
  278  * you.
  279  */
  280 
  281 /* fwd-decl prototypes to untangle header dependency :-/ */
  282 static inline void fd_context_assert_locked(struct fd_context *ctx);
  283 static inline void fd_context_lock(struct fd_context *ctx);
  284 static inline void fd_context_unlock(struct fd_context *ctx);
  285 
  286 static inline void
  287 fd_batch_reference_locked(struct fd_batch **ptr, struct fd_batch *batch)
  288 {
  289     struct fd_batch *old_batch = *ptr;
  290 
  291     /* only need lock if a reference is dropped: */
  292     if (old_batch)
  293         fd_context_assert_locked(old_batch->ctx);
  294 
  295     if (pipe_reference_described(&(*ptr)->reference, &batch->reference,
  296             (debug_reference_descriptor)__fd_batch_describe))
  297         __fd_batch_destroy(old_batch);
  298 
  299     *ptr = batch;
  300 }
  301 
  302 static inline void
  303 fd_batch_reference(struct fd_batch **ptr, struct fd_batch *batch)
  304 {
  305     struct fd_batch *old_batch = *ptr;
  306     struct fd_context *ctx = old_batch ? old_batch->ctx : NULL;
  307 
  308     if (ctx)
  309         fd_context_lock(ctx);
  310 
  311     fd_batch_reference_locked(ptr, batch);
  312 
  313     if (ctx)
  314         fd_context_unlock(ctx);
  315 }
  316 
  317 #include "freedreno_context.h"
  318 
  319 static inline void
  320 fd_reset_wfi(struct fd_batch *batch)
  321 {
  322     batch->needs_wfi = true;
  323 }
  324 
  325 void fd_wfi(struct fd_batch *batch, struct fd_ringbuffer *ring);
  326 
  327 /* emit a CP_EVENT_WRITE:
  328  */
  329 static inline void
  330 fd_event_write(struct fd_batch *batch, struct fd_ringbuffer *ring,
  331         enum vgt_event_type evt)
  332 {
  333     OUT_PKT3(ring, CP_EVENT_WRITE, 1);
  334     OUT_RING(ring, evt);
  335     fd_reset_wfi(batch);
  336 }
  337 
  338 #endif /* FREEDRENO_BATCH_H_ */