Home | History | Annotate | Line # | Download | only in iris
      1 /*
      2  * Copyright  2020 Intel Corporation
      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
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #ifndef IRIS_FINE_FENCE_DOT_H
     25 #define IRIS_FINE_FENCE_DOT_H
     26 
     27 #include <stdbool.h>
     28 #include <stdint.h>
     29 
     30 #include "iris_screen.h"
     31 #include "iris_resource.h"
     32 
     33 /**
     34  * A lightweight sequence number fence.
     35  *
     36  * We emit PIPE_CONTROLs inside a batch (possibly in the middle)
     37  * which update a monotonically increasing, 32-bit counter.  We
     38  * can then check if that moment has passed by either:
     39  *
     40  * 1. Checking on the CPU by snooping on the DWord via a coherent map
     41  *
     42  * 2. Blocking on the GPU with MI_SEMAPHORE_WAIT from a second batch
     43  *    (relying on mid-batch preemption to switch GPU execution to the
     44  *    batch that writes it).
     45  */
     46 struct iris_fine_fence {
     47    struct pipe_reference reference;
     48 
     49    /** Buffer where the seqno lives */
     50    struct iris_state_ref ref;
     51 
     52    /** Coherent CPU map of the buffer containing the seqno DWord. */
     53    const uint32_t *map;
     54 
     55    /**
     56     * A drm_syncobj pointing which will be signaled at the end of the
     57     * batch which writes this seqno.  This can be used to block until
     58     * the seqno has definitely passed (but may wait longer than necessary).
     59     */
     60    struct iris_syncobj *syncobj;
     61 
     62 #define IRIS_FENCE_BOTTOM_OF_PIPE 0x0 /**< Written by bottom-of-pipe flush */
     63 #define IRIS_FENCE_TOP_OF_PIPE    0x1 /**< Written by top-of-pipe flush */
     64 #define IRIS_FENCE_END            0x2 /**< Written at the end of a batch */
     65 
     66    /** Information about the type of flush involved (see IRIS_FENCE_*) */
     67    uint32_t flags;
     68 
     69    /**
     70     * Sequence number expected to be written by the flush we inserted
     71     * when creating this fence.  The iris_fine_fence is 'signaled' when *@map
     72     * (written by the flush on the GPU) is greater-than-or-equal to @seqno.
     73     */
     74    uint32_t seqno;
     75 };
     76 
     77 void iris_fine_fence_init(struct iris_batch *batch);
     78 
     79 struct iris_fine_fence *iris_fine_fence_new(struct iris_batch *batch, unsigned flags);
     80 
     81 void iris_fine_fence_destroy(struct iris_screen *screen, struct iris_fine_fence *sq);
     82 
     83 static inline void
     84 iris_fine_fence_reference(struct iris_screen *screen,
     85                           struct iris_fine_fence **dst,
     86                           struct iris_fine_fence *src)
     87 {
     88    if (pipe_reference(&(*dst)->reference, &src->reference))
     89       iris_fine_fence_destroy(screen, *dst);
     90 
     91    *dst = src;
     92 }
     93 
     94 /**
     95  * Return true if this seqno has passed.
     96  *
     97  * NULL is considered signaled.
     98  */
     99 static inline bool
    100 iris_fine_fence_signaled(const struct iris_fine_fence *sq)
    101 {
    102    return !sq || (READ_ONCE(*sq->map) >= sq->seqno);
    103 }
    104 
    105 #endif
    106