1 #include "pipe/p_context.h"
2 #include "pipe/p_state.h"
3 #include "pipe/p_util.h"
5 #include "nv40_context.h"
6 #include "nv40_state.h"
8 #include "nouveau/nouveau_channel.h"
9 #include "nouveau/nouveau_pushbuf.h"
12 nv40_vbo_format_to_hw(enum pipe_format pipe
, unsigned *fmt
, unsigned *ncomp
)
17 case PIPE_FORMAT_R32_FLOAT
:
18 case PIPE_FORMAT_R32G32_FLOAT
:
19 case PIPE_FORMAT_R32G32B32_FLOAT
:
20 case PIPE_FORMAT_R32G32B32A32_FLOAT
:
21 *fmt
= NV40TCL_VTXFMT_TYPE_FLOAT
;
23 case PIPE_FORMAT_R8_UNORM
:
24 case PIPE_FORMAT_R8G8_UNORM
:
25 case PIPE_FORMAT_R8G8B8_UNORM
:
26 case PIPE_FORMAT_R8G8B8A8_UNORM
:
27 *fmt
= NV40TCL_VTXFMT_TYPE_UBYTE
;
30 pf_sprint_name(fs
, pipe
);
31 NOUVEAU_ERR("Unknown format %s\n", fs
);
36 case PIPE_FORMAT_R8_UNORM
:
37 case PIPE_FORMAT_R32_FLOAT
:
40 case PIPE_FORMAT_R8G8_UNORM
:
41 case PIPE_FORMAT_R32G32_FLOAT
:
44 case PIPE_FORMAT_R8G8B8_UNORM
:
45 case PIPE_FORMAT_R32G32B32_FLOAT
:
48 case PIPE_FORMAT_R8G8B8A8_UNORM
:
49 case PIPE_FORMAT_R32G32B32A32_FLOAT
:
53 pf_sprint_name(fs
, pipe
);
54 NOUVEAU_ERR("Unknown format %s\n", fs
);
62 nv40_vbo_set_idxbuf(struct nv40_context
*nv40
, struct pipe_buffer
*ib
,
69 nv40
->idxbuf_format
= 0xdeadbeef;
73 /* No support for 8bit indices, no support at all on 0x4497 chips */
74 if (nv40
->screen
->curie
->grclass
== NV44TCL
|| ib_size
== 1)
79 type
= NV40TCL_IDXBUF_FORMAT_TYPE_U16
;
82 type
= NV40TCL_IDXBUF_FORMAT_TYPE_U32
;
88 if (ib
!= nv40
->idxbuf
||
89 type
!= nv40
->idxbuf_format
) {
90 nv40
->dirty
|= NV40_NEW_ARRAYS
;
92 nv40
->idxbuf_format
= type
;
99 nv40_vbo_static_attrib(struct nv40_context
*nv40
, int attrib
,
100 struct pipe_vertex_element
*ve
,
101 struct pipe_vertex_buffer
*vb
)
103 struct pipe_winsys
*ws
= nv40
->pipe
.winsys
;
104 unsigned type
, ncomp
;
107 if (nv40_vbo_format_to_hw(ve
->src_format
, &type
, &ncomp
))
110 map
= ws
->buffer_map(ws
, vb
->buffer
, PIPE_BUFFER_USAGE_CPU_READ
);
111 map
+= vb
->buffer_offset
+ ve
->src_offset
;
114 case NV40TCL_VTXFMT_TYPE_FLOAT
:
118 BEGIN_RING(curie
, NV40TCL_VTX_ATTR_4F_X(attrib
), 4);
145 ws
->buffer_unmap(ws
, vb
->buffer
);
151 ws
->buffer_unmap(ws
, vb
->buffer
);
155 ws
->buffer_unmap(ws
, vb
->buffer
);
161 nv40_draw_arrays(struct pipe_context
*pipe
, unsigned mode
, unsigned start
,
164 struct nv40_context
*nv40
= nv40_context(pipe
);
167 nv40_vbo_set_idxbuf(nv40
, NULL
, 0);
168 nv40_emit_hw_state(nv40
);
170 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
171 OUT_RING (nvgl_primitive(mode
));
175 BEGIN_RING(curie
, NV40TCL_VB_VERTEX_BATCH
, 1);
176 OUT_RING (((nr
- 1) << 24) | start
);
182 unsigned push
= nr
> 2047 ? 2047 : nr
;
186 BEGIN_RING_NI(curie
, NV40TCL_VB_VERTEX_BATCH
, push
);
188 OUT_RING(((0x100 - 1) << 24) | start
);
193 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
196 pipe
->flush(pipe
, 0);
201 nv40_draw_elements_u08(struct nv40_context
*nv40
, void *ib
,
202 unsigned start
, unsigned count
)
204 uint8_t *elts
= (uint8_t *)ib
+ start
;
208 BEGIN_RING(curie
, NV40TCL_VB_ELEMENT_U32
, 1);
214 push
= MIN2(count
, 2047 * 2);
216 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U16
, push
>> 1);
217 for (i
= 0; i
< push
; i
+=2)
218 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
226 nv40_draw_elements_u16(struct nv40_context
*nv40
, void *ib
,
227 unsigned start
, unsigned count
)
229 uint16_t *elts
= (uint16_t *)ib
+ start
;
233 BEGIN_RING(curie
, NV40TCL_VB_ELEMENT_U32
, 1);
239 push
= MIN2(count
, 2047 * 2);
241 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U16
, push
>> 1);
242 for (i
= 0; i
< push
; i
+=2)
243 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
251 nv40_draw_elements_u32(struct nv40_context
*nv40
, void *ib
,
252 unsigned start
, unsigned count
)
254 uint32_t *elts
= (uint32_t *)ib
+ start
;
258 push
= MIN2(count
, 2047);
260 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U32
, push
);
261 OUT_RINGp (elts
, push
);
269 nv40_draw_elements_inline(struct pipe_context
*pipe
,
270 struct pipe_buffer
*ib
, unsigned ib_size
,
271 unsigned mode
, unsigned start
, unsigned count
)
273 struct nv40_context
*nv40
= nv40_context(pipe
);
274 struct pipe_winsys
*ws
= pipe
->winsys
;
277 nv40_emit_hw_state(nv40
);
279 map
= ws
->buffer_map(ws
, ib
, PIPE_BUFFER_USAGE_CPU_READ
);
281 NOUVEAU_ERR("failed mapping ib\n");
285 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
286 OUT_RING (nvgl_primitive(mode
));
290 nv40_draw_elements_u08(nv40
, map
, start
, count
);
293 nv40_draw_elements_u16(nv40
, map
, start
, count
);
296 nv40_draw_elements_u32(nv40
, map
, start
, count
);
299 NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size
);
303 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
306 ws
->buffer_unmap(ws
, ib
);
312 nv40_draw_elements_vbo(struct pipe_context
*pipe
,
313 unsigned mode
, unsigned start
, unsigned count
)
315 struct nv40_context
*nv40
= nv40_context(pipe
);
318 nv40_emit_hw_state(nv40
);
320 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
321 OUT_RING (nvgl_primitive(mode
));
325 BEGIN_RING(curie
, NV40TCL_VB_INDEX_BATCH
, 1);
326 OUT_RING (((nr
- 1) << 24) | start
);
332 unsigned push
= nr
> 2047 ? 2047 : nr
;
336 BEGIN_RING_NI(curie
, NV40TCL_VB_INDEX_BATCH
, push
);
338 OUT_RING(((0x100 - 1) << 24) | start
);
343 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
350 nv40_draw_elements(struct pipe_context
*pipe
,
351 struct pipe_buffer
*indexBuffer
, unsigned indexSize
,
352 unsigned mode
, unsigned start
, unsigned count
)
354 struct nv40_context
*nv40
= nv40_context(pipe
);
356 if (nv40_vbo_set_idxbuf(nv40
, indexBuffer
, indexSize
)) {
357 nv40_draw_elements_vbo(pipe
, mode
, start
, count
);
359 nv40_draw_elements_inline(pipe
, indexBuffer
, indexSize
,
363 pipe
->flush(pipe
, 0);
368 nv40_vbo_validate(struct nv40_context
*nv40
)
370 struct nv40_vertex_program
*vp
= nv40
->vertprog
;
371 struct nouveau_stateobj
*vtxbuf
, *vtxfmt
;
372 struct pipe_buffer
*ib
= nv40
->idxbuf
;
373 unsigned ib_format
= nv40
->idxbuf_format
;
374 unsigned inputs
, hw
, num_hw
;
375 unsigned vb_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
378 for (hw
= 0; hw
< 16 && inputs
; hw
++) {
379 if (inputs
& (1 << hw
)) {
381 inputs
&= ~(1 << hw
);
386 vtxbuf
= so_new(20, 18);
387 so_method(vtxbuf
, nv40
->screen
->curie
, NV40TCL_VTXBUF_ADDRESS(0), num_hw
);
388 vtxfmt
= so_new(17, 0);
389 so_method(vtxfmt
, nv40
->screen
->curie
, NV40TCL_VTXFMT(0), num_hw
);
392 for (hw
= 0; hw
< num_hw
; hw
++) {
393 struct pipe_vertex_element
*ve
;
394 struct pipe_vertex_buffer
*vb
;
395 unsigned type
, ncomp
;
397 if (!(inputs
& (1 << hw
))) {
399 so_data(vtxfmt
, NV40TCL_VTXFMT_TYPE_FLOAT
);
403 ve
= &nv40
->vtxelt
[hw
];
404 vb
= &nv40
->vtxbuf
[ve
->vertex_buffer_index
];
406 if (!vb
->pitch
&& nv40_vbo_static_attrib(nv40
, hw
, ve
, vb
)) {
408 so_data(vtxfmt
, NV40TCL_VTXFMT_TYPE_FLOAT
);
412 if (nv40_vbo_format_to_hw(ve
->src_format
, &type
, &ncomp
))
415 so_reloc(vtxbuf
, vb
->buffer
, vb
->buffer_offset
+ ve
->src_offset
,
416 vb_flags
| NOUVEAU_BO_LOW
| NOUVEAU_BO_OR
,
417 0, NV40TCL_VTXBUF_ADDRESS_DMA1
);
418 so_data (vtxfmt
, ((vb
->pitch
<< NV40TCL_VTXFMT_STRIDE_SHIFT
) |
419 (ncomp
<< NV40TCL_VTXFMT_SIZE_SHIFT
) | type
));
423 so_method(vtxbuf
, nv40
->screen
->curie
, NV40TCL_IDXBUF_ADDRESS
, 2);
424 so_reloc (vtxbuf
, ib
, 0, vb_flags
| NOUVEAU_BO_LOW
, 0, 0);
425 so_reloc (vtxbuf
, ib
, ib_format
, vb_flags
| NOUVEAU_BO_OR
,
426 0, NV40TCL_IDXBUF_FORMAT_DMA1
);
429 so_method(vtxbuf
, nv40
->screen
->curie
, 0x1710, 1);
432 so_ref(vtxbuf
, &nv40
->state
.hw
[NV40_STATE_VTXBUF
]);
433 nv40
->state
.dirty
|= (1ULL << NV40_STATE_VTXBUF
);
434 so_ref(vtxfmt
, &nv40
->state
.hw
[NV40_STATE_VTXFMT
]);
435 nv40
->state
.dirty
|= (1ULL << NV40_STATE_VTXFMT
);
439 struct nv40_state_entry nv40_state_vbo
= {
440 .validate
= nv40_vbo_validate
,
442 .pipe
= NV40_NEW_ARRAYS
,