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