1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 2 3 /* 4 * Copyright (C) 2012 Rob Clark <robclark (at) freedesktop.org> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * Authors: 26 * Rob Clark <robclark (at) freedesktop.org> 27 */ 28 29 #ifndef FREEDRENO_CONTEXT_H_ 30 #define FREEDRENO_CONTEXT_H_ 31 32 #include "pipe/p_context.h" 33 #include "indices/u_primconvert.h" 34 #include "util/u_blitter.h" 35 #include "util/list.h" 36 #include "util/slab.h" 37 #include "util/u_string.h" 38 39 #include "freedreno_batch.h" 40 #include "freedreno_screen.h" 41 #include "freedreno_gmem.h" 42 #include "freedreno_util.h" 43 44 #define BORDER_COLOR_UPLOAD_SIZE (2 * PIPE_MAX_SAMPLERS * BORDERCOLOR_SIZE) 45 46 struct fd_vertex_stateobj; 47 48 struct fd_texture_stateobj { 49 struct pipe_sampler_view *textures[PIPE_MAX_SAMPLERS]; 50 unsigned num_textures; 51 unsigned valid_textures; 52 struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; 53 unsigned num_samplers; 54 unsigned valid_samplers; 55 }; 56 57 struct fd_program_stateobj { 58 void *vp, *fp; 59 60 /* rest only used by fd2.. split out: */ 61 uint8_t num_exports; 62 /* Indexed by semantic name or TGSI_SEMANTIC_COUNT + semantic index 63 * for TGSI_SEMANTIC_GENERIC. Special vs exports (position and point- 64 * size) are not included in this 65 */ 66 uint8_t export_linkage[63]; 67 }; 68 69 struct fd_constbuf_stateobj { 70 struct pipe_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS]; 71 uint32_t enabled_mask; 72 uint32_t dirty_mask; 73 }; 74 75 struct fd_vertexbuf_stateobj { 76 struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS]; 77 unsigned count; 78 uint32_t enabled_mask; 79 uint32_t dirty_mask; 80 }; 81 82 struct fd_vertex_stateobj { 83 struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS]; 84 unsigned num_elements; 85 }; 86 87 struct fd_streamout_stateobj { 88 struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS]; 89 unsigned num_targets; 90 /* Track offset from vtxcnt for streamout data. This counter 91 * is just incremented by # of vertices on each draw until 92 * reset or new streamout buffer bound. 93 * 94 * When we eventually have GS, the CPU won't actually know the 95 * number of vertices per draw, so I think we'll have to do 96 * something more clever. 97 */ 98 unsigned offsets[PIPE_MAX_SO_BUFFERS]; 99 }; 100 101 /* group together the vertex and vertexbuf state.. for ease of passing 102 * around, and because various internal operations (gmem<->mem, etc) 103 * need their own vertex state: 104 */ 105 struct fd_vertex_state { 106 struct fd_vertex_stateobj *vtx; 107 struct fd_vertexbuf_stateobj vertexbuf; 108 }; 109 110 111 struct fd_context { 112 struct pipe_context base; 113 114 struct fd_device *dev; 115 struct fd_screen *screen; 116 117 struct util_queue flush_queue; 118 119 struct blitter_context *blitter; 120 void *clear_rs_state; 121 struct primconvert_context *primconvert; 122 123 /* slab for pipe_transfer allocations: */ 124 struct slab_child_pool transfer_pool; 125 126 /* slabs for fd_hw_sample and fd_hw_sample_period allocations: */ 127 struct slab_mempool sample_pool; 128 struct slab_mempool sample_period_pool; 129 130 /* sample-providers for hw queries: */ 131 const struct fd_hw_sample_provider *sample_providers[MAX_HW_SAMPLE_PROVIDERS]; 132 133 /* list of active queries: */ 134 struct list_head active_queries; 135 136 /* table with PIPE_PRIM_MAX entries mapping PIPE_PRIM_x to 137 * DI_PT_x value to use for draw initiator. There are some 138 * slight differences between generation: 139 */ 140 const uint8_t *primtypes; 141 uint32_t primtype_mask; 142 143 /* shaders used by clear, and gmem->mem blits: */ 144 struct fd_program_stateobj solid_prog; // TODO move to screen? 145 146 /* shaders used by mem->gmem blits: */ 147 struct fd_program_stateobj blit_prog[MAX_RENDER_TARGETS]; // TODO move to screen? 148 struct fd_program_stateobj blit_z, blit_zs; 149 150 /* Stats/counters: 151 */ 152 struct { 153 uint64_t prims_emitted; 154 uint64_t prims_generated; 155 uint64_t draw_calls; 156 uint64_t batch_total, batch_sysmem, batch_gmem, batch_restore; 157 } stats; 158 159 /* Current batch.. the rule here is that you can deref ctx->batch 160 * in codepaths from pipe_context entrypoints. But not in code- 161 * paths from fd_batch_flush() (basically, the stuff that gets 162 * called from GMEM code), since in those code-paths the batch 163 * you care about is not necessarily the same as ctx->batch. 164 */ 165 struct fd_batch *batch; 166 167 struct pipe_fence_handle *last_fence; 168 169 /* Are we in process of shadowing a resource? Used to detect recursion 170 * in transfer_map, and skip unneeded synchronization. 171 */ 172 bool in_shadow : 1; 173 174 /* Ie. in blit situation where we no longer care about previous framebuffer 175 * contents. Main point is to eliminate blits from fd_try_shadow_resource(). 176 * For example, in case of texture upload + gen-mipmaps. 177 */ 178 bool in_blit : 1; 179 180 struct pipe_scissor_state scissor; 181 182 /* we don't have a disable/enable bit for scissor, so instead we keep 183 * a disabled-scissor state which matches the entire bound framebuffer 184 * and use that when scissor is not enabled. 185 */ 186 struct pipe_scissor_state disabled_scissor; 187 188 /* Current gmem/tiling configuration.. gets updated on render_tiles() 189 * if out of date with current maximal-scissor/cpp: 190 * 191 * (NOTE: this is kind of related to the batch, but moving it there 192 * means we'd always have to recalc tiles ever batch) 193 */ 194 struct fd_gmem_stateobj gmem; 195 struct fd_vsc_pipe pipe[8]; 196 struct fd_tile tile[512]; 197 198 /* which state objects need to be re-emit'd: */ 199 enum { 200 FD_DIRTY_BLEND = (1 << 0), 201 FD_DIRTY_RASTERIZER = (1 << 1), 202 FD_DIRTY_ZSA = (1 << 2), 203 FD_DIRTY_FRAGTEX = (1 << 3), 204 FD_DIRTY_VERTTEX = (1 << 4), 205 FD_DIRTY_TEXSTATE = (1 << 5), 206 207 FD_SHADER_DIRTY_VP = (1 << 6), 208 FD_SHADER_DIRTY_FP = (1 << 7), 209 /* skip geom/tcs/tes/compute */ 210 FD_DIRTY_PROG = FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP, 211 212 FD_DIRTY_BLEND_COLOR = (1 << 12), 213 FD_DIRTY_STENCIL_REF = (1 << 13), 214 FD_DIRTY_SAMPLE_MASK = (1 << 14), 215 FD_DIRTY_FRAMEBUFFER = (1 << 15), 216 FD_DIRTY_STIPPLE = (1 << 16), 217 FD_DIRTY_VIEWPORT = (1 << 17), 218 FD_DIRTY_CONSTBUF = (1 << 18), 219 FD_DIRTY_VTXSTATE = (1 << 19), 220 FD_DIRTY_VTXBUF = (1 << 20), 221 FD_DIRTY_INDEXBUF = (1 << 21), 222 FD_DIRTY_SCISSOR = (1 << 22), 223 FD_DIRTY_STREAMOUT = (1 << 23), 224 FD_DIRTY_UCP = (1 << 24), 225 FD_DIRTY_BLEND_DUAL = (1 << 25), 226 } dirty; 227 228 struct pipe_blend_state *blend; 229 struct pipe_rasterizer_state *rasterizer; 230 struct pipe_depth_stencil_alpha_state *zsa; 231 232 struct fd_texture_stateobj verttex, fragtex; 233 234 struct fd_program_stateobj prog; 235 236 struct fd_vertex_state vtx; 237 238 struct pipe_blend_color blend_color; 239 struct pipe_stencil_ref stencil_ref; 240 unsigned sample_mask; 241 struct pipe_poly_stipple stipple; 242 struct pipe_viewport_state viewport; 243 struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES]; 244 struct pipe_index_buffer indexbuf; 245 struct fd_streamout_stateobj streamout; 246 struct pipe_clip_state ucp; 247 248 struct pipe_query *cond_query; 249 bool cond_cond; /* inverted rendering condition */ 250 uint cond_mode; 251 252 struct pipe_debug_callback debug; 253 254 /* GMEM/tile handling fxns: */ 255 void (*emit_tile_init)(struct fd_batch *batch); 256 void (*emit_tile_prep)(struct fd_batch *batch, struct fd_tile *tile); 257 void (*emit_tile_mem2gmem)(struct fd_batch *batch, struct fd_tile *tile); 258 void (*emit_tile_renderprep)(struct fd_batch *batch, struct fd_tile *tile); 259 void (*emit_tile_gmem2mem)(struct fd_batch *batch, struct fd_tile *tile); 260 void (*emit_tile_fini)(struct fd_batch *batch); /* optional */ 261 262 /* optional, for GMEM bypass: */ 263 void (*emit_sysmem_prep)(struct fd_batch *batch); 264 void (*emit_sysmem_fini)(struct fd_batch *batch); 265 266 /* draw: */ 267 bool (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info); 268 void (*clear)(struct fd_context *ctx, unsigned buffers, 269 const union pipe_color_union *color, double depth, unsigned stencil); 270 271 /* constant emit: (note currently not used/needed for a2xx) */ 272 void (*emit_const)(struct fd_ringbuffer *ring, enum shader_t type, 273 uint32_t regid, uint32_t offset, uint32_t sizedwords, 274 const uint32_t *dwords, struct pipe_resource *prsc); 275 /* emit bo addresses as constant: */ 276 void (*emit_const_bo)(struct fd_ringbuffer *ring, enum shader_t type, boolean write, 277 uint32_t regid, uint32_t num, struct pipe_resource **prscs, uint32_t *offsets); 278 279 /* indirect-branch emit: */ 280 void (*emit_ib)(struct fd_ringbuffer *ring, struct fd_ringbuffer *target); 281 282 /* 283 * Common pre-cooked VBO state (used for a3xx and later): 284 */ 285 286 /* for clear/gmem->mem vertices, and mem->gmem */ 287 struct pipe_resource *solid_vbuf; 288 289 /* for mem->gmem tex coords: */ 290 struct pipe_resource *blit_texcoord_vbuf; 291 292 /* vertex state for solid_vbuf: 293 * - solid_vbuf / 12 / R32G32B32_FLOAT 294 */ 295 struct fd_vertex_state solid_vbuf_state; 296 297 /* vertex state for blit_prog: 298 * - blit_texcoord_vbuf / 8 / R32G32_FLOAT 299 * - solid_vbuf / 12 / R32G32B32_FLOAT 300 */ 301 struct fd_vertex_state blit_vbuf_state; 302 }; 303 304 static inline struct fd_context * 305 fd_context(struct pipe_context *pctx) 306 { 307 return (struct fd_context *)pctx; 308 } 309 310 static inline void 311 fd_context_assert_locked(struct fd_context *ctx) 312 { 313 pipe_mutex_assert_locked(ctx->screen->lock); 314 } 315 316 static inline void 317 fd_context_lock(struct fd_context *ctx) 318 { 319 pipe_mutex_lock(ctx->screen->lock); 320 } 321 322 static inline void 323 fd_context_unlock(struct fd_context *ctx) 324 { 325 pipe_mutex_unlock(ctx->screen->lock); 326 } 327 328 static inline struct pipe_scissor_state * 329 fd_context_get_scissor(struct fd_context *ctx) 330 { 331 if (ctx->rasterizer && ctx->rasterizer->scissor) 332 return &ctx->scissor; 333 return &ctx->disabled_scissor; 334 } 335 336 static inline bool 337 fd_supported_prim(struct fd_context *ctx, unsigned prim) 338 { 339 return (1 << prim) & ctx->primtype_mask; 340 } 341 342 void fd_context_setup_common_vbos(struct fd_context *ctx); 343 void fd_context_cleanup_common_vbos(struct fd_context *ctx); 344 345 struct pipe_context * fd_context_init(struct fd_context *ctx, 346 struct pipe_screen *pscreen, const uint8_t *primtypes, 347 void *priv); 348 349 void fd_context_destroy(struct pipe_context *pctx); 350 351 #endif /* FREEDRENO_CONTEXT_H_ */ 352