diff options
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_screen.h')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.h | 190 |
1 files changed, 165 insertions, 25 deletions
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 6e15230b486..c78ed50fe35 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -1,53 +1,193 @@ #ifndef __NV50_SCREEN_H__ #define __NV50_SCREEN_H__ +#define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" +#undef NOUVEAU_NVC0 +#include "nv50_winsys.h" +#include "nv50_stateobj.h" +#define NV50_TIC_MAX_ENTRIES 2048 +#define NV50_TSC_MAX_ENTRIES 2048 + +struct nv50_mman; struct nv50_context; +struct nv50_fence; + +#define NV50_SCRATCH_SIZE (2 << 20) +#define NV50_SCRATCH_NR_BUFFERS 2 struct nv50_screen { - struct nouveau_screen base; + struct nouveau_screen base; + struct nouveau_winsys *nvws; + + struct nv50_context *cur_ctx; + + struct nouveau_bo *code; + struct nouveau_bo *uniforms; + struct nouveau_bo *txc; /* TIC (offset 0) and TSC (65536) */ + struct nouveau_bo *stack_bo; + struct nouveau_bo *tls_bo; + + uint64_t tls_size; + + struct nouveau_resource *vp_code_heap; + struct nouveau_resource *gp_code_heap; + struct nouveau_resource *fp_code_heap; + + struct { + void **entries; + int next; + uint32_t lock[NV50_TIC_MAX_ENTRIES / 32]; + } tic; + + struct { + void **entries; + int next; + uint32_t lock[NV50_TSC_MAX_ENTRIES / 32]; + } tsc; + + struct { + uint32_t *map; + struct nv50_fence *head; + struct nv50_fence *tail; + struct nv50_fence *current; + uint32_t sequence; + uint32_t sequence_ack; + struct nouveau_bo *bo; + } fence; + + struct nouveau_notifier *sync; + + struct nv50_mman *mm_GART; + struct nv50_mman *mm_VRAM; + struct nv50_mman *mm_VRAM_fe0; + + struct nouveau_grobj *tesla; + struct nouveau_grobj *eng2d; + struct nouveau_grobj *m2mf; +}; - struct nouveau_winsys *nvws; +static INLINE struct nv50_screen * +nv50_screen(struct pipe_screen *screen) +{ + return (struct nv50_screen *)screen; +} - struct nv50_context *cur_ctx; +/* Since a resource can be migrated, we need to decouple allocations from + * them. This struct is linked with fences for delayed freeing of allocs. + */ +struct nv50_mm_allocation { + struct nv50_mm_allocation *next; + void *priv; + uint32_t offset; +}; - struct nouveau_grobj *tesla; - struct nouveau_grobj *eng2d; - struct nouveau_grobj *m2mf; - struct nouveau_notifier *sync; +static INLINE void +nv50_fence_sched_release(struct nv50_fence *nf, struct nv50_mm_allocation *mm) +{ + mm->next = nf->buffers; + nf->buffers = mm; +} - struct nouveau_bo *constbuf_misc[1]; - struct nouveau_bo *constbuf_parm[PIPE_SHADER_TYPES]; +extern struct nv50_mman * +nv50_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type); - struct nouveau_resource *immd_heap; +extern void +nv50_mm_destroy(struct nv50_mman *); - struct nouveau_bo *tic; - struct nouveau_bo *tsc; +extern struct nv50_mm_allocation * +nv50_mm_allocate(struct nv50_mman *, + uint32_t size, struct nouveau_bo **, uint32_t *offset); +extern void +nv50_mm_free(struct nv50_mm_allocation *); - struct nouveau_bo *stack_bo; /* control flow stack */ - struct nouveau_bo *local_bo; /* l[] memory */ +void nv50_screen_make_buffers_resident(struct nv50_screen *); - boolean force_push; -}; +int nv50_screen_tic_alloc(struct nv50_screen *, void *); +int nv50_screen_tsc_alloc(struct nv50_screen *, void *); -static INLINE struct nv50_screen * -nv50_screen(struct pipe_screen *screen) +static INLINE void +nv50_resource_fence(struct nv50_resource *res, uint32_t flags) { - return (struct nv50_screen *)screen; + struct nv50_screen *screen = nv50_screen(res->base.screen); + + if (res->mm) { + nv50_fence_reference(&res->fence, screen->fence.current); + + if (flags & NOUVEAU_BO_WR) + nv50_fence_reference(&res->fence_wr, screen->fence.current); + } } -extern void nv50_screen_relocs(struct nv50_screen *); +static INLINE void +nv50_resource_validate(struct nv50_resource *res, uint32_t flags) +{ + struct nv50_screen *screen = nv50_screen(res->base.screen); + + if (likely(res->bo)) { + nouveau_bo_validate(screen->base.channel, res->bo, flags); + + nv50_resource_fence(res, flags); + } +} -extern void nv50_screen_reloc_constbuf(struct nv50_screen *, unsigned cbi); + +boolean +nv50_screen_fence_new(struct nv50_screen *, struct nv50_fence **, boolean emit); + +void +nv50_screen_fence_next(struct nv50_screen *); +void +nv50_screen_fence_update(struct nv50_screen *, boolean flushed); + +static INLINE boolean +nv50_screen_fence_emit(struct nv50_screen *screen) +{ + nv50_fence_emit(screen->fence.current); + + return nv50_screen_fence_new(screen, &screen->fence.current, FALSE); +} struct nv50_format { - uint32_t rt; - uint32_t tic; - uint32_t vtx; - uint32_t usage; + uint32_t rt; + uint32_t tic; + uint32_t vtx; + uint32_t usage; }; extern const struct nv50_format nv50_format_table[]; +static INLINE void +nv50_screen_tic_unlock(struct nv50_screen *screen, struct nv50_tic_entry *tic) +{ + if (tic->id >= 0) + screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32)); +} + +static INLINE void +nv50_screen_tsc_unlock(struct nv50_screen *screen, struct nv50_tsc_entry *tsc) +{ + if (tsc->id >= 0) + screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32)); +} + +static INLINE void +nv50_screen_tic_free(struct nv50_screen *screen, struct nv50_tic_entry *tic) +{ + if (tic->id >= 0) { + screen->tic.entries[tic->id] = NULL; + screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32)); + } +} + +static INLINE void +nv50_screen_tsc_free(struct nv50_screen *screen, struct nv50_tsc_entry *tsc) +{ + if (tsc->id >= 0) { + screen->tsc.entries[tsc->id] = NULL; + screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32)); + } +} + #endif |