u_blitter: add a msaa parameter to util_blitter_clear
[mesa.git] / src / gallium / auxiliary / util / u_pack_color.h
index 3ebef9fb7491a7a5f17ef9086b2042d29aa4d9c3..0166126c56fca74b07cb574b1f556f89d7bb2f67 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "pipe/p_compiler.h"
 #include "pipe/p_format.h"
-#include "util/u_debug.h"
+#include "util/u_debug_gallium.h"
 #include "util/u_format.h"
 #include "util/u_math.h"
 
 
-
+/**
+ * Helper union for packing pixel values.
+ * Will often contain values in formats which are too complex to be described
+ * in simple terms, hence might just effectively contain a number of bytes.
+ * Must be big enough to hold data for all formats (currently 256 bits).
+ */
 union util_color {
    ubyte ub;
    ushort us;
-   uint ui;
+   uint ui[4];
+   ushort h[4]; /* half float */
    float f[4];
+   double d[4];
 };
 
 /**
  * Pack ubyte R,G,B,A into dest pixel.
  */
-static INLINE void
+static inline void
 util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
                    enum pipe_format format, union util_color *uc)
 {
    switch (format) {
-   case PIPE_FORMAT_A8B8G8R8_UNORM:
+   case PIPE_FORMAT_ABGR8888_UNORM:
       {
-         uc->ui = (r << 24) | (g << 16) | (b << 8) | a;
+         uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | a;
       }
       return;
-   case PIPE_FORMAT_X8B8G8R8_UNORM:
+   case PIPE_FORMAT_XBGR8888_UNORM:
       {
-         uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff;
+         uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | 0xff;
       }
       return;
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
+   case PIPE_FORMAT_BGRA8888_UNORM:
       {
-         uc->ui = (a << 24) | (r << 16) | (g << 8) | b;
+         uc->ui[0] = (a << 24) | (r << 16) | (g << 8) | b;
       }
       return;
-   case PIPE_FORMAT_B8G8R8X8_UNORM:
+   case PIPE_FORMAT_BGRX8888_UNORM:
       {
-         uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b;
+         uc->ui[0] = (0xff << 24) | (r << 16) | (g << 8) | b;
       }
       return;
-   case PIPE_FORMAT_A8R8G8B8_UNORM:
+   case PIPE_FORMAT_ARGB8888_UNORM:
       {
-         uc->ui = (b << 24) | (g << 16) | (r << 8) | a;
+         uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | a;
       }
       return;
-   case PIPE_FORMAT_X8R8G8B8_UNORM:
+   case PIPE_FORMAT_XRGB8888_UNORM:
       {
-         uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff;
+         uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | 0xff;
       }
       return;
    case PIPE_FORMAT_B5G6R5_UNORM:
@@ -116,7 +123,7 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
    case PIPE_FORMAT_L8_UNORM:
    case PIPE_FORMAT_I8_UNORM:
       {
-         uc->ub = a;
+         uc->ub = r;
       }
       return;
    case PIPE_FORMAT_R32G32B32A32_FLOAT:
@@ -154,59 +161,59 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
 /**
  * Unpack RGBA from a packed pixel, returning values as ubytes in [0,255].
  */
-static INLINE void
+static inline void
 util_unpack_color_ub(enum pipe_format format, union util_color *uc,
                      ubyte *r, ubyte *g, ubyte *b, ubyte *a)
 {
    switch (format) {
-   case PIPE_FORMAT_A8B8G8R8_UNORM:
+   case PIPE_FORMAT_ABGR8888_UNORM:
       {
-         uint p = uc->ui;
+         uint p = uc->ui[0];
          *r = (ubyte) ((p >> 24) & 0xff);
          *g = (ubyte) ((p >> 16) & 0xff);
          *b = (ubyte) ((p >>  8) & 0xff);
          *a = (ubyte) ((p >>  0) & 0xff);
       }
       return;
-   case PIPE_FORMAT_X8B8G8R8_UNORM:
+   case PIPE_FORMAT_XBGR8888_UNORM:
       {
-         uint p = uc->ui;
+         uint p = uc->ui[0];
          *r = (ubyte) ((p >> 24) & 0xff);
          *g = (ubyte) ((p >> 16) & 0xff);
          *b = (ubyte) ((p >>  8) & 0xff);
          *a = (ubyte) 0xff;
       }
       return;
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
+   case PIPE_FORMAT_BGRA8888_UNORM:
       {
-         uint p = uc->ui;
+         uint p = uc->ui[0];
          *r = (ubyte) ((p >> 16) & 0xff);
          *g = (ubyte) ((p >>  8) & 0xff);
          *b = (ubyte) ((p >>  0) & 0xff);
          *a = (ubyte) ((p >> 24) & 0xff);
       }
       return;
-   case PIPE_FORMAT_B8G8R8X8_UNORM:
+   case PIPE_FORMAT_BGRX8888_UNORM:
       {
-         uint p = uc->ui;
+         uint p = uc->ui[0];
          *r = (ubyte) ((p >> 16) & 0xff);
          *g = (ubyte) ((p >>  8) & 0xff);
          *b = (ubyte) ((p >>  0) & 0xff);
          *a = (ubyte) 0xff;
       }
       return;
-   case PIPE_FORMAT_A8R8G8B8_UNORM:
+   case PIPE_FORMAT_ARGB8888_UNORM:
       {
-         uint p = uc->ui;
+         uint p = uc->ui[0];
          *r = (ubyte) ((p >>  8) & 0xff);
          *g = (ubyte) ((p >> 16) & 0xff);
          *b = (ubyte) ((p >> 24) & 0xff);
          *a = (ubyte) ((p >>  0) & 0xff);
       }
       return;
-   case PIPE_FORMAT_X8R8G8B8_UNORM:
+   case PIPE_FORMAT_XRGB8888_UNORM:
       {
-         uint p = uc->ui;
+         uint p = uc->ui[0];
          *r = (ubyte) ((p >>  8) & 0xff);
          *g = (ubyte) ((p >> 16) & 0xff);
          *b = (ubyte) ((p >> 24) & 0xff);
@@ -323,8 +330,10 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc,
 
 /**
  * Note rgba outside [0,1] will be clamped for int pixel formats.
+ * This will not work (and might not really be useful with float input)
+ * for pure integer formats (which lack the pack_rgba_float function).
  */
-static INLINE void
+static inline void
 util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc)
 {
    ubyte r = 0;
@@ -341,34 +350,34 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color *
    }
 
    switch (format) {
-   case PIPE_FORMAT_A8B8G8R8_UNORM:
+   case PIPE_FORMAT_ABGR8888_UNORM:
       {
-         uc->ui = (r << 24) | (g << 16) | (b << 8) | a;
+         uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | a;
       }
       return;
-   case PIPE_FORMAT_X8B8G8R8_UNORM:
+   case PIPE_FORMAT_XBGR8888_UNORM:
       {
-         uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff;
+         uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | 0xff;
       }
       return;
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
+   case PIPE_FORMAT_BGRA8888_UNORM:
       {
-         uc->ui = (a << 24) | (r << 16) | (g << 8) | b;
+         uc->ui[0] = (a << 24) | (r << 16) | (g << 8) | b;
       }
       return;
-   case PIPE_FORMAT_B8G8R8X8_UNORM:
+   case PIPE_FORMAT_BGRX8888_UNORM:
       {
-         uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b;
+         uc->ui[0] = (0xffu << 24) | (r << 16) | (g << 8) | b;
       }
       return;
-   case PIPE_FORMAT_A8R8G8B8_UNORM:
+   case PIPE_FORMAT_ARGB8888_UNORM:
       {
-         uc->ui = (b << 24) | (g << 16) | (r << 8) | a;
+         uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | a;
       }
       return;
-   case PIPE_FORMAT_X8R8G8B8_UNORM:
+   case PIPE_FORMAT_XRGB8888_UNORM:
       {
-         uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff;
+         uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | 0xff;
       }
       return;
    case PIPE_FORMAT_B5G6R5_UNORM:
@@ -388,7 +397,7 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color *
       return;
    case PIPE_FORMAT_B4G4R4A4_UNORM:
       {
-         uc->ub = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
+         uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
       }
       return;
    case PIPE_FORMAT_A8_UNORM:
@@ -425,13 +434,93 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color *
    }
 }
  
+/* Integer versions of util_pack_z and util_pack_z_stencil - useful for
+ * constructing clear masks.
+ */
+static inline uint32_t
+util_pack_mask_z(enum pipe_format format, uint32_t z)
+{
+   switch (format) {
+   case PIPE_FORMAT_Z16_UNORM:
+      return z & 0xffff;
+   case PIPE_FORMAT_Z32_UNORM:
+   case PIPE_FORMAT_Z32_FLOAT:
+      return z;
+   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+   case PIPE_FORMAT_Z24X8_UNORM:
+      return z & 0xffffff;
+   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
+   case PIPE_FORMAT_X8Z24_UNORM:
+      return (z & 0xffffff) << 8;
+   case PIPE_FORMAT_S8_UINT:
+      return 0;
+   default:
+      debug_print_format("gallium: unhandled format in util_pack_mask_z()", format);
+      assert(0);
+      return 0;
+   }
+}
+
+
+static inline uint64_t
+util_pack64_mask_z(enum pipe_format format, uint32_t z)
+{
+   switch (format) {
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      return z;
+   default:
+      return util_pack_mask_z(format, z);
+   }
+}
+
+
+static inline uint32_t
+util_pack_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s)
+{
+   uint32_t packed = util_pack_mask_z(format, z);
+
+   switch (format) {
+   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+      packed |= (uint32_t)s << 24;
+      break;
+   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
+      packed |= s;
+      break;
+   case PIPE_FORMAT_S8_UINT:
+      packed |= s;
+      break;
+   default:
+      break;
+   }
+
+   return packed;
+}
+
+
+static inline uint64_t
+util_pack64_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s)
+{
+   uint64_t packed;
+
+   switch (format) {
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      packed = util_pack64_mask_z(format, z);
+      packed |= (uint64_t)s << 32ull;
+      return packed;
+   default:
+      return util_pack_mask_z_stencil(format, z, s);
+   }
+}
+
 
 /**
  * Note: it's assumed that z is in [0,1]
  */
-static INLINE uint
+static inline uint32_t
 util_pack_z(enum pipe_format format, double z)
 {
+   union fi fui;
+
    if (z == 0.0)
       return 0;
 
@@ -439,25 +528,26 @@ util_pack_z(enum pipe_format format, double z)
    case PIPE_FORMAT_Z16_UNORM:
       if (z == 1.0)
          return 0xffff;
-      return (uint(z * 0xffff);
+      return (uint32_t) lrint(z * 0xffff);
    case PIPE_FORMAT_Z32_UNORM:
       /* special-case to avoid overflow */
       if (z == 1.0)
          return 0xffffffff;
-      return (uint(z * 0xffffffff);
+      return (uint32_t) llrint(z * 0xffffffff);
    case PIPE_FORMAT_Z32_FLOAT:
-      return (uint)z;
-   case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+      fui.f = (float)z;
+      return fui.ui;
+   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    case PIPE_FORMAT_Z24X8_UNORM:
       if (z == 1.0)
          return 0xffffff;
-      return (uint(z * 0xffffff);
-   case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+      return (uint32_t) lrint(z * 0xffffff);
+   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    case PIPE_FORMAT_X8Z24_UNORM:
       if (z == 1.0)
          return 0xffffff00;
-      return ((uint(z * 0xffffff)) << 8;
-   case PIPE_FORMAT_S8_USCALED:
+      return ((uint32_t) lrint(z * 0xffffff)) << 8;
+   case PIPE_FORMAT_S8_UINT:
       /* this case can get it via util_pack_z_stencil() */
       return 0;
    default:
@@ -466,25 +556,43 @@ util_pack_z(enum pipe_format format, double z)
       return 0;
    }
 }
+
+
+static inline uint64_t
+util_pack64_z(enum pipe_format format, double z)
+{
+   union fi fui;
+
+   if (z == 0)
+      return 0;
+
+   switch (format) {
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      fui.f = (float)z;
+      return fui.ui;
+   default:
+      return util_pack_z(format, z);
+   }
+}
  
 
 /**
  * Pack Z and/or stencil values into a 32-bit value described by format.
  * Note: it's assumed that z is in [0,1] and s in [0,255]
  */
-static INLINE uint
-util_pack_z_stencil(enum pipe_format format, double z, uint s)
+static inline uint32_t
+util_pack_z_stencil(enum pipe_format format, double z, uint8_t s)
 {
-   unsigned packed = util_pack_z(format, z);
+   uint32_t packed = util_pack_z(format, z);
 
    switch (format) {
-   case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
-      packed |= s << 24;
+   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+      packed |= (uint32_t)s << 24;
       break;
-   case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
       packed |= s;
       break;
-   case PIPE_FORMAT_S8_USCALED:
+   case PIPE_FORMAT_S8_UINT:
       packed |= s;
       break;
    default:
@@ -495,10 +603,28 @@ util_pack_z_stencil(enum pipe_format format, double z, uint s)
 }
 
 
+static inline uint64_t
+util_pack64_z_stencil(enum pipe_format format, double z, uint8_t s)
+{
+   uint64_t packed;
+
+   switch (format) {
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      packed = util_pack64_z(format, z);
+      packed |= (uint64_t)s << 32ull;
+      break;
+   default:
+      return util_pack_z_stencil(format, z, s);
+   }
+
+   return packed;
+}
+
+
 /**
  * Pack 4 ubytes into a 4-byte word
  */
-static INLINE unsigned
+static inline unsigned
 pack_ub4(ubyte b0, ubyte b1, ubyte b2, ubyte b3)
 {
    return ((((unsigned int)b0) << 0) |
@@ -511,7 +637,7 @@ pack_ub4(ubyte b0, ubyte b1, ubyte b2, ubyte b3)
 /**
  * Pack/convert 4 floats into one 4-byte word.
  */
-static INLINE unsigned
+static inline unsigned
 pack_ui32_float4(float a, float b, float c, float d)
 {
    return pack_ub4( float_to_ubyte(a),