X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fnouveau%2Fnouveau_context.h;h=c3bbb11bd6047b332ba52d3f978cc23e8c0cb236;hb=50e913b9c5d311334281da89b4e9969d48fd62b6;hp=19bf7c84ac7350fde934a24963f6966c4a64a956;hpb=ea316c5e060cbd92b34e0d794c0707d4ca79e6e8;p=mesa.git diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h index 19bf7c84ac7..c3bbb11bd60 100644 --- a/src/gallium/drivers/nouveau/nouveau_context.h +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -2,22 +2,61 @@ #define __NOUVEAU_CONTEXT_H__ #include "pipe/p_context.h" +#include "pipe/p_state.h" +#include + +#define NOUVEAU_MAX_SCRATCH_BUFS 4 + +struct nv04_resource; struct nouveau_context { struct pipe_context pipe; struct nouveau_screen *screen; - boolean vbo_dirty; + 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, void *); + 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 * +static inline struct nouveau_context * nouveau_context(struct pipe_context *pipe) { return (struct nouveau_context *)pipe; @@ -26,4 +65,53 @@ nouveau_context(struct pipe_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