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"
10 #include "nouveau/nouveau_util.h"
15 nv30_vbo_format_to_hw(enum pipe_format pipe
, unsigned *fmt
, unsigned *ncomp
)
20 case PIPE_FORMAT_R32_FLOAT
:
21 case PIPE_FORMAT_R32G32_FLOAT
:
22 case PIPE_FORMAT_R32G32B32_FLOAT
:
23 case PIPE_FORMAT_R32G32B32A32_FLOAT
:
24 *fmt
= NV34TCL_VTXFMT_TYPE_FLOAT
;
26 case PIPE_FORMAT_R8_UNORM
:
27 case PIPE_FORMAT_R8G8_UNORM
:
28 case PIPE_FORMAT_R8G8B8_UNORM
:
29 case PIPE_FORMAT_R8G8B8A8_UNORM
:
30 *fmt
= NV34TCL_VTXFMT_TYPE_UBYTE
;
32 case PIPE_FORMAT_R16_SSCALED
:
33 case PIPE_FORMAT_R16G16_SSCALED
:
34 case PIPE_FORMAT_R16G16B16_SSCALED
:
35 case PIPE_FORMAT_R16G16B16A16_SSCALED
:
36 *fmt
= NV34TCL_VTXFMT_TYPE_USHORT
;
39 pf_sprint_name(fs
, pipe
);
40 NOUVEAU_ERR("Unknown format %s\n", fs
);
45 case PIPE_FORMAT_R8_UNORM
:
46 case PIPE_FORMAT_R32_FLOAT
:
47 case PIPE_FORMAT_R16_SSCALED
:
50 case PIPE_FORMAT_R8G8_UNORM
:
51 case PIPE_FORMAT_R32G32_FLOAT
:
52 case PIPE_FORMAT_R16G16_SSCALED
:
55 case PIPE_FORMAT_R8G8B8_UNORM
:
56 case PIPE_FORMAT_R32G32B32_FLOAT
:
57 case PIPE_FORMAT_R16G16B16_SSCALED
:
60 case PIPE_FORMAT_R8G8B8A8_UNORM
:
61 case PIPE_FORMAT_R32G32B32A32_FLOAT
:
62 case PIPE_FORMAT_R16G16B16A16_SSCALED
:
66 pf_sprint_name(fs
, pipe
);
67 NOUVEAU_ERR("Unknown format %s\n", fs
);
75 nv30_vbo_set_idxbuf(struct nv30_context
*nv30
, struct pipe_buffer
*ib
,
78 struct pipe_screen
*pscreen
= &nv30
->screen
->pipe
;
83 nv30
->idxbuf_format
= 0xdeadbeef;
87 if (!pscreen
->get_param(pscreen
, NOUVEAU_CAP_HW_IDXBUF
) || ib_size
== 1)
92 type
= NV34TCL_IDXBUF_FORMAT_TYPE_U16
;
95 type
= NV34TCL_IDXBUF_FORMAT_TYPE_U32
;
101 if (ib
!= nv30
->idxbuf
||
102 type
!= nv30
->idxbuf_format
) {
103 nv30
->dirty
|= NV30_NEW_ARRAYS
;
105 nv30
->idxbuf_format
= type
;
112 nv30_vbo_static_attrib(struct nv30_context
*nv30
, struct nouveau_stateobj
*so
,
113 int attrib
, struct pipe_vertex_element
*ve
,
114 struct pipe_vertex_buffer
*vb
)
116 struct pipe_winsys
*ws
= nv30
->pipe
.winsys
;
117 struct nouveau_grobj
*rankine
= nv30
->screen
->rankine
;
118 unsigned type
, ncomp
;
121 if (nv30_vbo_format_to_hw(ve
->src_format
, &type
, &ncomp
))
124 map
= ws
->buffer_map(ws
, vb
->buffer
, PIPE_BUFFER_USAGE_CPU_READ
);
125 map
+= vb
->buffer_offset
+ ve
->src_offset
;
128 case NV34TCL_VTXFMT_TYPE_FLOAT
:
134 so_method(so
, rankine
, NV34TCL_VTX_ATTR_4F_X(attrib
), 4);
135 so_data (so
, fui(v
[0]));
136 so_data (so
, fui(v
[1]));
137 so_data (so
, fui(v
[2]));
138 so_data (so
, fui(v
[3]));
141 so_method(so
, rankine
, NV34TCL_VTX_ATTR_3F_X(attrib
), 3);
142 so_data (so
, fui(v
[0]));
143 so_data (so
, fui(v
[1]));
144 so_data (so
, fui(v
[2]));
147 so_method(so
, rankine
, NV34TCL_VTX_ATTR_2F_X(attrib
), 2);
148 so_data (so
, fui(v
[0]));
149 so_data (so
, fui(v
[1]));
152 so_method(so
, rankine
, NV34TCL_VTX_ATTR_1F(attrib
), 1);
153 so_data (so
, fui(v
[0]));
156 ws
->buffer_unmap(ws
, vb
->buffer
);
162 ws
->buffer_unmap(ws
, vb
->buffer
);
166 ws
->buffer_unmap(ws
, vb
->buffer
);
172 nv30_draw_arrays(struct pipe_context
*pipe
,
173 unsigned mode
, unsigned start
, unsigned count
)
175 struct nv30_context
*nv30
= nv30_context(pipe
);
176 struct nouveau_channel
*chan
= nv30
->nvws
->channel
;
177 unsigned restart
= 0;
179 nv30_vbo_set_idxbuf(nv30
, NULL
, 0);
180 if (FORCE_SWTNL
|| !nv30_state_validate(nv30
)) {
181 /*return nv30_draw_elements_swtnl(pipe, NULL, 0,
182 mode, start, count);*/
189 nv30_state_emit(nv30
);
191 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 6, 256,
192 mode
, start
, count
, &restart
);
198 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
199 OUT_RING (nvgl_primitive(mode
));
203 BEGIN_RING(rankine
, NV34TCL_VB_VERTEX_BATCH
, 1);
204 OUT_RING (((nr
- 1) << 24) | start
);
210 unsigned push
= nr
> 2047 ? 2047 : nr
;
214 BEGIN_RING_NI(rankine
, NV34TCL_VB_VERTEX_BATCH
, push
);
216 OUT_RING(((0x100 - 1) << 24) | start
);
221 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
228 pipe
->flush(pipe
, 0, NULL
);
233 nv30_draw_elements_u08(struct nv30_context
*nv30
, void *ib
,
234 unsigned mode
, unsigned start
, unsigned count
)
236 struct nouveau_channel
*chan
= nv30
->nvws
->channel
;
239 uint8_t *elts
= (uint8_t *)ib
+ start
;
240 unsigned vc
, push
, restart
= 0;
242 nv30_state_emit(nv30
);
244 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 6, 2,
245 mode
, start
, count
, &restart
);
252 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
253 OUT_RING (nvgl_primitive(mode
));
256 BEGIN_RING(rankine
, NV34TCL_VB_ELEMENT_U32
, 1);
264 push
= MIN2(vc
, 2047 * 2);
266 BEGIN_RING_NI(rankine
, NV34TCL_VB_ELEMENT_U16
, push
>> 1);
267 for (i
= 0; i
< push
; i
+=2)
268 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
274 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
282 nv30_draw_elements_u16(struct nv30_context
*nv30
, void *ib
,
283 unsigned mode
, unsigned start
, unsigned count
)
285 struct nouveau_channel
*chan
= nv30
->nvws
->channel
;
288 uint16_t *elts
= (uint16_t *)ib
+ start
;
289 unsigned vc
, push
, restart
= 0;
291 nv30_state_emit(nv30
);
293 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 6, 2,
294 mode
, start
, count
, &restart
);
301 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
302 OUT_RING (nvgl_primitive(mode
));
305 BEGIN_RING(rankine
, NV34TCL_VB_ELEMENT_U32
, 1);
313 push
= MIN2(vc
, 2047 * 2);
315 BEGIN_RING_NI(rankine
, NV34TCL_VB_ELEMENT_U16
, push
>> 1);
316 for (i
= 0; i
< push
; i
+=2)
317 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
323 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
331 nv30_draw_elements_u32(struct nv30_context
*nv30
, void *ib
,
332 unsigned mode
, unsigned start
, unsigned count
)
334 struct nouveau_channel
*chan
= nv30
->nvws
->channel
;
337 uint32_t *elts
= (uint32_t *)ib
+ start
;
338 unsigned vc
, push
, restart
= 0;
340 nv30_state_emit(nv30
);
342 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 5, 1,
343 mode
, start
, count
, &restart
);
350 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
351 OUT_RING (nvgl_primitive(mode
));
354 push
= MIN2(vc
, 2047);
356 BEGIN_RING_NI(rankine
, NV34TCL_VB_ELEMENT_U32
, push
);
357 OUT_RINGp (elts
, push
);
363 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
371 nv30_draw_elements_inline(struct pipe_context
*pipe
,
372 struct pipe_buffer
*ib
, unsigned ib_size
,
373 unsigned mode
, unsigned start
, unsigned count
)
375 struct nv30_context
*nv30
= nv30_context(pipe
);
376 struct pipe_winsys
*ws
= pipe
->winsys
;
379 map
= ws
->buffer_map(ws
, ib
, PIPE_BUFFER_USAGE_CPU_READ
);
381 NOUVEAU_ERR("failed mapping ib\n");
387 nv30_draw_elements_u08(nv30
, map
, mode
, start
, count
);
390 nv30_draw_elements_u16(nv30
, map
, mode
, start
, count
);
393 nv30_draw_elements_u32(nv30
, map
, mode
, start
, count
);
396 NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size
);
400 ws
->buffer_unmap(ws
, ib
);
405 nv30_draw_elements_vbo(struct pipe_context
*pipe
,
406 unsigned mode
, unsigned start
, unsigned count
)
408 struct nv30_context
*nv30
= nv30_context(pipe
);
409 struct nouveau_channel
*chan
= nv30
->nvws
->channel
;
410 unsigned restart
= 0;
415 nv30_state_emit(nv30
);
417 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 6, 256,
418 mode
, start
, count
, &restart
);
424 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
425 OUT_RING (nvgl_primitive(mode
));
429 BEGIN_RING(rankine
, NV34TCL_VB_INDEX_BATCH
, 1);
430 OUT_RING (((nr
- 1) << 24) | start
);
436 unsigned push
= nr
> 2047 ? 2047 : nr
;
440 BEGIN_RING_NI(rankine
, NV34TCL_VB_INDEX_BATCH
, push
);
442 OUT_RING(((0x100 - 1) << 24) | start
);
447 BEGIN_RING(rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
458 nv30_draw_elements(struct pipe_context
*pipe
,
459 struct pipe_buffer
*indexBuffer
, unsigned indexSize
,
460 unsigned mode
, unsigned start
, unsigned count
)
462 struct nv30_context
*nv30
= nv30_context(pipe
);
465 idxbuf
= nv30_vbo_set_idxbuf(nv30
, indexBuffer
, indexSize
);
466 if (FORCE_SWTNL
|| !nv30_state_validate(nv30
)) {
467 /*return nv30_draw_elements_swtnl(pipe, NULL, 0,
468 mode, start, count);*/
473 nv30_draw_elements_vbo(pipe
, mode
, start
, count
);
475 nv30_draw_elements_inline(pipe
, indexBuffer
, indexSize
,
479 pipe
->flush(pipe
, 0, NULL
);
484 nv30_vbo_validate(struct nv30_context
*nv30
)
486 struct nouveau_stateobj
*vtxbuf
, *vtxfmt
, *sattr
= NULL
;
487 struct nouveau_grobj
*rankine
= nv30
->screen
->rankine
;
488 struct pipe_buffer
*ib
= nv30
->idxbuf
;
489 unsigned ib_format
= nv30
->idxbuf_format
;
490 unsigned vb_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
493 if (nv30
->edgeflags
) {
494 /*nv30->fallback_swtnl |= NV30_NEW_ARRAYS;*/
498 vtxbuf
= so_new(20, 18);
499 so_method(vtxbuf
, rankine
, NV34TCL_VTXBUF_ADDRESS(0), nv30
->vtxelt_nr
);
500 vtxfmt
= so_new(17, 0);
501 so_method(vtxfmt
, rankine
, NV34TCL_VTXFMT(0), nv30
->vtxelt_nr
);
503 for (hw
= 0; hw
< nv30
->vtxelt_nr
; hw
++) {
504 struct pipe_vertex_element
*ve
;
505 struct pipe_vertex_buffer
*vb
;
506 unsigned type
, ncomp
;
508 ve
= &nv30
->vtxelt
[hw
];
509 vb
= &nv30
->vtxbuf
[ve
->vertex_buffer_index
];
513 sattr
= so_new(16 * 5, 0);
515 if (nv30_vbo_static_attrib(nv30
, sattr
, hw
, ve
, vb
)) {
517 so_data(vtxfmt
, NV34TCL_VTXFMT_TYPE_FLOAT
);
522 if (nv30_vbo_format_to_hw(ve
->src_format
, &type
, &ncomp
)) {
523 /*nv30->fallback_swtnl |= NV30_NEW_ARRAYS;*/
524 so_ref(NULL
, &vtxbuf
);
525 so_ref(NULL
, &vtxfmt
);
529 so_reloc(vtxbuf
, vb
->buffer
, vb
->buffer_offset
+ ve
->src_offset
,
530 vb_flags
| NOUVEAU_BO_LOW
| NOUVEAU_BO_OR
,
531 0, NV34TCL_VTXBUF_ADDRESS_DMA1
);
532 so_data (vtxfmt
, ((vb
->pitch
<< NV34TCL_VTXFMT_STRIDE_SHIFT
) |
533 (ncomp
<< NV34TCL_VTXFMT_SIZE_SHIFT
) | type
));
537 so_method(vtxbuf
, rankine
, NV34TCL_IDXBUF_ADDRESS
, 2);
538 so_reloc (vtxbuf
, ib
, 0, vb_flags
| NOUVEAU_BO_LOW
, 0, 0);
539 so_reloc (vtxbuf
, ib
, ib_format
, vb_flags
| NOUVEAU_BO_OR
,
540 0, NV34TCL_IDXBUF_FORMAT_DMA1
);
543 so_method(vtxbuf
, rankine
, 0x1710, 1);
546 so_ref(vtxbuf
, &nv30
->state
.hw
[NV30_STATE_VTXBUF
]);
547 nv30
->state
.dirty
|= (1ULL << NV30_STATE_VTXBUF
);
548 so_ref(vtxfmt
, &nv30
->state
.hw
[NV30_STATE_VTXFMT
]);
549 nv30
->state
.dirty
|= (1ULL << NV30_STATE_VTXFMT
);
550 so_ref(sattr
, &nv30
->state
.hw
[NV30_STATE_VTXATTR
]);
551 nv30
->state
.dirty
|= (1ULL << NV30_STATE_VTXATTR
);
555 struct nv30_state_entry nv30_state_vbo
= {
556 .validate
= nv30_vbo_validate
,
558 .pipe
= NV30_NEW_ARRAYS
,