X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fnouveau%2Fnouveau_context.h;h=c3bbb11bd6047b332ba52d3f978cc23e8c0cb236;hb=e94d034a38b9993d0ea898dec550cf52541da8f1;hp=79efd08fa91c9d4d6de2caa1d65eb811af939d7b;hpb=a2fc42b899de22273c1df96091bfb5c636075cb0;p=mesa.git diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h index 79efd08fa91..c3bbb11bd60 100644 --- a/src/gallium/drivers/nouveau/nouveau_context.h +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -2,6 +2,12 @@ #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; @@ -9,9 +15,9 @@ struct nouveau_context { struct nouveau_client *client; struct nouveau_pushbuf *pushbuf; + struct pipe_debug_callback debug; - boolean vbo_dirty; - boolean cb_dirty; + bool vbo_dirty; void (*copy_data)(struct nouveau_context *, struct nouveau_bo *dst, unsigned, unsigned, @@ -21,12 +27,36 @@ struct nouveau_context { unsigned, const void *); /* base, size refer to the whole constant buffer */ void (*push_cb)(struct nouveau_context *, - struct nouveau_bo *, unsigned domain, - unsigned base, unsigned size, + 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; @@ -35,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