1 #ifndef __NOUVEAU_CONTEXT_H__ 2 #define __NOUVEAU_CONTEXT_H__ 3 4 #include "pipe/p_context.h" 5 #include "pipe/p_state.h" 6 #include <nouveau.h> 7 8 #define NOUVEAU_MAX_SCRATCH_BUFS 4 9 10 struct nv04_resource; 11 12 struct nouveau_context { 13 struct pipe_context pipe; 14 struct nouveau_screen *screen; 15 16 struct nouveau_client *client; 17 struct nouveau_pushbuf *pushbuf; 18 struct pipe_debug_callback debug; 19 20 bool vbo_dirty; 21 22 void (*copy_data)(struct nouveau_context *, 23 struct nouveau_bo *dst, unsigned, unsigned, 24 struct nouveau_bo *src, unsigned, unsigned, unsigned); 25 void (*push_data)(struct nouveau_context *, 26 struct nouveau_bo *dst, unsigned, unsigned, 27 unsigned, const void *); 28 /* base, size refer to the whole constant buffer */ 29 void (*push_cb)(struct nouveau_context *, 30 struct nv04_resource *, 31 unsigned offset, unsigned words, const uint32_t *); 32 33 /* @return: @ref reduced by nr of references found in context */ 34 int (*invalidate_resource_storage)(struct nouveau_context *, 35 struct pipe_resource *, 36 int ref); 37 38 struct { 39 uint8_t *map; 40 unsigned id; 41 unsigned wrap; 42 unsigned offset; 43 unsigned end; 44 struct nouveau_bo *bo[NOUVEAU_MAX_SCRATCH_BUFS]; 45 struct nouveau_bo *current; 46 struct runout { 47 unsigned nr; 48 struct nouveau_bo *bo[0]; 49 } *runout; 50 unsigned bo_size; 51 } scratch; 52 53 struct { 54 uint32_t buf_cache_count; 55 uint32_t buf_cache_frame; 56 } stats; 57 }; 58 59 static inline struct nouveau_context * 60 nouveau_context(struct pipe_context *pipe) 61 { 62 return (struct nouveau_context *)pipe; 63 } 64 65 void 66 nouveau_context_init_vdec(struct nouveau_context *); 67 68 void 69 nouveau_context_init(struct nouveau_context *); 70 71 void 72 nouveau_scratch_runout_release(struct nouveau_context *); 73 74 /* This is needed because we don't hold references outside of context::scratch, 75 * because we don't want to un-bo_ref each allocation every time. This is less 76 * work, and we need the wrap index anyway for extreme situations. 77 */ 78 static inline void 79 nouveau_scratch_done(struct nouveau_context *nv) 80 { 81 nv->scratch.wrap = nv->scratch.id; 82 if (unlikely(nv->scratch.runout)) 83 nouveau_scratch_runout_release(nv); 84 } 85 86 /* Get pointer to scratch buffer. 87 * The returned nouveau_bo is only referenced by the context, don't un-ref it ! 88 */ 89 void * 90 nouveau_scratch_get(struct nouveau_context *, unsigned size, uint64_t *gpu_addr, 91 struct nouveau_bo **); 92 93 static inline void 94 nouveau_context_destroy(struct nouveau_context *ctx) 95 { 96 int i; 97 98 for (i = 0; i < NOUVEAU_MAX_SCRATCH_BUFS; ++i) 99 if (ctx->scratch.bo[i]) 100 nouveau_bo_ref(NULL, &ctx->scratch.bo[i]); 101 102 FREE(ctx); 103 } 104 105 static inline void 106 nouveau_context_update_frame_stats(struct nouveau_context *nv) 107 { 108 nv->stats.buf_cache_frame <<= 1; 109 if (nv->stats.buf_cache_count) { 110 nv->stats.buf_cache_count = 0; 111 nv->stats.buf_cache_frame |= 1; 112 if ((nv->stats.buf_cache_frame & 0xf) == 0xf) 113 nv->screen->hint_buf_keep_sysmem_copy = true; 114 } 115 } 116 117 #endif 118