"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.9/src/etnaviv/drm/etnaviv_priv.h" (30 Sep 2020, 7355 Bytes) of package /linux/misc/mesa-20.1.9.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. See also the last Fossies "Diffs" side-by-side code changes report for "etnaviv_priv.h": 20.1.5_vs_20.2.0-rc1.

    1 /*
    2  * Copyright (C) 2014-2015 Etnaviv Project
    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  *    Christian Gmeiner <christian.gmeiner@gmail.com>
   25  */
   26 
   27 #ifndef ETNAVIV_PRIV_H_
   28 #define ETNAVIV_PRIV_H_
   29 
   30 #include <stdlib.h>
   31 #include <errno.h>
   32 #include <string.h>
   33 #include <unistd.h>
   34 #include <errno.h>
   35 #include <fcntl.h>
   36 #include <sys/ioctl.h>
   37 #include <pthread.h>
   38 #include <stdio.h>
   39 #include <assert.h>
   40 
   41 #include <xf86drm.h>
   42 
   43 #include "util/list.h"
   44 #include "util/macros.h"
   45 #include "util/u_atomic.h"
   46 #include "util/u_debug.h"
   47 #include "util/vma.h"
   48 
   49 #include "etnaviv_drmif.h"
   50 #include "drm-uapi/etnaviv_drm.h"
   51 
   52 struct etna_bo_bucket {
   53     uint32_t size;
   54     struct list_head list;
   55 };
   56 
   57 struct etna_bo_cache {
   58     struct etna_bo_bucket cache_bucket[14 * 4];
   59     unsigned num_buckets;
   60     time_t time;
   61 };
   62 
   63 struct etna_device {
   64     int fd;
   65     int refcnt;
   66 
   67     /* tables to keep track of bo's, to avoid "evil-twin" etna_bo objects:
   68      *
   69      *   handle_table: maps handle to etna_bo
   70      *   name_table: maps flink name to etna_bo
   71      *
   72      * We end up needing two tables, because DRM_IOCTL_GEM_OPEN always
   73      * returns a new handle.  So we need to figure out if the bo is already
   74      * open in the process first, before calling gem-open.
   75      */
   76     void *handle_table, *name_table;
   77 
   78     struct etna_bo_cache bo_cache;
   79 
   80     int use_softpin;
   81     struct util_vma_heap address_space;
   82 
   83     int closefd;        /* call close(fd) upon destruction */
   84 };
   85 
   86 void etna_bo_cache_init(struct etna_bo_cache *cache);
   87 void etna_bo_cache_cleanup(struct etna_bo_cache *cache, time_t time);
   88 struct etna_bo *etna_bo_cache_alloc(struct etna_bo_cache *cache,
   89         uint32_t *size, uint32_t flags);
   90 int etna_bo_cache_free(struct etna_bo_cache *cache, struct etna_bo *bo);
   91 
   92 /* for where @etna_drm_table_lock is already held: */
   93 void etna_device_del_locked(struct etna_device *dev);
   94 
   95 /* a GEM buffer object allocated from the DRM device */
   96 struct etna_bo {
   97     struct etna_device      *dev;
   98     void            *map;           /* userspace mmap'ing (if there is one) */
   99     uint32_t        size;
  100     uint32_t        handle;
  101     uint32_t        flags;
  102     uint32_t        name;           /* flink global handle (DRI2 name) */
  103     uint64_t        offset;         /* offset to mmap() */
  104     uint32_t        va;             /* GPU virtual address */
  105     int     refcnt;
  106 
  107     /*
  108      * To avoid excess hashtable lookups, cache the stream this bo was
  109      * last emitted on (since that will probably also be the next ring
  110      * it is emitted on).
  111      */
  112     struct etna_cmd_stream *current_stream;
  113     uint32_t idx;
  114 
  115     int reuse;
  116     struct list_head list;   /* bucket-list entry */
  117     time_t free_time;        /* time when added to bucket-list */
  118 };
  119 
  120 struct etna_gpu {
  121     struct etna_device *dev;
  122     uint32_t core;
  123     uint32_t model;
  124     uint32_t revision;
  125 };
  126 
  127 struct etna_pipe {
  128     enum etna_pipe_id id;
  129     struct etna_gpu *gpu;
  130 };
  131 
  132 struct etna_cmd_stream_priv {
  133     struct etna_cmd_stream base;
  134     struct etna_pipe *pipe;
  135 
  136     uint32_t last_timestamp;
  137 
  138     /* submit ioctl related tables: */
  139     struct {
  140         /* bo's table: */
  141         struct drm_etnaviv_gem_submit_bo *bos;
  142         uint32_t nr_bos, max_bos;
  143 
  144         /* reloc's table: */
  145         struct drm_etnaviv_gem_submit_reloc *relocs;
  146         uint32_t nr_relocs, max_relocs;
  147 
  148         /* perf's table: */
  149         struct drm_etnaviv_gem_submit_pmr *pmrs;
  150         uint32_t nr_pmrs, max_pmrs;
  151     } submit;
  152 
  153     /* should have matching entries in submit.bos: */
  154     struct etna_bo **bos;
  155     uint32_t nr_bos, max_bos;
  156 
  157     /* notify callback if buffer reset happened */
  158     void (*force_flush)(struct etna_cmd_stream *stream, void *priv);
  159     void *force_flush_priv;
  160 
  161     void *bo_table;
  162 };
  163 
  164 struct etna_perfmon {
  165     struct list_head domains;
  166     struct etna_pipe *pipe;
  167 };
  168 
  169 struct etna_perfmon_domain
  170 {
  171     struct list_head head;
  172     struct list_head signals;
  173     uint8_t id;
  174     char name[64];
  175 };
  176 
  177 struct etna_perfmon_signal
  178 {
  179     struct list_head head;
  180     struct etna_perfmon_domain *domain;
  181     uint8_t signal;
  182     char name[64];
  183 };
  184 
  185 #define ALIGN(v,a) (((v) + (a) - 1) & ~((a) - 1))
  186 
  187 #define enable_debug 0  /* TODO make dynamic */
  188 
  189 #define INFO_MSG(fmt, ...) \
  190         do { debug_printf("[I] "fmt " (%s:%d)\n", \
  191                 ##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0)
  192 #define DEBUG_MSG(fmt, ...) \
  193         do if (enable_debug) { debug_printf("[D] "fmt " (%s:%d)\n", \
  194                 ##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0)
  195 #define WARN_MSG(fmt, ...) \
  196         do { debug_printf("[W] "fmt " (%s:%d)\n", \
  197                 ##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0)
  198 #define ERROR_MSG(fmt, ...) \
  199         do { debug_printf("[E] " fmt " (%s:%d)\n", \
  200                 ##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0)
  201 
  202 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
  203 
  204 static inline void get_abs_timeout(struct drm_etnaviv_timespec *tv, uint64_t ns)
  205 {
  206     struct timespec t;
  207     clock_gettime(CLOCK_MONOTONIC, &t);
  208     tv->tv_sec = t.tv_sec + ns / 1000000000;
  209     tv->tv_nsec = t.tv_nsec + ns % 1000000000;
  210 }
  211 
  212 #if HAVE_VALGRIND
  213 #  include <valgrind/memcheck.h>
  214 
  215 /*
  216  * For tracking the backing memory (if valgrind enabled, we force a mmap
  217  * for the purposes of tracking)
  218  */
  219 static inline void VG_BO_ALLOC(struct etna_bo *bo)
  220 {
  221     if (bo && RUNNING_ON_VALGRIND) {
  222         VALGRIND_MALLOCLIKE_BLOCK(etna_bo_map(bo), bo->size, 0, 1);
  223     }
  224 }
  225 
  226 static inline void VG_BO_FREE(struct etna_bo *bo)
  227 {
  228     VALGRIND_FREELIKE_BLOCK(bo->map, 0);
  229 }
  230 
  231 /*
  232  * For tracking bo structs that are in the buffer-cache, so that valgrind
  233  * doesn't attribute ownership to the first one to allocate the recycled
  234  * bo.
  235  *
  236  * Note that the list_head in etna_bo is used to track the buffers in cache
  237  * so disable error reporting on the range while they are in cache so
  238  * valgrind doesn't squawk about list traversal.
  239  *
  240  */
  241 static inline void VG_BO_RELEASE(struct etna_bo *bo)
  242 {
  243     if (RUNNING_ON_VALGRIND) {
  244         VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, sizeof(*bo));
  245         VALGRIND_MAKE_MEM_NOACCESS(bo, sizeof(*bo));
  246         VALGRIND_FREELIKE_BLOCK(bo->map, 0);
  247     }
  248 }
  249 static inline void VG_BO_OBTAIN(struct etna_bo *bo)
  250 {
  251     if (RUNNING_ON_VALGRIND) {
  252         VALGRIND_MAKE_MEM_DEFINED(bo, sizeof(*bo));
  253         VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, sizeof(*bo));
  254         VALGRIND_MALLOCLIKE_BLOCK(bo->map, bo->size, 0, 1);
  255     }
  256 }
  257 #else
  258 static inline void VG_BO_ALLOC(struct etna_bo *bo)   {}
  259 static inline void VG_BO_FREE(struct etna_bo *bo)    {}
  260 static inline void VG_BO_RELEASE(struct etna_bo *bo) {}
  261 static inline void VG_BO_OBTAIN(struct etna_bo *bo)  {}
  262 #endif
  263 
  264 #endif /* ETNAVIV_PRIV_H_ */