summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2012-05-14 16:33:58 -0600
committerBrian Paul <[email protected]>2012-05-15 14:56:54 -0600
commit1459c18f45f5bd2a2d99145247093f1b540478ad (patch)
treeacf960b4fa1cf25aa9526872c8727fc1fb83009a
parent4a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38 (diff)
svga: fix FBO / viewport bugs
When drawing to a FBO, the viewport wasn't always set correctly. It was fine in the usual case of the viewport dims matching the surface dims but broken otherwise. In particular, this was happening because the viewport scale is negative for FBO rendering. The piglit fbo-viewport test exercises this. Reviewed-by: José Fonseca <[email protected]>
-rw-r--r--src/gallium/drivers/svga/svga_state_framebuffer.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c
index 3244023f3ad..402d5feac99 100644
--- a/src/gallium/drivers/svga/svga_state_framebuffer.c
+++ b/src/gallium/drivers/svga/svga_state_framebuffer.c
@@ -175,6 +175,7 @@ emit_viewport( struct svga_context *svga,
float range_max = 1.0;
float flip = -1.0;
boolean degenerate = FALSE;
+ boolean invertY = FALSE;
enum pipe_error ret;
float fb_width = svga->curr.framebuffer.width;
@@ -218,11 +219,12 @@ emit_viewport( struct svga_context *svga,
fx = viewport->scale[0] * 1.0 + viewport->translate[0];
}
- if (fh < 0) {
- prescale.scale[1] *= -1.0;
- prescale.translate[1] += -fh;
+ if (fh < 0.0) {
+ prescale.translate[1] = fh - 1 + fy * 2;
fh = -fh;
- fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1];
+ fy -= fh;
+ prescale.scale[1] = -1.0;
+ invertY = TRUE;
}
if (fx < 0) {
@@ -233,7 +235,12 @@ emit_viewport( struct svga_context *svga,
}
if (fy < 0) {
- prescale.translate[1] += fy;
+ if (invertY) {
+ prescale.translate[1] -= fy;
+ }
+ else {
+ prescale.translate[1] += fy;
+ }
prescale.scale[1] *= fh / (fh + fy);
fh += fy;
fy = 0;
@@ -249,8 +256,15 @@ emit_viewport( struct svga_context *svga,
if (fy + fh > fb_height) {
prescale.scale[1] *= fh / (fb_height - fy);
- prescale.translate[1] -= fy * (fh / (fb_height - fy));
- prescale.translate[1] += fy;
+ if (invertY) {
+ float in = fb_height - fy; /* number of vp pixels inside view */
+ float out = fy + fh - fb_height; /* number of vp pixels out of view */
+ prescale.translate[1] += fy * out / in;
+ }
+ else {
+ prescale.translate[1] -= fy * (fh / (fb_height - fy));
+ prescale.translate[1] += fy;
+ }
fh = fb_height - fy;
}
@@ -307,6 +321,9 @@ emit_viewport( struct svga_context *svga,
break;
}
+ if (invertY)
+ adjust_y = -adjust_y;
+
prescale.translate[0] += adjust_x;
prescale.translate[1] += adjust_y;
prescale.translate[2] = 0.5; /* D3D clip space */