14a49301eSmrg#ifndef __NOUVEAU_CONTEXT_H__ 24a49301eSmrg#define __NOUVEAU_CONTEXT_H__ 34a49301eSmrg 43464ebd5Sriastradh#include "pipe/p_context.h" 501e04c3fSmrg#include "pipe/p_state.h" 6af69d88dSmrg#include <nouveau.h> 7af69d88dSmrg 8af69d88dSmrg#define NOUVEAU_MAX_SCRATCH_BUFS 4 94a49301eSmrg 1001e04c3fSmrgstruct nv04_resource; 1101e04c3fSmrg 123464ebd5Sriastradhstruct nouveau_context { 133464ebd5Sriastradh struct pipe_context pipe; 143464ebd5Sriastradh struct nouveau_screen *screen; 153464ebd5Sriastradh 16af69d88dSmrg struct nouveau_client *client; 17af69d88dSmrg struct nouveau_pushbuf *pushbuf; 1801e04c3fSmrg struct pipe_debug_callback debug; 19af69d88dSmrg 2001e04c3fSmrg bool vbo_dirty; 213464ebd5Sriastradh 223464ebd5Sriastradh void (*copy_data)(struct nouveau_context *, 233464ebd5Sriastradh struct nouveau_bo *dst, unsigned, unsigned, 243464ebd5Sriastradh struct nouveau_bo *src, unsigned, unsigned, unsigned); 253464ebd5Sriastradh void (*push_data)(struct nouveau_context *, 263464ebd5Sriastradh struct nouveau_bo *dst, unsigned, unsigned, 27af69d88dSmrg unsigned, const void *); 28af69d88dSmrg /* base, size refer to the whole constant buffer */ 29af69d88dSmrg void (*push_cb)(struct nouveau_context *, 3001e04c3fSmrg struct nv04_resource *, 31af69d88dSmrg unsigned offset, unsigned words, const uint32_t *); 32af69d88dSmrg 33af69d88dSmrg /* @return: @ref reduced by nr of references found in context */ 34af69d88dSmrg int (*invalidate_resource_storage)(struct nouveau_context *, 35af69d88dSmrg struct pipe_resource *, 36af69d88dSmrg int ref); 37af69d88dSmrg 38af69d88dSmrg struct { 39af69d88dSmrg uint8_t *map; 40af69d88dSmrg unsigned id; 41af69d88dSmrg unsigned wrap; 42af69d88dSmrg unsigned offset; 43af69d88dSmrg unsigned end; 44af69d88dSmrg struct nouveau_bo *bo[NOUVEAU_MAX_SCRATCH_BUFS]; 45af69d88dSmrg struct nouveau_bo *current; 4601e04c3fSmrg struct runout { 4701e04c3fSmrg unsigned nr; 4801e04c3fSmrg struct nouveau_bo *bo[0]; 4901e04c3fSmrg } *runout; 50af69d88dSmrg unsigned bo_size; 51af69d88dSmrg } scratch; 52af69d88dSmrg 53af69d88dSmrg struct { 54af69d88dSmrg uint32_t buf_cache_count; 55af69d88dSmrg uint32_t buf_cache_frame; 56af69d88dSmrg } stats; 573464ebd5Sriastradh}; 583464ebd5Sriastradh 5901e04c3fSmrgstatic inline struct nouveau_context * 603464ebd5Sriastradhnouveau_context(struct pipe_context *pipe) 613464ebd5Sriastradh{ 623464ebd5Sriastradh return (struct nouveau_context *)pipe; 633464ebd5Sriastradh} 644a49301eSmrg 65af69d88dSmrgvoid 66af69d88dSmrgnouveau_context_init_vdec(struct nouveau_context *); 67af69d88dSmrg 6801e04c3fSmrgvoid 6901e04c3fSmrgnouveau_context_init(struct nouveau_context *); 7001e04c3fSmrg 71af69d88dSmrgvoid 72af69d88dSmrgnouveau_scratch_runout_release(struct nouveau_context *); 73af69d88dSmrg 74af69d88dSmrg/* This is needed because we don't hold references outside of context::scratch, 75af69d88dSmrg * because we don't want to un-bo_ref each allocation every time. This is less 76af69d88dSmrg * work, and we need the wrap index anyway for extreme situations. 77af69d88dSmrg */ 7801e04c3fSmrgstatic inline void 79af69d88dSmrgnouveau_scratch_done(struct nouveau_context *nv) 80af69d88dSmrg{ 81af69d88dSmrg nv->scratch.wrap = nv->scratch.id; 8201e04c3fSmrg if (unlikely(nv->scratch.runout)) 83af69d88dSmrg nouveau_scratch_runout_release(nv); 84af69d88dSmrg} 85af69d88dSmrg 86af69d88dSmrg/* Get pointer to scratch buffer. 87af69d88dSmrg * The returned nouveau_bo is only referenced by the context, don't un-ref it ! 88af69d88dSmrg */ 89af69d88dSmrgvoid * 90af69d88dSmrgnouveau_scratch_get(struct nouveau_context *, unsigned size, uint64_t *gpu_addr, 91af69d88dSmrg struct nouveau_bo **); 92af69d88dSmrg 9301e04c3fSmrgstatic inline void 94af69d88dSmrgnouveau_context_destroy(struct nouveau_context *ctx) 95af69d88dSmrg{ 96af69d88dSmrg int i; 97af69d88dSmrg 98af69d88dSmrg for (i = 0; i < NOUVEAU_MAX_SCRATCH_BUFS; ++i) 99af69d88dSmrg if (ctx->scratch.bo[i]) 100af69d88dSmrg nouveau_bo_ref(NULL, &ctx->scratch.bo[i]); 101af69d88dSmrg 102af69d88dSmrg FREE(ctx); 103af69d88dSmrg} 104af69d88dSmrg 10501e04c3fSmrgstatic inline void 106af69d88dSmrgnouveau_context_update_frame_stats(struct nouveau_context *nv) 107af69d88dSmrg{ 108af69d88dSmrg nv->stats.buf_cache_frame <<= 1; 109af69d88dSmrg if (nv->stats.buf_cache_count) { 110af69d88dSmrg nv->stats.buf_cache_count = 0; 111af69d88dSmrg nv->stats.buf_cache_frame |= 1; 112af69d88dSmrg if ((nv->stats.buf_cache_frame & 0xf) == 0xf) 11301e04c3fSmrg nv->screen->hint_buf_keep_sysmem_copy = true; 114af69d88dSmrg } 115af69d88dSmrg} 116af69d88dSmrg 1174a49301eSmrg#endif 118