Merge branch 'mesa_7_5_branch'
[mesa.git] / src / gallium / drivers / nouveau / nouveau_push.h
1 #ifndef __NOUVEAU_PUSH_H__
2 #define __NOUVEAU_PUSH_H__
3
4 #include "nouveau/nouveau_winsys.h"
5
6 #ifndef NOUVEAU_PUSH_CONTEXT
7 #error undefined push context
8 #endif
9
10 #define OUT_RING(data) do { \
11 NOUVEAU_PUSH_CONTEXT(pc); \
12 (*pc->base.channel->pushbuf->cur++) = (data); \
13 } while(0)
14
15 #define OUT_RINGp(src,size) do { \
16 NOUVEAU_PUSH_CONTEXT(pc); \
17 memcpy(pc->base.channel->pushbuf->cur, (src), (size) * 4); \
18 pc->base.channel->pushbuf->cur += (size); \
19 } while(0)
20
21 #define OUT_RINGf(data) do { \
22 union { float v; uint32_t u; } c; \
23 c.v = (data); \
24 OUT_RING(c.u); \
25 } while(0)
26
27 #define BEGIN_RING(obj,mthd,size) do { \
28 NOUVEAU_PUSH_CONTEXT(pc); \
29 struct nouveau_channel *chan = pc->base.channel; \
30 if (chan->pushbuf->remaining < ((size) + 1)) \
31 nouveau_pushbuf_flush(chan, ((size) + 1)); \
32 OUT_RING((pc->obj->subc << 13) | ((size) << 18) | (mthd)); \
33 chan->pushbuf->remaining -= ((size) + 1); \
34 } while(0)
35
36 #define BEGIN_RING_NI(obj,mthd,size) do { \
37 BEGIN_RING(obj, (mthd) | 0x40000000, (size)); \
38 } while(0)
39
40 static inline void
41 DO_FIRE_RING(struct nouveau_channel *chan, struct pipe_fence_handle **fence)
42 {
43 nouveau_pushbuf_flush(chan, 0);
44 if (fence)
45 *fence = NULL;
46 }
47
48 #define FIRE_RING(fence) do { \
49 NOUVEAU_PUSH_CONTEXT(pc); \
50 DO_FIRE_RING(pc->base.channel, fence); \
51 } while(0)
52
53 #define OUT_RELOC(bo,data,flags,vor,tor) do { \
54 NOUVEAU_PUSH_CONTEXT(pc); \
55 struct nouveau_channel *chan = pc->base.channel; \
56 nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, nouveau_bo(bo), \
57 (data), 0, (flags), (vor), (tor)); \
58 } while(0)
59
60 /* Raw data + flags depending on FB/TT buffer */
61 #define OUT_RELOCd(bo,data,flags,vor,tor) do { \
62 OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor)); \
63 } while(0)
64
65 /* FB/TT object handle */
66 #define OUT_RELOCo(bo,flags) do { \
67 OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \
68 pc->base.channel->vram->handle, \
69 pc->base.channel->gart->handle); \
70 } while(0)
71
72 /* Low 32-bits of offset */
73 #define OUT_RELOCl(bo,delta,flags) do { \
74 OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0); \
75 } while(0)
76
77 /* High 32-bits of offset */
78 #define OUT_RELOCh(bo,delta,flags) do { \
79 OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0); \
80 } while(0)
81
82 /* A reloc which'll recombine into a NV_DMA_METHOD packet header */
83 #define OUT_RELOCm(bo, flags, obj, mthd, size) do { \
84 NOUVEAU_PUSH_CONTEXT(pc); \
85 struct nouveau_channel *chan = pc->base.channel; \
86 if (chan->pushbuf->remaining < ((size) + 1)) \
87 nouveau_pushbuf_flush(chan, ((size) + 1)); \
88 OUT_RELOCd((bo), (pc->obj->subc << 13) | ((size) << 18) | (mthd), \
89 (flags), 0, 0); \
90 chan->pushbuf->remaining -= ((size) + 1); \
91 } while(0)
92
93 #endif