mesa/formats: add more MESA_FORMAT_LAYOUTs
[mesa.git] / src / mesa / state_tracker / st_format.c
index 5f951eb02705122220de7f8fba453896d81b2fc7..db7b5b71d66923c80612a2c6d804c6ed3211cfe1 100644 (file)
@@ -54,7 +54,7 @@
  * Translate Mesa format to Gallium format.
  */
 enum pipe_format
-st_mesa_format_to_pipe_format(mesa_format mesaFormat)
+st_mesa_format_to_pipe_format(struct st_context *st, mesa_format mesaFormat)
 {
    switch (mesaFormat) {
    case MESA_FORMAT_A8B8G8R8_UNORM:
@@ -83,12 +83,18 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat)
       return PIPE_FORMAT_B2G3R3_UNORM;
    case MESA_FORMAT_B10G10R10A2_UNORM:
       return PIPE_FORMAT_B10G10R10A2_UNORM;
+   case MESA_FORMAT_R10G10B10A2_UNORM:
+      return PIPE_FORMAT_R10G10B10A2_UNORM;
    case MESA_FORMAT_L4A4_UNORM:
       return PIPE_FORMAT_L4A4_UNORM;
    case MESA_FORMAT_L8A8_UNORM:
-      return PIPE_FORMAT_L8A8_UNORM;
+      return PIPE_FORMAT_LA88_UNORM;
+   case MESA_FORMAT_A8L8_UNORM:
+      return PIPE_FORMAT_AL88_UNORM;
    case MESA_FORMAT_L16A16_UNORM:
-      return PIPE_FORMAT_L16A16_UNORM;
+      return PIPE_FORMAT_LA1616_UNORM;
+   case MESA_FORMAT_A16L16_UNORM:
+      return PIPE_FORMAT_AL1616_UNORM;
    case MESA_FORMAT_A_UNORM8:
       return PIPE_FORMAT_A8_UNORM;
    case MESA_FORMAT_A_UNORM16:
@@ -109,7 +115,7 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat)
       return PIPE_FORMAT_S8_UINT_Z24_UNORM;
    case MESA_FORMAT_Z24_UNORM_S8_UINT:
       return PIPE_FORMAT_Z24_UNORM_S8_UINT;
-   case MESA_FORMAT_X8Z24_UNORM:
+   case MESA_FORMAT_X8_UINT_Z24_UNORM:
       return PIPE_FORMAT_X8Z24_UNORM;
    case MESA_FORMAT_Z24_UNORM_X8_UINT:
       return PIPE_FORMAT_Z24X8_UNORM;
@@ -121,6 +127,8 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat)
       return PIPE_FORMAT_Z32_FLOAT_S8X24_UINT;
    case MESA_FORMAT_YCBCR:
       return PIPE_FORMAT_UYVY;
+   case MESA_FORMAT_YCBCR_REV:
+      return PIPE_FORMAT_YUYV;
    case MESA_FORMAT_RGB_DXT1:
       return PIPE_FORMAT_DXT1_RGB;
    case MESA_FORMAT_RGBA_DXT1:
@@ -138,15 +146,21 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat)
    case MESA_FORMAT_SRGBA_DXT5:
       return PIPE_FORMAT_DXT5_SRGBA;
    case MESA_FORMAT_L8A8_SRGB:
-      return PIPE_FORMAT_L8A8_SRGB;
+      return PIPE_FORMAT_LA88_SRGB;
+   case MESA_FORMAT_A8L8_SRGB:
+      return PIPE_FORMAT_AL88_SRGB;
    case MESA_FORMAT_L_SRGB8:
       return PIPE_FORMAT_L8_SRGB;
    case MESA_FORMAT_BGR_SRGB8:
       return PIPE_FORMAT_R8G8B8_SRGB;
    case MESA_FORMAT_A8B8G8R8_SRGB:
-      return PIPE_FORMAT_A8B8G8R8_SRGB;
+      return PIPE_FORMAT_ABGR8888_SRGB;
+   case MESA_FORMAT_R8G8B8A8_SRGB:
+      return PIPE_FORMAT_RGBA8888_SRGB;
    case MESA_FORMAT_B8G8R8A8_SRGB:
-      return PIPE_FORMAT_B8G8R8A8_SRGB;
+      return PIPE_FORMAT_BGRA8888_SRGB;
+   case MESA_FORMAT_A8R8G8B8_SRGB:
+      return PIPE_FORMAT_ARGB8888_SRGB;
    case MESA_FORMAT_RGBA_FLOAT32:
       return PIPE_FORMAT_R32G32B32A32_FLOAT;
    case MESA_FORMAT_RGBA_FLOAT16:
@@ -185,9 +199,13 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat)
    case MESA_FORMAT_R_UNORM16:
       return PIPE_FORMAT_R16_UNORM;
    case MESA_FORMAT_R8G8_UNORM:
-      return PIPE_FORMAT_R8G8_UNORM;
+      return PIPE_FORMAT_RG88_UNORM;
+   case MESA_FORMAT_G8R8_UNORM:
+      return PIPE_FORMAT_GR88_UNORM;
    case MESA_FORMAT_R16G16_UNORM:
-      return PIPE_FORMAT_R16G16_UNORM;
+      return PIPE_FORMAT_RG1616_UNORM;
+   case MESA_FORMAT_G16R16_UNORM:
+      return PIPE_FORMAT_GR1616_UNORM;
    case MESA_FORMAT_RGBA_UNORM16:
       return PIPE_FORMAT_R16G16B16A16_UNORM;
 
@@ -317,30 +335,49 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat)
    case MESA_FORMAT_LA_LATC2_SNORM:
       return PIPE_FORMAT_LATC2_SNORM;
 
+   /* The destination RGBA format mustn't be changed, because it's also
+    * a destination format of the unpack/decompression function. */
    case MESA_FORMAT_ETC1_RGB8:
-      return PIPE_FORMAT_ETC1_RGB8;
+      return st->has_etc1 ? PIPE_FORMAT_ETC1_RGB8 : PIPE_FORMAT_R8G8B8A8_UNORM;
+
+   case MESA_FORMAT_BPTC_RGBA_UNORM:
+      return PIPE_FORMAT_BPTC_RGBA_UNORM;
+   case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
+      return PIPE_FORMAT_BPTC_SRGBA;
+   case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT:
+      return PIPE_FORMAT_BPTC_RGB_FLOAT;
+   case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT:
+      return PIPE_FORMAT_BPTC_RGB_UFLOAT;
 
    /* signed normalized formats */
    case MESA_FORMAT_R_SNORM8:
       return PIPE_FORMAT_R8_SNORM;
    case MESA_FORMAT_R8G8_SNORM:
-      return PIPE_FORMAT_R8G8_SNORM;
+      return PIPE_FORMAT_RG88_SNORM;
+   case MESA_FORMAT_G8R8_SNORM:
+      return PIPE_FORMAT_GR88_SNORM;
    case MESA_FORMAT_R8G8B8A8_SNORM:
-      return PIPE_FORMAT_R8G8B8A8_SNORM;
+      return PIPE_FORMAT_RGBA8888_SNORM;
+   case MESA_FORMAT_A8B8G8R8_SNORM:
+      return PIPE_FORMAT_ABGR8888_SNORM;
 
    case MESA_FORMAT_A_SNORM8:
       return PIPE_FORMAT_A8_SNORM;
    case MESA_FORMAT_L_SNORM8:
       return PIPE_FORMAT_L8_SNORM;
    case MESA_FORMAT_L8A8_SNORM:
-      return PIPE_FORMAT_L8A8_SNORM;
+      return PIPE_FORMAT_LA88_SNORM;
+   case MESA_FORMAT_A8L8_SNORM:
+      return PIPE_FORMAT_AL88_SNORM;
    case MESA_FORMAT_I_SNORM8:
       return PIPE_FORMAT_I8_SNORM;
 
    case MESA_FORMAT_R_SNORM16:
       return PIPE_FORMAT_R16_SNORM;
    case MESA_FORMAT_R16G16_SNORM:
-      return PIPE_FORMAT_R16G16_SNORM;
+      return PIPE_FORMAT_RG1616_SNORM;
+   case MESA_FORMAT_G16R16_SNORM:
+      return PIPE_FORMAT_GR1616_SNORM;
    case MESA_FORMAT_RGBA_SNORM16:
       return PIPE_FORMAT_R16G16B16A16_SNORM;
 
@@ -367,9 +404,13 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat)
    case MESA_FORMAT_B5G5R5X1_UNORM:
       return PIPE_FORMAT_B5G5R5X1_UNORM;
    case MESA_FORMAT_R8G8B8X8_SNORM:
-      return PIPE_FORMAT_R8G8B8X8_SNORM;
+      return PIPE_FORMAT_RGBX8888_SNORM;
+   case MESA_FORMAT_X8B8G8R8_SNORM:
+      return PIPE_FORMAT_XBGR8888_SNORM;
    case MESA_FORMAT_R8G8B8X8_SRGB:
-      return PIPE_FORMAT_R8G8B8X8_SRGB;
+      return PIPE_FORMAT_RGBX8888_SRGB;
+   case MESA_FORMAT_X8B8G8R8_SRGB:
+      return PIPE_FORMAT_XBGR8888_SRGB;
    case MESA_FORMAT_RGBX_UINT8:
       return PIPE_FORMAT_R8G8B8X8_UINT;
    case MESA_FORMAT_RGBX_SINT8:
@@ -393,6 +434,35 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat)
    case MESA_FORMAT_RGBX_SINT32:
       return PIPE_FORMAT_R32G32B32X32_SINT;
 
+   case MESA_FORMAT_B8G8R8X8_SRGB:
+      return PIPE_FORMAT_BGRX8888_SRGB;
+   case MESA_FORMAT_X8R8G8B8_SRGB:
+      return PIPE_FORMAT_XRGB8888_SRGB;
+
+   /* ETC2 formats are emulated as uncompressed ones.
+    * The destination formats mustn't be changed, because they are also
+    * destination formats of the unpack/decompression function. */
+   case MESA_FORMAT_ETC2_RGB8:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_RGB8 : PIPE_FORMAT_R8G8B8A8_UNORM;
+   case MESA_FORMAT_ETC2_SRGB8:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_SRGB8 : PIPE_FORMAT_B8G8R8A8_SRGB;
+   case MESA_FORMAT_ETC2_RGBA8_EAC:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_RGBA8 : PIPE_FORMAT_R8G8B8A8_UNORM;
+   case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_SRGBA8 : PIPE_FORMAT_B8G8R8A8_SRGB;
+   case MESA_FORMAT_ETC2_R11_EAC:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_R11_UNORM : PIPE_FORMAT_R16_UNORM;
+   case MESA_FORMAT_ETC2_RG11_EAC:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_RG11_UNORM : PIPE_FORMAT_R16G16_UNORM;
+   case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_R11_SNORM : PIPE_FORMAT_R16_SNORM;
+   case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_RG11_SNORM : PIPE_FORMAT_R16G16_SNORM;
+   case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_RGB8A1 : PIPE_FORMAT_R8G8B8A8_UNORM;
+   case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_SRGB8A1 : PIPE_FORMAT_B8G8R8A8_SRGB;
+
    default:
       return PIPE_FORMAT_NONE;
    }
@@ -432,12 +502,18 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
       return MESA_FORMAT_B2G3R3_UNORM;
    case PIPE_FORMAT_B10G10R10A2_UNORM:
       return MESA_FORMAT_B10G10R10A2_UNORM;
+   case PIPE_FORMAT_R10G10B10A2_UNORM:
+      return MESA_FORMAT_R10G10B10A2_UNORM;
    case PIPE_FORMAT_L4A4_UNORM:
       return MESA_FORMAT_L4A4_UNORM;
-   case PIPE_FORMAT_L8A8_UNORM:
+   case PIPE_FORMAT_LA88_UNORM:
       return MESA_FORMAT_L8A8_UNORM;
-   case PIPE_FORMAT_L16A16_UNORM:
+   case PIPE_FORMAT_AL88_UNORM:
+      return MESA_FORMAT_A8L8_UNORM;
+   case PIPE_FORMAT_LA1616_UNORM:
       return MESA_FORMAT_L16A16_UNORM;
+   case PIPE_FORMAT_AL1616_UNORM:
+      return MESA_FORMAT_A16L16_UNORM;
    case PIPE_FORMAT_A8_UNORM:
       return MESA_FORMAT_A_UNORM8;
    case PIPE_FORMAT_A16_UNORM:
@@ -463,7 +539,7 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
       return MESA_FORMAT_S8_UINT_Z24_UNORM;
    case PIPE_FORMAT_X8Z24_UNORM:
-      return MESA_FORMAT_X8Z24_UNORM;
+      return MESA_FORMAT_X8_UINT_Z24_UNORM;
    case PIPE_FORMAT_Z24X8_UNORM:
       return MESA_FORMAT_Z24_UNORM_X8_UINT;
    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
@@ -494,16 +570,22 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
       return MESA_FORMAT_SRGBA_DXT3;
    case PIPE_FORMAT_DXT5_SRGBA:
       return MESA_FORMAT_SRGBA_DXT5;
-   case PIPE_FORMAT_L8A8_SRGB:
+   case PIPE_FORMAT_LA88_SRGB:
       return MESA_FORMAT_L8A8_SRGB;
+   case PIPE_FORMAT_AL88_SRGB:
+      return MESA_FORMAT_A8L8_SRGB;
    case PIPE_FORMAT_L8_SRGB:
       return MESA_FORMAT_L_SRGB8;
    case PIPE_FORMAT_R8G8B8_SRGB:
       return MESA_FORMAT_BGR_SRGB8;
-   case PIPE_FORMAT_A8B8G8R8_SRGB:
+   case PIPE_FORMAT_ABGR8888_SRGB:
       return MESA_FORMAT_A8B8G8R8_SRGB;
-   case PIPE_FORMAT_B8G8R8A8_SRGB:
+   case PIPE_FORMAT_RGBA8888_SRGB:
+      return MESA_FORMAT_R8G8B8A8_SRGB;
+   case PIPE_FORMAT_BGRA8888_SRGB:
       return MESA_FORMAT_B8G8R8A8_SRGB;
+   case PIPE_FORMAT_ARGB8888_SRGB:
+      return MESA_FORMAT_A8R8G8B8_SRGB;
    case PIPE_FORMAT_R32G32B32A32_FLOAT:
       return MESA_FORMAT_RGBA_FLOAT32;
    case PIPE_FORMAT_R16G16B16A16_FLOAT:
@@ -541,10 +623,14 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
       return MESA_FORMAT_R_UNORM8;
    case PIPE_FORMAT_R16_UNORM:
       return MESA_FORMAT_R_UNORM16;
-   case PIPE_FORMAT_R8G8_UNORM:
+   case PIPE_FORMAT_RG88_UNORM:
       return MESA_FORMAT_R8G8_UNORM;
-   case PIPE_FORMAT_R16G16_UNORM:
+   case PIPE_FORMAT_GR88_UNORM:
+      return MESA_FORMAT_G8R8_UNORM;
+   case PIPE_FORMAT_RG1616_UNORM:
       return MESA_FORMAT_R16G16_UNORM;
+   case PIPE_FORMAT_GR1616_UNORM:
+      return MESA_FORMAT_G16R16_UNORM;
 
    case PIPE_FORMAT_A8_UINT:
       return MESA_FORMAT_A_UINT8;
@@ -674,27 +760,44 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
    case PIPE_FORMAT_ETC1_RGB8:
       return MESA_FORMAT_ETC1_RGB8;
 
+   case PIPE_FORMAT_BPTC_RGBA_UNORM:
+      return MESA_FORMAT_BPTC_RGBA_UNORM;
+   case PIPE_FORMAT_BPTC_SRGBA:
+      return MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM;
+   case PIPE_FORMAT_BPTC_RGB_FLOAT:
+      return MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT;
+   case PIPE_FORMAT_BPTC_RGB_UFLOAT:
+      return MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT;
+
    /* signed normalized formats */
    case PIPE_FORMAT_R8_SNORM:
       return MESA_FORMAT_R_SNORM8;
-   case PIPE_FORMAT_R8G8_SNORM:
+   case PIPE_FORMAT_RG88_SNORM:
       return MESA_FORMAT_R8G8_SNORM;
-   case PIPE_FORMAT_R8G8B8A8_SNORM:
+   case PIPE_FORMAT_GR88_SNORM:
+      return MESA_FORMAT_G8R8_SNORM;
+   case PIPE_FORMAT_RGBA8888_SNORM:
       return MESA_FORMAT_R8G8B8A8_SNORM;
+   case PIPE_FORMAT_ABGR8888_SNORM:
+      return MESA_FORMAT_A8B8G8R8_SNORM;
 
    case PIPE_FORMAT_A8_SNORM:
       return MESA_FORMAT_A_SNORM8;
    case PIPE_FORMAT_L8_SNORM:
       return MESA_FORMAT_L_SNORM8;
-   case PIPE_FORMAT_L8A8_SNORM:
+   case PIPE_FORMAT_LA88_SNORM:
       return MESA_FORMAT_L8A8_SNORM;
+   case PIPE_FORMAT_AL88_SNORM:
+      return MESA_FORMAT_A8L8_SNORM;
    case PIPE_FORMAT_I8_SNORM:
       return MESA_FORMAT_I_SNORM8;
 
    case PIPE_FORMAT_R16_SNORM:
       return MESA_FORMAT_R_SNORM16;
-   case PIPE_FORMAT_R16G16_SNORM:
+   case PIPE_FORMAT_RG1616_SNORM:
       return MESA_FORMAT_R16G16_SNORM;
+   case PIPE_FORMAT_GR1616_SNORM:
+      return MESA_FORMAT_G16R16_SNORM;
    case PIPE_FORMAT_R16G16B16A16_SNORM:
       return MESA_FORMAT_RGBA_SNORM16;
 
@@ -721,10 +824,14 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
       return MESA_FORMAT_B4G4R4X4_UNORM;
    case PIPE_FORMAT_B5G5R5X1_UNORM:
       return MESA_FORMAT_B5G5R5X1_UNORM;
-   case PIPE_FORMAT_R8G8B8X8_SNORM:
+   case PIPE_FORMAT_RGBX8888_SNORM:
       return MESA_FORMAT_R8G8B8X8_SNORM;
-   case PIPE_FORMAT_R8G8B8X8_SRGB:
+   case PIPE_FORMAT_XBGR8888_SNORM:
+      return MESA_FORMAT_X8B8G8R8_SNORM;
+   case PIPE_FORMAT_RGBX8888_SRGB:
       return MESA_FORMAT_R8G8B8X8_SRGB;
+   case PIPE_FORMAT_XBGR8888_SRGB:
+      return MESA_FORMAT_X8B8G8R8_SRGB;
    case PIPE_FORMAT_R8G8B8X8_UINT:
       return MESA_FORMAT_RGBX_UINT8;
    case PIPE_FORMAT_R8G8B8X8_SINT:
@@ -748,13 +855,83 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
    case PIPE_FORMAT_R32G32B32X32_SINT:
       return MESA_FORMAT_RGBX_SINT32;
 
+   case PIPE_FORMAT_BGRX8888_SRGB:
+      return MESA_FORMAT_B8G8R8X8_SRGB;
+   case PIPE_FORMAT_XRGB8888_SRGB:
+      return MESA_FORMAT_X8R8G8B8_SRGB;
+
+   case PIPE_FORMAT_ETC2_RGB8:
+      return MESA_FORMAT_ETC2_RGB8;
+   case PIPE_FORMAT_ETC2_SRGB8:
+      return MESA_FORMAT_ETC2_SRGB8;
+   case PIPE_FORMAT_ETC2_RGB8A1:
+      return MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
+   case PIPE_FORMAT_ETC2_SRGB8A1:
+      return MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
+   case PIPE_FORMAT_ETC2_RGBA8:
+      return MESA_FORMAT_ETC2_RGBA8_EAC;
+   case PIPE_FORMAT_ETC2_SRGBA8:
+      return MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC;
+   case PIPE_FORMAT_ETC2_R11_UNORM:
+      return MESA_FORMAT_ETC2_R11_EAC;
+   case PIPE_FORMAT_ETC2_R11_SNORM:
+      return MESA_FORMAT_ETC2_SIGNED_R11_EAC;
+   case PIPE_FORMAT_ETC2_RG11_UNORM:
+      return MESA_FORMAT_ETC2_RG11_EAC;
+   case PIPE_FORMAT_ETC2_RG11_SNORM:
+      return MESA_FORMAT_ETC2_SIGNED_RG11_EAC;
+
    default:
-      assert(0);
       return MESA_FORMAT_NONE;
    }
 }
 
 
+/**
+ * Debug only: check that the two functions above correctly map
+ * Mesa formats to Gallium formats and back again.
+ */
+static void
+test_format_conversion(struct st_context *st)
+{
+   GLuint i;
+
+   /* test all Mesa formats */
+   for (i = 1; i < MESA_FORMAT_COUNT; i++) {
+      enum pipe_format pf;
+
+      /* ETC formats are translated differently, skip them. */
+      if (_mesa_is_format_etc2(i))
+         continue;
+      if (i == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)
+         continue;
+
+      pf = st_mesa_format_to_pipe_format(st, i);
+      if (pf != PIPE_FORMAT_NONE) {
+         mesa_format mf = st_pipe_format_to_mesa_format(pf);
+         assert(mf == i);
+      }
+   }
+
+   /* Test all Gallium formats */
+   for (i = 1; i < PIPE_FORMAT_COUNT; i++) {
+      mesa_format mf = st_pipe_format_to_mesa_format(i);
+
+      /* ETC formats are translated differently, skip them. */
+      if (i == PIPE_FORMAT_ETC1_RGB8 && !st->has_etc1)
+         continue;
+
+      if (_mesa_is_format_etc2(mf) && !st->has_etc2)
+         continue;
+
+      if (mf != MESA_FORMAT_NONE) {
+         enum pipe_format pf = st_mesa_format_to_pipe_format(st, mf);
+         assert(pf == i);
+      }
+   }
+}
+
+
 /**
  * Map GL texture formats to Gallium pipe formats.
  */
@@ -782,6 +959,7 @@ struct format_mapping
 
 #define DEFAULT_SRGBA_FORMATS \
       PIPE_FORMAT_B8G8R8A8_SRGB, \
+      PIPE_FORMAT_R8G8B8A8_SRGB, \
       PIPE_FORMAT_A8R8G8B8_SRGB, \
       PIPE_FORMAT_A8B8G8R8_SRGB, \
       0
@@ -813,19 +991,20 @@ static const struct format_mapping format_map[] = {
    {
       { GL_RGB10, 0 },
       { PIPE_FORMAT_B10G10R10X2_UNORM, PIPE_FORMAT_B10G10R10A2_UNORM,
-        DEFAULT_RGB_FORMATS }
+        PIPE_FORMAT_R10G10B10A2_UNORM, DEFAULT_RGB_FORMATS }
    },
    {
       { GL_RGB10_A2, 0 },
-      { PIPE_FORMAT_B10G10R10A2_UNORM, DEFAULT_RGBA_FORMATS }
+      { PIPE_FORMAT_B10G10R10A2_UNORM, PIPE_FORMAT_R10G10B10A2_UNORM,
+        DEFAULT_RGBA_FORMATS }
    },
    {
       { 4, GL_RGBA, GL_RGBA8, 0 },
-      { PIPE_FORMAT_R8G8B8A8_UNORM, DEFAULT_RGBA_FORMATS }
+      { DEFAULT_RGBA_FORMATS }
    },
    {
       { GL_BGRA, 0 },
-      { PIPE_FORMAT_B8G8R8A8_UNORM, DEFAULT_RGBA_FORMATS }
+      { DEFAULT_RGBA_FORMATS }
    },
    {
       { 3, GL_RGB, GL_RGB8, 0 },
@@ -1006,7 +1185,8 @@ static const struct format_mapping format_map[] = {
    /* sRGB formats */
    {
       { GL_SRGB_EXT, GL_SRGB8_EXT, 0 },
-      { PIPE_FORMAT_R8G8B8X8_SRGB, DEFAULT_SRGBA_FORMATS }
+      { PIPE_FORMAT_R8G8B8X8_SRGB, PIPE_FORMAT_B8G8R8X8_SRGB,
+        DEFAULT_SRGBA_FORMATS }
    },
    {
       { GL_SRGB_ALPHA_EXT, GL_SRGB8_ALPHA8_EXT, 0 },
@@ -1015,7 +1195,7 @@ static const struct format_mapping format_map[] = {
    {
       { GL_COMPRESSED_SRGB_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 0 },
       { PIPE_FORMAT_DXT1_SRGB, PIPE_FORMAT_R8G8B8X8_SRGB,
-        DEFAULT_SRGBA_FORMATS }
+        PIPE_FORMAT_B8G8R8X8_SRGB, DEFAULT_SRGBA_FORMATS }
    },
    {
       { GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0 },
@@ -1192,6 +1372,24 @@ static const struct format_mapping format_map[] = {
       { PIPE_FORMAT_ETC1_RGB8, 0 }
    },
 
+   /* BPTC */
+   {
+      { GL_COMPRESSED_RGBA_BPTC_UNORM, 0 },
+      { PIPE_FORMAT_BPTC_RGBA_UNORM, 0 },
+   },
+   {
+      { GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, 0 },
+      { PIPE_FORMAT_BPTC_SRGBA, 0 },
+   },
+   {
+      { GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, 0 },
+      { PIPE_FORMAT_BPTC_RGB_FLOAT, 0 },
+   },
+   {
+      { GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, 0 },
+      { PIPE_FORMAT_BPTC_RGB_UFLOAT, 0 },
+   },
+
    /* signed/unsigned integer formats.
     */
    {
@@ -1627,9 +1825,22 @@ st_choose_format(struct st_context *st, GLenum internalFormat,
                  unsigned bindings, boolean allow_dxt)
 {
    struct pipe_screen *screen = st->pipe->screen;
-   int i, j;
+   unsigned i;
+   int j;
    enum pipe_format pf;
 
+#ifdef DEBUG
+   {
+      static boolean firstCall = TRUE;
+      if (firstCall) {
+         test_format_conversion(st);
+         firstCall = FALSE;
+      }
+   }
+#else
+   (void) test_format_conversion;
+#endif
+
    /* can't render to compressed formats at this time */
    if (_mesa_is_compressed_format(st->ctx, internalFormat)
        && (bindings & ~PIPE_BIND_SAMPLER_VIEW)) {
@@ -1644,7 +1855,7 @@ st_choose_format(struct st_context *st, GLenum internalFormat,
       return pf;
 
    /* search table for internalFormat */
-   for (i = 0; i < Elements(format_map); i++) {
+   for (i = 0; i < ARRAY_SIZE(format_map); i++) {
       const struct format_mapping *mapping = &format_map[i];
       for (j = 0; mapping->glFormats[j]; j++) {
          if (mapping->glFormats[j] == internalFormat) {
@@ -1688,19 +1899,27 @@ st_choose_renderbuffer_format(struct st_context *st,
  * If no format is supported, return PIPE_FORMAT_NONE.
  */
 enum pipe_format
-st_choose_matching_format(struct pipe_screen *screen, unsigned bind,
+st_choose_matching_format(struct st_context *st, unsigned bind,
                          GLenum format, GLenum type, GLboolean swapBytes)
 {
+   struct pipe_screen *screen = st->pipe->screen;
    mesa_format mesa_format;
 
    for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) {
       if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) {
          continue;
       }
+      if (_mesa_get_format_bits(mesa_format, GL_TEXTURE_INTENSITY_SIZE) > 0) {
+         /* If `format` is GL_RED/GL_RED_INTEGER, then we might match some
+          * intensity formats, which we don't want.
+          */
+         continue;
+      }
 
       if (_mesa_format_matches_format_and_type(mesa_format, format, type,
                                                swapBytes)) {
-         enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format);
+         enum pipe_format format =
+            st_mesa_format_to_pipe_format(st, mesa_format);
 
          if (format &&
              screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0,
@@ -1723,11 +1942,6 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
                        GLint internalFormat,
                        GLenum format, GLenum type)
 {
-   const boolean want_renderable =
-      internalFormat == 3 || internalFormat == 4 ||
-      internalFormat == GL_RGB || internalFormat == GL_RGBA ||
-      internalFormat == GL_RGB8 || internalFormat == GL_RGBA8 ||
-      internalFormat == GL_BGRA;
    struct st_context *st = st_context(ctx);
    enum pipe_format pFormat;
    unsigned bindings;
@@ -1743,15 +1957,17 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
    }
 
    /* GL textures may wind up being render targets, but we don't know
-    * that in advance.  Specify potential render target flags now.
+    * that in advance.  Specify potential render target flags now for formats
+    * that we know should always be renderable.
     */
    bindings = PIPE_BIND_SAMPLER_VIEW;
-   if (want_renderable) {
-      if (_mesa_is_depth_or_stencil_format(internalFormat))
-        bindings |= PIPE_BIND_DEPTH_STENCIL;
-      else
+   if (_mesa_is_depth_or_stencil_format(internalFormat))
+      bindings |= PIPE_BIND_DEPTH_STENCIL;
+   else if (internalFormat == 3 || internalFormat == 4 ||
+            internalFormat == GL_RGB || internalFormat == GL_RGBA ||
+            internalFormat == GL_RGB8 || internalFormat == GL_RGBA8 ||
+            internalFormat == GL_BGRA)
         bindings |= PIPE_BIND_RENDER_TARGET;
-   }
 
    /* GLES allows the driver to choose any format which matches
     * the format+type combo, because GLES only supports unsized internal
@@ -1770,16 +1986,14 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
        * with the "format".
        */
       if (iformat == baseFormat && iformat == basePackFormat) {
-         pFormat = st_choose_matching_format(st->pipe->screen, bindings,
-                                             format, type,
+         pFormat = st_choose_matching_format(st, bindings, format, type,
                                              ctx->Unpack.SwapBytes);
 
          if (pFormat != PIPE_FORMAT_NONE)
             return st_pipe_format_to_mesa_format(pFormat);
 
          /* try choosing format again, this time without render target bindings */
-         pFormat = st_choose_matching_format(st->pipe->screen,
-                                             PIPE_BIND_SAMPLER_VIEW,
+         pFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
                                              format, type,
                                              ctx->Unpack.SwapBytes);
          if (pFormat != PIPE_FORMAT_NONE)