1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 * Interface between 'draw' module's output and the llvmpipe rasterizer/setup
30 * code. When the 'draw' module has finished filling a vertex buffer, the
31 * draw_arrays() functions below will be called. Loop over the vertices and
32 * call the point/line/tri setup functions.
39 #include "lp_context.h"
41 #include "lp_prim_vbuf.h"
42 #include "lp_prim_setup.h"
44 #include "draw/draw_context.h"
45 #include "draw/draw_vbuf.h"
46 #include "util/u_memory.h"
47 #include "util/u_prim.h"
50 #define LP_MAX_VBUF_INDEXES 1024
51 #define LP_MAX_VBUF_SIZE 4096
53 typedef const float (*cptrf4
)[4];
56 * Subclass of vbuf_render.
58 struct llvmpipe_vbuf_render
60 struct vbuf_render base
;
61 struct llvmpipe_context
*llvmpipe
;
65 uint vertex_buffer_size
;
71 static struct llvmpipe_vbuf_render
*
72 llvmpipe_vbuf_render(struct vbuf_render
*vbr
)
74 return (struct llvmpipe_vbuf_render
*) vbr
;
78 static const struct vertex_info
*
79 lp_vbuf_get_vertex_info(struct vbuf_render
*vbr
)
81 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
82 return llvmpipe_get_vbuf_vertex_info(cvbr
->llvmpipe
);
87 lp_vbuf_allocate_vertices(struct vbuf_render
*vbr
,
88 ushort vertex_size
, ushort nr_vertices
)
90 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
91 unsigned size
= vertex_size
* nr_vertices
;
93 if (cvbr
->vertex_buffer_size
< size
) {
94 align_free(cvbr
->vertex_buffer
);
95 cvbr
->vertex_buffer
= align_malloc(size
, 16);
96 cvbr
->vertex_buffer_size
= size
;
99 cvbr
->vertex_size
= vertex_size
;
100 cvbr
->nr_vertices
= nr_vertices
;
102 return cvbr
->vertex_buffer
!= NULL
;
106 lp_vbuf_release_vertices(struct vbuf_render
*vbr
)
110 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
111 const struct vertex_info
*info
=
112 llvmpipe_get_vbuf_vertex_info(cvbr
->llvmpipe
);
113 const float *vtx
= (const float *) cvbr
->vertex_buffer
;
115 debug_printf("%s (vtx_size = %u, vtx_used = %u)\n",
116 __FUNCTION__
, cvbr
->vertex_size
, cvbr
->nr_vertices
);
117 for (i
= 0; i
< cvbr
->nr_vertices
; i
++) {
118 for (j
= 0; j
< info
->num_attribs
; j
++) {
120 switch (info
->attrib
[j
].emit
) {
121 case EMIT_4F
: k
= 4; break;
122 case EMIT_3F
: k
= 3; break;
123 case EMIT_2F
: k
= 2; break;
124 case EMIT_1F
: k
= 1; break;
127 debug_printf("Vert %u attr %u: ", i
, j
);
129 debug_printf("%g ", vtx
[0]);
138 /* keep the old allocation for next time */
142 lp_vbuf_map_vertices(struct vbuf_render
*vbr
)
144 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
145 return cvbr
->vertex_buffer
;
149 lp_vbuf_unmap_vertices(struct vbuf_render
*vbr
,
153 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
154 assert( cvbr
->vertex_buffer_size
>= (max_index
+1) * cvbr
->vertex_size
);
160 lp_vbuf_set_primitive(struct vbuf_render
*vbr
, unsigned prim
)
162 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
164 /* XXX: break this dependency - make setup_context live under
165 * llvmpipe, rename the old "setup" draw stage to something else.
167 struct setup_context
*setup_ctx
= lp_draw_setup_context(cvbr
->llvmpipe
->setup
);
169 llvmpipe_setup_prepare( setup_ctx
);
171 cvbr
->llvmpipe
->reduced_prim
= u_reduced_prim(prim
);
178 static INLINE cptrf4
get_vert( const void *vertex_buffer
,
182 return (cptrf4
)((char *)vertex_buffer
+ index
* stride
);
187 * draw elements / indexed primitives
190 lp_vbuf_draw(struct vbuf_render
*vbr
, const ushort
*indices
, uint nr
)
192 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
193 struct llvmpipe_context
*llvmpipe
= cvbr
->llvmpipe
;
194 const unsigned stride
= llvmpipe
->vertex_info_vbuf
.size
* sizeof(float);
195 const void *vertex_buffer
= cvbr
->vertex_buffer
;
198 /* XXX: break this dependency - make setup_context live under
199 * llvmpipe, rename the old "setup" draw stage to something else.
201 struct draw_stage
*setup
= llvmpipe
->setup
;
202 struct setup_context
*setup_ctx
= lp_draw_setup_context(setup
);
204 switch (cvbr
->prim
) {
205 case PIPE_PRIM_POINTS
:
206 for (i
= 0; i
< nr
; i
++) {
207 llvmpipe_setup_point( setup_ctx
,
208 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
212 case PIPE_PRIM_LINES
:
213 for (i
= 1; i
< nr
; i
+= 2) {
214 llvmpipe_setup_line( setup_ctx
,
215 get_vert(vertex_buffer
, indices
[i
-1], stride
),
216 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
220 case PIPE_PRIM_LINE_STRIP
:
221 for (i
= 1; i
< nr
; i
++) {
222 llvmpipe_setup_line( setup_ctx
,
223 get_vert(vertex_buffer
, indices
[i
-1], stride
),
224 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
228 case PIPE_PRIM_LINE_LOOP
:
229 for (i
= 1; i
< nr
; i
++) {
230 llvmpipe_setup_line( setup_ctx
,
231 get_vert(vertex_buffer
, indices
[i
-1], stride
),
232 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
235 llvmpipe_setup_line( setup_ctx
,
236 get_vert(vertex_buffer
, indices
[nr
-1], stride
),
237 get_vert(vertex_buffer
, indices
[0], stride
) );
241 case PIPE_PRIM_TRIANGLES
:
242 if (llvmpipe
->rasterizer
->flatshade_first
) {
243 for (i
= 2; i
< nr
; i
+= 3) {
244 llvmpipe_setup_tri( setup_ctx
,
245 get_vert(vertex_buffer
, indices
[i
-1], stride
),
246 get_vert(vertex_buffer
, indices
[i
-0], stride
),
247 get_vert(vertex_buffer
, indices
[i
-2], stride
) );
251 for (i
= 2; i
< nr
; i
+= 3) {
252 llvmpipe_setup_tri( setup_ctx
,
253 get_vert(vertex_buffer
, indices
[i
-2], stride
),
254 get_vert(vertex_buffer
, indices
[i
-1], stride
),
255 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
260 case PIPE_PRIM_TRIANGLE_STRIP
:
261 if (llvmpipe
->rasterizer
->flatshade_first
) {
262 for (i
= 2; i
< nr
; i
+= 1) {
263 llvmpipe_setup_tri( setup_ctx
,
264 get_vert(vertex_buffer
, indices
[i
+(i
&1)-1], stride
),
265 get_vert(vertex_buffer
, indices
[i
-(i
&1)], stride
),
266 get_vert(vertex_buffer
, indices
[i
-2], stride
) );
270 for (i
= 2; i
< nr
; i
+= 1) {
271 llvmpipe_setup_tri( setup_ctx
,
272 get_vert(vertex_buffer
, indices
[i
+(i
&1)-2], stride
),
273 get_vert(vertex_buffer
, indices
[i
-(i
&1)-1], stride
),
274 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
279 case PIPE_PRIM_TRIANGLE_FAN
:
280 if (llvmpipe
->rasterizer
->flatshade_first
) {
281 for (i
= 2; i
< nr
; i
+= 1) {
282 llvmpipe_setup_tri( setup_ctx
,
283 get_vert(vertex_buffer
, indices
[i
-0], stride
),
284 get_vert(vertex_buffer
, indices
[0], stride
),
285 get_vert(vertex_buffer
, indices
[i
-1], stride
) );
289 for (i
= 2; i
< nr
; i
+= 1) {
290 llvmpipe_setup_tri( setup_ctx
,
291 get_vert(vertex_buffer
, indices
[0], stride
),
292 get_vert(vertex_buffer
, indices
[i
-1], stride
),
293 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
298 case PIPE_PRIM_QUADS
:
299 if (llvmpipe
->rasterizer
->flatshade_first
) {
300 for (i
= 3; i
< nr
; i
+= 4) {
301 llvmpipe_setup_tri( setup_ctx
,
302 get_vert(vertex_buffer
, indices
[i
-2], stride
),
303 get_vert(vertex_buffer
, indices
[i
-1], stride
),
304 get_vert(vertex_buffer
, indices
[i
-3], stride
) );
305 llvmpipe_setup_tri( setup_ctx
,
306 get_vert(vertex_buffer
, indices
[i
-1], stride
),
307 get_vert(vertex_buffer
, indices
[i
-0], stride
),
308 get_vert(vertex_buffer
, indices
[i
-3], stride
) );
312 for (i
= 3; i
< nr
; i
+= 4) {
313 llvmpipe_setup_tri( setup_ctx
,
314 get_vert(vertex_buffer
, indices
[i
-3], stride
),
315 get_vert(vertex_buffer
, indices
[i
-2], stride
),
316 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
318 llvmpipe_setup_tri( setup_ctx
,
319 get_vert(vertex_buffer
, indices
[i
-2], stride
),
320 get_vert(vertex_buffer
, indices
[i
-1], stride
),
321 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
326 case PIPE_PRIM_QUAD_STRIP
:
327 if (llvmpipe
->rasterizer
->flatshade_first
) {
328 for (i
= 3; i
< nr
; i
+= 2) {
329 llvmpipe_setup_tri( setup_ctx
,
330 get_vert(vertex_buffer
, indices
[i
-0], stride
),
331 get_vert(vertex_buffer
, indices
[i
-1], stride
),
332 get_vert(vertex_buffer
, indices
[i
-3], stride
));
333 llvmpipe_setup_tri( setup_ctx
,
334 get_vert(vertex_buffer
, indices
[i
-2], stride
),
335 get_vert(vertex_buffer
, indices
[i
-0], stride
),
336 get_vert(vertex_buffer
, indices
[i
-3], stride
) );
340 for (i
= 3; i
< nr
; i
+= 2) {
341 llvmpipe_setup_tri( setup_ctx
,
342 get_vert(vertex_buffer
, indices
[i
-3], stride
),
343 get_vert(vertex_buffer
, indices
[i
-2], stride
),
344 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
345 llvmpipe_setup_tri( setup_ctx
,
346 get_vert(vertex_buffer
, indices
[i
-1], stride
),
347 get_vert(vertex_buffer
, indices
[i
-3], stride
),
348 get_vert(vertex_buffer
, indices
[i
-0], stride
) );
353 case PIPE_PRIM_POLYGON
:
354 /* Almost same as tri fan but the _first_ vertex specifies the flat
355 * shading color. Note that the first polygon vertex is passed as
356 * the last triangle vertex here.
357 * flatshade_first state makes no difference.
359 for (i
= 2; i
< nr
; i
+= 1) {
360 llvmpipe_setup_tri( setup_ctx
,
361 get_vert(vertex_buffer
, indices
[i
-0], stride
),
362 get_vert(vertex_buffer
, indices
[i
-1], stride
),
363 get_vert(vertex_buffer
, indices
[0], stride
) );
371 /* XXX: why are we calling this??? If we had to call something, it
372 * would be a function in lp_setup.c:
374 lp_draw_flush( setup
);
379 * This function is hit when the draw module is working in pass-through mode.
380 * It's up to us to convert the vertex array into point/line/tri prims.
383 lp_vbuf_draw_arrays(struct vbuf_render
*vbr
, uint start
, uint nr
)
385 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
386 struct llvmpipe_context
*llvmpipe
= cvbr
->llvmpipe
;
387 const unsigned stride
= llvmpipe
->vertex_info_vbuf
.size
* sizeof(float);
388 const void *vertex_buffer
=
389 (void *) get_vert(cvbr
->vertex_buffer
, start
, stride
);
392 /* XXX: break this dependency - make setup_context live under
393 * llvmpipe, rename the old "setup" draw stage to something else.
395 struct draw_stage
*setup
= llvmpipe
->setup
;
396 struct setup_context
*setup_ctx
= lp_draw_setup_context(setup
);
398 switch (cvbr
->prim
) {
399 case PIPE_PRIM_POINTS
:
400 for (i
= 0; i
< nr
; i
++) {
401 llvmpipe_setup_point( setup_ctx
,
402 get_vert(vertex_buffer
, i
-0, stride
) );
406 case PIPE_PRIM_LINES
:
407 for (i
= 1; i
< nr
; i
+= 2) {
408 llvmpipe_setup_line( setup_ctx
,
409 get_vert(vertex_buffer
, i
-1, stride
),
410 get_vert(vertex_buffer
, i
-0, stride
) );
414 case PIPE_PRIM_LINE_STRIP
:
415 for (i
= 1; i
< nr
; i
++) {
416 llvmpipe_setup_line( setup_ctx
,
417 get_vert(vertex_buffer
, i
-1, stride
),
418 get_vert(vertex_buffer
, i
-0, stride
) );
422 case PIPE_PRIM_LINE_LOOP
:
423 for (i
= 1; i
< nr
; i
++) {
424 llvmpipe_setup_line( setup_ctx
,
425 get_vert(vertex_buffer
, i
-1, stride
),
426 get_vert(vertex_buffer
, i
-0, stride
) );
429 llvmpipe_setup_line( setup_ctx
,
430 get_vert(vertex_buffer
, nr
-1, stride
),
431 get_vert(vertex_buffer
, 0, stride
) );
435 case PIPE_PRIM_TRIANGLES
:
436 if (llvmpipe
->rasterizer
->flatshade_first
) {
437 for (i
= 2; i
< nr
; i
+= 3) {
438 llvmpipe_setup_tri( setup_ctx
,
439 get_vert(vertex_buffer
, i
-1, stride
),
440 get_vert(vertex_buffer
, i
-0, stride
),
441 get_vert(vertex_buffer
, i
-2, stride
) );
445 for (i
= 2; i
< nr
; i
+= 3) {
446 llvmpipe_setup_tri( setup_ctx
,
447 get_vert(vertex_buffer
, i
-2, stride
),
448 get_vert(vertex_buffer
, i
-1, stride
),
449 get_vert(vertex_buffer
, i
-0, stride
) );
454 case PIPE_PRIM_TRIANGLE_STRIP
:
455 if (llvmpipe
->rasterizer
->flatshade_first
) {
456 for (i
= 2; i
< nr
; i
++) {
457 llvmpipe_setup_tri( setup_ctx
,
458 get_vert(vertex_buffer
, i
+(i
&1)-1, stride
),
459 get_vert(vertex_buffer
, i
-(i
&1), stride
),
460 get_vert(vertex_buffer
, i
-2, stride
) );
464 for (i
= 2; i
< nr
; i
++) {
465 llvmpipe_setup_tri( setup_ctx
,
466 get_vert(vertex_buffer
, i
+(i
&1)-2, stride
),
467 get_vert(vertex_buffer
, i
-(i
&1)-1, stride
),
468 get_vert(vertex_buffer
, i
-0, stride
) );
473 case PIPE_PRIM_TRIANGLE_FAN
:
474 if (llvmpipe
->rasterizer
->flatshade_first
) {
475 for (i
= 2; i
< nr
; i
+= 1) {
476 llvmpipe_setup_tri( setup_ctx
,
477 get_vert(vertex_buffer
, i
-0, stride
),
478 get_vert(vertex_buffer
, 0, stride
),
479 get_vert(vertex_buffer
, i
-1, stride
) );
483 for (i
= 2; i
< nr
; i
+= 1) {
484 llvmpipe_setup_tri( setup_ctx
,
485 get_vert(vertex_buffer
, 0, stride
),
486 get_vert(vertex_buffer
, i
-1, stride
),
487 get_vert(vertex_buffer
, i
-0, stride
) );
492 case PIPE_PRIM_QUADS
:
493 if (llvmpipe
->rasterizer
->flatshade_first
) {
494 for (i
= 3; i
< nr
; i
+= 4) {
495 llvmpipe_setup_tri( setup_ctx
,
496 get_vert(vertex_buffer
, i
-2, stride
),
497 get_vert(vertex_buffer
, i
-1, stride
),
498 get_vert(vertex_buffer
, i
-3, stride
) );
499 llvmpipe_setup_tri( setup_ctx
,
500 get_vert(vertex_buffer
, i
-1, stride
),
501 get_vert(vertex_buffer
, i
-0, stride
),
502 get_vert(vertex_buffer
, i
-3, stride
) );
506 for (i
= 3; i
< nr
; i
+= 4) {
507 llvmpipe_setup_tri( setup_ctx
,
508 get_vert(vertex_buffer
, i
-3, stride
),
509 get_vert(vertex_buffer
, i
-2, stride
),
510 get_vert(vertex_buffer
, i
-0, stride
) );
511 llvmpipe_setup_tri( setup_ctx
,
512 get_vert(vertex_buffer
, i
-2, stride
),
513 get_vert(vertex_buffer
, i
-1, stride
),
514 get_vert(vertex_buffer
, i
-0, stride
) );
519 case PIPE_PRIM_QUAD_STRIP
:
520 if (llvmpipe
->rasterizer
->flatshade_first
) {
521 for (i
= 3; i
< nr
; i
+= 2) {
522 llvmpipe_setup_tri( setup_ctx
,
523 get_vert(vertex_buffer
, i
-0, stride
),
524 get_vert(vertex_buffer
, i
-1, stride
),
525 get_vert(vertex_buffer
, i
-3, stride
) );
526 llvmpipe_setup_tri( setup_ctx
,
527 get_vert(vertex_buffer
, i
-2, stride
),
528 get_vert(vertex_buffer
, i
-0, stride
),
529 get_vert(vertex_buffer
, i
-3, stride
) );
533 for (i
= 3; i
< nr
; i
+= 2) {
534 llvmpipe_setup_tri( setup_ctx
,
535 get_vert(vertex_buffer
, i
-3, stride
),
536 get_vert(vertex_buffer
, i
-2, stride
),
537 get_vert(vertex_buffer
, i
-0, stride
) );
538 llvmpipe_setup_tri( setup_ctx
,
539 get_vert(vertex_buffer
, i
-1, stride
),
540 get_vert(vertex_buffer
, i
-3, stride
),
541 get_vert(vertex_buffer
, i
-0, stride
) );
546 case PIPE_PRIM_POLYGON
:
547 /* Almost same as tri fan but the _first_ vertex specifies the flat
548 * shading color. Note that the first polygon vertex is passed as
549 * the last triangle vertex here.
550 * flatshade_first state makes no difference.
552 for (i
= 2; i
< nr
; i
+= 1) {
553 llvmpipe_setup_tri( setup_ctx
,
554 get_vert(vertex_buffer
, i
-1, stride
),
555 get_vert(vertex_buffer
, i
-0, stride
),
556 get_vert(vertex_buffer
, 0, stride
) );
568 lp_vbuf_destroy(struct vbuf_render
*vbr
)
570 struct llvmpipe_vbuf_render
*cvbr
= llvmpipe_vbuf_render(vbr
);
571 cvbr
->llvmpipe
->vbuf_render
= NULL
;
577 * Initialize the post-transform vertex buffer information for the given
581 lp_init_vbuf(struct llvmpipe_context
*lp
)
585 lp
->vbuf_render
= CALLOC_STRUCT(llvmpipe_vbuf_render
);
587 lp
->vbuf_render
->base
.max_indices
= LP_MAX_VBUF_INDEXES
;
588 lp
->vbuf_render
->base
.max_vertex_buffer_bytes
= LP_MAX_VBUF_SIZE
;
590 lp
->vbuf_render
->base
.get_vertex_info
= lp_vbuf_get_vertex_info
;
591 lp
->vbuf_render
->base
.allocate_vertices
= lp_vbuf_allocate_vertices
;
592 lp
->vbuf_render
->base
.map_vertices
= lp_vbuf_map_vertices
;
593 lp
->vbuf_render
->base
.unmap_vertices
= lp_vbuf_unmap_vertices
;
594 lp
->vbuf_render
->base
.set_primitive
= lp_vbuf_set_primitive
;
595 lp
->vbuf_render
->base
.draw
= lp_vbuf_draw
;
596 lp
->vbuf_render
->base
.draw_arrays
= lp_vbuf_draw_arrays
;
597 lp
->vbuf_render
->base
.release_vertices
= lp_vbuf_release_vertices
;
598 lp
->vbuf_render
->base
.destroy
= lp_vbuf_destroy
;
600 lp
->vbuf_render
->llvmpipe
= lp
;
602 lp
->vbuf
= draw_vbuf_stage(lp
->draw
, &lp
->vbuf_render
->base
);
604 draw_set_rasterize_stage(lp
->draw
, lp
->vbuf
);
606 draw_set_render(lp
->draw
, &lp
->vbuf_render
->base
);