1 #ifndef __NOUVEAU_STATEOBJ_H__
2 #define __NOUVEAU_STATEOBJ_H__
4 #include "util/u_debug.h"
6 struct nouveau_stateobj_reloc
{
18 struct nouveau_stateobj
{
19 struct pipe_reference reference
;
22 struct nouveau_stateobj_reloc
*reloc
;
29 static INLINE
struct nouveau_stateobj
*
30 so_new(unsigned push
, unsigned reloc
)
32 struct nouveau_stateobj
*so
;
34 so
= MALLOC(sizeof(struct nouveau_stateobj
));
35 pipe_reference_init(&so
->reference
, 1);
36 so
->push
= MALLOC(sizeof(unsigned) * push
);
37 so
->reloc
= MALLOC(sizeof(struct nouveau_stateobj_reloc
) * reloc
);
40 so
->cur_reloc
= so
->cur_packet
= 0;
46 so_ref(struct nouveau_stateobj
*ref
, struct nouveau_stateobj
**pso
)
48 struct nouveau_stateobj
*so
= *pso
;
51 if (pipe_reference((struct pipe_reference
**)pso
, &ref
->reference
)) {
53 for (i
= 0; i
< so
->cur_reloc
; i
++)
54 nouveau_bo_ref(NULL
, &so
->reloc
[i
].bo
);
61 so_data(struct nouveau_stateobj
*so
, unsigned data
)
63 (*so
->cur
++) = (data
);
68 so_datap(struct nouveau_stateobj
*so
, unsigned *data
, unsigned size
)
70 so
->cur_packet
+= (4 * size
);
72 (*so
->cur
++) = (*data
++);
76 so_method(struct nouveau_stateobj
*so
, struct nouveau_grobj
*gr
,
77 unsigned mthd
, unsigned size
)
79 so
->cur_packet
= (gr
->subc
<< 13) | (1 << 18) | (mthd
- 4);
80 so_data(so
, (gr
->subc
<< 13) | (size
<< 18) | mthd
);
84 so_reloc(struct nouveau_stateobj
*so
, struct nouveau_bo
*bo
,
85 unsigned data
, unsigned flags
, unsigned vor
, unsigned tor
)
87 struct nouveau_stateobj_reloc
*r
= &so
->reloc
[so
->cur_reloc
++];
90 nouveau_bo_ref(bo
, &r
->bo
);
91 r
->offset
= so
->cur
- so
->push
;
92 r
->packet
= so
->cur_packet
;
101 so_dump(struct nouveau_stateobj
*so
)
103 unsigned i
, nr
= so
->cur
- so
->push
;
105 for (i
= 0; i
< nr
; i
++)
106 debug_printf("+0x%04x: 0x%08x\n", i
, so
->push
[i
]);
110 so_emit(struct nouveau_channel
*chan
, struct nouveau_stateobj
*so
)
112 struct nouveau_pushbuf
*pb
= chan
->pushbuf
;
115 nr
= so
->cur
- so
->push
;
116 if (pb
->remaining
< nr
)
117 nouveau_pushbuf_flush(chan
, nr
);
120 memcpy(pb
->cur
, so
->push
, nr
* 4);
121 for (i
= 0; i
< so
->cur_reloc
; i
++) {
122 struct nouveau_stateobj_reloc
*r
= &so
->reloc
[i
];
124 nouveau_pushbuf_emit_reloc(chan
, pb
->cur
+ r
->offset
,
125 r
->bo
, r
->data
, 0, r
->flags
,
132 so_emit_reloc_markers(struct nouveau_channel
*chan
, struct nouveau_stateobj
*so
)
134 struct nouveau_pushbuf
*pb
= chan
->pushbuf
;
140 i
= so
->cur_reloc
<< 1;
141 if (pb
->remaining
< i
)
142 nouveau_pushbuf_flush(chan
, i
);
145 for (i
= 0; i
< so
->cur_reloc
; i
++) {
146 struct nouveau_stateobj_reloc
*r
= &so
->reloc
[i
];
148 nouveau_pushbuf_emit_reloc(chan
, pb
->cur
++, r
->bo
, r
->packet
, 0,
149 (r
->flags
& (NOUVEAU_BO_VRAM
|
152 NOUVEAU_BO_DUMMY
, 0, 0);
153 nouveau_pushbuf_emit_reloc(chan
, pb
->cur
++, r
->bo
, r
->data
, 0,
154 r
->flags
| NOUVEAU_BO_DUMMY
,