1848b8605Smrg#ifndef __NOUVEAU_CONTEXT_H__ 2848b8605Smrg#define __NOUVEAU_CONTEXT_H__ 3848b8605Smrg 4848b8605Smrg#include "pipe/p_context.h" 5b8e80941Smrg#include "pipe/p_state.h" 6848b8605Smrg#include <nouveau.h> 7848b8605Smrg 8848b8605Smrg#define NOUVEAU_MAX_SCRATCH_BUFS 4 9848b8605Smrg 10b8e80941Smrgstruct nv04_resource; 11b8e80941Smrg 12848b8605Smrgstruct nouveau_context { 13848b8605Smrg struct pipe_context pipe; 14848b8605Smrg struct nouveau_screen *screen; 15848b8605Smrg 16848b8605Smrg struct nouveau_client *client; 17848b8605Smrg struct nouveau_pushbuf *pushbuf; 18b8e80941Smrg struct pipe_debug_callback debug; 19848b8605Smrg 20b8e80941Smrg bool vbo_dirty; 21848b8605Smrg 22848b8605Smrg void (*copy_data)(struct nouveau_context *, 23848b8605Smrg struct nouveau_bo *dst, unsigned, unsigned, 24848b8605Smrg struct nouveau_bo *src, unsigned, unsigned, unsigned); 25848b8605Smrg void (*push_data)(struct nouveau_context *, 26848b8605Smrg struct nouveau_bo *dst, unsigned, unsigned, 27848b8605Smrg unsigned, const void *); 28848b8605Smrg /* base, size refer to the whole constant buffer */ 29848b8605Smrg void (*push_cb)(struct nouveau_context *, 30b8e80941Smrg struct nv04_resource *, 31848b8605Smrg unsigned offset, unsigned words, const uint32_t *); 32848b8605Smrg 33848b8605Smrg /* @return: @ref reduced by nr of references found in context */ 34848b8605Smrg int (*invalidate_resource_storage)(struct nouveau_context *, 35848b8605Smrg struct pipe_resource *, 36848b8605Smrg int ref); 37848b8605Smrg 38848b8605Smrg struct { 39848b8605Smrg uint8_t *map; 40848b8605Smrg unsigned id; 41848b8605Smrg unsigned wrap; 42848b8605Smrg unsigned offset; 43848b8605Smrg unsigned end; 44848b8605Smrg struct nouveau_bo *bo[NOUVEAU_MAX_SCRATCH_BUFS]; 45848b8605Smrg struct nouveau_bo *current; 46b8e80941Smrg struct runout { 47b8e80941Smrg unsigned nr; 48b8e80941Smrg struct nouveau_bo *bo[0]; 49b8e80941Smrg } *runout; 50848b8605Smrg unsigned bo_size; 51848b8605Smrg } scratch; 52848b8605Smrg 53848b8605Smrg struct { 54848b8605Smrg uint32_t buf_cache_count; 55848b8605Smrg uint32_t buf_cache_frame; 56848b8605Smrg } stats; 57848b8605Smrg}; 58848b8605Smrg 59b8e80941Smrgstatic inline struct nouveau_context * 60848b8605Smrgnouveau_context(struct pipe_context *pipe) 61848b8605Smrg{ 62848b8605Smrg return (struct nouveau_context *)pipe; 63848b8605Smrg} 64848b8605Smrg 65848b8605Smrgvoid 66848b8605Smrgnouveau_context_init_vdec(struct nouveau_context *); 67848b8605Smrg 68b8e80941Smrgvoid 69b8e80941Smrgnouveau_context_init(struct nouveau_context *); 70b8e80941Smrg 71848b8605Smrgvoid 72848b8605Smrgnouveau_scratch_runout_release(struct nouveau_context *); 73848b8605Smrg 74848b8605Smrg/* This is needed because we don't hold references outside of context::scratch, 75848b8605Smrg * because we don't want to un-bo_ref each allocation every time. This is less 76848b8605Smrg * work, and we need the wrap index anyway for extreme situations. 77848b8605Smrg */ 78b8e80941Smrgstatic inline void 79848b8605Smrgnouveau_scratch_done(struct nouveau_context *nv) 80848b8605Smrg{ 81848b8605Smrg nv->scratch.wrap = nv->scratch.id; 82b8e80941Smrg if (unlikely(nv->scratch.runout)) 83848b8605Smrg nouveau_scratch_runout_release(nv); 84848b8605Smrg} 85848b8605Smrg 86848b8605Smrg/* Get pointer to scratch buffer. 87848b8605Smrg * The returned nouveau_bo is only referenced by the context, don't un-ref it ! 88848b8605Smrg */ 89848b8605Smrgvoid * 90848b8605Smrgnouveau_scratch_get(struct nouveau_context *, unsigned size, uint64_t *gpu_addr, 91848b8605Smrg struct nouveau_bo **); 92848b8605Smrg 93b8e80941Smrgstatic inline void 94848b8605Smrgnouveau_context_destroy(struct nouveau_context *ctx) 95848b8605Smrg{ 96848b8605Smrg int i; 97848b8605Smrg 98848b8605Smrg for (i = 0; i < NOUVEAU_MAX_SCRATCH_BUFS; ++i) 99848b8605Smrg if (ctx->scratch.bo[i]) 100848b8605Smrg nouveau_bo_ref(NULL, &ctx->scratch.bo[i]); 101848b8605Smrg 102848b8605Smrg FREE(ctx); 103848b8605Smrg} 104848b8605Smrg 105b8e80941Smrgstatic inline void 106848b8605Smrgnouveau_context_update_frame_stats(struct nouveau_context *nv) 107848b8605Smrg{ 108848b8605Smrg nv->stats.buf_cache_frame <<= 1; 109848b8605Smrg if (nv->stats.buf_cache_count) { 110848b8605Smrg nv->stats.buf_cache_count = 0; 111848b8605Smrg nv->stats.buf_cache_frame |= 1; 112848b8605Smrg if ((nv->stats.buf_cache_frame & 0xf) == 0xf) 113b8e80941Smrg nv->screen->hint_buf_keep_sysmem_copy = true; 114848b8605Smrg } 115848b8605Smrg} 116848b8605Smrg 117848b8605Smrg#endif 118