Unify handling of userplanes and regular planes to simplify
the clipping code. (really done by Keith)
This commit is contained in:
@@ -50,13 +50,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
/** bitmask for the first view-frustum clip planes */
|
||||
#define VIEWPLANE_MASK ((1 << 6) - 1)
|
||||
|
||||
/** bitmask for the user-defined clip planes */
|
||||
#define USERPLANE_MASK (((1 << PIPE_MAX_CLIP_PLANES) - 1) << 6)
|
||||
|
||||
|
||||
|
||||
struct clipper {
|
||||
struct draw_stage stage; /**< base class */
|
||||
@@ -335,10 +328,6 @@ do_clip_line( struct draw_stage *stage,
|
||||
const float dp0 = dot4( pos0, plane );
|
||||
const float dp1 = dot4( pos1, plane );
|
||||
|
||||
/* need this to handle user-clip planes properly */
|
||||
if (dp0 < 0.0F && dp1 < 0.0F)
|
||||
return;
|
||||
|
||||
if (dp1 < 0.0F) {
|
||||
float t = dp1 / (dp1 - dp0);
|
||||
t1 = MAX2(t1, t);
|
||||
@@ -392,21 +381,8 @@ static void
|
||||
clip_point( struct draw_stage *stage,
|
||||
struct prim_header *header )
|
||||
{
|
||||
if (header->v[0]->clipmask == 0) {
|
||||
if (header->v[0]->clipmask == 0)
|
||||
stage->next->point( stage->next, header );
|
||||
}
|
||||
else if (header->v[0]->clipmask & USERPLANE_MASK) {
|
||||
/* test against user clip planes now */
|
||||
const struct clipper *clipper = clipper_stage( stage );
|
||||
uint i;
|
||||
for (i = 6; i < stage->draw->nr_planes; i++) {
|
||||
float dot = dot4(clipper->plane[i], header->v[0]->clip);
|
||||
if (dot < 0.0F)
|
||||
return; /* clipped! */
|
||||
}
|
||||
/* not clipped */
|
||||
stage->next->point( stage->next, header );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -421,22 +397,8 @@ clip_line( struct draw_stage *stage,
|
||||
/* no clipping needed */
|
||||
stage->next->line( stage->next, header );
|
||||
}
|
||||
else if (((header->v[0]->clipmask &
|
||||
header->v[1]->clipmask &
|
||||
VIEWPLANE_MASK) == 0) ||
|
||||
(clipmask & USERPLANE_MASK)) {
|
||||
/* About the above predicate: the clipmask bits for the view volume
|
||||
* exactly indicate whether the coordinate is inside or outside each
|
||||
* frustum plane. However, the bits for user-defined planes are set
|
||||
* if the plane is enabled, and does not really indicate if the
|
||||
* coordinate is inside or outside the user-defined plane.
|
||||
*
|
||||
* To change this (so that the user-plane bits really indicate
|
||||
* inside/outside) we'd have to compute the dot products earlier
|
||||
* in the draw_prim.c code (see compute_clipmask()).
|
||||
* We will probably do that when we have support for user clip coord
|
||||
* in vertex shaders...
|
||||
*/
|
||||
else if ((header->v[0]->clipmask &
|
||||
header->v[1]->clipmask) == 0) {
|
||||
do_clip_line(stage, header, clipmask);
|
||||
}
|
||||
/* else, totally clipped */
|
||||
@@ -455,11 +417,9 @@ clip_tri( struct draw_stage *stage,
|
||||
/* no clipping needed */
|
||||
stage->next->tri( stage->next, header );
|
||||
}
|
||||
else if (((header->v[0]->clipmask &
|
||||
header->v[1]->clipmask &
|
||||
header->v[2]->clipmask &
|
||||
VIEWPLANE_MASK) == 0) ||
|
||||
(clipmask & USERPLANE_MASK)) {
|
||||
else if ((header->v[0]->clipmask &
|
||||
header->v[1]->clipmask &
|
||||
header->v[2]->clipmask) == 0) {
|
||||
do_clip_tri(stage, header, clipmask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,8 +145,6 @@ void draw_set_clip_state( struct draw_context *draw,
|
||||
assert(clip->nr <= PIPE_MAX_CLIP_PLANES);
|
||||
memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0]));
|
||||
draw->nr_planes = 6 + clip->nr;
|
||||
/* bitmask of the enabled user-defined clip planes */
|
||||
draw->user_clipmask = ((1 << clip->nr) - 1) << 6;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -177,7 +177,6 @@ struct draw_context
|
||||
*/
|
||||
float plane[12][4];
|
||||
unsigned nr_planes;
|
||||
unsigned user_clipmask;
|
||||
|
||||
/** Describes the layout of post-transformation vertices */
|
||||
struct vertex_info vertex_info;
|
||||
|
||||
@@ -40,17 +40,27 @@
|
||||
|
||||
#include "pipe/tgsi/exec/tgsi_core.h"
|
||||
|
||||
|
||||
static INLINE float dot4(const float *a, const float *b)
|
||||
{
|
||||
float result = (a[0]*b[0] +
|
||||
a[1]*b[1] +
|
||||
a[2]*b[2] +
|
||||
a[3]*b[3]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static INLINE unsigned
|
||||
compute_clipmask(float cx, float cy, float cz, float cw)
|
||||
compute_clipmask(const float *clip, const float (*plane)[4], unsigned nr)
|
||||
{
|
||||
unsigned mask = 0;
|
||||
unsigned i;
|
||||
|
||||
if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
|
||||
if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
|
||||
if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
|
||||
if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
|
||||
if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
|
||||
if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (dot4(clip, plane[i]) < 0)
|
||||
mask |= (1<<i);
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
@@ -127,13 +137,18 @@ run_vertex_program(struct draw_context *draw,
|
||||
unsigned slot;
|
||||
float x, y, z, w;
|
||||
|
||||
/* Handle attr[0] (position) specially: */
|
||||
/* Handle attr[0] (position) specially:
|
||||
*
|
||||
* XXX: Computing the clipmask should be done in the vertex
|
||||
* program as a set of DP4 instructions appended to the
|
||||
* user-provided code.
|
||||
*/
|
||||
x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j];
|
||||
y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j];
|
||||
z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j];
|
||||
w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j];
|
||||
|
||||
vOut[j]->clipmask = compute_clipmask(x, y, z, w) | draw->user_clipmask;
|
||||
vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes);
|
||||
vOut[j]->edgeflag = 1;
|
||||
|
||||
/* divide by w */
|
||||
|
||||
Reference in New Issue
Block a user