gallium: Port timing functions to WinCE.
[mesa.git] / src / gallium / auxiliary / util / p_tile.c
index 3f795a38989dc54027fec0963b344c3e26851fc7..5728757d2fb492a2f98a15cdc070eb9a2367cb67 100644 (file)
@@ -50,6 +50,7 @@ pipe_get_tile_raw(struct pipe_context *pipe,
                   uint x, uint y, uint w, uint h,
                   void *p, int dst_stride)
 {
+   struct pipe_screen *screen = pipe->screen;
    const uint cpp = ps->cpp;
    const ubyte *pSrc;
    const uint src_stride = ps->pitch * cpp;
@@ -63,7 +64,11 @@ pipe_get_tile_raw(struct pipe_context *pipe,
    if (pipe_clip_tile(x, y, &w, &h, ps))
       return;
 
-   pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp;
+   pSrc = (const ubyte *) screen->surface_map(screen, ps,
+                                              PIPE_BUFFER_USAGE_CPU_READ);
+   assert(pSrc);                /* XXX: proper error handling! */
+
+   pSrc += (y * ps->pitch + x) * cpp;
    pDest = (ubyte *) p;
 
    for (i = 0; i < h; i++) {
@@ -72,7 +77,7 @@ pipe_get_tile_raw(struct pipe_context *pipe,
       pSrc += src_stride;
    }
 
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
 }
 
 
@@ -86,6 +91,7 @@ pipe_put_tile_raw(struct pipe_context *pipe,
                   uint x, uint y, uint w, uint h,
                   const void *p, int src_stride)
 {
+   struct pipe_screen *screen = pipe->screen;
    const uint cpp = ps->cpp;
    const ubyte *pSrc;
    const uint dst_stride = ps->pitch * cpp;
@@ -100,7 +106,11 @@ pipe_put_tile_raw(struct pipe_context *pipe,
       return;
 
    pSrc = (const ubyte *) p;
-   pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp;
+
+   pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+   assert(pDest);               /* XXX: proper error handling */
+
+   pDest += (y * ps->pitch + x) * cpp;
 
    for (i = 0; i < h; i++) {
       memcpy(pDest, pSrc, w * cpp);
@@ -108,7 +118,7 @@ pipe_put_tile_raw(struct pipe_context *pipe,
       pSrc += src_stride;
    }
 
-   pipe_surface_unmap(ps);
+   screen->surface_unmap(screen, ps);
 }
 
 
@@ -169,6 +179,52 @@ a8r8g8b8_put_tile_rgba(unsigned *dst,
 }
 
 
+/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
+
+static void
+x8r8g8b8_get_tile_rgba(unsigned *src,
+                       unsigned w, unsigned h,
+                       float *p,
+                       unsigned dst_stride)
+{
+   unsigned i, j;
+
+   for (i = 0; i < h; i++) {
+      float *pRow = p;
+      for (j = 0; j < w; j++, pRow += 4) {
+         const unsigned pixel = *src++;
+         pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
+         pRow[1] = UBYTE_TO_FLOAT((pixel >>  8) & 0xff);
+         pRow[2] = UBYTE_TO_FLOAT((pixel >>  0) & 0xff);
+         pRow[3] = UBYTE_TO_FLOAT(0xff);
+      }
+      p += dst_stride;
+   }
+}
+
+
+static void
+x8r8g8b8_put_tile_rgba(unsigned *dst,
+                       unsigned w, unsigned h,
+                       const float *p,
+                       unsigned src_stride)
+{
+   unsigned i, j;
+
+   for (i = 0; i < h; i++) {
+      const float *pRow = p;
+      for (j = 0; j < w; j++, pRow += 4) {
+         unsigned r, g, b;
+         UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
+         UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
+         UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
+         *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
+      }
+      p += src_stride;
+   }
+}
+
+
 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
 
 static void
@@ -339,7 +395,7 @@ z16_get_tile_rgba(ushort *src,
 
 
 
-/*** PIPE_FORMAT_U_L8 ***/
+/*** PIPE_FORMAT_L8_UNORM ***/
 
 static void
 l8_get_tile_rgba(ubyte *src,
@@ -362,7 +418,7 @@ l8_get_tile_rgba(ubyte *src,
 }
 
 
-/*** PIPE_FORMAT_U_A8 ***/
+/*** PIPE_FORMAT_A8_UNORM ***/
 
 static void
 a8_get_tile_rgba(ubyte *src,
@@ -430,7 +486,7 @@ r16g16b16a16_put_tile_rgba(short *dst,
 
 
 
-/*** PIPE_FORMAT_U_I8 ***/
+/*** PIPE_FORMAT_I8_UNORM ***/
 
 static void
 i8_get_tile_rgba(ubyte *src,
@@ -453,7 +509,7 @@ i8_get_tile_rgba(ubyte *src,
 }
 
 
-/*** PIPE_FORMAT_U_A8_L8 ***/
+/*** PIPE_FORMAT_A8L8_UNORM ***/
 
 static void
 a8_l8_get_tile_rgba(ushort *src,
@@ -560,6 +616,70 @@ z24s8_get_tile_rgba(unsigned *src,
 }
 
 
+/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
+
+/**
+ * Convert YCbCr (or YCrCb) to RGBA.
+ */
+static void
+ycbcr_get_tile_rgba(ushort *src,
+                    unsigned w, unsigned h,
+                    float *p,
+                    unsigned dst_stride,
+                    boolean rev)
+{
+   const float scale = 1.0f / 255.0f;
+   unsigned i, j;
+
+   /* we're assuming we're being asked for an even number of texels */
+   assert((w & 1) == 0);
+
+   for (i = 0; i < h; i++) {
+      float *pRow = p;
+      /* do two texels at a time */
+      for (j = 0; j < w; j += 2, src += 2) {
+         const ushort t0 = src[0];
+         const ushort t1 = src[1];
+         const ubyte y0 = (t0 >> 8) & 0xff;  /* luminance */
+         const ubyte y1 = (t1 >> 8) & 0xff;  /* luminance */
+         ubyte cb, cr;
+         float r, g, b;
+
+         if (rev) {
+            cb = t1 & 0xff;         /* chroma U */
+            cr = t0 & 0xff;         /* chroma V */
+         }
+         else {
+            cb = t0 & 0xff;         /* chroma U */
+            cr = t1 & 0xff;         /* chroma V */
+         }
+
+         /* even pixel: y0,cr,cb */
+         r = 1.164f * (y0-16) + 1.596f * (cr-128);
+         g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+         b = 1.164f * (y0-16) + 2.018f * (cb-128);
+         pRow[0] = r * scale;
+         pRow[1] = g * scale;
+         pRow[2] = b * scale;
+         pRow[3] = 1.0f;
+         pRow += 4;
+
+         /* odd pixel: use y1,cr,cb */
+         r = 1.164f * (y1-16) + 1.596f * (cr-128);
+         g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+         b = 1.164f * (y1-16) + 2.018f * (cb-128);
+         pRow[0] = r * scale;
+         pRow[1] = g * scale;
+         pRow[2] = b * scale;
+         pRow[3] = 1.0f;
+         pRow += 4;
+
+      }
+      p += dst_stride;
+   }
+}
+
+
 void
 pipe_get_tile_rgba(struct pipe_context *pipe,
                    struct pipe_surface *ps,
@@ -583,6 +703,9 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
    case PIPE_FORMAT_A8R8G8B8_UNORM:
       a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
       break;
+   case PIPE_FORMAT_X8R8G8B8_UNORM:
+      x8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+      break;
    case PIPE_FORMAT_B8G8R8A8_UNORM:
       b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
       break;
@@ -595,16 +718,16 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
    case PIPE_FORMAT_R5G6B5_UNORM:
       r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
       break;
-   case PIPE_FORMAT_U_L8:
+   case PIPE_FORMAT_L8_UNORM:
       l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
       break;
-   case PIPE_FORMAT_U_A8:
+   case PIPE_FORMAT_A8_UNORM:
       a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
       break;
-   case PIPE_FORMAT_U_I8:
+   case PIPE_FORMAT_I8_UNORM:
       i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
       break;
-   case PIPE_FORMAT_U_A8_L8:
+   case PIPE_FORMAT_A8L8_UNORM:
       a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
       break;
    case PIPE_FORMAT_R16G16B16A16_SNORM:
@@ -617,11 +740,20 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
       z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
       break;
    case PIPE_FORMAT_S8Z24_UNORM:
+   case PIPE_FORMAT_X8Z24_UNORM:
       s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
       break;
    case PIPE_FORMAT_Z24S8_UNORM:
       z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
       break;
+   case PIPE_FORMAT_YCBCR:
+      assert((x & 1) == 0);
+      ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE);
+      break;
+   case PIPE_FORMAT_YCBCR_REV:
+      assert((x & 1) == 0);
+      ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE);
+      break;
    default:
       assert(0);
    }
@@ -651,6 +783,9 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
    case PIPE_FORMAT_A8R8G8B8_UNORM:
       a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
       break;
+   case PIPE_FORMAT_X8R8G8B8_UNORM:
+      x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
+      break;
    case PIPE_FORMAT_B8G8R8A8_UNORM:
       b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
       break;
@@ -662,16 +797,16 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
       break;
    case PIPE_FORMAT_R8G8B8A8_UNORM:
       break;
-   case PIPE_FORMAT_U_L8:
+   case PIPE_FORMAT_L8_UNORM:
       /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
       break;
-   case PIPE_FORMAT_U_A8:
+   case PIPE_FORMAT_A8_UNORM:
       /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
       break;
-   case PIPE_FORMAT_U_I8:
+   case PIPE_FORMAT_I8_UNORM:
       /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
       break;
-   case PIPE_FORMAT_U_A8_L8:
+   case PIPE_FORMAT_A8L8_UNORM:
       /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
       break;
    case PIPE_FORMAT_R16G16B16A16_SNORM:
@@ -684,6 +819,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
       /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
       break;
    case PIPE_FORMAT_S8Z24_UNORM:
+   case PIPE_FORMAT_X8Z24_UNORM:
       /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
       break;
    case PIPE_FORMAT_Z24S8_UNORM:
@@ -697,3 +833,145 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
 
    FREE(packed);
 }
+
+
+/**
+ * Get a block of Z values, converted to 32-bit range.
+ */
+void
+pipe_get_tile_z(struct pipe_context *pipe,
+                struct pipe_surface *ps,
+                uint x, uint y, uint w, uint h,
+                uint *z)
+{
+   struct pipe_screen *screen = pipe->screen;
+   const uint dstStride = w;
+   void *map;
+   uint *pDest = z;
+   uint i, j;
+
+   if (pipe_clip_tile(x, y, &w, &h, ps))
+      return;
+
+   map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
+   if (!map) {
+      assert(0);
+      return;
+   }
+
+   switch (ps->format) {
+   case PIPE_FORMAT_Z32_UNORM:
+      {
+         const uint *pSrc
+            = (const uint *)map  + (y * ps->pitch + x);
+         for (i = 0; i < h; i++) {
+            memcpy(pDest, pSrc, 4 * w);
+            pDest += dstStride;
+            pSrc += ps->pitch;
+         }
+      }
+      break;
+   case PIPE_FORMAT_S8Z24_UNORM:
+   case PIPE_FORMAT_X8Z24_UNORM:
+      {
+         const uint *pSrc
+            = (const uint *)map + (y * ps->pitch + x);
+         for (i = 0; i < h; i++) {
+            for (j = 0; j < w; j++) {
+               /* convert 24-bit Z to 32-bit Z */
+               pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff);
+            }
+            pDest += dstStride;
+            pSrc += ps->pitch;
+         }
+      }
+      break;
+   case PIPE_FORMAT_Z16_UNORM:
+      {
+         const ushort *pSrc
+            = (const ushort *)map + (y * ps->pitch + x);
+         for (i = 0; i < h; i++) {
+            for (j = 0; j < w; j++) {
+               /* convert 16-bit Z to 32-bit Z */
+               pDest[j] = (pSrc[j] << 16) | pSrc[j];
+            }
+            pDest += dstStride;
+            pSrc += ps->pitch;
+         }
+      }
+      break;
+   default:
+      assert(0);
+   }
+
+   screen->surface_unmap(screen, ps);
+}
+
+
+void
+pipe_put_tile_z(struct pipe_context *pipe,
+                struct pipe_surface *ps,
+                uint x, uint y, uint w, uint h,
+                const uint *zSrc)
+{
+   struct pipe_screen *screen = pipe->screen;
+   const uint srcStride = w;
+   const uint *pSrc = zSrc;
+   void *map;
+   uint i, j;
+
+   if (pipe_clip_tile(x, y, &w, &h, ps))
+      return;
+
+   map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+   if (!map) {
+      assert(0);
+      return;
+   }
+
+   switch (ps->format) {
+   case PIPE_FORMAT_Z32_UNORM:
+      {
+         uint *pDest = (uint *) map + (y * ps->pitch + x);
+         for (i = 0; i < h; i++) {
+            memcpy(pDest, pSrc, 4 * w);
+            pDest += ps->pitch;
+            pSrc += srcStride;
+         }
+      }
+      break;
+   case PIPE_FORMAT_S8Z24_UNORM:
+   case PIPE_FORMAT_X8Z24_UNORM:
+      {
+         uint *pDest = (uint *) map + (y * ps->pitch + x);
+         for (i = 0; i < h; i++) {
+            for (j = 0; j < w; j++) {
+               /* convert 32-bit Z to 24-bit Z (0 stencil) */
+               pDest[j] = pSrc[j] >> 8;
+            }
+            pDest += ps->pitch;
+            pSrc += srcStride;
+         }
+      }
+      break;
+   case PIPE_FORMAT_Z16_UNORM:
+      {
+         ushort *pDest = (ushort *) map + (y * ps->pitch + x);
+         for (i = 0; i < h; i++) {
+            for (j = 0; j < w; j++) {
+               /* convert 32-bit Z to 16-bit Z */
+               pDest[j] = pSrc[j] >> 16;
+            }
+            pDest += ps->pitch;
+            pSrc += srcStride;
+         }
+      }
+      break;
+   default:
+      assert(0);
+   }
+
+   screen->surface_unmap(screen, ps);
+}
+
+