1 #include "pipe/p_context.h"
2 #include "pipe/p_state.h"
3 #include "pipe/p_util.h"
5 #include "nv30_context.h"
6 #include "nv30_state.h"
8 #include "nouveau/nouveau_channel.h"
9 #include "nouveau/nouveau_pushbuf.h"
12 nv30_vbo_ncomp(uint format
)
16 if (pf_size_x(format
)) ncomp
++;
17 if (pf_size_y(format
)) ncomp
++;
18 if (pf_size_z(format
)) ncomp
++;
19 if (pf_size_w(format
)) ncomp
++;
25 nv30_vbo_type(uint format
)
27 switch (pf_type(format
)) {
28 case PIPE_FORMAT_TYPE_FLOAT
:
29 return NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT
;
30 case PIPE_FORMAT_TYPE_UNORM
:
31 return NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_UBYTE
;
33 NOUVEAU_ERR("Unknown format 0x%08x\n", format
);
34 return NV40TCL_VTXFMT_TYPE_FLOAT
;
39 nv30_vbo_static_attrib(struct nv30_context
*nv30
, int attrib
,
40 struct pipe_vertex_element
*ve
,
41 struct pipe_vertex_buffer
*vb
)
43 struct pipe_winsys
*ws
= nv30
->pipe
.winsys
;
47 type
= nv30_vbo_type(ve
->src_format
);
48 ncomp
= nv30_vbo_ncomp(ve
->src_format
);
50 map
= ws
->buffer_map(ws
, vb
->buffer
, PIPE_BUFFER_USAGE_CPU_READ
);
51 map
+= vb
->buffer_offset
+ ve
->src_offset
;
54 case NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT
:
58 BEGIN_RING(rankine
, NV34TCL_VERTEX_ATTR_4F_X(attrib
), 4);
85 ws
->buffer_unmap(ws
, vb
->buffer
);
91 ws
->buffer_unmap(ws
, vb
->buffer
);
95 ws
->buffer_unmap(ws
, vb
->buffer
);
101 nv30_vbo_arrays_update(struct nv30_context
*nv30
)
103 struct nv30_vertex_program
*vp
= nv30
->vertprog
.active
;
104 uint32_t inputs
, vtxfmt
[16];
110 for (hw
= 0; hw
< 16 && inputs
; hw
++) {
111 if (inputs
& (1 << hw
)) {
113 inputs
&= ~(1 << hw
);
119 for (hw
= 0; hw
< num_hw
; hw
++) {
120 struct pipe_vertex_element
*ve
;
121 struct pipe_vertex_buffer
*vb
;
123 if (!(inputs
& (1 << hw
))) {
124 vtxfmt
[hw
] = NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT
;
128 ve
= &nv30
->vtxelt
[hw
];
129 vb
= &nv30
->vtxbuf
[ve
->vertex_buffer_index
];
131 if (vb
->pitch
== 0) {
132 vtxfmt
[hw
] = NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT
;
133 if (nv30_vbo_static_attrib(nv30
, hw
, ve
, vb
) == TRUE
)
137 nv30
->vb_enable
|= (1 << hw
);
138 nv30
->vb
[hw
].delta
= vb
->buffer_offset
+ ve
->src_offset
;
139 nv30
->vb
[hw
].buffer
= vb
->buffer
;
141 vtxfmt
[hw
] = ((vb
->pitch
<< NV34TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT
) |
142 (nv30_vbo_ncomp(ve
->src_format
) <<
143 NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_SHIFT
) |
144 nv30_vbo_type(ve
->src_format
));
147 BEGIN_RING(rankine
, NV34TCL_VERTEX_ARRAY_FORMAT(0), num_hw
);
148 OUT_RINGp (vtxfmt
, num_hw
);
152 nv30_vbo_validate_state(struct nv30_context
*nv30
,
153 struct pipe_buffer
*ib
, unsigned ib_format
)
157 nv30_emit_hw_state(nv30
);
159 if (nv30
->dirty
& NV30_NEW_ARRAYS
) {
160 nv30_vbo_arrays_update(nv30
);
161 nv30
->dirty
&= ~NV30_NEW_ARRAYS
;
164 inputs
= nv30
->vb_enable
;
166 unsigned a
= ffs(inputs
) - 1;
170 BEGIN_RING(rankine
, NV34TCL_VERTEX_BUFFER_ADDRESS(a
), 1);
171 OUT_RELOC (nv30
->vb
[a
].buffer
, nv30
->vb
[a
].delta
,
172 NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_LOW
|
173 NOUVEAU_BO_OR
| NOUVEAU_BO_RD
, 0,
174 NV34TCL_VERTEX_BUFFER_ADDRESS_DMA1
);
178 BEGIN_RING(rankine
, NV40TCL_IDXBUF_ADDRESS
, 2);
179 OUT_RELOCl(ib
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
|
181 OUT_RELOCd(ib
, ib_format
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
|
182 NOUVEAU_BO_RD
| NOUVEAU_BO_OR
,
183 0, NV40TCL_IDXBUF_FORMAT_DMA1
);
186 BEGIN_RING(rankine
, 0x1710, 1);
187 OUT_RING (0); /* vtx cache flush */
193 nv30_draw_arrays(struct pipe_context
*pipe
, unsigned mode
, unsigned start
,
196 struct nv30_context
*nv30
= nv30_context(pipe
);
200 ret
= nv30_vbo_validate_state(nv30
, NULL
, 0);
202 NOUVEAU_ERR("state validate failed\n");
206 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
207 OUT_RING (nvgl_primitive(mode
));
211 BEGIN_RING(rankine
, NV34TCL_VB_VERTEX_BATCH
, 1);
212 OUT_RING (((nr
- 1) << 24) | start
);
218 unsigned push
= nr
> 2047 ? 2047 : nr
;
222 BEGIN_RING_NI(rankine
, NV34TCL_VB_VERTEX_BATCH
, push
);
224 OUT_RING(((0x100 - 1) << 24) | start
);
229 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
232 pipe
->flush(pipe
, 0, NULL
);
237 nv30_draw_elements_u08(struct nv30_context
*nv30
, void *ib
,
238 unsigned start
, unsigned count
)
240 uint8_t *elts
= (uint8_t *)ib
+ start
;
244 BEGIN_RING(rankine
, NV34TCL_VB_ELEMENT_U32
, 1);
250 push
= MIN2(count
, 2047 * 2);
252 BEGIN_RING_NI(rankine
, NV34TCL_VB_ELEMENT_U16
, push
>> 1);
253 for (i
= 0; i
< push
; i
+=2)
254 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
262 nv30_draw_elements_u16(struct nv30_context
*nv30
, void *ib
,
263 unsigned start
, unsigned count
)
265 uint16_t *elts
= (uint16_t *)ib
+ start
;
269 BEGIN_RING(rankine
, NV34TCL_VB_ELEMENT_U32
, 1);
275 push
= MIN2(count
, 2047 * 2);
277 BEGIN_RING_NI(rankine
, NV34TCL_VB_ELEMENT_U16
, push
>> 1);
278 for (i
= 0; i
< push
; i
+=2)
279 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
287 nv30_draw_elements_u32(struct nv30_context
*nv30
, void *ib
,
288 unsigned start
, unsigned count
)
290 uint32_t *elts
= (uint32_t *)ib
+ start
;
294 push
= MIN2(count
, 2047);
296 BEGIN_RING_NI(rankine
, NV34TCL_VB_ELEMENT_U32
, push
);
297 OUT_RINGp (elts
, push
);
305 nv30_draw_elements_inline(struct pipe_context
*pipe
,
306 struct pipe_buffer
*ib
, unsigned ib_size
,
307 unsigned mode
, unsigned start
, unsigned count
)
309 struct nv30_context
*nv30
= nv30_context(pipe
);
310 struct pipe_winsys
*ws
= pipe
->winsys
;
314 ret
= nv30_vbo_validate_state(nv30
, NULL
, 0);
316 NOUVEAU_ERR("state validate failed\n");
320 map
= ws
->buffer_map(ws
, ib
, PIPE_BUFFER_USAGE_CPU_READ
);
322 NOUVEAU_ERR("failed mapping ib\n");
326 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
327 OUT_RING (nvgl_primitive(mode
));
331 nv30_draw_elements_u08(nv30
, map
, start
, count
);
334 nv30_draw_elements_u16(nv30
, map
, start
, count
);
337 nv30_draw_elements_u32(nv30
, map
, start
, count
);
340 NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size
);
344 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
347 ws
->buffer_unmap(ws
, ib
);
353 nv30_draw_elements_vbo(struct pipe_context
*pipe
,
354 struct pipe_buffer
*ib
, unsigned ib_size
,
355 unsigned mode
, unsigned start
, unsigned count
)
357 struct nv30_context
*nv30
= nv30_context(pipe
);
363 type
= NV40TCL_IDXBUF_FORMAT_TYPE_U16
;
366 type
= NV40TCL_IDXBUF_FORMAT_TYPE_U32
;
369 NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size
);
373 ret
= nv30_vbo_validate_state(nv30
, ib
, type
);
375 NOUVEAU_ERR("failed state validation\n");
379 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
380 OUT_RING (nvgl_primitive(mode
));
384 BEGIN_RING(rankine
, NV40TCL_VB_INDEX_BATCH
, 1);
385 OUT_RING (((nr
- 1) << 24) | start
);
391 unsigned push
= nr
> 2047 ? 2047 : nr
;
395 BEGIN_RING_NI(rankine
, NV40TCL_VB_INDEX_BATCH
, push
);
397 OUT_RING(((0x100 - 1) << 24) | start
);
402 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
409 nv30_draw_elements(struct pipe_context
*pipe
,
410 struct pipe_buffer
*indexBuffer
, unsigned indexSize
,
411 unsigned mode
, unsigned start
, unsigned count
)
413 /* if (indexSize != 1) {
414 nv30_draw_elements_vbo(pipe, indexBuffer, indexSize,
417 nv30_draw_elements_inline(pipe
, indexBuffer
, indexSize
,
421 pipe
->flush(pipe
, 0, NULL
);