Merge remote branch 'origin/master' into nvc0-new
[mesa.git] / src / gallium / drivers / nvc0 / nvc0_screen.h
1 #ifndef __NVC0_SCREEN_H__
2 #define __NVC0_SCREEN_H__
3
4 #define NOUVEAU_NVC0
5 #include "nouveau/nouveau_screen.h"
6 #undef NOUVEAU_NVC0
7 #include "nvc0_winsys.h"
8 #include "nvc0_stateobj.h"
9
10 #define NVC0_TIC_MAX_ENTRIES 2048
11 #define NVC0_TSC_MAX_ENTRIES 2048
12
13 struct nvc0_mman;
14 struct nvc0_context;
15 struct nvc0_fence;
16
17 #define NVC0_SCRATCH_SIZE (2 << 20)
18 #define NVC0_SCRATCH_NR_BUFFERS 2
19
20 struct nvc0_screen {
21 struct nouveau_screen base;
22 struct nouveau_winsys *nvws;
23
24 struct nvc0_context *cur_ctx;
25
26 struct nouveau_bo *text;
27 struct nouveau_bo *uniforms;
28 struct nouveau_bo *tls;
29 struct nouveau_bo *txc; /* TIC (offset 0) and TSC (65536) */
30 struct nouveau_bo *mp_stack_bo;
31
32 uint64_t tls_size;
33
34 struct nouveau_resource *text_heap;
35
36 struct {
37 struct nouveau_bo *bo[NVC0_SCRATCH_NR_BUFFERS];
38 uint8_t *buf;
39 int index;
40 uint32_t offset;
41 } scratch;
42
43 struct {
44 void **entries;
45 int next;
46 uint32_t lock[NVC0_TIC_MAX_ENTRIES / 32];
47 } tic;
48
49 struct {
50 void **entries;
51 int next;
52 uint32_t lock[NVC0_TSC_MAX_ENTRIES / 32];
53 } tsc;
54
55 struct {
56 uint32_t *map;
57 struct nvc0_fence *head;
58 struct nvc0_fence *tail;
59 struct nvc0_fence *current;
60 uint32_t sequence;
61 uint32_t sequence_ack;
62 struct nouveau_bo *bo;
63 } fence;
64
65 struct nvc0_mman *mm_GART;
66 struct nvc0_mman *mm_VRAM;
67 struct nvc0_mman *mm_VRAM_fe0;
68
69 struct nouveau_grobj *fermi;
70 struct nouveau_grobj *eng2d;
71 struct nouveau_grobj *m2mf;
72 };
73
74 static INLINE struct nvc0_screen *
75 nvc0_screen(struct pipe_screen *screen)
76 {
77 return (struct nvc0_screen *)screen;
78 }
79
80 /* Since a resource can be migrated, we need to decouple allocations from
81 * them. This struct is linked with fences for delayed freeing of allocs.
82 */
83 struct nvc0_mm_allocation {
84 struct nvc0_mm_allocation *next;
85 void *priv;
86 uint32_t offset;
87 };
88
89 extern struct nvc0_mman *
90 nvc0_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type);
91
92 extern struct nvc0_mm_allocation *
93 nvc0_mm_allocate(struct nvc0_mman *,
94 uint32_t size, struct nouveau_bo **, uint32_t *offset);
95 extern void
96 nvc0_mm_free(struct nvc0_mm_allocation *);
97
98 void nvc0_screen_make_buffers_resident(struct nvc0_screen *);
99
100 int nvc0_screen_tic_alloc(struct nvc0_screen *, void *);
101 int nvc0_screen_tsc_alloc(struct nvc0_screen *, void *);
102
103 static INLINE void
104 nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags)
105 {
106 struct nvc0_screen *screen = nvc0_screen(res->base.screen);
107
108 assert(res->mm);
109
110 nvc0_fence_reference(&res->fence, screen->fence.current);
111
112 if (flags & NOUVEAU_BO_WR)
113 nvc0_fence_reference(&res->fence_wr, screen->fence.current);
114
115 nouveau_reloc_emit(screen->base.channel,
116 NULL, 0, NULL, res->bo, 0, 0, NOUVEAU_BO_RDWR, 0, 0);
117 }
118
119
120 boolean
121 nvc0_screen_fence_new(struct nvc0_screen *, struct nvc0_fence **, boolean emit);
122
123 void
124 nvc0_screen_fence_next(struct nvc0_screen *);
125
126 static INLINE boolean
127 nvc0_screen_fence_emit(struct nvc0_screen *screen)
128 {
129 nvc0_fence_emit(screen->fence.current);
130
131 return nvc0_screen_fence_new(screen, &screen->fence.current, FALSE);
132 }
133
134 struct nvc0_format {
135 uint32_t rt;
136 uint32_t tic;
137 uint32_t vtx;
138 uint32_t usage;
139 };
140
141 extern const struct nvc0_format nvc0_format_table[];
142
143 static INLINE void
144 nvc0_screen_tic_unlock(struct nvc0_screen *screen, struct nvc0_tic_entry *tic)
145 {
146 if (tic->id >= 0)
147 screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32));
148 }
149
150 static INLINE void
151 nvc0_screen_tsc_unlock(struct nvc0_screen *screen, struct nvc0_tsc_entry *tsc)
152 {
153 if (tsc->id >= 0)
154 screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32));
155 }
156
157 static INLINE void
158 nvc0_screen_tic_free(struct nvc0_screen *screen, struct nvc0_tic_entry *tic)
159 {
160 if (tic->id >= 0) {
161 screen->tic.entries[tic->id] = NULL;
162 screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32));
163 }
164 }
165
166 static INLINE void
167 nvc0_screen_tsc_free(struct nvc0_screen *screen, struct nvc0_tsc_entry *tsc)
168 {
169 if (tsc->id >= 0) {
170 screen->tsc.entries[tsc->id] = NULL;
171 screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32));
172 }
173 }
174
175 #endif