OSDN Git Service

nv50: make use of nouveau drm 0.0.11 to get 3d going
[android-x86/external-mesa.git] / src / gallium / drivers / nouveau / nouveau_stateobj.h
1 #ifndef __NOUVEAU_STATEOBJ_H__
2 #define __NOUVEAU_STATEOBJ_H__
3
4 #include "pipe/p_util.h"
5 #include "pipe/p_debug.h"
6
7 struct nouveau_stateobj_reloc {
8         struct pipe_buffer *bo;
9
10         unsigned offset;
11         unsigned packet;
12
13         unsigned data;
14         unsigned flags;
15         unsigned vor;
16         unsigned tor;
17 };
18
19 struct nouveau_stateobj {
20         int refcount;
21
22         unsigned *push;
23         struct nouveau_stateobj_reloc *reloc;
24
25         unsigned *cur;
26         unsigned cur_packet;
27         unsigned cur_reloc;
28 };
29
30 static INLINE struct nouveau_stateobj *
31 so_new(unsigned push, unsigned reloc)
32 {
33         struct nouveau_stateobj *so;
34
35         so = MALLOC(sizeof(struct nouveau_stateobj));
36         so->refcount = 0;
37         so->push = MALLOC(sizeof(unsigned) * push);
38         so->reloc = MALLOC(sizeof(struct nouveau_stateobj_reloc) * reloc);
39
40         so->cur = so->push;
41         so->cur_reloc = so->cur_packet = 0;
42
43         return so;
44 }
45
46 static INLINE void
47 so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso)
48 {
49         struct nouveau_stateobj *so = *pso;
50
51         if (ref) {
52                 ref->refcount++;
53         }
54
55         if (so && --so->refcount <= 0) {
56                 free(so->push);
57                 free(so->reloc);
58                 free(so);
59         }
60
61         *pso = ref;
62 }
63
64 static INLINE void
65 so_data(struct nouveau_stateobj *so, unsigned data)
66 {
67         (*so->cur++) = (data);
68         so->cur_packet += 4;
69 }
70
71 static INLINE void
72 so_datap(struct nouveau_stateobj *so, unsigned *data, unsigned size)
73 {
74         so->cur_packet += (4 * size);
75         while (size--)
76                 (*so->cur++) = (*data++);
77 }
78
79 static INLINE void
80 so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr,
81           unsigned mthd, unsigned size)
82 {
83         so->cur_packet = (gr->subc << 13) | (1 << 18) | (mthd - 4);
84         so_data(so, (gr->subc << 13) | (size << 18) | mthd);
85 }
86
87 static INLINE void
88 so_reloc(struct nouveau_stateobj *so, struct pipe_buffer *bo,
89          unsigned data, unsigned flags, unsigned vor, unsigned tor)
90 {
91         struct nouveau_stateobj_reloc *r = &so->reloc[so->cur_reloc++];
92         
93         r->bo = bo;
94         r->offset = so->cur - so->push;
95         r->packet = so->cur_packet;
96         r->data = data;
97         r->flags = flags;
98         r->vor = vor;
99         r->tor = tor;
100         so_data(so, data);
101 }
102
103 static INLINE void
104 so_dump(struct nouveau_stateobj *so)
105 {
106         unsigned i, nr = so->cur - so->push;
107
108         for (i = 0; i < nr; i++)
109                 debug_printf("+0x%04x: 0x%08x\n", i, so->push[i]);
110 }
111
112 static INLINE void
113 so_emit(struct nouveau_winsys *nvws, struct nouveau_stateobj *so)
114 {
115         struct nouveau_pushbuf *pb = nvws->channel->pushbuf;
116         unsigned nr, i;
117
118         nr = so->cur - so->push;
119         if (pb->remaining < nr)
120                 nvws->push_flush(nvws, nr, NULL);
121         pb->remaining -= nr;
122
123         memcpy(pb->cur, so->push, nr * 4);
124         for (i = 0; i < so->cur_reloc; i++) {
125                 struct nouveau_stateobj_reloc *r = &so->reloc[i];
126
127                 nvws->push_reloc(nvws, pb->cur + r->offset, r->bo,
128                                  r->data, r->flags, r->vor, r->tor);
129         }
130         pb->cur += nr;
131 }
132
133 static INLINE void
134 so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so)
135 {
136         struct nouveau_pushbuf *pb = nvws->channel->pushbuf;
137         unsigned i;
138
139         if (!so)
140                 return;
141
142         i = so->cur_reloc << 1;
143         if (nvws->channel->pushbuf->remaining < i)
144                 nvws->push_flush(nvws, i, NULL);
145         nvws->channel->pushbuf->remaining -= i;
146
147         for (i = 0; i < so->cur_reloc; i++) {
148                 struct nouveau_stateobj_reloc *r = &so->reloc[i];
149
150                 nvws->push_reloc(nvws, pb->cur++, r->bo, r->packet,
151                                  (r->flags &
152                                   (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)) |
153                                  NOUVEAU_BO_DUMMY, 0, 0);
154                 nvws->push_reloc(nvws, pb->cur++, r->bo, r->data,
155                                  r->flags | NOUVEAU_BO_DUMMY, r->vor, r->tor);
156         }
157 }
158
159 #endif