nvc0: force vertex data through FIFO if we need to convert it
[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 static INLINE void
90 nvc0_fence_sched_release(struct nvc0_fence *nf, struct nvc0_mm_allocation *mm)
91 {
92 mm->next = nf->buffers;
93 nf->buffers = mm;
94 }
95
96 extern struct nvc0_mman *
97 nvc0_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type);
98
99 extern void
100 nvc0_mm_destroy(struct nvc0_mman *);
101
102 extern struct nvc0_mm_allocation *
103 nvc0_mm_allocate(struct nvc0_mman *,
104 uint32_t size, struct nouveau_bo **, uint32_t *offset);
105 extern void
106 nvc0_mm_free(struct nvc0_mm_allocation *);
107
108 void nvc0_screen_make_buffers_resident(struct nvc0_screen *);
109
110 int nvc0_screen_tic_alloc(struct nvc0_screen *, void *);
111 int nvc0_screen_tsc_alloc(struct nvc0_screen *, void *);
112
113 static INLINE void
114 nvc0_resource_fence(struct nvc0_resource *res, uint32_t flags)
115 {
116 struct nvc0_screen *screen = nvc0_screen(res->base.screen);
117
118 if (res->mm) {
119 nvc0_fence_reference(&res->fence, screen->fence.current);
120
121 if (flags & NOUVEAU_BO_WR)
122 nvc0_fence_reference(&res->fence_wr, screen->fence.current);
123 }
124 }
125
126 static INLINE void
127 nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags)
128 {
129 struct nvc0_screen *screen = nvc0_screen(res->base.screen);
130
131 if (likely(res->bo)) {
132 nouveau_bo_validate(screen->base.channel, res->bo, flags);
133
134 nvc0_resource_fence(res, flags);
135 }
136 }
137
138
139 boolean
140 nvc0_screen_fence_new(struct nvc0_screen *, struct nvc0_fence **, boolean emit);
141
142 void
143 nvc0_screen_fence_next(struct nvc0_screen *);
144
145 static INLINE boolean
146 nvc0_screen_fence_emit(struct nvc0_screen *screen)
147 {
148 nvc0_fence_emit(screen->fence.current);
149
150 return nvc0_screen_fence_new(screen, &screen->fence.current, FALSE);
151 }
152
153 struct nvc0_format {
154 uint32_t rt;
155 uint32_t tic;
156 uint32_t vtx;
157 uint32_t usage;
158 };
159
160 extern const struct nvc0_format nvc0_format_table[];
161
162 static INLINE void
163 nvc0_screen_tic_unlock(struct nvc0_screen *screen, struct nvc0_tic_entry *tic)
164 {
165 if (tic->id >= 0)
166 screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32));
167 }
168
169 static INLINE void
170 nvc0_screen_tsc_unlock(struct nvc0_screen *screen, struct nvc0_tsc_entry *tsc)
171 {
172 if (tsc->id >= 0)
173 screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32));
174 }
175
176 static INLINE void
177 nvc0_screen_tic_free(struct nvc0_screen *screen, struct nvc0_tic_entry *tic)
178 {
179 if (tic->id >= 0) {
180 screen->tic.entries[tic->id] = NULL;
181 screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32));
182 }
183 }
184
185 static INLINE void
186 nvc0_screen_tsc_free(struct nvc0_screen *screen, struct nvc0_tsc_entry *tsc)
187 {
188 if (tsc->id >= 0) {
189 screen->tsc.entries[tsc->id] = NULL;
190 screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32));
191 }
192 }
193
194 #endif