1 #ifndef __NOUVEAU_STATEOBJ_H__
2 #define __NOUVEAU_STATEOBJ_H__
4 #include "pipe/p_util.h"
5 #include "pipe/p_debug.h"
7 struct nouveau_stateobj_reloc {
8 struct pipe_buffer *bo;
19 struct nouveau_stateobj {
23 struct nouveau_stateobj_reloc *reloc;
30 static INLINE struct nouveau_stateobj *
31 so_new(unsigned push, unsigned reloc)
33 struct nouveau_stateobj *so;
35 so = MALLOC(sizeof(struct nouveau_stateobj));
37 so->push = MALLOC(sizeof(unsigned) * push);
38 so->reloc = MALLOC(sizeof(struct nouveau_stateobj_reloc) * reloc);
41 so->cur_reloc = so->cur_packet = 0;
47 so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso)
49 struct nouveau_stateobj *so = *pso;
55 if (so && --so->refcount <= 0) {
65 so_data(struct nouveau_stateobj *so, unsigned data)
67 (*so->cur++) = (data);
72 so_datap(struct nouveau_stateobj *so, unsigned *data, unsigned size)
74 so->cur_packet += (4 * size);
76 (*so->cur++) = (*data++);
80 so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr,
81 unsigned mthd, unsigned size)
83 so->cur_packet = (gr->subc << 13) | (1 << 18) | (mthd - 4);
84 so_data(so, (gr->subc << 13) | (size << 18) | mthd);
88 so_reloc(struct nouveau_stateobj *so, struct pipe_buffer *bo,
89 unsigned data, unsigned flags, unsigned vor, unsigned tor)
91 struct nouveau_stateobj_reloc *r = &so->reloc[so->cur_reloc++];
94 r->offset = so->cur - so->push;
95 r->packet = so->cur_packet;
104 so_dump(struct nouveau_stateobj *so)
106 unsigned i, nr = so->cur - so->push;
108 for (i = 0; i < nr; i++)
109 debug_printf("+0x%04x: 0x%08x\n", i, so->push[i]);
113 so_emit(struct nouveau_winsys *nvws, struct nouveau_stateobj *so)
115 struct nouveau_pushbuf *pb = nvws->channel->pushbuf;
118 nr = so->cur - so->push;
119 if (pb->remaining < nr)
120 nvws->push_flush(nvws, nr, NULL);
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];
127 nvws->push_reloc(nvws, pb->cur + r->offset, r->bo,
128 r->data, r->flags, r->vor, r->tor);
134 so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so)
136 struct nouveau_pushbuf *pb = nvws->channel->pushbuf;
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;
147 for (i = 0; i < so->cur_reloc; i++) {
148 struct nouveau_stateobj_reloc *r = &so->reloc[i];
150 nvws->push_reloc(nvws, pb->cur++, r->bo, r->packet,
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);