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
);