mesa/formats: add more MESA_FORMAT_LAYOUTs
[mesa.git] / src / mesa / state_tracker / st_format.c
index 3d822a5a4e4fa7e7025bf6fc6b5f264c822c7c37..db7b5b71d66923c80612a2c6d804c6ed3211cfe1 100644 (file)
@@ -88,9 +88,13 @@ st_mesa_format_to_pipe_format(struct st_context *st, mesa_format mesaFormat)
    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:
@@ -142,17 +146,21 @@ st_mesa_format_to_pipe_format(struct st_context *st, 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;
-   case MESA_FORMAT_B8G8R8A8_SRGB:
-      return PIPE_FORMAT_B8G8R8A8_SRGB;
+      return PIPE_FORMAT_ABGR8888_SRGB;
    case MESA_FORMAT_R8G8B8A8_SRGB:
-      return PIPE_FORMAT_R8G8B8A8_SRGB;
+      return PIPE_FORMAT_RGBA8888_SRGB;
+   case MESA_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:
@@ -191,9 +199,13 @@ st_mesa_format_to_pipe_format(struct st_context *st, 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;
 
@@ -323,30 +335,49 @@ st_mesa_format_to_pipe_format(struct st_context *st, 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;
 
@@ -373,9 +404,13 @@ st_mesa_format_to_pipe_format(struct st_context *st, 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:
@@ -400,27 +435,33 @@ st_mesa_format_to_pipe_format(struct st_context *st, mesa_format mesaFormat)
       return PIPE_FORMAT_R32G32B32X32_SINT;
 
    case MESA_FORMAT_B8G8R8X8_SRGB:
-      return PIPE_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:
-   case MESA_FORMAT_ETC2_RGBA8_EAC:
-   case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
-      return PIPE_FORMAT_R8G8B8A8_UNORM;
+      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:
-   case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
-      return PIPE_FORMAT_B8G8R8A8_SRGB;
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_SRGBA8 : PIPE_FORMAT_B8G8R8A8_SRGB;
    case MESA_FORMAT_ETC2_R11_EAC:
-      return PIPE_FORMAT_R16_UNORM;
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_R11_UNORM : PIPE_FORMAT_R16_UNORM;
    case MESA_FORMAT_ETC2_RG11_EAC:
-      return PIPE_FORMAT_R16G16_UNORM;
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_RG11_UNORM : PIPE_FORMAT_R16G16_UNORM;
    case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
-      return PIPE_FORMAT_R16_SNORM;
+      return st->has_etc2 ? PIPE_FORMAT_ETC2_R11_SNORM : PIPE_FORMAT_R16_SNORM;
    case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
-      return PIPE_FORMAT_R16G16_SNORM;
+      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;
@@ -465,10 +506,14 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
       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:
@@ -525,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:
@@ -572,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;
@@ -705,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;
 
@@ -752,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:
@@ -779,10 +855,31 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
    case PIPE_FORMAT_R32G32B32X32_SINT:
       return MESA_FORMAT_RGBX_SINT32;
 
-   case PIPE_FORMAT_B8G8R8X8_SRGB:
+   case PIPE_FORMAT_BGRX8888_SRGB:
       return MESA_FORMAT_B8G8R8X8_SRGB;
-   case PIPE_FORMAT_R8G8B8A8_SRGB:
-      return MESA_FORMAT_R8G8B8A8_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:
       return MESA_FORMAT_NONE;
@@ -801,11 +898,15 @@ test_format_conversion(struct st_context *st)
 
    /* test all Mesa formats */
    for (i = 1; i < MESA_FORMAT_COUNT; i++) {
-      /* ETC2 formats are translated differently, skip them. */
+      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;
 
-      enum pipe_format pf = st_mesa_format_to_pipe_format(st, i);
+      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);
@@ -815,6 +916,14 @@ test_format_conversion(struct st_context *st)
    /* 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);
@@ -850,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
@@ -881,7 +991,7 @@ 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 },
@@ -890,11 +1000,11 @@ static const struct format_mapping format_map[] = {
    },
    {
       { 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 },
@@ -1262,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.
     */
    {
@@ -1697,7 +1825,8 @@ 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
@@ -1726,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) {
@@ -1813,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;
@@ -1833,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