summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-07-27 10:50:35 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-07-27 10:50:35 -0600
commit05ba76757b7349f0c3de2d9ce42c543fa7e931c2 (patch)
tree61e486fcd903df3adac18eef7d5c6eb3755a953e
parent05bde092f39e16463dfbbe038f22f17da4346527 (diff)
Clip triangles against softpipe->cliprect which includes scissor and surface bounds.
This prevents rendering out of bounds when the viewport is partially outside the surface bounds.
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_setup.c72
-rw-r--r--src/mesa/pipe/softpipe/sp_state_derived.c8
2 files changed, 36 insertions, 44 deletions
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c
index 63568404dc..d07bd5381d 100644
--- a/src/mesa/pipe/softpipe/sp_prim_setup.c
+++ b/src/mesa/pipe/softpipe/sp_prim_setup.c
@@ -110,28 +110,31 @@ static inline struct setup_stage *setup_stage( struct draw_stage *stage )
static INLINE void
quad_clip(struct setup_stage *setup)
{
- const struct softpipe_context *sp = setup->softpipe;
- if (setup->quad.x0 >= sp->cliprect.maxx ||
- setup->quad.y0 >= sp->cliprect.maxy ||
- setup->quad.x0 + 1 < sp->cliprect.minx ||
- setup->quad.y0 + 1 < sp->cliprect.miny) {
+ const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect;
+ if (setup->quad.x0 >= cliprect->maxx ||
+ setup->quad.y0 >= cliprect->maxy ||
+ setup->quad.x0 + 1 < cliprect->minx ||
+ setup->quad.y0 + 1 < cliprect->miny) {
/* totally clipped */
setup->quad.mask = 0x0;
return;
}
- if (setup->quad.x0 < sp->cliprect.minx)
+ if (setup->quad.x0 < cliprect->minx)
setup->quad.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT);
- if (setup->quad.y0 < sp->cliprect.miny)
+ if (setup->quad.y0 < cliprect->miny)
setup->quad.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT);
- if (setup->quad.x0 == sp->cliprect.maxx - 1)
+ if (setup->quad.x0 == cliprect->maxx - 1)
setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
- if (setup->quad.y0 == sp->cliprect.maxy - 1)
+ if (setup->quad.y0 == cliprect->maxy - 1)
setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT);
}
/**
* Emit/render a quad.
+ * Called during point/line rendering. For triangles, we call
+ * run_shader_block() which doesn't do clipping (since clipping is
+ * done at a higher level for tris).
* This passes the quad to the first stage of per-fragment operations.
*/
static INLINE void
@@ -162,11 +165,11 @@ static inline GLint block( GLint x )
static void run_shader_block( struct setup_stage *setup,
GLint x, GLint y, GLuint mask )
{
+ struct softpipe_context *sp = setup->softpipe;
setup->quad.x0 = x;
setup->quad.y0 = y;
setup->quad.mask = mask;
-
- quad_emit(setup);
+ sp->quad.first->run(sp->quad.first, &setup->quad);
}
@@ -501,38 +504,31 @@ static void setup_tri_edges( struct setup_stage *setup )
/**
* Render the upper or lower half of a triangle.
- * Scissoring is applied here too.
+ * Scissoring/cliprect is applied here too.
*/
static void subtriangle( struct setup_stage *setup,
struct edge *eleft,
struct edge *eright,
GLuint lines )
{
+ const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect;
GLint y, start_y, finish_y;
GLint sy = (GLint)eleft->sy;
assert((GLint)eleft->sy == (GLint) eright->sy);
- assert((GLint)eleft->sy >= 0); /* catch bug in x64? */
- /* scissor y:
- */
- if (setup->softpipe->setup.scissor) {
- start_y = sy;
- finish_y = start_y + lines;
+ /* clip top/bottom */
+ start_y = sy;
+ finish_y = sy + lines;
- if (start_y < setup->softpipe->scissor.miny)
- start_y = setup->softpipe->scissor.miny;
+ if (start_y < cliprect->miny)
+ start_y = cliprect->miny;
- if (finish_y > setup->softpipe->scissor.maxy)
- finish_y = setup->softpipe->scissor.maxy;
+ if (finish_y > cliprect->maxy)
+ finish_y = cliprect->maxy;
- start_y -= sy;
- finish_y -= sy;
- }
- else {
- start_y = 0;
- finish_y = lines;
- }
+ start_y -= sy;
+ finish_y -= sy;
/*
_mesa_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y);
@@ -549,15 +545,11 @@ static void subtriangle( struct setup_stage *setup,
GLint left = (GLint)(eleft->sx + y * eleft->dxdy);
GLint right = (GLint)(eright->sx + y * eright->dxdy);
- /* scissor x:
- */
- if (setup->softpipe->setup.scissor) {
- if (left < setup->softpipe->scissor.minx)
- left = setup->softpipe->scissor.minx;
-
- if (right > setup->softpipe->scissor.maxx)
- right = setup->softpipe->scissor.maxx;
- }
+ /* clip left/right */
+ if (left < cliprect->minx)
+ left = cliprect->minx;
+ if (right > cliprect->maxx)
+ right = cliprect->maxx;
if (left < right) {
GLint _y = sy+y;
@@ -875,8 +867,8 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
{
struct setup_stage *setup = setup_stage( stage );
/*XXX this should be a vertex attrib! */
- GLfloat halfSize = 0.5 * setup->softpipe->setup.point_size;
- GLboolean round = setup->softpipe->setup.point_smooth;
+ const GLfloat halfSize = 0.5 * setup->softpipe->setup.point_size;
+ const GLboolean round = setup->softpipe->setup.point_smooth;
const struct vertex_header *v0 = prim->v[0];
const GLfloat x = v0->data[FRAG_ATTRIB_WPOS][0];
const GLfloat y = v0->data[FRAG_ATTRIB_WPOS][1];
diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c
index 9572890afe..e1faaed93c 100644
--- a/src/mesa/pipe/softpipe/sp_state_derived.c
+++ b/src/mesa/pipe/softpipe/sp_state_derived.c
@@ -185,15 +185,15 @@ compute_cliprect(struct softpipe_context *sp)
/* clip to scissor rect */
sp->cliprect.minx = MAX2(sp->scissor.minx, 0);
sp->cliprect.miny = MAX2(sp->scissor.miny, 0);
- sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth - 1);
- sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight - 1);
+ sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth);
+ sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight);
}
else {
/* clip to surface bounds */
sp->cliprect.minx = 0;
sp->cliprect.miny = 0;
- sp->cliprect.maxx = surfWidth - 1;
- sp->cliprect.maxy = surfHeight - 1;
+ sp->cliprect.maxx = surfWidth;
+ sp->cliprect.maxy = surfHeight;
}
}