nvc0: use tile flags in a way compatible with nouveau
[mesa.git] / src / gallium / drivers / nvc0 / nvc0_winsys.h
1
2 #ifndef __NVC0_WINSYS_H__
3 #define __NVC0_WINSYS_H__
4
5 #include <stdint.h>
6 #include <unistd.h>
7 #include "pipe/p_defines.h"
8
9 #include "nouveau/nouveau_bo.h"
10 #include "nouveau/nouveau_channel.h"
11 #include "nouveau/nouveau_device.h"
12 #include "nouveau/nouveau_resource.h"
13 #include "nouveau/nouveau_reloc.h"
14
15 #include "nvc0_resource.h" /* OUT_RESRC */
16
17 #ifndef NV04_PFIFO_MAX_PACKET_LEN
18 #define NV04_PFIFO_MAX_PACKET_LEN 2047
19 #endif
20
21 #define SLEEP(us) usleep(us)
22
23 extern uint64_t nouveau_bo_gpu_address(struct nouveau_bo *);
24
25 #define NVC0_SUBCH_3D 1
26 #define NVC0_SUBCH_2D 2
27 #define NVC0_SUBCH_MF 3
28
29 #define NVC0_MF_(n) NVC0_M2MF_##n
30
31 #define RING_3D(n) ((NVC0_SUBCH_3D << 13) | (NVC0_3D_##n >> 2))
32 #define RING_2D(n) ((NVC0_SUBCH_2D << 13) | (NVC0_2D_##n >> 2))
33 #define RING_MF(n) ((NVC0_SUBCH_MF << 13) | (NVC0_MF_(n) >> 2))
34
35 #define RING_3D_(m) ((NVC0_SUBCH_3D << 13) | ((m) >> 2))
36 #define RING_2D_(m) ((NVC0_SUBCH_2D << 13) | ((m) >> 2))
37 #define RING_MF_(m) ((NVC0_SUBCH_MF << 13) | ((m) >> 2))
38
39 #define RING_ANY(m) ((NVC0_SUBCH_3D << 13) | ((m) >> 2))
40
41 int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
42
43 static inline uint32_t
44 nouveau_bo_tile_layout(struct nouveau_bo *bo)
45 {
46 return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
47 }
48
49 static INLINE void
50 WAIT_RING(struct nouveau_channel *chan, unsigned size)
51 {
52 if (chan->cur + size > chan->end)
53 nouveau_pushbuf_flush(chan, size);
54 }
55
56 static INLINE void
57 OUT_RING(struct nouveau_channel *chan, uint32_t data)
58 {
59 *(chan->cur++) = (data);
60 }
61
62 /* incremental methods */
63 static INLINE void
64 BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
65 {
66 WAIT_RING(chan, size + 1);
67 OUT_RING (chan, (0x2 << 28) | (size << 16) | mthd);
68 }
69
70 /* non-incremental */
71 static INLINE void
72 BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
73 {
74 WAIT_RING(chan, size + 1);
75 OUT_RING (chan, (0x6 << 28) | (size << 16) | mthd);
76 }
77
78 /* increment-once */
79 static INLINE void
80 BEGIN_RING_1I(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
81 {
82 WAIT_RING(chan, size + 1);
83 OUT_RING (chan, (0xa << 28) | (size << 16) | mthd);
84 }
85
86 /* inline-data */
87 static INLINE void
88 INLIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data)
89 {
90 WAIT_RING(chan, 1);
91 OUT_RING (chan, (0x8 << 28) | (data << 16) | mthd);
92 }
93
94 int
95 nouveau_pushbuf_marker_emit(struct nouveau_channel *chan,
96 unsigned wait_dwords, unsigned wait_relocs);
97 int
98 nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr,
99 struct nouveau_bo *, uint32_t data, uint32_t data2,
100 uint32_t flags, uint32_t vor, uint32_t tor);
101 int
102 nouveau_pushbuf_submit(struct nouveau_channel *chan, struct nouveau_bo *bo,
103 unsigned offset, unsigned length);
104
105 static INLINE int
106 MARK_RING(struct nouveau_channel *chan, unsigned dwords, unsigned relocs)
107 {
108 return nouveau_pushbuf_marker_emit(chan, dwords, relocs);
109 }
110
111 static INLINE void
112 OUT_RINGf(struct nouveau_channel *chan, float data)
113 {
114 union { uint32_t i; float f; } u;
115 u.f = data;
116 OUT_RING(chan, u.i);
117 }
118
119 static INLINE unsigned
120 AVAIL_RING(struct nouveau_channel *chan)
121 {
122 return chan->end - chan->cur;
123 }
124
125 static INLINE void
126 OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned size)
127 {
128 memcpy(chan->cur, data, size * 4);
129 chan->cur += size;
130 }
131
132 static INLINE int
133 OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo,
134 unsigned data, unsigned flags, unsigned vor, unsigned tor)
135 {
136 return nouveau_pushbuf_emit_reloc(chan, chan->cur++, bo,
137 data, 0, flags, vor, tor);
138 }
139
140 static INLINE int
141 OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo,
142 unsigned delta, unsigned flags)
143 {
144 return OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0);
145 }
146
147 static INLINE int
148 OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo,
149 unsigned delta, unsigned flags)
150 {
151 return OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0);
152 }
153
154 static INLINE int
155 OUT_RESRCh(struct nouveau_channel *chan, struct nvc0_resource *res,
156 unsigned delta, unsigned flags)
157 {
158 return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
159 }
160
161 static INLINE int
162 OUT_RESRCl(struct nouveau_channel *chan, struct nvc0_resource *res,
163 unsigned delta, unsigned flags)
164 {
165 return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
166 }
167
168 static INLINE void
169 FIRE_RING(struct nouveau_channel *chan)
170 {
171 nouveau_pushbuf_flush(chan, 0);
172 }
173
174 #endif