1/* 2 * Copyright (C) 2012 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_SCREEN_H_ 28#define FREEDRENO_SCREEN_H_ 29 30#include "common/freedreno_dev_info.h" 31#include "drm/freedreno_drmif.h" 32#include "drm/freedreno_ringbuffer.h" 33#include "perfcntrs/freedreno_perfcntr.h" 34 35#include "pipe/p_screen.h" 36#include "renderonly/renderonly.h" 37#include "util/debug.h" 38#include "util/simple_mtx.h" 39#include "util/slab.h" 40#include "util/u_idalloc.h" 41#include "util/u_memory.h" 42#include "util/u_queue.h" 43 44#include "freedreno_batch_cache.h" 45#include "freedreno_gmem.h" 46#include "freedreno_util.h" 47 48struct fd_bo; 49 50/* Potential reasons for needing to skip bypass path and use GMEM, the 51 * generation backend can override this with screen->gmem_reason_mask 52 */ 53enum fd_gmem_reason { 54 FD_GMEM_CLEARS_DEPTH_STENCIL = BIT(0), 55 FD_GMEM_DEPTH_ENABLED = BIT(1), 56 FD_GMEM_STENCIL_ENABLED = BIT(2), 57 FD_GMEM_BLEND_ENABLED = BIT(3), 58 FD_GMEM_LOGICOP_ENABLED = BIT(4), 59 FD_GMEM_FB_READ = BIT(5), 60}; 61 62struct fd_screen { 63 struct pipe_screen base; 64 65 struct list_head context_list; 66 67 simple_mtx_t lock; 68 69 /* it would be tempting to use pipe_reference here, but that 70 * really doesn't work well if it isn't the first member of 71 * the struct, so not quite so awesome to be adding refcnting 72 * further down the inheritance hierarchy: 73 */ 74 int refcnt; 75 76 /* place for winsys to stash it's own stuff: */ 77 void *winsys_priv; 78 79 struct slab_parent_pool transfer_pool; 80 81 uint64_t gmem_base; 82 uint32_t gmemsize_bytes; 83 84 const struct fd_dev_id *dev_id; 85 uint8_t gen; /* GPU (major) generation */ 86 uint32_t gpu_id; /* 220, 305, etc */ 87 uint64_t chip_id; /* coreid:8 majorrev:8 minorrev:8 patch:8 */ 88 uint32_t max_freq; 89 uint32_t ram_size; 90 uint32_t max_rts; /* max # of render targets */ 91 uint32_t priority_mask; 92 bool has_timestamp; 93 bool has_robustness; 94 bool has_syncobj; 95 96 const struct fd_dev_info *info; 97 uint32_t ccu_offset_gmem; 98 uint32_t ccu_offset_bypass; 99 100 /* Bitmask of gmem_reasons that do not force GMEM path over bypass 101 * for current generation. 102 */ 103 enum fd_gmem_reason gmem_reason_mask; 104 105 unsigned num_perfcntr_groups; 106 const struct fd_perfcntr_group *perfcntr_groups; 107 108 /* generated at startup from the perfcntr groups: */ 109 unsigned num_perfcntr_queries; 110 struct pipe_driver_query_info *perfcntr_queries; 111 112 void *compiler; /* currently unused for a2xx */ 113 struct util_queue compile_queue; /* currently unused for a2xx */ 114 115 struct fd_device *dev; 116 117 /* NOTE: we still need a pipe associated with the screen in a few 118 * places, like screen->get_timestamp(). For anything context 119 * related, use ctx->pipe instead. 120 */ 121 struct fd_pipe *pipe; 122 123 uint32_t (*setup_slices)(struct fd_resource *rsc); 124 unsigned (*tile_mode)(const struct pipe_resource *prsc); 125 int (*layout_resource_for_modifier)(struct fd_resource *rsc, 126 uint64_t modifier); 127 128 /* indirect-branch emit: */ 129 void (*emit_ib)(struct fd_ringbuffer *ring, struct fd_ringbuffer *target); 130 131 /* simple gpu "memcpy": */ 132 void (*mem_to_mem)(struct fd_ringbuffer *ring, struct pipe_resource *dst, 133 unsigned dst_off, struct pipe_resource *src, 134 unsigned src_off, unsigned sizedwords); 135 136 int64_t cpu_gpu_time_delta; 137 138 struct fd_batch_cache batch_cache; 139 struct fd_gmem_cache gmem_cache; 140 141 bool reorder; 142 143 uint16_t rsc_seqno; 144 uint16_t ctx_seqno; 145 struct util_idalloc_mt buffer_ids; 146 147 unsigned num_supported_modifiers; 148 const uint64_t *supported_modifiers; 149 150 struct renderonly *ro; 151 152 /* the blob seems to always use 8K factor and 128K param sizes, copy them */ 153#define FD6_TESS_FACTOR_SIZE (8 * 1024) 154#define FD6_TESS_PARAM_SIZE (128 * 1024) 155#define FD6_TESS_BO_SIZE (FD6_TESS_FACTOR_SIZE + FD6_TESS_PARAM_SIZE) 156 struct fd_bo *tess_bo; 157 158 /* table with PIPE_PRIM_MAX+1 entries mapping PIPE_PRIM_x to 159 * DI_PT_x value to use for draw initiator. There are some 160 * slight differences between generation. 161 * 162 * Note that primtypes[PRIM_TYPE_MAX] is used to map to the 163 * internal RECTLIST primtype, if available, used for blits/ 164 * clears. 165 */ 166 const enum pc_di_primtype *primtypes; 167 uint32_t primtypes_mask; 168}; 169 170static inline struct fd_screen * 171fd_screen(struct pipe_screen *pscreen) 172{ 173 return (struct fd_screen *)pscreen; 174} 175 176static inline void 177fd_screen_lock(struct fd_screen *screen) 178{ 179 simple_mtx_lock(&screen->lock); 180} 181 182static inline void 183fd_screen_unlock(struct fd_screen *screen) 184{ 185 simple_mtx_unlock(&screen->lock); 186} 187 188static inline void 189fd_screen_assert_locked(struct fd_screen *screen) 190{ 191 simple_mtx_assert_locked(&screen->lock); 192} 193 194bool fd_screen_bo_get_handle(struct pipe_screen *pscreen, struct fd_bo *bo, 195 struct renderonly_scanout *scanout, 196 unsigned stride, struct winsys_handle *whandle); 197struct fd_bo *fd_screen_bo_from_handle(struct pipe_screen *pscreen, 198 struct winsys_handle *whandle); 199 200struct pipe_screen *fd_screen_create(struct fd_device *dev, 201 struct renderonly *ro, 202 const struct pipe_screen_config *config); 203 204static inline boolean 205is_a20x(struct fd_screen *screen) 206{ 207 return (screen->gpu_id >= 200) && (screen->gpu_id < 210); 208} 209 210static inline boolean 211is_a2xx(struct fd_screen *screen) 212{ 213 return screen->gen == 2; 214} 215 216/* is a3xx patch revision 0? */ 217/* TODO a306.0 probably doesn't need this.. be more clever?? */ 218static inline boolean 219is_a3xx_p0(struct fd_screen *screen) 220{ 221 return (screen->chip_id & 0xff0000ff) == 0x03000000; 222} 223 224static inline boolean 225is_a3xx(struct fd_screen *screen) 226{ 227 return screen->gen == 3; 228} 229 230static inline boolean 231is_a4xx(struct fd_screen *screen) 232{ 233 return screen->gen == 4; 234} 235 236static inline boolean 237is_a5xx(struct fd_screen *screen) 238{ 239 return screen->gen == 5; 240} 241 242static inline boolean 243is_a6xx(struct fd_screen *screen) 244{ 245 return screen->gen == 6; 246} 247 248/* is it using the ir3 compiler (shader isa introduced with a3xx)? */ 249static inline boolean 250is_ir3(struct fd_screen *screen) 251{ 252 return is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || 253 is_a6xx(screen); 254} 255 256static inline bool 257has_compute(struct fd_screen *screen) 258{ 259 return is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); 260} 261 262#endif /* FREEDRENO_SCREEN_H_ */ 263