1 #include "pipe/p_context.h"
2 #include "pipe/p_state.h"
3 #include "pipe/p_util.h"
5 #include "nv40_context.h"
7 #include "nv40_state.h"
10 nv40_vbo_ncomp(uint format
)
14 if (pf_size_x(format
)) ncomp
++;
15 if (pf_size_y(format
)) ncomp
++;
16 if (pf_size_z(format
)) ncomp
++;
17 if (pf_size_w(format
)) ncomp
++;
23 nv40_vbo_type(uint format
)
25 switch (pf_type(format
)) {
26 case PIPE_FORMAT_TYPE_FLOAT
:
27 return NV40TCL_VTXFMT_TYPE_FLOAT
;
28 case PIPE_FORMAT_TYPE_UNORM
:
29 return NV40TCL_VTXFMT_TYPE_UBYTE
;
36 nv40_vbo_static_attrib(struct nv40_context
*nv40
, int attrib
,
37 struct pipe_vertex_element
*ve
,
38 struct pipe_vertex_buffer
*vb
)
40 struct pipe_winsys
*ws
= nv40
->pipe
.winsys
;
44 type
= nv40_vbo_type(ve
->src_format
);
45 ncomp
= nv40_vbo_ncomp(ve
->src_format
);
47 map
= ws
->buffer_map(ws
, vb
->buffer
, PIPE_BUFFER_FLAG_READ
);
48 map
+= vb
->buffer_offset
+ ve
->src_offset
;
51 case NV40TCL_VTXFMT_TYPE_FLOAT
:
55 BEGIN_RING(curie
, NV40TCL_VTX_ATTR_4F_X(attrib
), 4);
82 ws
->buffer_unmap(ws
, vb
->buffer
);
88 ws
->buffer_unmap(ws
, vb
->buffer
);
92 ws
->buffer_unmap(ws
, vb
->buffer
);
98 nv40_vbo_arrays_update(struct nv40_context
*nv40
)
100 struct nv40_vertex_program
*vp
= nv40
->vertprog
.active
;
101 uint32_t inputs
, vtxfmt
[16];
105 for (hw
= 0; hw
< 16 && inputs
; hw
++) {
106 if (inputs
& (1 << hw
)) {
108 inputs
&= ~(1 << hw
);
114 for (hw
= 0; hw
< num_hw
; hw
++) {
115 struct pipe_vertex_element
*ve
;
116 struct pipe_vertex_buffer
*vb
;
118 if (!(inputs
& (1 << hw
))) {
119 vtxfmt
[hw
] = NV40TCL_VTXFMT_TYPE_FLOAT
;
123 ve
= &nv40
->vtxelt
[hw
];
124 vb
= &nv40
->vtxbuf
[ve
->vertex_buffer_index
];
126 if (vb
->pitch
== 0) {
127 vtxfmt
[hw
] = NV40TCL_VTXFMT_TYPE_FLOAT
;
128 if (nv40_vbo_static_attrib(nv40
, hw
, ve
, vb
) == TRUE
)
132 BEGIN_RING(curie
, NV40TCL_VTXBUF_ADDRESS(hw
), 1);
133 OUT_RELOC(vb
->buffer
, vb
->buffer_offset
+ ve
->src_offset
,
134 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_LOW
|
135 NOUVEAU_BO_OR
| NOUVEAU_BO_RD
, 0,
136 NV40TCL_VTXBUF_ADDRESS_DMA1
);
137 vtxfmt
[hw
] = ((vb
->pitch
<< NV40TCL_VTXFMT_STRIDE_SHIFT
) |
138 (nv40_vbo_ncomp(ve
->src_format
) <<
139 NV40TCL_VTXFMT_SIZE_SHIFT
) |
140 nv40_vbo_type(ve
->src_format
));
143 BEGIN_RING(curie
, 0x1710, 1);
144 OUT_RING (0); /* vtx cache flush */
145 BEGIN_RING(curie
, NV40TCL_VTXFMT(0), num_hw
);
146 OUT_RINGp (vtxfmt
, num_hw
);
150 nv40_vbo_validate_state(struct nv40_context
*nv40
)
152 if (nv40
->dirty
& ~NV40_NEW_ARRAYS
)
153 nv40_emit_hw_state(nv40
);
155 if (nv40
->dirty
& NV40_NEW_ARRAYS
) {
156 nv40_vbo_arrays_update(nv40
);
157 nv40
->dirty
&= ~NV40_NEW_ARRAYS
;
164 nv40_draw_arrays(struct pipe_context
*pipe
, unsigned mode
, unsigned start
,
167 struct nv40_context
*nv40
= (struct nv40_context
*)pipe
;
170 assert(nv40_vbo_validate_state(nv40
));
172 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
173 OUT_RING (nvgl_primitive(mode
));
177 BEGIN_RING(curie
, NV40TCL_VB_VERTEX_BATCH
, 1);
178 OUT_RING (((nr
- 1) << 24) | start
);
184 unsigned push
= nr
> 2047 ? 2047 : nr
;
188 BEGIN_RING_NI(curie
, NV40TCL_VB_VERTEX_BATCH
, push
);
190 OUT_RING(((0x100 - 1) << 24) | start
);
195 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
198 pipe
->flush(pipe
, 0);
203 nv40_draw_elements_u08(struct nv40_context
*nv40
, void *ib
,
204 unsigned start
, unsigned count
)
206 uint8_t *elts
= (uint8_t *)ib
+ start
;
210 BEGIN_RING(curie
, NV40TCL_VB_ELEMENT_U32
, 1);
216 push
= MIN2(count
, 2046);
218 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U16
, push
);
219 for (i
= 0; i
< push
; i
+=2)
220 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
228 nv40_draw_elements_u16(struct nv40_context
*nv40
, void *ib
,
229 unsigned start
, unsigned count
)
231 uint16_t *elts
= (uint16_t *)ib
+ start
;
235 BEGIN_RING(curie
, NV40TCL_VB_ELEMENT_U32
, 1);
241 push
= MIN2(count
, 2046);
243 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U16
, push
);
244 for (i
= 0; i
< push
; i
+=2)
245 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
253 nv40_draw_elements_u32(struct nv40_context
*nv40
, void *ib
,
254 unsigned start
, unsigned count
)
256 uint32_t *elts
= (uint32_t *)ib
+ start
;
260 push
= MIN2(count
, 2047);
262 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U32
, push
);
263 OUT_RINGp (elts
, push
);
271 nv40_draw_elements(struct pipe_context
*pipe
,
272 struct pipe_buffer_handle
*indexBuffer
, unsigned indexSize
,
273 unsigned mode
, unsigned start
, unsigned count
)
275 struct nv40_context
*nv40
= (struct nv40_context
*)pipe
;
278 assert(nv40_vbo_validate_state(nv40
));
280 ib
= pipe
->winsys
->buffer_map(pipe
->winsys
, indexBuffer
,
281 PIPE_BUFFER_FLAG_READ
);
283 NOUVEAU_ERR("Couldn't map index buffer!!\n");
287 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
288 OUT_RING (nvgl_primitive(mode
));
292 nv40_draw_elements_u08(nv40
, ib
, start
, count
);
295 nv40_draw_elements_u16(nv40
, ib
, start
, count
);
298 nv40_draw_elements_u32(nv40
, ib
, start
, count
);
301 NOUVEAU_ERR("unsupported elt size %d\n", indexSize
);
305 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
308 pipe
->winsys
->buffer_unmap(pipe
->winsys
, indexBuffer
);
309 pipe
->flush(pipe
, 0);