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 * \brief Primitive rasterization/rendering (points, lines, triangles)
31 * \author Keith Whitwell <keith@tungstengraphics.com>
35 #include "lp_context.h"
36 #include "lp_prim_setup.h"
38 #include "lp_quad_pipe.h"
41 #include "draw/draw_context.h"
42 #include "draw/draw_private.h"
43 #include "draw/draw_vertex.h"
44 #include "pipe/p_shader_tokens.h"
45 #include "pipe/p_thread.h"
46 #include "util/u_math.h"
47 #include "util/u_memory.h"
57 float dx
; /**< X(v1) - X(v0), used only during setup */
58 float dy
; /**< Y(v1) - Y(v0), used only during setup */
59 float dxdy
; /**< dx/dy */
60 float sx
, sy
; /**< first sample point coord */
61 int lines
; /**< number of lines on this edge */
69 * Triangle setup info (derived from draw_stage).
70 * Also used for line drawing (taking some liberties).
72 struct setup_context
{
73 struct llvmpipe_context
*llvmpipe
;
75 /* Vertices are just an array of floats making up each attribute in
76 * turn. Currently fixed at 4 floats, but should change in time.
77 * Codegen will help cope with this.
79 const float (*vmax
)[4];
80 const float (*vmid
)[4];
81 const float (*vmin
)[4];
82 const float (*vprovoke
)[4];
91 struct quad_header quad
[MAX_QUADS
];
92 struct quad_header
*quad_ptrs
[MAX_QUADS
];
95 struct tgsi_interp_coef coef
[PIPE_MAX_SHADER_INPUTS
];
96 struct tgsi_interp_coef posCoef
; /* For Z, W */
99 int left
[2]; /**< [0] = row0, [1] = row1 */
105 uint numFragsEmitted
; /**< per primitive */
106 uint numFragsWritten
; /**< per primitive */
109 unsigned winding
; /* which winding to cull */
116 * Do triangle cull test using tri determinant (sign indicates orientation)
117 * \return true if triangle is to be culled.
119 static INLINE boolean
120 cull_tri(const struct setup_context
*setup
, float det
)
123 /* if (det < 0 then Z points toward camera and triangle is
124 * counter-clockwise winding.
126 unsigned winding
= (det
< 0) ? PIPE_WINDING_CCW
: PIPE_WINDING_CW
;
128 if ((winding
& setup
->winding
) == 0)
140 * Clip setup->quad against the scissor/surface bounds.
143 quad_clip( struct setup_context
*setup
, struct quad_header
*quad
)
145 const struct pipe_scissor_state
*cliprect
= &setup
->llvmpipe
->cliprect
;
146 const int minx
= (int) cliprect
->minx
;
147 const int maxx
= (int) cliprect
->maxx
;
148 const int miny
= (int) cliprect
->miny
;
149 const int maxy
= (int) cliprect
->maxy
;
151 if (quad
->input
.x0
>= maxx
||
152 quad
->input
.y0
>= maxy
||
153 quad
->input
.x0
+ 1 < minx
||
154 quad
->input
.y0
+ 1 < miny
) {
155 /* totally clipped */
156 quad
->inout
.mask
= 0x0;
159 if (quad
->input
.x0
< minx
)
160 quad
->inout
.mask
&= (MASK_BOTTOM_RIGHT
| MASK_TOP_RIGHT
);
161 if (quad
->input
.y0
< miny
)
162 quad
->inout
.mask
&= (MASK_BOTTOM_LEFT
| MASK_BOTTOM_RIGHT
);
163 if (quad
->input
.x0
== maxx
- 1)
164 quad
->inout
.mask
&= (MASK_BOTTOM_LEFT
| MASK_TOP_LEFT
);
165 if (quad
->input
.y0
== maxy
- 1)
166 quad
->inout
.mask
&= (MASK_TOP_LEFT
| MASK_TOP_RIGHT
);
171 * Emit a quad (pass to next stage) with clipping.
174 clip_emit_quad( struct setup_context
*setup
, struct quad_header
*quad
)
176 quad_clip( setup
, quad
);
178 if (quad
->inout
.mask
) {
179 struct llvmpipe_context
*lp
= setup
->llvmpipe
;
181 lp
->quad
.first
->run( lp
->quad
.first
, &quad
, 1 );
188 * Given an X or Y coordinate, return the block/quad coordinate that it
191 static INLINE
int block( int x
)
196 static INLINE
int block_x( int x
)
203 * Render a horizontal span of quads
205 static void flush_spans( struct setup_context
*setup
)
208 const int xleft0
= setup
->span
.left
[0];
209 const int xleft1
= setup
->span
.left
[1];
210 const int xright0
= setup
->span
.right
[0];
211 const int xright1
= setup
->span
.right
[1];
212 struct quad_stage
*pipe
= setup
->llvmpipe
->quad
.first
;
215 int minleft
= block_x(MIN2(xleft0
, xleft1
));
216 int maxright
= MAX2(xright0
, xright1
);
219 for (x
= minleft
; x
< maxright
; x
+= step
) {
220 unsigned skip_left0
= CLAMP(xleft0
- x
, 0, step
);
221 unsigned skip_left1
= CLAMP(xleft1
- x
, 0, step
);
222 unsigned skip_right0
= CLAMP(x
+ step
- xright0
, 0, step
);
223 unsigned skip_right1
= CLAMP(x
+ step
- xright1
, 0, step
);
227 unsigned skipmask_left0
= (1U << skip_left0
) - 1U;
228 unsigned skipmask_left1
= (1U << skip_left1
) - 1U;
230 /* These calculations fail when step == 32 and skip_right == 0.
232 unsigned skipmask_right0
= ~0U << (unsigned)(step
- skip_right0
);
233 unsigned skipmask_right1
= ~0U << (unsigned)(step
- skip_right1
);
235 unsigned mask0
= ~skipmask_left0
& ~skipmask_right0
;
236 unsigned mask1
= ~skipmask_left1
& ~skipmask_right1
;
240 unsigned quadmask
= (mask0
& 3) | ((mask1
& 3) << 2);
242 setup
->quad
[q
].input
.x0
= lx
;
243 setup
->quad
[q
].input
.y0
= setup
->span
.y
;
244 setup
->quad
[q
].inout
.mask
= quadmask
;
245 setup
->quad_ptrs
[q
] = &setup
->quad
[q
];
251 } while (mask0
| mask1
);
253 pipe
->run( pipe
, setup
->quad_ptrs
, q
);
259 setup
->span
.right
[0] = 0;
260 setup
->span
.right
[1] = 0;
261 setup
->span
.left
[0] = 1000000; /* greater than right[0] */
262 setup
->span
.left
[1] = 1000000; /* greater than right[1] */
267 static void print_vertex(const struct setup_context
*setup
,
271 debug_printf(" Vertex: (%p)\n", v
);
272 for (i
= 0; i
< setup
->quad
[0].nr_attrs
; i
++) {
273 debug_printf(" %d: %f %f %f %f\n", i
,
274 v
[i
][0], v
[i
][1], v
[i
][2], v
[i
][3]);
275 if (util_is_inf_or_nan(v
[i
][0])) {
276 debug_printf(" NaN!\n");
283 * Sort the vertices from top to bottom order, setting up the triangle
284 * edge fields (ebot, emaj, etop).
285 * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise
287 static boolean
setup_sort_vertices( struct setup_context
*setup
,
289 const float (*v0
)[4],
290 const float (*v1
)[4],
291 const float (*v2
)[4] )
293 setup
->vprovoke
= v2
;
295 /* determine bottom to top order of vertices */
342 setup
->ebot
.dx
= setup
->vmid
[0][0] - setup
->vmin
[0][0];
343 setup
->ebot
.dy
= setup
->vmid
[0][1] - setup
->vmin
[0][1];
344 setup
->emaj
.dx
= setup
->vmax
[0][0] - setup
->vmin
[0][0];
345 setup
->emaj
.dy
= setup
->vmax
[0][1] - setup
->vmin
[0][1];
346 setup
->etop
.dx
= setup
->vmax
[0][0] - setup
->vmid
[0][0];
347 setup
->etop
.dy
= setup
->vmax
[0][1] - setup
->vmid
[0][1];
350 * Compute triangle's area. Use 1/area to compute partial
351 * derivatives of attributes later.
353 * The area will be the same as prim->det, but the sign may be
354 * different depending on how the vertices get sorted above.
356 * To determine whether the primitive is front or back facing we
357 * use the prim->det value because its sign is correct.
360 const float area
= (setup
->emaj
.dx
* setup
->ebot
.dy
-
361 setup
->ebot
.dx
* setup
->emaj
.dy
);
363 setup
->oneoverarea
= 1.0f
/ area
;
366 debug_printf("%s one-over-area %f area %f det %f\n",
367 __FUNCTION__, setup->oneoverarea, area, det );
369 if (util_is_inf_or_nan(setup
->oneoverarea
))
373 /* We need to know if this is a front or back-facing triangle for:
374 * - the GLSL gl_FrontFacing fragment attribute (bool)
375 * - two-sided stencil test
379 (setup
->llvmpipe
->rasterizer
->front_winding
== PIPE_WINDING_CW
));
386 * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
387 * The value value comes from vertex[slot][i].
388 * The result will be put into setup->coef[slot].a0[i].
389 * \param slot which attribute slot
390 * \param i which component of the slot (0..3)
392 static void const_coeff( struct setup_context
*setup
,
393 struct tgsi_interp_coef
*coef
,
394 uint vertSlot
, uint i
)
401 /* need provoking vertex info!
403 coef
->a0
[i
] = setup
->vprovoke
[vertSlot
][i
];
408 * Compute a0, dadx and dady for a linearly interpolated coefficient,
411 static void tri_linear_coeff( struct setup_context
*setup
,
412 struct tgsi_interp_coef
*coef
,
413 uint vertSlot
, uint i
)
415 float botda
= setup
->vmid
[vertSlot
][i
] - setup
->vmin
[vertSlot
][i
];
416 float majda
= setup
->vmax
[vertSlot
][i
] - setup
->vmin
[vertSlot
][i
];
417 float a
= setup
->ebot
.dy
* majda
- botda
* setup
->emaj
.dy
;
418 float b
= setup
->emaj
.dx
* botda
- majda
* setup
->ebot
.dx
;
419 float dadx
= a
* setup
->oneoverarea
;
420 float dady
= b
* setup
->oneoverarea
;
424 coef
->dadx
[i
] = dadx
;
425 coef
->dady
[i
] = dady
;
427 /* calculate a0 as the value which would be sampled for the
428 * fragment at (0,0), taking into account that we want to sample at
429 * pixel centers, in other words (0.5, 0.5).
431 * this is neat but unfortunately not a good way to do things for
432 * triangles with very large values of dadx or dady as it will
433 * result in the subtraction and re-addition from a0 of a very
434 * large number, which means we'll end up loosing a lot of the
435 * fractional bits and precision from a0. the way to fix this is
436 * to define a0 as the sample at a pixel center somewhere near vmin
437 * instead - i'll switch to this later.
439 coef
->a0
[i
] = (setup
->vmin
[vertSlot
][i
] -
440 (dadx
* (setup
->vmin
[0][0] - 0.5f
) +
441 dady
* (setup
->vmin
[0][1] - 0.5f
)));
444 debug_printf("attr[%d].%c: %f dx:%f dy:%f\n",
446 setup->coef[slot].a0[i],
447 setup->coef[slot].dadx[i],
448 setup->coef[slot].dady[i]);
454 * Compute a0, dadx and dady for a perspective-corrected interpolant,
456 * We basically multiply the vertex value by 1/w before computing
457 * the plane coefficients (a0, dadx, dady).
458 * Later, when we compute the value at a particular fragment position we'll
459 * divide the interpolated value by the interpolated W at that fragment.
461 static void tri_persp_coeff( struct setup_context
*setup
,
462 struct tgsi_interp_coef
*coef
,
463 uint vertSlot
, uint i
)
465 /* premultiply by 1/w (v[0][3] is always W):
467 float mina
= setup
->vmin
[vertSlot
][i
] * setup
->vmin
[0][3];
468 float mida
= setup
->vmid
[vertSlot
][i
] * setup
->vmid
[0][3];
469 float maxa
= setup
->vmax
[vertSlot
][i
] * setup
->vmax
[0][3];
470 float botda
= mida
- mina
;
471 float majda
= maxa
- mina
;
472 float a
= setup
->ebot
.dy
* majda
- botda
* setup
->emaj
.dy
;
473 float b
= setup
->emaj
.dx
* botda
- majda
* setup
->ebot
.dx
;
474 float dadx
= a
* setup
->oneoverarea
;
475 float dady
= b
* setup
->oneoverarea
;
478 debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i,
479 setup->vmin[vertSlot][i],
480 setup->vmid[vertSlot][i],
481 setup->vmax[vertSlot][i]
486 coef
->dadx
[i
] = dadx
;
487 coef
->dady
[i
] = dady
;
488 coef
->a0
[i
] = (mina
-
489 (dadx
* (setup
->vmin
[0][0] - 0.5f
) +
490 dady
* (setup
->vmin
[0][1] - 0.5f
)));
495 * Special coefficient setup for gl_FragCoord.
496 * X and Y are trivial, though Y has to be inverted for OpenGL.
497 * Z and W are copied from posCoef which should have already been computed.
498 * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
501 setup_fragcoord_coeff(struct setup_context
*setup
, uint slot
)
504 setup
->coef
[slot
].a0
[0] = 0;
505 setup
->coef
[slot
].dadx
[0] = 1.0;
506 setup
->coef
[slot
].dady
[0] = 0.0;
508 setup
->coef
[slot
].a0
[1] = 0.0;
509 setup
->coef
[slot
].dadx
[1] = 0.0;
510 setup
->coef
[slot
].dady
[1] = 1.0;
512 setup
->coef
[slot
].a0
[2] = setup
->posCoef
.a0
[2];
513 setup
->coef
[slot
].dadx
[2] = setup
->posCoef
.dadx
[2];
514 setup
->coef
[slot
].dady
[2] = setup
->posCoef
.dady
[2];
516 setup
->coef
[slot
].a0
[3] = setup
->posCoef
.a0
[3];
517 setup
->coef
[slot
].dadx
[3] = setup
->posCoef
.dadx
[3];
518 setup
->coef
[slot
].dady
[3] = setup
->posCoef
.dady
[3];
524 * Compute the setup->coef[] array dadx, dady, a0 values.
525 * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
527 static void setup_tri_coefficients( struct setup_context
*setup
)
529 struct llvmpipe_context
*llvmpipe
= setup
->llvmpipe
;
530 const struct lp_fragment_shader
*lpfs
= llvmpipe
->fs
;
531 const struct vertex_info
*vinfo
= llvmpipe_get_vertex_info(llvmpipe
);
534 /* z and w are done by linear interpolation:
536 tri_linear_coeff(setup
, &setup
->posCoef
, 0, 2);
537 tri_linear_coeff(setup
, &setup
->posCoef
, 0, 3);
539 /* setup interpolation for all the remaining attributes:
541 for (fragSlot
= 0; fragSlot
< lpfs
->info
.num_inputs
; fragSlot
++) {
542 const uint vertSlot
= vinfo
->attrib
[fragSlot
].src_index
;
545 switch (vinfo
->attrib
[fragSlot
].interp_mode
) {
546 case INTERP_CONSTANT
:
547 for (j
= 0; j
< NUM_CHANNELS
; j
++)
548 const_coeff(setup
, &setup
->coef
[fragSlot
], vertSlot
, j
);
551 for (j
= 0; j
< NUM_CHANNELS
; j
++)
552 tri_linear_coeff(setup
, &setup
->coef
[fragSlot
], vertSlot
, j
);
554 case INTERP_PERSPECTIVE
:
555 for (j
= 0; j
< NUM_CHANNELS
; j
++)
556 tri_persp_coeff(setup
, &setup
->coef
[fragSlot
], vertSlot
, j
);
559 setup_fragcoord_coeff(setup
, fragSlot
);
565 if (lpfs
->info
.input_semantic_name
[fragSlot
] == TGSI_SEMANTIC_FACE
) {
566 setup
->coef
[fragSlot
].a0
[0] = 1.0f
- setup
->facing
;
567 setup
->coef
[fragSlot
].dadx
[0] = 0.0;
568 setup
->coef
[fragSlot
].dady
[0] = 0.0;
575 static void setup_tri_edges( struct setup_context
*setup
)
577 float vmin_x
= setup
->vmin
[0][0] + 0.5f
;
578 float vmid_x
= setup
->vmid
[0][0] + 0.5f
;
580 float vmin_y
= setup
->vmin
[0][1] - 0.5f
;
581 float vmid_y
= setup
->vmid
[0][1] - 0.5f
;
582 float vmax_y
= setup
->vmax
[0][1] - 0.5f
;
584 setup
->emaj
.sy
= ceilf(vmin_y
);
585 setup
->emaj
.lines
= (int) ceilf(vmax_y
- setup
->emaj
.sy
);
586 setup
->emaj
.dxdy
= setup
->emaj
.dx
/ setup
->emaj
.dy
;
587 setup
->emaj
.sx
= vmin_x
+ (setup
->emaj
.sy
- vmin_y
) * setup
->emaj
.dxdy
;
589 setup
->etop
.sy
= ceilf(vmid_y
);
590 setup
->etop
.lines
= (int) ceilf(vmax_y
- setup
->etop
.sy
);
591 setup
->etop
.dxdy
= setup
->etop
.dx
/ setup
->etop
.dy
;
592 setup
->etop
.sx
= vmid_x
+ (setup
->etop
.sy
- vmid_y
) * setup
->etop
.dxdy
;
594 setup
->ebot
.sy
= ceilf(vmin_y
);
595 setup
->ebot
.lines
= (int) ceilf(vmid_y
- setup
->ebot
.sy
);
596 setup
->ebot
.dxdy
= setup
->ebot
.dx
/ setup
->ebot
.dy
;
597 setup
->ebot
.sx
= vmin_x
+ (setup
->ebot
.sy
- vmin_y
) * setup
->ebot
.dxdy
;
602 * Render the upper or lower half of a triangle.
603 * Scissoring/cliprect is applied here too.
605 static void subtriangle( struct setup_context
*setup
,
610 const struct pipe_scissor_state
*cliprect
= &setup
->llvmpipe
->cliprect
;
611 const int minx
= (int) cliprect
->minx
;
612 const int maxx
= (int) cliprect
->maxx
;
613 const int miny
= (int) cliprect
->miny
;
614 const int maxy
= (int) cliprect
->maxy
;
615 int y
, start_y
, finish_y
;
616 int sy
= (int)eleft
->sy
;
618 assert((int)eleft
->sy
== (int) eright
->sy
);
620 /* clip top/bottom */
625 finish_y
= sy
+ lines
;
633 debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y);
636 for (y
= start_y
; y
< finish_y
; y
++) {
638 /* avoid accumulating adds as floats don't have the precision to
639 * accurately iterate large triangle edges that way. luckily we
640 * can just multiply these days.
642 * this is all drowned out by the attribute interpolation anyway.
644 int left
= (int)(eleft
->sx
+ y
* eleft
->dxdy
);
645 int right
= (int)(eright
->sx
+ y
* eright
->dxdy
);
647 /* clip left/right */
655 if (block(_y
) != setup
->span
.y
) {
657 setup
->span
.y
= block(_y
);
660 setup
->span
.left
[_y
&1] = left
;
661 setup
->span
.right
[_y
&1] = right
;
666 /* save the values so that emaj can be restarted:
668 eleft
->sx
+= lines
* eleft
->dxdy
;
669 eright
->sx
+= lines
* eright
->dxdy
;
676 * Recalculate prim's determinant. This is needed as we don't have
677 * get this information through the vbuf_render interface & we must
681 calc_det( const float (*v0
)[4],
682 const float (*v1
)[4],
683 const float (*v2
)[4] )
685 /* edge vectors e = v0 - v2, f = v1 - v2 */
686 const float ex
= v0
[0][0] - v2
[0][0];
687 const float ey
= v0
[0][1] - v2
[0][1];
688 const float fx
= v1
[0][0] - v2
[0][0];
689 const float fy
= v1
[0][1] - v2
[0][1];
691 /* det = cross(e,f).z */
692 return ex
* fy
- ey
* fx
;
697 * Do setup for triangle rasterization, then render the triangle.
699 void setup_tri( struct setup_context
*setup
,
700 const float (*v0
)[4],
701 const float (*v1
)[4],
702 const float (*v2
)[4] )
707 debug_printf("Setup triangle:\n");
708 print_vertex(setup
, v0
);
709 print_vertex(setup
, v1
);
710 print_vertex(setup
, v2
);
713 if (setup
->llvmpipe
->no_rast
)
716 det
= calc_det(v0
, v1
, v2
);
718 debug_printf("%s\n", __FUNCTION__ );
722 setup
->numFragsEmitted
= 0;
723 setup
->numFragsWritten
= 0;
726 if (cull_tri( setup
, det
))
729 if (!setup_sort_vertices( setup
, det
, v0
, v1
, v2
))
731 setup_tri_coefficients( setup
);
732 setup_tri_edges( setup
);
734 assert(setup
->llvmpipe
->reduced_prim
== PIPE_PRIM_TRIANGLES
);
737 setup
->span
.right
[0] = 0;
738 setup
->span
.right
[1] = 0;
739 /* setup->span.z_mode = tri_z_mode( setup->ctx ); */
741 /* init_constant_attribs( setup ); */
743 if (setup
->oneoverarea
< 0.0) {
746 subtriangle( setup
, &setup
->emaj
, &setup
->ebot
, setup
->ebot
.lines
);
747 subtriangle( setup
, &setup
->emaj
, &setup
->etop
, setup
->etop
.lines
);
752 subtriangle( setup
, &setup
->ebot
, &setup
->emaj
, setup
->ebot
.lines
);
753 subtriangle( setup
, &setup
->etop
, &setup
->emaj
, setup
->etop
.lines
);
756 flush_spans( setup
);
759 printf("Tri: %u frags emitted, %u written\n",
760 setup
->numFragsEmitted
,
761 setup
->numFragsWritten
);
768 * Compute a0, dadx and dady for a linearly interpolated coefficient,
772 line_linear_coeff(const struct setup_context
*setup
,
773 struct tgsi_interp_coef
*coef
,
774 uint vertSlot
, uint i
)
776 const float da
= setup
->vmax
[vertSlot
][i
] - setup
->vmin
[vertSlot
][i
];
777 const float dadx
= da
* setup
->emaj
.dx
* setup
->oneoverarea
;
778 const float dady
= da
* setup
->emaj
.dy
* setup
->oneoverarea
;
779 coef
->dadx
[i
] = dadx
;
780 coef
->dady
[i
] = dady
;
781 coef
->a0
[i
] = (setup
->vmin
[vertSlot
][i
] -
782 (dadx
* (setup
->vmin
[0][0] - 0.5f
) +
783 dady
* (setup
->vmin
[0][1] - 0.5f
)));
788 * Compute a0, dadx and dady for a perspective-corrected interpolant,
792 line_persp_coeff(const struct setup_context
*setup
,
793 struct tgsi_interp_coef
*coef
,
794 uint vertSlot
, uint i
)
796 /* XXX double-check/verify this arithmetic */
797 const float a0
= setup
->vmin
[vertSlot
][i
] * setup
->vmin
[0][3];
798 const float a1
= setup
->vmax
[vertSlot
][i
] * setup
->vmax
[0][3];
799 const float da
= a1
- a0
;
800 const float dadx
= da
* setup
->emaj
.dx
* setup
->oneoverarea
;
801 const float dady
= da
* setup
->emaj
.dy
* setup
->oneoverarea
;
802 coef
->dadx
[i
] = dadx
;
803 coef
->dady
[i
] = dady
;
804 coef
->a0
[i
] = (setup
->vmin
[vertSlot
][i
] -
805 (dadx
* (setup
->vmin
[0][0] - 0.5f
) +
806 dady
* (setup
->vmin
[0][1] - 0.5f
)));
811 * Compute the setup->coef[] array dadx, dady, a0 values.
812 * Must be called after setup->vmin,vmax are initialized.
814 static INLINE boolean
815 setup_line_coefficients(struct setup_context
*setup
,
816 const float (*v0
)[4],
817 const float (*v1
)[4])
819 struct llvmpipe_context
*llvmpipe
= setup
->llvmpipe
;
820 const struct lp_fragment_shader
*lpfs
= llvmpipe
->fs
;
821 const struct vertex_info
*vinfo
= llvmpipe_get_vertex_info(llvmpipe
);
825 /* use setup->vmin, vmax to point to vertices */
826 if (llvmpipe
->rasterizer
->flatshade_first
)
827 setup
->vprovoke
= v0
;
829 setup
->vprovoke
= v1
;
833 setup
->emaj
.dx
= setup
->vmax
[0][0] - setup
->vmin
[0][0];
834 setup
->emaj
.dy
= setup
->vmax
[0][1] - setup
->vmin
[0][1];
836 /* NOTE: this is not really area but something proportional to it */
837 area
= setup
->emaj
.dx
* setup
->emaj
.dx
+ setup
->emaj
.dy
* setup
->emaj
.dy
;
838 if (area
== 0.0f
|| util_is_inf_or_nan(area
))
840 setup
->oneoverarea
= 1.0f
/ area
;
842 /* z and w are done by linear interpolation:
844 line_linear_coeff(setup
, &setup
->posCoef
, 0, 2);
845 line_linear_coeff(setup
, &setup
->posCoef
, 0, 3);
847 /* setup interpolation for all the remaining attributes:
849 for (fragSlot
= 0; fragSlot
< lpfs
->info
.num_inputs
; fragSlot
++) {
850 const uint vertSlot
= vinfo
->attrib
[fragSlot
].src_index
;
853 switch (vinfo
->attrib
[fragSlot
].interp_mode
) {
854 case INTERP_CONSTANT
:
855 for (j
= 0; j
< NUM_CHANNELS
; j
++)
856 const_coeff(setup
, &setup
->coef
[fragSlot
], vertSlot
, j
);
859 for (j
= 0; j
< NUM_CHANNELS
; j
++)
860 line_linear_coeff(setup
, &setup
->coef
[fragSlot
], vertSlot
, j
);
862 case INTERP_PERSPECTIVE
:
863 for (j
= 0; j
< NUM_CHANNELS
; j
++)
864 line_persp_coeff(setup
, &setup
->coef
[fragSlot
], vertSlot
, j
);
867 setup_fragcoord_coeff(setup
, fragSlot
);
873 if (lpfs
->info
.input_semantic_name
[fragSlot
] == TGSI_SEMANTIC_FACE
) {
874 setup
->coef
[fragSlot
].a0
[0] = 1.0f
- setup
->facing
;
875 setup
->coef
[fragSlot
].dadx
[0] = 0.0;
876 setup
->coef
[fragSlot
].dady
[0] = 0.0;
884 * Plot a pixel in a line segment.
887 plot(struct setup_context
*setup
, int x
, int y
)
889 const int iy
= y
& 1;
890 const int ix
= x
& 1;
891 const int quadX
= x
- ix
;
892 const int quadY
= y
- iy
;
893 const int mask
= (1 << ix
) << (2 * iy
);
895 if (quadX
!= setup
->quad
[0].input
.x0
||
896 quadY
!= setup
->quad
[0].input
.y0
)
898 /* flush prev quad, start new quad */
900 if (setup
->quad
[0].input
.x0
!= -1)
901 clip_emit_quad( setup
, &setup
->quad
[0] );
903 setup
->quad
[0].input
.x0
= quadX
;
904 setup
->quad
[0].input
.y0
= quadY
;
905 setup
->quad
[0].inout
.mask
= 0x0;
908 setup
->quad
[0].inout
.mask
|= mask
;
913 * Do setup for line rasterization, then render the line.
914 * Single-pixel width, no stipple, etc. We rely on the 'draw' module
915 * to handle stippling and wide lines.
918 setup_line(struct setup_context
*setup
,
919 const float (*v0
)[4],
920 const float (*v1
)[4])
922 int x0
= (int) v0
[0][0];
923 int x1
= (int) v1
[0][0];
924 int y0
= (int) v0
[0][1];
925 int y1
= (int) v1
[0][1];
931 debug_printf("Setup line:\n");
932 print_vertex(setup
, v0
);
933 print_vertex(setup
, v1
);
936 if (setup
->llvmpipe
->no_rast
)
939 if (dx
== 0 && dy
== 0)
942 if (!setup_line_coefficients(setup
, v0
, v1
))
945 assert(v0
[0][0] < 1.0e9
);
946 assert(v0
[0][1] < 1.0e9
);
947 assert(v1
[0][0] < 1.0e9
);
948 assert(v1
[0][1] < 1.0e9
);
951 dx
= -dx
; /* make positive */
959 dy
= -dy
; /* make positive */
968 assert(setup
->llvmpipe
->reduced_prim
== PIPE_PRIM_LINES
);
970 setup
->quad
[0].input
.x0
= setup
->quad
[0].input
.y0
= -1;
971 setup
->quad
[0].inout
.mask
= 0x0;
973 /* XXX temporary: set coverage to 1.0 so the line appears
974 * if AA mode happens to be enabled.
976 setup
->quad
[0].input
.coverage
[0] =
977 setup
->quad
[0].input
.coverage
[1] =
978 setup
->quad
[0].input
.coverage
[2] =
979 setup
->quad
[0].input
.coverage
[3] = 1.0;
982 /*** X-major line ***/
984 const int errorInc
= dy
+ dy
;
985 int error
= errorInc
- dx
;
986 const int errorDec
= error
- dx
;
988 for (i
= 0; i
< dx
; i
++) {
1002 /*** Y-major line ***/
1004 const int errorInc
= dx
+ dx
;
1005 int error
= errorInc
- dy
;
1006 const int errorDec
= error
- dy
;
1008 for (i
= 0; i
< dy
; i
++) {
1009 plot(setup
, x0
, y0
);
1022 /* draw final quad */
1023 if (setup
->quad
[0].inout
.mask
) {
1024 clip_emit_quad( setup
, &setup
->quad
[0] );
1030 point_persp_coeff(const struct setup_context
*setup
,
1031 const float (*vert
)[4],
1032 struct tgsi_interp_coef
*coef
,
1033 uint vertSlot
, uint i
)
1036 coef
->dadx
[i
] = 0.0F
;
1037 coef
->dady
[i
] = 0.0F
;
1038 coef
->a0
[i
] = vert
[vertSlot
][i
] * vert
[0][3];
1043 * Do setup for point rasterization, then render the point.
1044 * Round or square points...
1045 * XXX could optimize a lot for 1-pixel points.
1048 setup_point( struct setup_context
*setup
,
1049 const float (*v0
)[4] )
1051 struct llvmpipe_context
*llvmpipe
= setup
->llvmpipe
;
1052 const struct lp_fragment_shader
*lpfs
= llvmpipe
->fs
;
1053 const int sizeAttr
= setup
->llvmpipe
->psize_slot
;
1055 = sizeAttr
> 0 ? v0
[sizeAttr
][0]
1056 : setup
->llvmpipe
->rasterizer
->point_size
;
1057 const float halfSize
= 0.5F
* size
;
1058 const boolean round
= (boolean
) setup
->llvmpipe
->rasterizer
->point_smooth
;
1059 const float x
= v0
[0][0]; /* Note: data[0] is always position */
1060 const float y
= v0
[0][1];
1061 const struct vertex_info
*vinfo
= llvmpipe_get_vertex_info(llvmpipe
);
1065 debug_printf("Setup point:\n");
1066 print_vertex(setup
, v0
);
1069 if (llvmpipe
->no_rast
)
1072 assert(setup
->llvmpipe
->reduced_prim
== PIPE_PRIM_POINTS
);
1074 /* For points, all interpolants are constant-valued.
1075 * However, for point sprites, we'll need to setup texcoords appropriately.
1076 * XXX: which coefficients are the texcoords???
1077 * We may do point sprites as textured quads...
1079 * KW: We don't know which coefficients are texcoords - ultimately
1080 * the choice of what interpolation mode to use for each attribute
1081 * should be determined by the fragment program, using
1082 * per-attribute declaration statements that include interpolation
1083 * mode as a parameter. So either the fragment program will have
1084 * to be adjusted for pointsprite vs normal point behaviour, or
1085 * otherwise a special interpolation mode will have to be defined
1086 * which matches the required behaviour for point sprites. But -
1087 * the latter is not a feature of normal hardware, and as such
1088 * probably should be ruled out on that basis.
1090 setup
->vprovoke
= v0
;
1093 const_coeff(setup
, &setup
->posCoef
, 0, 2);
1094 const_coeff(setup
, &setup
->posCoef
, 0, 3);
1096 for (fragSlot
= 0; fragSlot
< lpfs
->info
.num_inputs
; fragSlot
++) {
1097 const uint vertSlot
= vinfo
->attrib
[fragSlot
].src_index
;
1100 switch (vinfo
->attrib
[fragSlot
].interp_mode
) {
1101 case INTERP_CONSTANT
:
1104 for (j
= 0; j
< NUM_CHANNELS
; j
++)
1105 const_coeff(setup
, &setup
->coef
[fragSlot
], vertSlot
, j
);
1107 case INTERP_PERSPECTIVE
:
1108 for (j
= 0; j
< NUM_CHANNELS
; j
++)
1109 point_persp_coeff(setup
, setup
->vprovoke
,
1110 &setup
->coef
[fragSlot
], vertSlot
, j
);
1113 setup_fragcoord_coeff(setup
, fragSlot
);
1119 if (lpfs
->info
.input_semantic_name
[fragSlot
] == TGSI_SEMANTIC_FACE
) {
1120 setup
->coef
[fragSlot
].a0
[0] = 1.0f
- setup
->facing
;
1121 setup
->coef
[fragSlot
].dadx
[0] = 0.0;
1122 setup
->coef
[fragSlot
].dady
[0] = 0.0;
1127 if (halfSize
<= 0.5 && !round
) {
1128 /* special case for 1-pixel points */
1129 const int ix
= ((int) x
) & 1;
1130 const int iy
= ((int) y
) & 1;
1131 setup
->quad
[0].input
.x0
= (int) x
- ix
;
1132 setup
->quad
[0].input
.y0
= (int) y
- iy
;
1133 setup
->quad
[0].inout
.mask
= (1 << ix
) << (2 * iy
);
1134 clip_emit_quad( setup
, &setup
->quad
[0] );
1138 /* rounded points */
1139 const int ixmin
= block((int) (x
- halfSize
));
1140 const int ixmax
= block((int) (x
+ halfSize
));
1141 const int iymin
= block((int) (y
- halfSize
));
1142 const int iymax
= block((int) (y
+ halfSize
));
1143 const float rmin
= halfSize
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1144 const float rmax
= halfSize
+ 0.7071F
;
1145 const float rmin2
= MAX2(0.0F
, rmin
* rmin
);
1146 const float rmax2
= rmax
* rmax
;
1147 const float cscale
= 1.0F
/ (rmax2
- rmin2
);
1150 for (iy
= iymin
; iy
<= iymax
; iy
+= 2) {
1151 for (ix
= ixmin
; ix
<= ixmax
; ix
+= 2) {
1152 float dx
, dy
, dist2
, cover
;
1154 setup
->quad
[0].inout
.mask
= 0x0;
1156 dx
= (ix
+ 0.5f
) - x
;
1157 dy
= (iy
+ 0.5f
) - y
;
1158 dist2
= dx
* dx
+ dy
* dy
;
1159 if (dist2
<= rmax2
) {
1160 cover
= 1.0F
- (dist2
- rmin2
) * cscale
;
1161 setup
->quad
[0].input
.coverage
[QUAD_TOP_LEFT
] = MIN2(cover
, 1.0f
);
1162 setup
->quad
[0].inout
.mask
|= MASK_TOP_LEFT
;
1165 dx
= (ix
+ 1.5f
) - x
;
1166 dy
= (iy
+ 0.5f
) - y
;
1167 dist2
= dx
* dx
+ dy
* dy
;
1168 if (dist2
<= rmax2
) {
1169 cover
= 1.0F
- (dist2
- rmin2
) * cscale
;
1170 setup
->quad
[0].input
.coverage
[QUAD_TOP_RIGHT
] = MIN2(cover
, 1.0f
);
1171 setup
->quad
[0].inout
.mask
|= MASK_TOP_RIGHT
;
1174 dx
= (ix
+ 0.5f
) - x
;
1175 dy
= (iy
+ 1.5f
) - y
;
1176 dist2
= dx
* dx
+ dy
* dy
;
1177 if (dist2
<= rmax2
) {
1178 cover
= 1.0F
- (dist2
- rmin2
) * cscale
;
1179 setup
->quad
[0].input
.coverage
[QUAD_BOTTOM_LEFT
] = MIN2(cover
, 1.0f
);
1180 setup
->quad
[0].inout
.mask
|= MASK_BOTTOM_LEFT
;
1183 dx
= (ix
+ 1.5f
) - x
;
1184 dy
= (iy
+ 1.5f
) - y
;
1185 dist2
= dx
* dx
+ dy
* dy
;
1186 if (dist2
<= rmax2
) {
1187 cover
= 1.0F
- (dist2
- rmin2
) * cscale
;
1188 setup
->quad
[0].input
.coverage
[QUAD_BOTTOM_RIGHT
] = MIN2(cover
, 1.0f
);
1189 setup
->quad
[0].inout
.mask
|= MASK_BOTTOM_RIGHT
;
1192 if (setup
->quad
[0].inout
.mask
) {
1193 setup
->quad
[0].input
.x0
= ix
;
1194 setup
->quad
[0].input
.y0
= iy
;
1195 clip_emit_quad( setup
, &setup
->quad
[0] );
1202 const int xmin
= (int) (x
+ 0.75 - halfSize
);
1203 const int ymin
= (int) (y
+ 0.25 - halfSize
);
1204 const int xmax
= xmin
+ (int) size
;
1205 const int ymax
= ymin
+ (int) size
;
1206 /* XXX could apply scissor to xmin,ymin,xmax,ymax now */
1207 const int ixmin
= block(xmin
);
1208 const int ixmax
= block(xmax
- 1);
1209 const int iymin
= block(ymin
);
1210 const int iymax
= block(ymax
- 1);
1214 debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax);
1216 for (iy
= iymin
; iy
<= iymax
; iy
+= 2) {
1219 /* above the top edge */
1220 rowMask
&= (MASK_BOTTOM_LEFT
| MASK_BOTTOM_RIGHT
);
1222 if (iy
+ 1 >= ymax
) {
1223 /* below the bottom edge */
1224 rowMask
&= (MASK_TOP_LEFT
| MASK_TOP_RIGHT
);
1227 for (ix
= ixmin
; ix
<= ixmax
; ix
+= 2) {
1228 uint mask
= rowMask
;
1231 /* fragment is past left edge of point, turn off left bits */
1232 mask
&= (MASK_BOTTOM_RIGHT
| MASK_TOP_RIGHT
);
1234 if (ix
+ 1 >= xmax
) {
1235 /* past the right edge */
1236 mask
&= (MASK_BOTTOM_LEFT
| MASK_TOP_LEFT
);
1239 setup
->quad
[0].inout
.mask
= mask
;
1240 setup
->quad
[0].input
.x0
= ix
;
1241 setup
->quad
[0].input
.y0
= iy
;
1242 clip_emit_quad( setup
, &setup
->quad
[0] );
1249 void setup_prepare( struct setup_context
*setup
)
1251 struct llvmpipe_context
*lp
= setup
->llvmpipe
;
1254 llvmpipe_update_derived(lp
);
1257 lp
->quad
.first
->begin( lp
->quad
.first
);
1259 if (lp
->reduced_api_prim
== PIPE_PRIM_TRIANGLES
&&
1260 lp
->rasterizer
->fill_cw
== PIPE_POLYGON_MODE_FILL
&&
1261 lp
->rasterizer
->fill_ccw
== PIPE_POLYGON_MODE_FILL
) {
1262 /* we'll do culling */
1263 setup
->winding
= lp
->rasterizer
->cull_mode
;
1266 /* 'draw' will do culling */
1267 setup
->winding
= PIPE_WINDING_NONE
;
1273 void setup_destroy_context( struct setup_context
*setup
)
1280 * Create a new primitive setup/render stage.
1282 struct setup_context
*setup_create_context( struct llvmpipe_context
*llvmpipe
)
1284 struct setup_context
*setup
= CALLOC_STRUCT(setup_context
);
1287 setup
->llvmpipe
= llvmpipe
;
1289 for (i
= 0; i
< MAX_QUADS
; i
++) {
1290 setup
->quad
[i
].coef
= setup
->coef
;
1291 setup
->quad
[i
].posCoef
= &setup
->posCoef
;
1294 setup
->span
.left
[0] = 1000000; /* greater than right[0] */
1295 setup
->span
.left
[1] = 1000000; /* greater than right[1] */