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 "pipe/nouveau/nouveau_channel.h"
9 #include "pipe/nouveau/nouveau_pushbuf.h"
12 nv40_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 nv40_vbo_type(uint format)
27 switch (pf_type(format)) {
28 case PIPE_FORMAT_TYPE_FLOAT:
29 return NV40TCL_VTXFMT_TYPE_FLOAT;
30 case PIPE_FORMAT_TYPE_UNORM:
31 return NV40TCL_VTXFMT_TYPE_UBYTE;
38 nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib,
39 struct pipe_vertex_element *ve,
40 struct pipe_vertex_buffer *vb)
42 struct pipe_winsys *ws = nv40->pipe.winsys;
46 type = nv40_vbo_type(ve->src_format);
47 ncomp = nv40_vbo_ncomp(ve->src_format);
49 map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_FLAG_READ);
50 map += vb->buffer_offset + ve->src_offset;
53 case NV40TCL_VTXFMT_TYPE_FLOAT:
57 BEGIN_RING(curie, NV40TCL_VTX_ATTR_4F_X(attrib), 4);
84 ws->buffer_unmap(ws, vb->buffer);
90 ws->buffer_unmap(ws, vb->buffer);
94 ws->buffer_unmap(ws, vb->buffer);
100 nv40_vbo_arrays_update(struct nv40_context *nv40)
102 struct nv40_vertex_program *vp = nv40->vertprog.active;
103 uint32_t inputs, vtxfmt[16];
109 for (hw = 0; hw < 16 && inputs; hw++) {
110 if (inputs & (1 << hw)) {
112 inputs &= ~(1 << hw);
118 for (hw = 0; hw < num_hw; hw++) {
119 struct pipe_vertex_element *ve;
120 struct pipe_vertex_buffer *vb;
122 if (!(inputs & (1 << hw))) {
123 vtxfmt[hw] = NV40TCL_VTXFMT_TYPE_FLOAT;
127 ve = &nv40->vtxelt[hw];
128 vb = &nv40->vtxbuf[ve->vertex_buffer_index];
130 if (vb->pitch == 0) {
131 vtxfmt[hw] = NV40TCL_VTXFMT_TYPE_FLOAT;
132 if (nv40_vbo_static_attrib(nv40, hw, ve, vb) == TRUE)
136 nv40->vb_enable |= (1 << hw);
137 nv40->vb[hw].delta = vb->buffer_offset + ve->src_offset;
138 nv40->vb[hw].buffer = vb->buffer;
140 vtxfmt[hw] = ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) |
141 (nv40_vbo_ncomp(ve->src_format) <<
142 NV40TCL_VTXFMT_SIZE_SHIFT) |
143 nv40_vbo_type(ve->src_format));
146 BEGIN_RING(curie, NV40TCL_VTXFMT(0), num_hw);
147 OUT_RINGp (vtxfmt, num_hw);
151 nv40_vbo_validate_state(struct nv40_context *nv40,
152 struct pipe_buffer_handle *ib, unsigned ib_format)
156 nv40_emit_hw_state(nv40);
158 if (nv40->dirty & NV40_NEW_ARRAYS) {
159 nv40_vbo_arrays_update(nv40);
160 nv40->dirty &= ~NV40_NEW_ARRAYS;
163 inputs = nv40->vb_enable;
165 unsigned a = ffs(inputs) - 1;
169 BEGIN_RING(curie, NV40TCL_VTXBUF_ADDRESS(a), 1);
170 OUT_RELOC (nv40->vb[a].buffer, nv40->vb[a].delta,
171 NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_LOW |
172 NOUVEAU_BO_OR | NOUVEAU_BO_RD, 0,
173 NV40TCL_VTXBUF_ADDRESS_DMA1);
177 BEGIN_RING(curie, NV40TCL_IDXBUF_ADDRESS, 2);
178 OUT_RELOCl(ib, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
180 OUT_RELOCd(ib, ib_format, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
181 NOUVEAU_BO_RD | NOUVEAU_BO_OR,
182 0, NV40TCL_IDXBUF_FORMAT_DMA1);
185 BEGIN_RING(curie, 0x1710, 1);
186 OUT_RING (0); /* vtx cache flush */
192 nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
195 struct nv40_context *nv40 = nv40_context(pipe);
198 assert(nv40_vbo_validate_state(nv40, NULL, 0));
200 BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
201 OUT_RING (nvgl_primitive(mode));
205 BEGIN_RING(curie, NV40TCL_VB_VERTEX_BATCH, 1);
206 OUT_RING (((nr - 1) << 24) | start);
212 unsigned push = nr > 2047 ? 2047 : nr;
216 BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, push);
218 OUT_RING(((0x100 - 1) << 24) | start);
223 BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
226 pipe->flush(pipe, 0);
231 nv40_draw_elements_u08(struct nv40_context *nv40, void *ib,
232 unsigned start, unsigned count)
234 uint8_t *elts = (uint8_t *)ib + start;
238 BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1);
244 push = MIN2(count, 2046);
246 BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push);
247 for (i = 0; i < push; i+=2)
248 OUT_RING((elts[i+1] << 16) | elts[i]);
256 nv40_draw_elements_u16(struct nv40_context *nv40, void *ib,
257 unsigned start, unsigned count)
259 uint16_t *elts = (uint16_t *)ib + start;
263 BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1);
269 push = MIN2(count, 2046);
271 BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push);
272 for (i = 0; i < push; i+=2)
273 OUT_RING((elts[i+1] << 16) | elts[i]);
281 nv40_draw_elements_u32(struct nv40_context *nv40, void *ib,
282 unsigned start, unsigned count)
284 uint32_t *elts = (uint32_t *)ib + start;
288 push = MIN2(count, 2047);
290 BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push);
291 OUT_RINGp (elts, push);
299 nv40_draw_elements_inline(struct pipe_context *pipe,
300 struct pipe_buffer_handle *ib, unsigned ib_size,
301 unsigned mode, unsigned start, unsigned count)
303 struct nv40_context *nv40 = nv40_context(pipe);
304 struct pipe_winsys *ws = pipe->winsys;
307 assert(nv40_vbo_validate_state(nv40, NULL, 0));
309 map = ws->buffer_map(ws, ib, PIPE_BUFFER_FLAG_READ);
313 BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
314 OUT_RING (nvgl_primitive(mode));
318 nv40_draw_elements_u08(nv40, map, start, count);
321 nv40_draw_elements_u16(nv40, map, start, count);
324 nv40_draw_elements_u32(nv40, map, start, count);
331 BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
334 ws->buffer_unmap(ws, ib);
340 nv40_draw_elements_vbo(struct pipe_context *pipe,
341 struct pipe_buffer_handle *ib, unsigned ib_size,
342 unsigned mode, unsigned start, unsigned count)
344 struct nv40_context *nv40 = nv40_context(pipe);
349 type = NV40TCL_IDXBUF_FORMAT_TYPE_U16;
352 type = NV40TCL_IDXBUF_FORMAT_TYPE_U32;
358 assert(nv40_vbo_validate_state(nv40, ib, type));
360 BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
361 OUT_RING (nvgl_primitive(mode));
365 BEGIN_RING(curie, NV40TCL_VB_INDEX_BATCH, 1);
366 OUT_RING (((nr - 1) << 24) | start);
372 unsigned push = nr > 2047 ? 2047 : nr;
376 BEGIN_RING_NI(curie, NV40TCL_VB_INDEX_BATCH, push);
378 OUT_RING(((0x100 - 1) << 24) | start);
383 BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
390 nv40_draw_elements(struct pipe_context *pipe,
391 struct pipe_buffer_handle *indexBuffer, unsigned indexSize,
392 unsigned mode, unsigned start, unsigned count)
394 if (indexSize != 1) {
395 nv40_draw_elements_vbo(pipe, indexBuffer, indexSize,
398 nv40_draw_elements_inline(pipe, indexBuffer, indexSize,
402 pipe->flush(pipe, 0);