1 #include "pipe/p_context.h"
2 #include "pipe/p_state.h"
3 #include "pipe/p_inlines.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
)
18 case PIPE_FORMAT_R32_FLOAT
:
19 case PIPE_FORMAT_R32G32_FLOAT
:
20 case PIPE_FORMAT_R32G32B32_FLOAT
:
21 case PIPE_FORMAT_R32G32B32A32_FLOAT
:
22 *fmt
= NV34TCL_VTXFMT_TYPE_FLOAT
;
24 case PIPE_FORMAT_R8_UNORM
:
25 case PIPE_FORMAT_R8G8_UNORM
:
26 case PIPE_FORMAT_R8G8B8_UNORM
:
27 case PIPE_FORMAT_R8G8B8A8_UNORM
:
28 *fmt
= NV34TCL_VTXFMT_TYPE_UBYTE
;
30 case PIPE_FORMAT_R16_SSCALED
:
31 case PIPE_FORMAT_R16G16_SSCALED
:
32 case PIPE_FORMAT_R16G16B16_SSCALED
:
33 case PIPE_FORMAT_R16G16B16A16_SSCALED
:
34 *fmt
= NV34TCL_VTXFMT_TYPE_USHORT
;
37 NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe
));
42 case PIPE_FORMAT_R8_UNORM
:
43 case PIPE_FORMAT_R32_FLOAT
:
44 case PIPE_FORMAT_R16_SSCALED
:
47 case PIPE_FORMAT_R8G8_UNORM
:
48 case PIPE_FORMAT_R32G32_FLOAT
:
49 case PIPE_FORMAT_R16G16_SSCALED
:
52 case PIPE_FORMAT_R8G8B8_UNORM
:
53 case PIPE_FORMAT_R32G32B32_FLOAT
:
54 case PIPE_FORMAT_R16G16B16_SSCALED
:
57 case PIPE_FORMAT_R8G8B8A8_UNORM
:
58 case PIPE_FORMAT_R32G32B32A32_FLOAT
:
59 case PIPE_FORMAT_R16G16B16A16_SSCALED
:
63 NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe
));
71 nv30_vbo_set_idxbuf(struct nv30_context
*nv30
, struct pipe_buffer
*ib
,
74 struct pipe_screen
*pscreen
= &nv30
->screen
->base
.base
;
79 nv30
->idxbuf_format
= 0xdeadbeef;
83 if (!pscreen
->get_param(pscreen
, NOUVEAU_CAP_HW_IDXBUF
) || ib_size
== 1)
88 type
= NV34TCL_IDXBUF_FORMAT_TYPE_U16
;
91 type
= NV34TCL_IDXBUF_FORMAT_TYPE_U32
;
97 if (ib
!= nv30
->idxbuf
||
98 type
!= nv30
->idxbuf_format
) {
99 nv30
->dirty
|= NV30_NEW_ARRAYS
;
101 nv30
->idxbuf_format
= type
;
108 nv30_vbo_static_attrib(struct nv30_context
*nv30
, struct nouveau_stateobj
*so
,
109 int attrib
, struct pipe_vertex_element
*ve
,
110 struct pipe_vertex_buffer
*vb
)
112 struct pipe_screen
*pscreen
= nv30
->pipe
.screen
;
113 struct nouveau_grobj
*rankine
= nv30
->screen
->rankine
;
114 unsigned type
, ncomp
;
117 if (nv30_vbo_format_to_hw(ve
->src_format
, &type
, &ncomp
))
120 map
= pipe_buffer_map(pscreen
, vb
->buffer
, PIPE_BUFFER_USAGE_CPU_READ
);
121 map
+= vb
->buffer_offset
+ ve
->src_offset
;
124 case NV34TCL_VTXFMT_TYPE_FLOAT
:
130 so_method(so
, rankine
, NV34TCL_VTX_ATTR_4F_X(attrib
), 4);
131 so_data (so
, fui(v
[0]));
132 so_data (so
, fui(v
[1]));
133 so_data (so
, fui(v
[2]));
134 so_data (so
, fui(v
[3]));
137 so_method(so
, rankine
, NV34TCL_VTX_ATTR_3F_X(attrib
), 3);
138 so_data (so
, fui(v
[0]));
139 so_data (so
, fui(v
[1]));
140 so_data (so
, fui(v
[2]));
143 so_method(so
, rankine
, NV34TCL_VTX_ATTR_2F_X(attrib
), 2);
144 so_data (so
, fui(v
[0]));
145 so_data (so
, fui(v
[1]));
148 so_method(so
, rankine
, NV34TCL_VTX_ATTR_1F(attrib
), 1);
149 so_data (so
, fui(v
[0]));
152 pipe_buffer_unmap(pscreen
, vb
->buffer
);
158 pipe_buffer_unmap(pscreen
, vb
->buffer
);
162 pipe_buffer_unmap(pscreen
, vb
->buffer
);
167 nv30_draw_arrays(struct pipe_context
*pipe
,
168 unsigned mode
, unsigned start
, unsigned count
)
170 struct nv30_context
*nv30
= nv30_context(pipe
);
171 struct nv30_screen
*screen
= nv30
->screen
;
172 struct nouveau_channel
*chan
= screen
->base
.channel
;
173 struct nouveau_grobj
*rankine
= screen
->rankine
;
174 unsigned restart
= 0;
176 nv30_vbo_set_idxbuf(nv30
, NULL
, 0);
177 if (FORCE_SWTNL
|| !nv30_state_validate(nv30
)) {
178 /*return nv30_draw_elements_swtnl(pipe, NULL, 0,
179 mode, start, count);*/
186 nv30_state_emit(nv30
);
188 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 6, 256,
189 mode
, start
, count
, &restart
);
195 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
196 OUT_RING (chan
, nvgl_primitive(mode
));
200 BEGIN_RING(chan
, rankine
, NV34TCL_VB_VERTEX_BATCH
, 1);
201 OUT_RING (chan
, ((nr
- 1) << 24) | start
);
207 unsigned push
= nr
> 2047 ? 2047 : nr
;
211 BEGIN_RING_NI(chan
, rankine
, NV34TCL_VB_VERTEX_BATCH
, push
);
213 OUT_RING(chan
, ((0x100 - 1) << 24) | start
);
218 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
225 pipe
->flush(pipe
, 0, NULL
);
230 nv30_draw_elements_u08(struct nv30_context
*nv30
, void *ib
,
231 unsigned mode
, unsigned start
, unsigned count
)
233 struct nv30_screen
*screen
= nv30
->screen
;
234 struct nouveau_channel
*chan
= screen
->base
.channel
;
235 struct nouveau_grobj
*rankine
= screen
->rankine
;
238 uint8_t *elts
= (uint8_t *)ib
+ start
;
239 unsigned vc
, push
, restart
= 0;
241 nv30_state_emit(nv30
);
243 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 6, 2,
244 mode
, start
, count
, &restart
);
251 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
252 OUT_RING (chan
, nvgl_primitive(mode
));
255 BEGIN_RING(chan
, rankine
, NV34TCL_VB_ELEMENT_U32
, 1);
256 OUT_RING (chan
, elts
[0]);
263 push
= MIN2(vc
, 2047 * 2);
265 BEGIN_RING_NI(chan
, rankine
, NV34TCL_VB_ELEMENT_U16
, push
>> 1);
266 for (i
= 0; i
< push
; i
+=2)
267 OUT_RING(chan
, (elts
[i
+1] << 16) | elts
[i
]);
273 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
281 nv30_draw_elements_u16(struct nv30_context
*nv30
, void *ib
,
282 unsigned mode
, unsigned start
, unsigned count
)
284 struct nv30_screen
*screen
= nv30
->screen
;
285 struct nouveau_channel
*chan
= screen
->base
.channel
;
286 struct nouveau_grobj
*rankine
= screen
->rankine
;
289 uint16_t *elts
= (uint16_t *)ib
+ start
;
290 unsigned vc
, push
, restart
= 0;
292 nv30_state_emit(nv30
);
294 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 6, 2,
295 mode
, start
, count
, &restart
);
302 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
303 OUT_RING (chan
, nvgl_primitive(mode
));
306 BEGIN_RING(chan
, rankine
, NV34TCL_VB_ELEMENT_U32
, 1);
307 OUT_RING (chan
, elts
[0]);
314 push
= MIN2(vc
, 2047 * 2);
316 BEGIN_RING_NI(chan
, rankine
, NV34TCL_VB_ELEMENT_U16
, push
>> 1);
317 for (i
= 0; i
< push
; i
+=2)
318 OUT_RING(chan
, (elts
[i
+1] << 16) | elts
[i
]);
324 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
332 nv30_draw_elements_u32(struct nv30_context
*nv30
, void *ib
,
333 unsigned mode
, unsigned start
, unsigned count
)
335 struct nv30_screen
*screen
= nv30
->screen
;
336 struct nouveau_channel
*chan
= screen
->base
.channel
;
337 struct nouveau_grobj
*rankine
= screen
->rankine
;
340 uint32_t *elts
= (uint32_t *)ib
+ start
;
341 unsigned vc
, push
, restart
= 0;
343 nv30_state_emit(nv30
);
345 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 5, 1,
346 mode
, start
, count
, &restart
);
353 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
354 OUT_RING (chan
, nvgl_primitive(mode
));
357 push
= MIN2(vc
, 2047);
359 BEGIN_RING_NI(chan
, rankine
, NV34TCL_VB_ELEMENT_U32
, push
);
360 OUT_RINGp (chan
, elts
, push
);
366 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
374 nv30_draw_elements_inline(struct pipe_context
*pipe
,
375 struct pipe_buffer
*ib
, unsigned ib_size
,
376 unsigned mode
, unsigned start
, unsigned count
)
378 struct nv30_context
*nv30
= nv30_context(pipe
);
379 struct pipe_screen
*pscreen
= pipe
->screen
;
382 map
= pipe_buffer_map(pscreen
, ib
, PIPE_BUFFER_USAGE_CPU_READ
);
384 NOUVEAU_ERR("failed mapping ib\n");
390 nv30_draw_elements_u08(nv30
, map
, mode
, start
, count
);
393 nv30_draw_elements_u16(nv30
, map
, mode
, start
, count
);
396 nv30_draw_elements_u32(nv30
, map
, mode
, start
, count
);
399 NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size
);
403 pipe_buffer_unmap(pscreen
, ib
);
407 nv30_draw_elements_vbo(struct pipe_context
*pipe
,
408 unsigned mode
, unsigned start
, unsigned count
)
410 struct nv30_context
*nv30
= nv30_context(pipe
);
411 struct nv30_screen
*screen
= nv30
->screen
;
412 struct nouveau_channel
*chan
= screen
->base
.channel
;
413 struct nouveau_grobj
*rankine
= screen
->rankine
;
414 unsigned restart
= 0;
419 nv30_state_emit(nv30
);
421 vc
= nouveau_vbuf_split(chan
->pushbuf
->remaining
, 6, 256,
422 mode
, start
, count
, &restart
);
428 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
429 OUT_RING (chan
, nvgl_primitive(mode
));
433 BEGIN_RING(chan
, rankine
, NV34TCL_VB_INDEX_BATCH
, 1);
434 OUT_RING (chan
, ((nr
- 1) << 24) | start
);
440 unsigned push
= nr
> 2047 ? 2047 : nr
;
444 BEGIN_RING_NI(chan
, rankine
, NV34TCL_VB_INDEX_BATCH
, push
);
446 OUT_RING(chan
, ((0x100 - 1) << 24) | start
);
451 BEGIN_RING(chan
, rankine
, NV34TCL_VERTEX_BEGIN_END
, 1);
460 nv30_draw_elements(struct pipe_context
*pipe
,
461 struct pipe_buffer
*indexBuffer
, unsigned indexSize
,
462 unsigned mode
, unsigned start
, unsigned count
)
464 struct nv30_context
*nv30
= nv30_context(pipe
);
467 idxbuf
= nv30_vbo_set_idxbuf(nv30
, indexBuffer
, indexSize
);
468 if (FORCE_SWTNL
|| !nv30_state_validate(nv30
)) {
469 /*return nv30_draw_elements_swtnl(pipe, NULL, 0,
470 mode, start, count);*/
475 nv30_draw_elements_vbo(pipe
, mode
, start
, count
);
477 nv30_draw_elements_inline(pipe
, indexBuffer
, indexSize
,
481 pipe
->flush(pipe
, 0, NULL
);
485 nv30_vbo_validate(struct nv30_context
*nv30
)
487 struct nouveau_stateobj
*vtxbuf
, *vtxfmt
, *sattr
= NULL
;
488 struct nouveau_grobj
*rankine
= nv30
->screen
->rankine
;
489 struct pipe_buffer
*ib
= nv30
->idxbuf
;
490 unsigned ib_format
= nv30
->idxbuf_format
;
491 unsigned vb_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
494 vtxbuf
= so_new(3, 17, 18);
495 so_method(vtxbuf
, rankine
, NV34TCL_VTXBUF_ADDRESS(0), nv30
->vtxelt_nr
);
496 vtxfmt
= so_new(1, 16, 0);
497 so_method(vtxfmt
, rankine
, NV34TCL_VTXFMT(0), nv30
->vtxelt_nr
);
499 for (hw
= 0; hw
< nv30
->vtxelt_nr
; hw
++) {
500 struct pipe_vertex_element
*ve
;
501 struct pipe_vertex_buffer
*vb
;
502 unsigned type
, ncomp
;
504 ve
= &nv30
->vtxelt
[hw
];
505 vb
= &nv30
->vtxbuf
[ve
->vertex_buffer_index
];
509 sattr
= so_new(16, 16 * 4, 0);
511 if (nv30_vbo_static_attrib(nv30
, sattr
, hw
, ve
, vb
)) {
513 so_data(vtxfmt
, NV34TCL_VTXFMT_TYPE_FLOAT
);
518 if (nv30_vbo_format_to_hw(ve
->src_format
, &type
, &ncomp
)) {
519 /*nv30->fallback_swtnl |= NV30_NEW_ARRAYS;*/
520 so_ref(NULL
, &vtxbuf
);
521 so_ref(NULL
, &vtxfmt
);
525 so_reloc(vtxbuf
, nouveau_bo(vb
->buffer
), vb
->buffer_offset
+
526 ve
->src_offset
, vb_flags
| NOUVEAU_BO_LOW
|
527 NOUVEAU_BO_OR
, 0, NV34TCL_VTXBUF_ADDRESS_DMA1
);
528 so_data (vtxfmt
, ((vb
->stride
<< NV34TCL_VTXFMT_STRIDE_SHIFT
) |
529 (ncomp
<< NV34TCL_VTXFMT_SIZE_SHIFT
) | type
));
533 struct nouveau_bo
*bo
= nouveau_bo(ib
);
535 so_method(vtxbuf
, rankine
, NV34TCL_IDXBUF_ADDRESS
, 2);
536 so_reloc (vtxbuf
, bo
, 0, vb_flags
| NOUVEAU_BO_LOW
, 0, 0);
537 so_reloc (vtxbuf
, bo
, ib_format
, vb_flags
| NOUVEAU_BO_OR
,
538 0, NV34TCL_IDXBUF_FORMAT_DMA1
);
541 so_method(vtxbuf
, rankine
, 0x1710, 1);
544 so_ref(vtxbuf
, &nv30
->state
.hw
[NV30_STATE_VTXBUF
]);
545 so_ref(NULL
, &vtxbuf
);
546 nv30
->state
.dirty
|= (1ULL << NV30_STATE_VTXBUF
);
547 so_ref(vtxfmt
, &nv30
->state
.hw
[NV30_STATE_VTXFMT
]);
548 so_ref(NULL
, &vtxfmt
);
549 nv30
->state
.dirty
|= (1ULL << NV30_STATE_VTXFMT
);
550 so_ref(sattr
, &nv30
->state
.hw
[NV30_STATE_VTXATTR
]);
551 so_ref(NULL
, &sattr
);
552 nv30
->state
.dirty
|= (1ULL << NV30_STATE_VTXATTR
);
556 struct nv30_state_entry nv30_state_vbo
= {
557 .validate
= nv30_vbo_validate
,
559 .pipe
= NV30_NEW_ARRAYS
,