X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fnouveau%2Fnouveau_context.h;h=c3bbb11bd6047b332ba52d3f978cc23e8c0cb236;hb=6b73aafceb1eb8e81754e2f349826994de678466;hp=6a28d40da7b81d0621437d4316a255a6d4636a7e;hpb=4bced42341d13303ae023957d3001a640cf7ea2d;p=mesa.git diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h index 6a28d40da7b..c3bbb11bd60 100644 --- a/src/gallium/drivers/nouveau/nouveau_context.h +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -1,11 +1,117 @@ #ifndef __NOUVEAU_CONTEXT_H__ #define __NOUVEAU_CONTEXT_H__ -unsigned int -nouveau_is_texture_referenced(struct pipe_context *, struct pipe_texture *, - unsigned face, unsigned level); +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include -unsigned int -nouveau_is_buffer_referenced(struct pipe_context *, struct pipe_buffer *); +#define NOUVEAU_MAX_SCRATCH_BUFS 4 + +struct nv04_resource; + +struct nouveau_context { + struct pipe_context pipe; + struct nouveau_screen *screen; + + struct nouveau_client *client; + struct nouveau_pushbuf *pushbuf; + struct pipe_debug_callback debug; + + bool vbo_dirty; + + void (*copy_data)(struct nouveau_context *, + struct nouveau_bo *dst, unsigned, unsigned, + struct nouveau_bo *src, unsigned, unsigned, unsigned); + void (*push_data)(struct nouveau_context *, + struct nouveau_bo *dst, unsigned, unsigned, + unsigned, const void *); + /* base, size refer to the whole constant buffer */ + void (*push_cb)(struct nouveau_context *, + struct nv04_resource *, + unsigned offset, unsigned words, const uint32_t *); + + /* @return: @ref reduced by nr of references found in context */ + int (*invalidate_resource_storage)(struct nouveau_context *, + struct pipe_resource *, + int ref); + + struct { + uint8_t *map; + unsigned id; + unsigned wrap; + unsigned offset; + unsigned end; + struct nouveau_bo *bo[NOUVEAU_MAX_SCRATCH_BUFS]; + struct nouveau_bo *current; + struct runout { + unsigned nr; + struct nouveau_bo *bo[0]; + } *runout; + unsigned bo_size; + } scratch; + + struct { + uint32_t buf_cache_count; + uint32_t buf_cache_frame; + } stats; +}; + +static inline struct nouveau_context * +nouveau_context(struct pipe_context *pipe) +{ + return (struct nouveau_context *)pipe; +} + +void +nouveau_context_init_vdec(struct nouveau_context *); + +void +nouveau_context_init(struct nouveau_context *); + +void +nouveau_scratch_runout_release(struct nouveau_context *); + +/* This is needed because we don't hold references outside of context::scratch, + * because we don't want to un-bo_ref each allocation every time. This is less + * work, and we need the wrap index anyway for extreme situations. + */ +static inline void +nouveau_scratch_done(struct nouveau_context *nv) +{ + nv->scratch.wrap = nv->scratch.id; + if (unlikely(nv->scratch.runout)) + nouveau_scratch_runout_release(nv); +} + +/* Get pointer to scratch buffer. + * The returned nouveau_bo is only referenced by the context, don't un-ref it ! + */ +void * +nouveau_scratch_get(struct nouveau_context *, unsigned size, uint64_t *gpu_addr, + struct nouveau_bo **); + +static inline void +nouveau_context_destroy(struct nouveau_context *ctx) +{ + int i; + + for (i = 0; i < NOUVEAU_MAX_SCRATCH_BUFS; ++i) + if (ctx->scratch.bo[i]) + nouveau_bo_ref(NULL, &ctx->scratch.bo[i]); + + FREE(ctx); +} + +static inline void +nouveau_context_update_frame_stats(struct nouveau_context *nv) +{ + nv->stats.buf_cache_frame <<= 1; + if (nv->stats.buf_cache_count) { + nv->stats.buf_cache_count = 0; + nv->stats.buf_cache_frame |= 1; + if ((nv->stats.buf_cache_frame & 0xf) == 0xf) + nv->screen->hint_buf_keep_sysmem_copy = true; + } +} #endif