Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 1 | |
2 | #include "pipe/p_state.h" |
||
3 | #include "util/u_inlines.h" |
||
4 | #include "util/u_format.h" |
||
5 | #include "translate/translate.h" |
||
6 | |||
7 | |||
8 | #include "nvc0/nvc0_resource.h" |
||
9 | |||
10 | |||
11 | |||
12 | |||
13 | struct nouveau_pushbuf *push; |
||
14 | |||
15 | |||
16 | void *dest; |
||
17 | const void *idxbuf; |
||
18 | |||
19 | |||
20 | uint32_t restart_index; |
||
21 | uint32_t instance_id; |
||
22 | |||
23 | |||
24 | boolean need_vertex_id; |
||
25 | |||
26 | |||
27 | boolean enabled; |
||
28 | boolean value; |
||
29 | unsigned stride; |
||
30 | const uint8_t *data; |
||
31 | } edgeflag; |
||
32 | }; |
||
33 | |||
34 | |||
35 | struct nvc0_context *, |
||
36 | const struct pipe_draw_info *); |
||
37 | |||
38 | |||
39 | nvc0_push_context_init(struct nvc0_context *nvc0, struct push_context *ctx) |
||
40 | { |
||
41 | ctx->push = nvc0->base.pushbuf; |
||
42 | |||
43 | |||
44 | ctx->vertex_size = nvc0->vertex->size; |
||
45 | |||
46 | |||
47 | nvc0->vertprog->vp.need_vertex_id && (nvc0->vertex->num_elements < 32); |
||
48 | |||
49 | |||
50 | ctx->edgeflag.enabled = nvc0->vertprog->vp.edgeflag < PIPE_MAX_ATTRIBS; |
||
51 | |||
52 | |||
53 | ctx->edgeflag.data = NULL; |
||
54 | ctx->edgeflag.stride = 0; |
||
55 | } |
||
56 | |||
57 | |||
58 | nvc0_vertex_configure_translate(struct nvc0_context *nvc0, int32_t index_bias) |
||
59 | { |
||
60 | struct translate *translate = nvc0->vertex->translate; |
||
61 | unsigned i; |
||
62 | |||
63 | |||
64 | const uint8_t *map; |
||
65 | const struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[i]; |
||
66 | |||
67 | |||
68 | map = (const uint8_t *)vb->user_buffer; |
||
69 | else |
||
70 | map = nouveau_resource_map_offset(&nvc0->base, |
||
71 | nv04_resource(vb->buffer), vb->buffer_offset, NOUVEAU_BO_RD); |
||
72 | |||
73 | |||
74 | map += (intptr_t)index_bias * vb->stride; |
||
75 | |||
76 | |||
77 | } |
||
78 | } |
||
79 | |||
80 | |||
81 | nvc0_push_map_idxbuf(struct push_context *ctx, struct nvc0_context *nvc0) |
||
82 | { |
||
83 | if (nvc0->idxbuf.buffer) { |
||
84 | struct nv04_resource *buf = nv04_resource(nvc0->idxbuf.buffer); |
||
85 | ctx->idxbuf = nouveau_resource_map_offset(&nvc0->base, |
||
86 | buf, nvc0->idxbuf.offset, NOUVEAU_BO_RD); |
||
87 | } else { |
||
88 | ctx->idxbuf = nvc0->idxbuf.user_buffer; |
||
89 | } |
||
90 | } |
||
91 | |||
92 | |||
93 | nvc0_push_map_edgeflag(struct push_context *ctx, struct nvc0_context *nvc0, |
||
94 | int32_t index_bias) |
||
95 | { |
||
96 | unsigned attr = nvc0->vertprog->vp.edgeflag; |
||
97 | struct pipe_vertex_element *ve = &nvc0->vertex->element[attr].pipe; |
||
98 | struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[ve->vertex_buffer_index]; |
||
99 | struct nv04_resource *buf = nv04_resource(vb->buffer); |
||
100 | |||
101 | |||
102 | if (buf) { |
||
103 | unsigned offset = vb->buffer_offset + ve->src_offset; |
||
104 | ctx->edgeflag.data = nouveau_resource_map_offset(&nvc0->base, |
||
105 | buf, offset, NOUVEAU_BO_RD); |
||
106 | } else { |
||
107 | ctx->edgeflag.data = (const uint8_t *)vb->user_buffer + ve->src_offset; |
||
108 | } |
||
109 | |||
110 | |||
111 | ctx->edgeflag.data += (intptr_t)index_bias * vb->stride; |
||
112 | } |
||
113 | |||
114 | |||
115 | prim_restart_search_i08(const uint8_t *elts, unsigned push, uint8_t index) |
||
116 | { |
||
117 | unsigned i; |
||
118 | for (i = 0; i < push && elts[i] != index; ++i); |
||
119 | return i; |
||
120 | } |
||
121 | |||
122 | |||
123 | prim_restart_search_i16(const uint16_t *elts, unsigned push, uint16_t index) |
||
124 | { |
||
125 | unsigned i; |
||
126 | for (i = 0; i < push && elts[i] != index; ++i); |
||
127 | return i; |
||
128 | } |
||
129 | |||
130 | |||
131 | prim_restart_search_i32(const uint32_t *elts, unsigned push, uint32_t index) |
||
132 | { |
||
133 | unsigned i; |
||
134 | for (i = 0; i < push && elts[i] != index; ++i); |
||
135 | return i; |
||
136 | } |
||
137 | |||
138 | |||
139 | ef_value(const struct push_context *ctx, uint32_t index) |
||
140 | { |
||
141 | float *pf = (float *)&ctx->edgeflag.data[index * ctx->edgeflag.stride]; |
||
142 | return *pf ? TRUE : FALSE; |
||
143 | } |
||
144 | |||
145 | |||
146 | ef_toggle(struct push_context *ctx) |
||
147 | { |
||
148 | ctx->edgeflag.value = !ctx->edgeflag.value; |
||
149 | return ctx->edgeflag.value; |
||
150 | } |
||
151 | |||
152 | |||
153 | ef_toggle_search_i08(struct push_context *ctx, const uint8_t *elts, unsigned n) |
||
154 | { |
||
155 | unsigned i; |
||
156 | for (i = 0; i < n && ef_value(ctx, elts[i]) == ctx->edgeflag.value; ++i); |
||
157 | return i; |
||
158 | } |
||
159 | |||
160 | |||
161 | ef_toggle_search_i16(struct push_context *ctx, const uint16_t *elts, unsigned n) |
||
162 | { |
||
163 | unsigned i; |
||
164 | for (i = 0; i < n && ef_value(ctx, elts[i]) == ctx->edgeflag.value; ++i); |
||
165 | return i; |
||
166 | } |
||
167 | |||
168 | |||
169 | ef_toggle_search_i32(struct push_context *ctx, const uint32_t *elts, unsigned n) |
||
170 | { |
||
171 | unsigned i; |
||
172 | for (i = 0; i < n && ef_value(ctx, elts[i]) == ctx->edgeflag.value; ++i); |
||
173 | return i; |
||
174 | } |
||
175 | |||
176 | |||
177 | ef_toggle_search_seq(struct push_context *ctx, unsigned start, unsigned n) |
||
178 | { |
||
179 | unsigned i; |
||
180 | for (i = 0; i < n && ef_value(ctx, start++) == ctx->edgeflag.value; ++i); |
||
181 | return i; |
||
182 | } |
||
183 | |||
184 | |||
185 | nvc0_push_setup_vertex_array(struct nvc0_context *nvc0, const unsigned count) |
||
186 | { |
||
187 | struct nouveau_pushbuf *push = nvc0->base.pushbuf; |
||
188 | struct nouveau_bo *bo; |
||
189 | uint64_t va; |
||
190 | const unsigned size = count * nvc0->vertex->size; |
||
191 | |||
192 | |||
193 | |||
194 | |||
195 | PUSH_DATAh(push, va); |
||
196 | PUSH_DATA (push, va); |
||
197 | BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_LIMIT_HIGH(0)), 2); |
||
198 | PUSH_DATAh(push, va + size - 1); |
||
199 | PUSH_DATA (push, va + size - 1); |
||
200 | |||
201 | |||
202 | bo); |
||
203 | nouveau_pushbuf_validate(push); |
||
204 | |||
205 | |||
206 | } |
||
207 | |||
208 | |||
209 | disp_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) |
||
210 | { |
||
211 | struct nouveau_pushbuf *push = ctx->push; |
||
212 | struct translate *translate = ctx->translate; |
||
213 | const uint8_t *restrict elts = (uint8_t *)ctx->idxbuf + start; |
||
214 | unsigned pos = 0; |
||
215 | |||
216 | |||
217 | unsigned nR = count; |
||
218 | |||
219 | |||
220 | nR = prim_restart_search_i08(elts, nR, ctx->restart_index); |
||
221 | |||
222 | |||
223 | count -= nR; |
||
224 | ctx->dest += nR * ctx->vertex_size; |
||
225 | |||
226 | |||
227 | unsigned nE = nR; |
||
228 | |||
229 | |||
230 | nE = ef_toggle_search_i08(ctx, elts, nR); |
||
231 | |||
232 | |||
233 | if (likely(nE >= 2)) { |
||
234 | BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2); |
||
235 | PUSH_DATA (push, pos); |
||
236 | PUSH_DATA (push, nE); |
||
237 | } else |
||
238 | if (nE) { |
||
239 | if (pos <= 0xff) { |
||
240 | IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_U32), pos); |
||
241 | } else { |
||
242 | BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1); |
||
243 | PUSH_DATA (push, pos); |
||
244 | } |
||
245 | } |
||
246 | if (unlikely(nE != nR)) |
||
247 | IMMED_NVC0(push, NVC0_3D(EDGEFLAG), ef_toggle(ctx)); |
||
248 | |||
249 | |||
250 | elts += nE; |
||
251 | nR -= nE; |
||
252 | } |
||
253 | if (count) { |
||
254 | BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1); |
||
255 | PUSH_DATA (push, 0xffffffff); |
||
256 | ++elts; |
||
257 | ctx->dest += ctx->vertex_size; |
||
258 | ++pos; |
||
259 | --count; |
||
260 | } |
||
261 | } while (count); |
||
262 | } |
||
263 | |||
264 | |||
265 | disp_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) |
||
266 | { |
||
267 | struct nouveau_pushbuf *push = ctx->push; |
||
268 | struct translate *translate = ctx->translate; |
||
269 | const uint16_t *restrict elts = (uint16_t *)ctx->idxbuf + start; |
||
270 | unsigned pos = 0; |
||
271 | |||
272 | |||
273 | unsigned nR = count; |
||
274 | |||
275 | |||
276 | nR = prim_restart_search_i16(elts, nR, ctx->restart_index); |
||
277 | |||
278 | |||
279 | count -= nR; |
||
280 | ctx->dest += nR * ctx->vertex_size; |
||
281 | |||
282 | |||
283 | unsigned nE = nR; |
||
284 | |||
285 | |||
286 | nE = ef_toggle_search_i16(ctx, elts, nR); |
||
287 | |||
288 | |||
289 | if (likely(nE >= 2)) { |
||
290 | BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2); |
||
291 | PUSH_DATA (push, pos); |
||
292 | PUSH_DATA (push, nE); |
||
293 | } else |
||
294 | if (nE) { |
||
295 | if (pos <= 0xff) { |
||
296 | IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_U32), pos); |
||
297 | } else { |
||
298 | BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1); |
||
299 | PUSH_DATA (push, pos); |
||
300 | } |
||
301 | } |
||
302 | if (unlikely(nE != nR)) |
||
303 | IMMED_NVC0(push, NVC0_3D(EDGEFLAG), ef_toggle(ctx)); |
||
304 | |||
305 | |||
306 | elts += nE; |
||
307 | nR -= nE; |
||
308 | } |
||
309 | if (count) { |
||
310 | BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1); |
||
311 | PUSH_DATA (push, 0xffffffff); |
||
312 | ++elts; |
||
313 | ctx->dest += ctx->vertex_size; |
||
314 | ++pos; |
||
315 | --count; |
||
316 | } |
||
317 | } while (count); |
||
318 | } |
||
319 | |||
320 | |||
321 | disp_vertices_i32(struct push_context *ctx, unsigned start, unsigned count) |
||
322 | { |
||
323 | struct nouveau_pushbuf *push = ctx->push; |
||
324 | struct translate *translate = ctx->translate; |
||
325 | const uint32_t *restrict elts = (uint32_t *)ctx->idxbuf + start; |
||
326 | unsigned pos = 0; |
||
327 | |||
328 | |||
329 | unsigned nR = count; |
||
330 | |||
331 | |||
332 | nR = prim_restart_search_i32(elts, nR, ctx->restart_index); |
||
333 | |||
334 | |||
335 | count -= nR; |
||
336 | ctx->dest += nR * ctx->vertex_size; |
||
337 | |||
338 | |||
339 | unsigned nE = nR; |
||
340 | |||
341 | |||
342 | nE = ef_toggle_search_i32(ctx, elts, nR); |
||
343 | |||
344 | |||
345 | if (likely(nE >= 2)) { |
||
346 | BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2); |
||
347 | PUSH_DATA (push, pos); |
||
348 | PUSH_DATA (push, nE); |
||
349 | } else |
||
350 | if (nE) { |
||
351 | if (pos <= 0xff) { |
||
352 | IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_U32), pos); |
||
353 | } else { |
||
354 | BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1); |
||
355 | PUSH_DATA (push, pos); |
||
356 | } |
||
357 | } |
||
358 | if (unlikely(nE != nR)) |
||
359 | IMMED_NVC0(push, NVC0_3D(EDGEFLAG), ef_toggle(ctx)); |
||
360 | |||
361 | |||
362 | elts += nE; |
||
363 | nR -= nE; |
||
364 | } |
||
365 | if (count) { |
||
366 | BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1); |
||
367 | PUSH_DATA (push, 0xffffffff); |
||
368 | ++elts; |
||
369 | ctx->dest += ctx->vertex_size; |
||
370 | ++pos; |
||
371 | --count; |
||
372 | } |
||
373 | } while (count); |
||
374 | } |
||
375 | |||
376 | |||
377 | disp_vertices_seq(struct push_context *ctx, unsigned start, unsigned count) |
||
378 | { |
||
379 | struct nouveau_pushbuf *push = ctx->push; |
||
380 | struct translate *translate = ctx->translate; |
||
381 | unsigned pos = 0; |
||
382 | |||
383 | |||
384 | * maybe we should avoid that ? |
||
385 | */ |
||
386 | translate->run(translate, start, count, 0, ctx->instance_id, ctx->dest); |
||
387 | do { |
||
388 | unsigned nr = count; |
||
389 | |||
390 | |||
391 | nr = ef_toggle_search_seq(ctx, start + pos, nr); |
||
392 | |||
393 | |||
394 | if (likely(nr)) { |
||
395 | BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2); |
||
396 | PUSH_DATA (push, pos); |
||
397 | PUSH_DATA (push, nr); |
||
398 | } |
||
399 | if (unlikely(nr != count)) |
||
400 | IMMED_NVC0(push, NVC0_3D(EDGEFLAG), ef_toggle(ctx)); |
||
401 | |||
402 | |||
403 | count -= nr; |
||
404 | } while (count); |
||
405 | } |
||
406 | |||
407 | |||
408 | |||
409 | case PIPE_PRIM_##n: return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n |
||
410 | |||
411 | |||
412 | nvc0_prim_gl(unsigned prim) |
||
413 | { |
||
414 | switch (prim) { |
||
415 | NVC0_PRIM_GL_CASE(POINTS); |
||
416 | NVC0_PRIM_GL_CASE(LINES); |
||
417 | NVC0_PRIM_GL_CASE(LINE_LOOP); |
||
418 | NVC0_PRIM_GL_CASE(LINE_STRIP); |
||
419 | NVC0_PRIM_GL_CASE(TRIANGLES); |
||
420 | NVC0_PRIM_GL_CASE(TRIANGLE_STRIP); |
||
421 | NVC0_PRIM_GL_CASE(TRIANGLE_FAN); |
||
422 | NVC0_PRIM_GL_CASE(QUADS); |
||
423 | NVC0_PRIM_GL_CASE(QUAD_STRIP); |
||
424 | NVC0_PRIM_GL_CASE(POLYGON); |
||
425 | NVC0_PRIM_GL_CASE(LINES_ADJACENCY); |
||
426 | NVC0_PRIM_GL_CASE(LINE_STRIP_ADJACENCY); |
||
427 | NVC0_PRIM_GL_CASE(TRIANGLES_ADJACENCY); |
||
428 | NVC0_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY); |
||
429 | /* |
||
430 | NVC0_PRIM_GL_CASE(PATCHES); */ |
||
431 | default: |
||
432 | return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS; |
||
433 | } |
||
434 | } |
||
435 | |||
436 | |||
437 | nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) |
||
438 | { |
||
439 | struct push_context ctx; |
||
440 | unsigned i, index_size; |
||
441 | unsigned inst_count = info->instance_count; |
||
442 | unsigned vert_count = info->count; |
||
443 | unsigned prim; |
||
444 | |||
445 | |||
446 | |||
447 | |||
448 | |||
449 | |||
450 | /* this is already taken care of by translate */ |
||
451 | IMMED_NVC0(ctx.push, NVC0_3D(VB_ELEMENT_BASE), 0); |
||
452 | nvc0->state.index_bias = 0; |
||
453 | } |
||
454 | |||
455 | |||
456 | nvc0_push_map_edgeflag(&ctx, nvc0, info->index_bias); |
||
457 | |||
458 | |||
459 | ctx.restart_index = info->restart_index; |
||
460 | |||
461 | |||
462 | /* NOTE: I hope we won't ever need that last index (~0). |
||
463 | * If we do, we have to disable primitive restart here always and |
||
464 | * use END,BEGIN to restart. (XXX: would that affect PrimitiveID ?) |
||
465 | * We could also deactive PRIM_RESTART_WITH_DRAW_ARRAYS temporarily, |
||
466 | * and add manual restart to disp_vertices_seq. |
||
467 | */ |
||
468 | BEGIN_NVC0(ctx.push, NVC0_3D(PRIM_RESTART_ENABLE), 2); |
||
469 | PUSH_DATA (ctx.push, 1); |
||
470 | PUSH_DATA (ctx.push, info->indexed ? 0xffffffff : info->restart_index); |
||
471 | } else |
||
472 | if (nvc0->state.prim_restart) { |
||
473 | IMMED_NVC0(ctx.push, NVC0_3D(PRIM_RESTART_ENABLE), 0); |
||
474 | } |
||
475 | nvc0->state.prim_restart = info->primitive_restart; |
||
476 | |||
477 | |||
478 | nvc0_push_map_idxbuf(&ctx, nvc0); |
||
479 | index_size = nvc0->idxbuf.index_size; |
||
480 | } else { |
||
481 | if (unlikely(info->count_from_stream_output)) { |
||
482 | struct pipe_context *pipe = &nvc0->base.pipe; |
||
483 | struct nvc0_so_target *targ; |
||
484 | targ = nvc0_so_target(info->count_from_stream_output); |
||
485 | pipe->get_query_result(pipe, targ->pq, TRUE, (void *)&vert_count); |
||
486 | vert_count /= targ->stride; |
||
487 | } |
||
488 | ctx.idxbuf = NULL; /* shut up warnings */ |
||
489 | index_size = 0; |
||
490 | } |
||
491 | |||
492 | |||
493 | |||
494 | |||
495 | do { |
||
496 | PUSH_SPACE(ctx.push, 9); |
||
497 | |||
498 | |||
499 | if (unlikely(!ctx.dest)) |
||
500 | break; |
||
501 | |||
502 | |||
503 | nvc0_push_upload_vertex_ids(&ctx, nvc0, info); |
||
504 | |||
505 | |||
506 | IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0); |
||
507 | BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_BEGIN_GL), 1); |
||
508 | PUSH_DATA (ctx.push, prim); |
||
509 | switch (index_size) { |
||
510 | case 1: |
||
511 | disp_vertices_i08(&ctx, info->start, vert_count); |
||
512 | break; |
||
513 | case 2: |
||
514 | disp_vertices_i16(&ctx, info->start, vert_count); |
||
515 | break; |
||
516 | case 4: |
||
517 | disp_vertices_i32(&ctx, info->start, vert_count); |
||
518 | break; |
||
519 | default: |
||
520 | assert(index_size == 0); |
||
521 | disp_vertices_seq(&ctx, info->start, vert_count); |
||
522 | break; |
||
523 | } |
||
524 | PUSH_SPACE(ctx.push, 1); |
||
525 | IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_END_GL), 0); |
||
526 | |||
527 | |||
528 | prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; |
||
529 | ++ctx.instance_id; |
||
530 | } |
||
531 | nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX_TMP); |
||
532 | nouveau_scratch_done(&nvc0->base); |
||
533 | } while (inst_count); |
||
534 | |||
535 | |||
536 | |||
537 | |||
538 | |||
539 | PUSH_SPACE(ctx.push, 1); |
||
540 | IMMED_NVC0(ctx.push, NVC0_3D(EDGEFLAG), 1); |
||
541 | } |
||
542 | |||
543 | |||
544 | PUSH_SPACE(ctx.push, 4); |
||
545 | IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 0); |
||
546 | BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(1)), 1); |
||
547 | PUSH_DATA (ctx.push, |
||
548 | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST | |
||
549 | NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT | |
||
550 | NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32); |
||
551 | IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ARRAY_FETCH(1)), 0); |
||
552 | } |
||
553 | |||
554 | |||
555 | nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer)); |
||
556 | for (i = 0; i < nvc0->num_vtxbufs; ++i) |
||
557 | nouveau_resource_unmap(nv04_resource(nvc0->vtxbuf[i].buffer)); |
||
558 | |||
559 | |||
560 | } |
||
561 | |||
562 | |||
563 | copy_indices_u8(uint32_t *dst, const uint8_t *elts, uint32_t bias, unsigned n) |
||
564 | { |
||
565 | unsigned i; |
||
566 | for (i = 0; i < n; ++i) |
||
567 | dst[i] = elts[i] + bias; |
||
568 | } |
||
569 | |||
570 | |||
571 | copy_indices_u16(uint32_t *dst, const uint16_t *elts, uint32_t bias, unsigned n) |
||
572 | { |
||
573 | unsigned i; |
||
574 | for (i = 0; i < n; ++i) |
||
575 | dst[i] = elts[i] + bias; |
||
576 | } |
||
577 | |||
578 | |||
579 | copy_indices_u32(uint32_t *dst, const uint32_t *elts, uint32_t bias, unsigned n) |
||
580 | { |
||
581 | unsigned i; |
||
582 | for (i = 0; i < n; ++i) |
||
583 | dst[i] = elts[i] + bias; |
||
584 | } |
||
585 | |||
586 | |||
587 | nvc0_push_upload_vertex_ids(struct push_context *ctx, |
||
588 | struct nvc0_context *nvc0, |
||
589 | const struct pipe_draw_info *info) |
||
590 | |||
591 | |||
592 | struct nouveau_pushbuf *push = ctx->push; |
||
593 | struct nouveau_bo *bo; |
||
594 | uint64_t va; |
||
595 | uint32_t *data; |
||
596 | uint32_t format; |
||
597 | unsigned index_size = nvc0->idxbuf.index_size; |
||
598 | unsigned i; |
||
599 | unsigned a = nvc0->vertex->num_elements; |
||
600 | |||
601 | |||
602 | index_size = 4; |
||
603 | data = (uint32_t *)nouveau_scratch_get(&nvc0->base, |
||
604 | info->count * index_size, &va, &bo); |
||
605 | |||
606 | |||
607 | bo); |
||
608 | nouveau_pushbuf_validate(push); |
||
609 | |||
610 | |||
611 | if (!info->index_bias) { |
||
612 | memcpy(data, ctx->idxbuf, info->count * index_size); |
||
613 | } else { |
||
614 | switch (nvc0->idxbuf.index_size) { |
||
615 | case 1: |
||
616 | copy_indices_u8(data, ctx->idxbuf, info->index_bias, info->count); |
||
617 | break; |
||
618 | case 2: |
||
619 | copy_indices_u16(data, ctx->idxbuf, info->index_bias, info->count); |
||
620 | break; |
||
621 | default: |
||
622 | copy_indices_u32(data, ctx->idxbuf, info->index_bias, info->count); |
||
623 | break; |
||
624 | } |
||
625 | } |
||
626 | } else { |
||
627 | for (i = 0; i < info->count; ++i) |
||
628 | data[i] = i + (info->start + info->index_bias); |
||
629 | } |
||
630 | |||
631 | |||
632 | NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_UINT; |
||
633 | |||
634 | |||
635 | case 1: |
||
636 | format |= NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_8; |
||
637 | break; |
||
638 | case 2: |
||
639 | format |= NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_16; |
||
640 | break; |
||
641 | default: |
||
642 | format |= NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32; |
||
643 | break; |
||
644 | } |
||
645 | |||
646 | |||
647 | |||
648 | |||
649 | nvc0->state.instance_elts &= ~2; |
||
650 | IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(1)), 0); |
||
651 | } |
||
652 | |||
653 | |||
654 | PUSH_DATA (push, format); |
||
655 | |||
656 | |||
657 | PUSH_DATA (push, NVC0_3D_VERTEX_ARRAY_FETCH_ENABLE | index_size); |
||
658 | PUSH_DATAh(push, va); |
||
659 | PUSH_DATA (push, va); |
||
660 | BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_LIMIT_HIGH(1)), 2); |
||
661 | PUSH_DATAh(push, va + info->count * index_size - 1); |
||
662 | PUSH_DATA (push, va + info->count * index_size - 1); |
||
663 | |||
664 | |||
665 | (((0x80 + (a) * 0x10) / 4) << NVC0_3D_VERTEX_ID_REPLACE_SOURCE__SHIFT) |
||
666 | |||
667 | |||
668 | PUSH_DATA (push, NVC0_3D_VERTEX_ID_REPLACE_SOURCE_ATTR_X(a) | 1); |
||
669 | }><>><>>>>>>>=>=>=>>>>>>>>><>>>> |
||
670 |