1 /************************************************************************** 2 * 3 * Copyright 2018-2019 Alyssa Rosenzweig 4 * Copyright 2018-2019 Collabora, Ltd. 5 * Copyright 2015 Intel Corporation 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sub license, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the 17 * next paragraph) shall be included in all copies or substantial portions 18 * of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 23 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 * 28 **************************************************************************/ 29 30 #ifndef PAN_DEVICE_H 31 #define PAN_DEVICE_H 32 33 #include <xf86drm.h> 34 #include "renderonly/renderonly.h" 35 #include "util/u_dynarray.h" 36 #include "util/bitset.h" 37 #include "util/list.h" 38 #include "util/sparse_array.h" 39 40 #include "panfrost/util/pan_ir.h" 41 #include "pan_pool.h" 42 #include "pan_util.h" 43 44 #include <genxml/gen_macros.h> 45 46 #if defined(__cplusplus) 47 extern "C" { 48 #endif 49 50 /* Driver limits */ 51 #define PAN_MAX_CONST_BUFFERS 16 52 53 /* How many power-of-two levels in the BO cache do we want? 2^12 54 * minimum chosen as it is the page size that all allocations are 55 * rounded to */ 56 57 #define MIN_BO_CACHE_BUCKET (12) /* 2^12 = 4KB */ 58 #define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */ 59 60 /* Fencepost problem, hence the off-by-one */ 61 #define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1) 62 63 struct pan_blitter { 64 struct { 65 struct pan_pool *pool; 66 struct hash_table *blit; 67 struct hash_table *blend; 68 pthread_mutex_t lock; 69 } shaders; 70 struct { 71 struct pan_pool *pool; 72 struct hash_table *rsds; 73 pthread_mutex_t lock; 74 } rsds; 75 }; 76 77 struct pan_blend_shaders { 78 struct hash_table *shaders; 79 pthread_mutex_t lock; 80 }; 81 82 enum pan_indirect_draw_flags { 83 PAN_INDIRECT_DRAW_NO_INDEX = 0 << 0, 84 PAN_INDIRECT_DRAW_1B_INDEX = 1 << 0, 85 PAN_INDIRECT_DRAW_2B_INDEX = 2 << 0, 86 PAN_INDIRECT_DRAW_4B_INDEX = 3 << 0, 87 PAN_INDIRECT_DRAW_INDEX_SIZE_MASK = 3 << 0, 88 PAN_INDIRECT_DRAW_HAS_PSIZ = 1 << 2, 89 PAN_INDIRECT_DRAW_PRIMITIVE_RESTART = 1 << 3, 90 PAN_INDIRECT_DRAW_UPDATE_PRIM_SIZE = 1 << 4, 91 PAN_INDIRECT_DRAW_LAST_FLAG = PAN_INDIRECT_DRAW_UPDATE_PRIM_SIZE, 92 PAN_INDIRECT_DRAW_FLAGS_MASK = (PAN_INDIRECT_DRAW_LAST_FLAG << 1) - 1, 93 PAN_INDIRECT_DRAW_MIN_MAX_SEARCH_1B_INDEX = PAN_INDIRECT_DRAW_LAST_FLAG << 1, 94 PAN_INDIRECT_DRAW_MIN_MAX_SEARCH_2B_INDEX, 95 PAN_INDIRECT_DRAW_MIN_MAX_SEARCH_4B_INDEX, 96 PAN_INDIRECT_DRAW_MIN_MAX_SEARCH_1B_INDEX_PRIM_RESTART, 97 PAN_INDIRECT_DRAW_MIN_MAX_SEARCH_2B_INDEX_PRIM_RESTART, 98 PAN_INDIRECT_DRAW_MIN_MAX_SEARCH_3B_INDEX_PRIM_RESTART, 99 PAN_INDIRECT_DRAW_NUM_SHADERS, 100 }; 101 102 struct pan_indirect_draw_shader { 103 struct panfrost_ubo_push push; 104 mali_ptr rsd; 105 }; 106 107 struct pan_indirect_draw_shaders { 108 struct pan_indirect_draw_shader shaders[PAN_INDIRECT_DRAW_NUM_SHADERS]; 109 110 /* Take the lock when initializing the draw shaders context or when 111 * allocating from the binary pool. 112 */ 113 pthread_mutex_t lock; 114 115 /* A memory pool for shader binaries. We currently don't allocate a 116 * single BO for all shaders up-front because estimating shader size 117 * is not trivial, and changes to the compiler might influence this 118 * estimation. 119 */ 120 struct pan_pool *bin_pool; 121 122 /* BO containing all renderer states attached to the compute shaders. 123 * Those are built at shader compilation time and re-used every time 124 * panfrost_emit_indirect_draw() is called. 125 */ 126 struct panfrost_bo *states; 127 128 /* Varying memory is allocated dynamically by compute jobs from this 129 * heap. 130 */ 131 struct panfrost_bo *varying_heap; 132 }; 133 134 struct pan_indirect_dispatch { 135 struct panfrost_ubo_push push; 136 struct panfrost_bo *bin; 137 struct panfrost_bo *descs; 138 }; 139 140 /** Implementation-defined tiler features */ 141 struct panfrost_tiler_features { 142 /** Number of bytes per tiler bin */ 143 unsigned bin_size; 144 145 /** Maximum number of levels that may be simultaneously enabled. 146 * Invariant: bitcount(hierarchy_mask) <= max_levels */ 147 unsigned max_levels; 148 }; 149 150 struct panfrost_device { 151 /* For ralloc */ 152 void *memctx; 153 154 int fd; 155 156 /* Properties of the GPU in use */ 157 unsigned arch; 158 unsigned gpu_id; 159 unsigned core_count; 160 unsigned thread_tls_alloc; 161 struct panfrost_tiler_features tiler_features; 162 unsigned quirks; 163 bool has_afbc; 164 165 /* Table of formats, indexed by a PIPE format */ 166 const struct panfrost_format *formats; 167 168 /* Bitmask of supported compressed texture formats */ 169 uint32_t compressed_formats; 170 171 /* debug flags, see pan_util.h how to interpret */ 172 unsigned debug; 173 174 drmVersionPtr kernel_version; 175 176 struct renderonly *ro; 177 178 pthread_mutex_t bo_map_lock; 179 struct util_sparse_array bo_map; 180 181 struct { 182 pthread_mutex_t lock; 183 184 /* List containing all cached BOs sorted in LRU (Least 185 * Recently Used) order. This allows us to quickly evict BOs 186 * that are more than 1 second old. 187 */ 188 struct list_head lru; 189 190 /* The BO cache is a set of buckets with power-of-two sizes 191 * ranging from 2^12 (4096, the page size) to 192 * 2^(12 + MAX_BO_CACHE_BUCKETS). 193 * Each bucket is a linked list of free panfrost_bo objects. */ 194 195 struct list_head buckets[NR_BO_CACHE_BUCKETS]; 196 } bo_cache; 197 198 struct pan_blitter blitter; 199 struct pan_blend_shaders blend_shaders; 200 struct pan_indirect_draw_shaders indirect_draw_shaders; 201 struct pan_indirect_dispatch indirect_dispatch; 202 203 /* Tiler heap shared across all tiler jobs, allocated against the 204 * device since there's only a single tiler. Since this is invisible to 205 * the CPU, it's okay for multiple contexts to reference it 206 * simultaneously; by keeping on the device struct, we eliminate a 207 * costly per-context allocation. */ 208 209 struct panfrost_bo *tiler_heap; 210 211 /* The tiler heap is shared by all contexts, and is written by tiler 212 * jobs and read by fragment job. We need to ensure that a 213 * vertex/tiler job chain from one context is not inserted between 214 * the vertex/tiler and fragment job of another context, otherwise 215 * we end up with tiler heap corruption. 216 */ 217 pthread_mutex_t submit_lock; 218 219 /* Sample positions are preloaded into a write-once constant buffer, 220 * such that they can be referenced fore free later. Needed 221 * unconditionally on Bifrost, and useful for sharing with Midgard */ 222 223 struct panfrost_bo *sample_positions; 224 }; 225 226 void 227 panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev); 228 229 void 230 panfrost_close_device(struct panfrost_device *dev); 231 232 bool 233 panfrost_supports_compressed_format(struct panfrost_device *dev, unsigned fmt); 234 235 void 236 panfrost_upload_sample_positions(struct panfrost_device *dev); 237 238 mali_ptr 239 panfrost_sample_positions(const struct panfrost_device *dev, 240 enum mali_sample_pattern pattern); 241 void 242 panfrost_query_sample_position( 243 enum mali_sample_pattern pattern, 244 unsigned sample_idx, 245 float *out); 246 247 static inline struct panfrost_bo * 248 pan_lookup_bo(struct panfrost_device *dev, uint32_t gem_handle) 249 { 250 return (struct panfrost_bo *)util_sparse_array_get(&dev->bo_map, gem_handle); 251 } 252 253 static inline bool 254 pan_is_bifrost(const struct panfrost_device *dev) 255 { 256 return dev->arch >= 6 && dev->arch <= 7; 257 } 258 259 #if defined(__cplusplus) 260 } // extern "C" 261 #endif 262 263 #endif 264