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_draw_arrays(struct pipe_context
*pipe
, unsigned mode
, unsigned start
,
13 struct nv40_context
*nv40
= (struct nv40_context
*)pipe
;
17 nv40_emit_hw_state(nv40
);
19 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
20 OUT_RING (nvgl_primitive(mode
));
24 BEGIN_RING(curie
, NV40TCL_VB_VERTEX_BATCH
, 1);
25 OUT_RING (((nr
- 1) << 24) | start
);
29 /*XXX: large arrays (nr>2047) will blow up */
34 BEGIN_RING_NI(curie
, NV40TCL_VB_VERTEX_BATCH
, nr
);
36 OUT_RING(((0x100 - 1) << 24) | start
);
41 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
49 nv40_draw_elements_u08(struct nv40_context
*nv40
, void *ib
,
50 unsigned start
, unsigned count
)
52 uint8_t *elts
= (uint8_t *)ib
+ start
;
56 BEGIN_RING(curie
, NV40TCL_VB_ELEMENT_U32
, 1);
62 push
= MIN2(count
, 2046);
64 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U16
, push
);
65 for (i
= 0; i
< push
; i
+=2)
66 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
74 nv40_draw_elements_u16(struct nv40_context
*nv40
, void *ib
,
75 unsigned start
, unsigned count
)
77 uint16_t *elts
= (uint16_t *)ib
+ start
;
81 BEGIN_RING(curie
, NV40TCL_VB_ELEMENT_U32
, 1);
87 push
= MIN2(count
, 2046);
89 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U16
, push
);
90 for (i
= 0; i
< push
; i
+=2)
91 OUT_RING((elts
[i
+1] << 16) | elts
[i
]);
99 nv40_draw_elements_u32(struct nv40_context
*nv40
, void *ib
,
100 unsigned start
, unsigned count
)
102 uint32_t *elts
= (uint32_t *)ib
+ start
;
106 push
= MIN2(count
, 2047);
108 BEGIN_RING_NI(curie
, NV40TCL_VB_ELEMENT_U32
, push
);
109 OUT_RINGp (elts
, push
);
117 nv40_draw_elements(struct pipe_context
*pipe
,
118 struct pipe_buffer_handle
*indexBuffer
, unsigned indexSize
,
119 unsigned mode
, unsigned start
, unsigned count
)
121 struct nv40_context
*nv40
= (struct nv40_context
*)pipe
;
125 nv40_emit_hw_state(nv40
);
127 ib
= pipe
->winsys
->buffer_map(pipe
->winsys
, indexBuffer
,
128 PIPE_BUFFER_FLAG_READ
);
130 NOUVEAU_ERR("Couldn't map index buffer!!\n");
134 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
135 OUT_RING (nvgl_primitive(mode
));
139 nv40_draw_elements_u08(nv40
, ib
, start
, count
);
142 nv40_draw_elements_u16(nv40
, ib
, start
, count
);
145 nv40_draw_elements_u32(nv40
, ib
, start
, count
);
148 NOUVEAU_ERR("unsupported elt size %d\n", indexSize
);
152 BEGIN_RING(curie
, NV40TCL_BEGIN_END
, 1);
155 pipe
->winsys
->buffer_unmap(pipe
->winsys
, ib
);
156 pipe
->flush(pipe
, 0);
161 nv40_vbo_ncomp(uint format
)
165 if (pf_size_x(format
)) ncomp
++;
166 if (pf_size_y(format
)) ncomp
++;
167 if (pf_size_z(format
)) ncomp
++;
168 if (pf_size_w(format
)) ncomp
++;
174 nv40_vbo_type(uint format
)
176 switch (pf_type(format
)) {
177 case PIPE_FORMAT_TYPE_FLOAT
:
178 return NV40TCL_VTXFMT_TYPE_FLOAT
;
179 case PIPE_FORMAT_TYPE_UNORM
:
180 return NV40TCL_VTXFMT_TYPE_UBYTE
;
187 nv40_vbo_arrays_update(struct nv40_context
*nv40
)
189 struct nv40_vertex_program
*vp
= nv40
->vertprog
.active
;
190 uint32_t inputs
, vtxfmt
[16];
194 for (hw
= 0; hw
< 16 && inputs
; hw
++) {
195 if (inputs
& (1 << hw
)) {
197 inputs
&= ~(1 << hw
);
203 BEGIN_RING(curie
, NV40TCL_VTXBUF_ADDRESS(0), num_hw
);
204 for (hw
= 0; hw
< num_hw
; hw
++) {
205 struct pipe_vertex_element
*ve
;
206 struct pipe_vertex_buffer
*vb
;
208 if (!(inputs
& (1 << hw
))) {
210 vtxfmt
[hw
] = NV40TCL_VTXFMT_TYPE_FLOAT
;
214 ve
= &nv40
->vtxelt
[hw
];
215 vb
= &nv40
->vtxbuf
[ve
->vertex_buffer_index
];
217 OUT_RELOC(vb
->buffer
, vb
->buffer_offset
+ ve
->src_offset
,
218 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_LOW
|
219 NOUVEAU_BO_OR
| NOUVEAU_BO_RD
, 0,
220 NV40TCL_VTXBUF_ADDRESS_DMA1
);
221 vtxfmt
[hw
] = ((vb
->pitch
<< NV40TCL_VTXFMT_STRIDE_SHIFT
) |
222 (nv40_vbo_ncomp(ve
->src_format
) <<
223 NV40TCL_VTXFMT_SIZE_SHIFT
) |
224 nv40_vbo_type(ve
->src_format
));
227 BEGIN_RING(curie
, 0x1710, 1);
228 OUT_RING (0); /* vtx cache flush */
229 BEGIN_RING(curie
, NV40TCL_VTXFMT(0), num_hw
);
230 OUT_RINGp (vtxfmt
, num_hw
);