[965] Bug #9151: make fragment.position return window coords not screen coords.
authorEric Anholt <eric@anholt.net>
Thu, 28 Feb 2008 21:18:12 +0000 (13:18 -0800)
committerEric Anholt <eric@anholt.net>
Thu, 28 Feb 2008 21:18:48 +0000 (13:18 -0800)
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_emit.c
src/mesa/drivers/dri/i965/brw_wm_glsl.c

index 9b8c8a2..342e7f8 100644 (file)
@@ -292,7 +292,30 @@ static void brw_wm_populate_key( struct brw_context *brw,
            key->yuvtex_mask |= 1<<i;
       }
    }
-         
+
+   /* _NEW_BUFFERS */
+   /*
+    * Include the draw buffer origin and height so that we can calculate
+    * fragment position values relative to the bottom left of the drawable,
+    * from the incoming screen origin relative position we get as part of our
+    * payload.
+    *
+    * We could avoid recompiling by including this as a constant referenced by
+    * our program, but if we were to do that it would also be nice to handle
+    * getting that constant updated at batchbuffer submit time (when we
+    * hold the lock and know where the buffer really is) rather than at emit
+    * time when we don't hold the lock and are just guessing.  We could also
+    * just avoid using this as key data if the program doesn't use
+    * fragment.position.
+    *
+    * This pretty much becomes moot with DRI2 and redirected buffers anyway,
+    * as our origins will always be zero then.
+    */
+   if (brw->intel.driDrawable != NULL) {
+      key->origin_x = brw->intel.driDrawable->x;
+      key->origin_y = brw->intel.driDrawable->y;
+      key->drawable_height = brw->intel.driDrawable->h;
+   }
 
    /* Extra info:
     */
@@ -331,6 +354,7 @@ const struct brw_tracked_state brw_wm_prog = {
                _NEW_POLYGON |
                _NEW_LINE |
                _NEW_LIGHT |
+               _NEW_BUFFERS |
                _NEW_TEXTURE),
       .brw   = (BRW_NEW_FRAGMENT_PROGRAM |
                BRW_NEW_WM_INPUT_DIMENSIONS |
index 01e3859..645286d 100644 (file)
@@ -72,6 +72,8 @@ struct brw_wm_prog_key {
    GLuint pad1:24;
 
    GLuint program_string_id:32;
+   GLuint origin_x, origin_y;
+   GLuint drawable_height;
 };
 
 
index 6bafa44..df51f73 100644 (file)
@@ -122,26 +122,30 @@ static void emit_delta_xy(struct brw_compile *p,
    }
 }
 
-static void emit_wpos_xy(struct brw_compile *p,
-                          const struct brw_reg *dst,
-                          GLuint mask,
-                          const struct brw_reg *arg0)
+static void emit_wpos_xy(struct brw_wm_compile *c,
+                        const struct brw_reg *dst,
+                        GLuint mask,
+                        const struct brw_reg *arg0)
 {
-   /* Calc delta X,Y by subtracting origin in r1 from the pixel
-    * centers.
+   struct brw_compile *p = &c->func;
+
+   /* Calculate the pixel offset from window bottom left into destination
+    * X and Y channels.
     */
    if (mask & WRITEMASK_X) {
-      brw_MOV(p,
+      /* X' = X - origin */
+      brw_ADD(p,
              dst[0],
-             retype(arg0[0], BRW_REGISTER_TYPE_UW));
+             retype(arg0[0], BRW_REGISTER_TYPE_W),
+             brw_imm_d(- c->key.origin_x));
    }
 
    if (mask & WRITEMASK_Y) {
-      /* TODO -- window_height - Y */
-      brw_MOV(p,
+      /* Y' = height - (Y - origin_y) = height + origin_y - Y */
+      brw_ADD(p,
              dst[1],
-             negate(retype(arg0[1], BRW_REGISTER_TYPE_UW)));
-
+             negate(retype(arg0[1], BRW_REGISTER_TYPE_W)),
+             brw_imm_d(c->key.origin_y + c->key.drawable_height));
    }
 }
 
@@ -1114,7 +1118,7 @@ void brw_wm_emit( struct brw_wm_compile *c )
         break;
 
       case WM_WPOSXY:
-        emit_wpos_xy(p, dst, dst_flags, args[0]);
+        emit_wpos_xy(c, dst, dst_flags, args[0]);
         break;
 
       case WM_PIXELW:
index 0a93d06..fd237ee 100644 (file)
@@ -967,21 +967,23 @@ static void emit_wpos_xy(struct brw_wm_compile *c,
     src0[0] = get_src_reg(c, &inst->SrcReg[0], 0, 1);
     src0[1] = get_src_reg(c, &inst->SrcReg[0], 1, 1);
 
-    /* Calc delta X,Y by subtracting origin in r1 from the pixel
-     * centers.
+    /* Calculate the pixel offset from window bottom left into destination
+     * X and Y channels.
      */
     if (mask & WRITEMASK_X) {
-       brw_MOV(p,
+       /* X' = X - origin_x */
+       brw_ADD(p,
                dst[0],
-               retype(src0[0], BRW_REGISTER_TYPE_UW));
+               retype(src0[0], BRW_REGISTER_TYPE_W),
+               brw_imm_d(- c->key.origin_x));
     }
 
     if (mask & WRITEMASK_Y) {
-       /* TODO -- window_height - Y */
-       brw_MOV(p,
+       /* Y' = height - (Y - origin_y) = height + origin_y - Y */
+       brw_ADD(p,
                dst[1],
-               retype(src0[1], BRW_REGISTER_TYPE_UW));
-
+               negate(retype(src0[1], BRW_REGISTER_TYPE_W)),
+               brw_imm_d(c->key.origin_y + c->key.drawable_height));
     }
 }