nv50: fix viewport transform
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 28 Jul 2009 23:21:41 +0000 (01:21 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 28 Jul 2009 23:40:34 +0000 (09:40 +1000)
The translation also needs to be inverted, and in bypass mode
the state tracker incorrectly assumes that Y = 0 = TOP, so we
need inversion there to; NDC clipping has to be deactivated
explicitly.

src/gallium/drivers/nv50/nv50_state_validate.c

index 03aed81fed7eec28b11f96746864f6f3aea8cee3..ce8e44fb0063b3ccd0b418aac171e773dcc72572 100644 (file)
@@ -258,6 +258,7 @@ scissor_uptodate:
 
        if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) {
                unsigned bypass;
+               float y_translate = (float)nv50->framebuffer.height;
 
                if (!nv50->rasterizer->pipe.bypass_vs_clip_and_viewport)
                        bypass = 0;
@@ -271,25 +272,33 @@ scissor_uptodate:
                nv50->state.viewport_bypass = bypass;
 
                so = so_new(12, 0);
+               so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
                if (!bypass) {
-                       so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3);
+                       so_data(so, 0x0000);
+                       y_translate -= nv50->viewport.translate[1];
+                       so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3);
                        so_data  (so, fui(nv50->viewport.translate[0]));
-                       so_data  (so, fui(nv50->viewport.translate[1]));
+                       so_data  (so, fui(y_translate));
                        so_data  (so, fui(nv50->viewport.translate[2]));
-                       so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3);
+                       so_method(so, tesla, NV50TCL_VIEWPORT_SCALE(0), 3);
                        so_data  (so, fui(nv50->viewport.scale[0]));
                        so_data  (so, fui(-nv50->viewport.scale[1]));
                        so_data  (so, fui(nv50->viewport.scale[2]));
-                       so_method(so, tesla, 0x192c, 1);
-                       so_data  (so, 1);
-                       so_method(so, tesla, 0x0f90, 1);
-                       so_data  (so, 0);
                } else {
-                       so_method(so, tesla, 0x192c, 1);
-                       so_data  (so, 0);
-                       so_method(so, tesla, 0x0f90, 1);
-                       so_data  (so, 1);
+                       /* don't do xy-clipping in NDC space */
+                       so_data(so, 0x0800);
+                       /* in bypass mode, y = 0 would be bottom */
+                       so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3);
+                       so_data  (so, fui(0.0f));
+                       so_data  (so, fui(y_translate));
+                       so_data  (so, fui(0.0f));
+                       so_method(so, tesla, NV50TCL_VIEWPORT_SCALE(0), 3);
+                       so_data  (so, fui(1.0f));
+                       so_data  (so, fui(-1.0f));
+                       so_data  (so, fui(1.0f));
                }
+               so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
+               so_data  (so, 1);
 
                so_ref(so, &nv50->state.viewport);
                so_ref(NULL, &so);