+#define R300_NIBBLES(x0, y0, x1, y1, x2, y2, d0y, d0x) \
+ (((x0) & 0xf) | (((y0) & 0xf) << 4) | \
+ (((x1) & 0xf) << 8) | (((y1) & 0xf) << 12) | \
+ (((x2) & 0xf) << 16) | (((y2) & 0xf) << 20) | \
+ (((d0y) & 0xf) << 24) | (((d0x) & 0xf) << 28))
+
+static unsigned r300_get_mspos(int index, unsigned *p)
+{
+ unsigned reg, i, distx, disty, dist;
+
+ if (index == 0) {
+ /* MSPOS0 contains positions for samples 0,1,2 as (X,Y) pairs of nibbles,
+ * followed by a (Y,X) pair containing the minimum distance from the pixel
+ * edge:
+ * X0, Y0, X1, Y1, X2, Y2, D0_Y, D0_X
+ *
+ * There is a quirk when setting D0_X. The value represents the distance
+ * from the left edge of the pixel quad to the first sample in subpixels.
+ * All values less than eight should use the actual value, but „7‟ should
+ * be used for the distance „8‟. The hardware will convert 7 into 8 internally.
+ */
+ distx = 11;
+ for (i = 0; i < 12; i += 2) {
+ if (p[i] < distx)
+ distx = p[i];
+ }
+
+ disty = 11;
+ for (i = 1; i < 12; i += 2) {
+ if (p[i] < disty)
+ disty = p[i];
+ }
+
+ if (distx == 8)
+ distx = 7;
+
+ reg = R300_NIBBLES(p[0], p[1], p[2], p[3], p[4], p[5], disty, distx);
+ } else {
+ /* MSPOS1 contains positions for samples 3,4,5 as (X,Y) pairs of nibbles,
+ * followed by the minimum distance from the pixel edge (not sure if X or Y):
+ * X3, Y3, X4, Y4, X5, Y5, D1
+ */
+ dist = 11;
+ for (i = 0; i < 12; i++) {
+ if (p[i] < dist)
+ dist = p[i];
+ }
+
+ reg = R300_NIBBLES(p[6], p[7], p[8], p[9], p[10], p[11], dist, 0);
+ }
+ return reg;
+}
+