+ return get_texel_2d_no_border( sp_sview, addr, x, y );
+ }
+}
+
+
+/*
+ * Here's the complete logic (HOLY CRAP) for finding next face and doing the
+ * corresponding coord wrapping, implemented by get_next_face,
+ * get_next_xcoord, get_next_ycoord.
+ * Read like that (first line):
+ * If face is +x and s coord is below zero, then
+ * new face is +z, new s is max , new t is old t
+ * (max is always cube size - 1).
+ *
+ * +x s- -> +z: s = max, t = t
+ * +x s+ -> -z: s = 0, t = t
+ * +x t- -> +y: s = max, t = max-s
+ * +x t+ -> -y: s = max, t = s
+ *
+ * -x s- -> -z: s = max, t = t
+ * -x s+ -> +z: s = 0, t = t
+ * -x t- -> +y: s = 0, t = s
+ * -x t+ -> -y: s = 0, t = max-s
+ *
+ * +y s- -> -x: s = t, t = 0
+ * +y s+ -> +x: s = max-t, t = 0
+ * +y t- -> -z: s = max-s, t = 0
+ * +y t+ -> +z: s = s, t = 0
+ *
+ * -y s- -> -x: s = max-t, t = max
+ * -y s+ -> +x: s = t, t = max
+ * -y t- -> +z: s = s, t = max
+ * -y t+ -> -z: s = max-s, t = max
+
+ * +z s- -> -x: s = max, t = t
+ * +z s+ -> +x: s = 0, t = t
+ * +z t- -> +y: s = s, t = max
+ * +z t+ -> -y: s = s, t = 0
+
+ * -z s- -> +x: s = max, t = t
+ * -z s+ -> -x: s = 0, t = t
+ * -z t- -> +y: s = max-s, t = 0
+ * -z t+ -> -y: s = max-s, t = max
+ */
+
+
+/*
+ * seamless cubemap neighbour array.
+ * this array is used to find the adjacent face in each of 4 directions,
+ * left, right, up, down. (or -x, +x, -y, +y).
+ */
+static const unsigned face_array[PIPE_TEX_FACE_MAX][4] = {
+ /* pos X first then neg X is Z different, Y the same */
+ /* PIPE_TEX_FACE_POS_X,*/
+ { PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z,
+ PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
+ /* PIPE_TEX_FACE_NEG_X */
+ { PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z,
+ PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
+
+ /* pos Y first then neg Y is X different, X the same */
+ /* PIPE_TEX_FACE_POS_Y */
+ { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
+ PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z },
+
+ /* PIPE_TEX_FACE_NEG_Y */
+ { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
+ PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z },
+
+ /* pos Z first then neg Y is X different, X the same */
+ /* PIPE_TEX_FACE_POS_Z */
+ { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
+ PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
+
+ /* PIPE_TEX_FACE_NEG_Z */
+ { PIPE_TEX_FACE_POS_X, PIPE_TEX_FACE_NEG_X,
+ PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y }
+};
+
+static INLINE unsigned
+get_next_face(unsigned face, int idx)
+{
+ return face_array[face][idx];
+}
+
+/*
+ * return a new xcoord based on old face, old coords, cube size
+ * and fall_off_index (0 for x-, 1 for x+, 2 for y-, 3 for y+)
+ */
+static INLINE int
+get_next_xcoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
+{
+ if ((face == 0 && fall_off_index != 1) ||
+ (face == 1 && fall_off_index == 0) ||
+ (face == 4 && fall_off_index == 0) ||
+ (face == 5 && fall_off_index == 0)) {
+ return max;
+ }
+ if ((face == 1 && fall_off_index != 0) ||
+ (face == 0 && fall_off_index == 1) ||
+ (face == 4 && fall_off_index == 1) ||
+ (face == 5 && fall_off_index == 1)) {
+ return 0;
+ }
+ if ((face == 4 && fall_off_index >= 2) ||
+ (face == 2 && fall_off_index == 3) ||
+ (face == 3 && fall_off_index == 2)) {
+ return xc;