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) 47extern "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 63struct 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 77struct pan_blend_shaders { 78 struct hash_table *shaders; 79 pthread_mutex_t lock; 80}; 81 82enum 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 102struct pan_indirect_draw_shader { 103 struct panfrost_ubo_push push; 104 mali_ptr rsd; 105}; 106 107struct 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 134struct 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 */ 141struct 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 150struct 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 226void 227panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev); 228 229void 230panfrost_close_device(struct panfrost_device *dev); 231 232bool 233panfrost_supports_compressed_format(struct panfrost_device *dev, unsigned fmt); 234 235void 236panfrost_upload_sample_positions(struct panfrost_device *dev); 237 238mali_ptr 239panfrost_sample_positions(const struct panfrost_device *dev, 240 enum mali_sample_pattern pattern); 241void 242panfrost_query_sample_position( 243 enum mali_sample_pattern pattern, 244 unsigned sample_idx, 245 float *out); 246 247static inline struct panfrost_bo * 248pan_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 253static inline bool 254pan_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