g3dvl: Use Gallium thread wrappers.
[mesa.git] / src / gallium / winsys / drm / nouveau / nouveau_local.h
1 #ifndef __NOUVEAU_LOCAL_H__
2 #define __NOUVEAU_LOCAL_H__
3
4 #include "pipe/p_compiler.h"
5 #include "nouveau_winsys_pipe.h"
6 #include <stdio.h>
7
8 struct pipe_buffer;
9
10 /* Debug output */
11 #define NOUVEAU_MSG(fmt, args...) do { \
12 fprintf(stdout, "nouveau: "fmt, ##args); \
13 fflush(stdout); \
14 } while(0)
15
16 #define NOUVEAU_ERR(fmt, args...) do { \
17 fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); \
18 fflush(stderr); \
19 } while(0)
20
21 #define NOUVEAU_TIME_MSEC() 0
22
23 /* User FIFO control */
24 //#define NOUVEAU_DMA_TRACE
25 //#define NOUVEAU_DMA_DEBUG
26 //#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF
27 #define NOUVEAU_DMA_BARRIER
28 #define NOUVEAU_DMA_TIMEOUT 2000
29
30 /* Push buffer access macros */
31 static INLINE void
32 OUT_RING(struct nouveau_channel *chan, unsigned data)
33 {
34 *(chan->pushbuf->cur++) = (data);
35 }
36
37 static INLINE void
38 OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size)
39 {
40 memcpy(chan->pushbuf->cur, data, size * 4);
41 chan->pushbuf->cur += size;
42 }
43
44 static INLINE void
45 OUT_RINGf(struct nouveau_channel *chan, float f)
46 {
47 union { uint32_t i; float f; } c;
48 c.f = f;
49 OUT_RING(chan, c.i);
50 }
51
52 static INLINE void
53 BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr,
54 unsigned mthd, unsigned size)
55 {
56 if (chan->pushbuf->remaining < (size + 1))
57 nouveau_pushbuf_flush(chan, (size + 1));
58 OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd);
59 chan->pushbuf->remaining -= (size + 1);
60 }
61
62 static INLINE void
63 FIRE_RING(struct nouveau_channel *chan)
64 {
65 nouveau_pushbuf_flush(chan, 0);
66 }
67
68 static INLINE void
69 BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc)
70 {
71 gr->subc = subc;
72 BEGIN_RING(chan, gr, 0x0000, 1);
73 OUT_RING (chan, gr->handle);
74 }
75
76 static INLINE void
77 OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo,
78 unsigned data, unsigned flags, unsigned vor, unsigned tor)
79 {
80 nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo,
81 data, flags, vor, tor);
82 }
83
84 /* Raw data + flags depending on FB/TT buffer */
85 static INLINE void
86 OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo,
87 unsigned data, unsigned flags, unsigned vor, unsigned tor)
88 {
89 OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor);
90 }
91
92 /* FB/TT object handle */
93 static INLINE void
94 OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo,
95 unsigned flags)
96 {
97 OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR,
98 chan->vram->handle, chan->gart->handle);
99 }
100
101 /* Low 32-bits of offset */
102 static INLINE void
103 OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo,
104 unsigned delta, unsigned flags)
105 {
106 OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0);
107 }
108
109 /* High 32-bits of offset */
110 static INLINE void
111 OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo,
112 unsigned delta, unsigned flags)
113 {
114 OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0);
115 }
116
117 #endif