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