st/mesa: rewrite st_choose_format() to be table driven
authorBrian Paul <brianp@vmware.com>
Sat, 21 May 2011 16:43:49 +0000 (10:43 -0600)
committerBrian Paul <brianp@vmware.com>
Tue, 24 May 2011 14:49:01 +0000 (08:49 -0600)
Instead of using a giant switch statement with lots of code, use a
table to convert GL format enums to pipe formats.

Tested by running the old code next to the new and asserting that
the return value was the same for piglit tests.

We're doing a linear search, but if that ever appears to be too slow
the table could easily be sorted or hashed.

src/mesa/state_tracker/st_format.c

index b1362108f0ad263d87456f7bd84ab32944853f43..6ebe721bfd6d70ad730c2296a7ebcf04e7fd6332 100644 (file)
@@ -562,19 +562,546 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
 }
 
 
+/**
+ * Map GL texture formats to Gallium pipe formats.
+ */
+struct format_mapping
+{
+   GLenum glFormats[18];       /**< list of GLenum formats, 0-terminated */
+   enum pipe_format pipeFormats[10]; /**< list of pipe formats, 0-terminated */
+};
+
+
+#define DEFAULT_RGBA_FORMATS \
+      PIPE_FORMAT_B8G8R8A8_UNORM, \
+      PIPE_FORMAT_A8R8G8B8_UNORM, \
+      PIPE_FORMAT_A8B8G8R8_UNORM, \
+      PIPE_FORMAT_B5G6R5_UNORM, \
+      0
+
+#define DEFAULT_RGB_FORMATS \
+      PIPE_FORMAT_B8G8R8X8_UNORM, \
+      PIPE_FORMAT_X8R8G8B8_UNORM, \
+      PIPE_FORMAT_X8B8G8R8_UNORM, \
+      PIPE_FORMAT_B8G8R8A8_UNORM, \
+      PIPE_FORMAT_A8R8G8B8_UNORM, \
+      PIPE_FORMAT_A8B8G8R8_UNORM, \
+      PIPE_FORMAT_B5G6R5_UNORM, \
+      0
+
+#define DEFAULT_SRGBA_FORMATS \
+      PIPE_FORMAT_B8G8R8A8_SRGB, \
+      PIPE_FORMAT_A8R8G8B8_SRGB, \
+      PIPE_FORMAT_A8B8G8R8_SRGB, \
+      0
+
+/**
+ * This table maps OpenGL texture format enums to Gallium pipe_format enums.
+ * Multiple GL enums might map to multiple pipe_formats.
+ * The first pipe format in the list that's supported is the one that's chosen.
+ */
+static struct format_mapping format_map[] = {
+   /* Basic RGB, RGBA formats */
+   {
+      { GL_RGB10, GL_RGB10_A2, 0 },
+      { PIPE_FORMAT_B10G10R10A2_UNORM, 0 }
+   },
+   {
+      { 4, GL_RGBA, GL_RGBA8, 0 },
+      { DEFAULT_RGBA_FORMATS, 0 }
+   },
+   {
+      { GL_BGRA, 0 },
+      { PIPE_FORMAT_B8G8R8A8_UNORM, DEFAULT_RGB_FORMATS, 0 }
+   },
+   {
+      { 3, GL_RGB, GL_RGB8, 0 },
+      { DEFAULT_RGB_FORMATS, 0 }
+   },
+   {
+      { GL_RGB12, GL_RGB16, GL_RGBA12, GL_RGBA16, 0 },
+      { PIPE_FORMAT_R16G16B16A16_UNORM, DEFAULT_RGB_FORMATS, 0 }
+   },
+   {
+      { GL_RGBA4, GL_RGBA2, 0 },
+      { PIPE_FORMAT_B4G4R4A4_UNORM, DEFAULT_RGBA_FORMATS }
+   },
+   {
+      { GL_RGB5_A1, 0 },
+      { PIPE_FORMAT_B5G5R5A1_UNORM, DEFAULT_RGBA_FORMATS, 0 }
+   },
+   {
+      { GL_R3_G3_B2, 0 },
+      { PIPE_FORMAT_B2G3R3_UNORM, PIPE_FORMAT_B5G6R5_UNORM,
+        PIPE_FORMAT_B5G5R5A1_UNORM, DEFAULT_RGBA_FORMATS }
+   },
+   {
+      { GL_RGB5, GL_RGB4 },
+      { PIPE_FORMAT_B5G6R5_UNORM, PIPE_FORMAT_B5G5R5A1_UNORM,
+        DEFAULT_RGBA_FORMATS }
+   },
+
+   /* basic Alpha formats */
+   {
+      { GL_ALPHA12, GL_ALPHA16, 0 },
+      { PIPE_FORMAT_A16_UNORM, PIPE_FORMAT_A8_UNORM,
+        DEFAULT_RGBA_FORMATS }
+   },
+   {
+      { GL_ALPHA, GL_ALPHA4, GL_ALPHA8, GL_COMPRESSED_ALPHA, 0 },
+      { PIPE_FORMAT_A8_UNORM, DEFAULT_RGBA_FORMATS }
+   },
+
+   /* basic Luminance formats */
+   {
+      { GL_LUMINANCE12, GL_LUMINANCE16, 0 },
+      { PIPE_FORMAT_L16_UNORM, PIPE_FORMAT_L8_UNORM, DEFAULT_RGBA_FORMATS, 0 }
+   },
+   {
+      { 1, GL_LUMINANCE, GL_LUMINANCE4, GL_LUMINANCE8, 0 },
+      { PIPE_FORMAT_L8_UNORM, DEFAULT_RGBA_FORMATS }
+   },
+
+   /* basic Luminance/Alpha formats */
+   {
+      { GL_LUMINANCE12_ALPHA4, GL_LUMINANCE12_ALPHA12,
+        GL_LUMINANCE16_ALPHA16, 0},
+      { PIPE_FORMAT_L16A16_UNORM, PIPE_FORMAT_L8A8_UNORM,
+        PIPE_FORMAT_L8A8_UNORM, DEFAULT_RGBA_FORMATS }
+   },
+   {
+      { 2, GL_LUMINANCE_ALPHA, GL_LUMINANCE6_ALPHA2, GL_LUMINANCE8_ALPHA8, 0 },
+      { PIPE_FORMAT_L8A8_UNORM, DEFAULT_RGBA_FORMATS }
+   },
+   {
+      { GL_LUMINANCE4_ALPHA4, 0 },
+      { PIPE_FORMAT_L4A4_UNORM, PIPE_FORMAT_L4A4_UNORM,
+        DEFAULT_RGBA_FORMATS }
+   },
+
+   /* basic Intensity formats */
+   {
+      { GL_INTENSITY12, GL_INTENSITY16, 0 },
+      { PIPE_FORMAT_I16_UNORM, PIPE_FORMAT_I8_UNORM, DEFAULT_RGBA_FORMATS }
+   },
+   {
+      { GL_INTENSITY, GL_INTENSITY4, GL_INTENSITY8,
+        GL_COMPRESSED_INTENSITY, 0 },
+      { PIPE_FORMAT_I8_UNORM, DEFAULT_RGBA_FORMATS }
+   },
+
+   /* YCbCr */
+   {
+      { GL_YCBCR_MESA, 0 },
+      { PIPE_FORMAT_UYVY, PIPE_FORMAT_YUYV, 0 }
+   },
+
+   /* compressed formats */ /* XXX PIPE_BIND_SAMPLER_VIEW only */
+   {
+      { GL_COMPRESSED_RGB, 0 },
+      { PIPE_FORMAT_DXT1_RGB, 0 }
+   },
+   {
+      { GL_COMPRESSED_RGBA, 0 },
+      { PIPE_FORMAT_DXT5_RGBA, 0 }
+   },
+   {
+      { GL_RGB_S3TC, GL_RGB4_S3TC, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 0 },
+      { PIPE_FORMAT_DXT1_RGB, 0 }
+   },
+   {
+      { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0 },
+      { PIPE_FORMAT_DXT1_RGBA, 0 }
+   },
+   {
+      { GL_RGBA_S3TC, GL_RGBA4_S3TC, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0 },
+      { PIPE_FORMAT_DXT3_RGBA, 0 }
+   },
+   {
+      { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0 },
+      { PIPE_FORMAT_DXT5_RGBA, 0 }
+   },
+
+#if 0
+   {
+      { GL_COMPRESSED_RGB_FXT1_3DFX, 0 },
+      { PIPE_FORMAT_RGB_FXT1, 0 }
+   },
+   {
+      { GL_COMPRESSED_RGBA_FXT1_3DFX, 0 },
+      { PIPE_FORMAT_RGB_FXT1, 0 }
+   },
+#endif
+
+   /* Depth formats */
+   {
+      { GL_DEPTH_COMPONENT16, 0 },
+      { PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+        PIPE_FORMAT_S8_USCALED_Z24_UNORM, PIPE_FORMAT_Z32_UNORM, 0 }
+   },
+   {
+      { GL_DEPTH_COMPONENT24, 0 },
+      { PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+        PIPE_FORMAT_S8_USCALED_Z24_UNORM, PIPE_FORMAT_Z32_UNORM, 0 }
+   },
+   {
+      { GL_DEPTH_COMPONENT32, 0 },
+      { PIPE_FORMAT_Z32_UNORM, 0 }
+   },
+   {
+      { GL_DEPTH_COMPONENT, 0 },
+      { PIPE_FORMAT_Z32_UNORM, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+        PIPE_FORMAT_S8_USCALED_Z24_UNORM, PIPE_FORMAT_Z16_UNORM, 0 }
+   },
+
+   /* stencil formats */
+   {
+      { GL_STENCIL_INDEX, GL_STENCIL_INDEX1_EXT, GL_STENCIL_INDEX4_EXT,
+        GL_STENCIL_INDEX8_EXT, GL_STENCIL_INDEX16_EXT, 0 },
+      {
+         PIPE_FORMAT_S8_USCALED, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+         PIPE_FORMAT_S8_USCALED_Z24_UNORM, 0
+      }
+   },
+
+   /* Depth / Stencil formats */
+   {
+      { GL_DEPTH_STENCIL_EXT, GL_DEPTH24_STENCIL8_EXT, 0 },
+      { PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_S8_USCALED_Z24_UNORM, 0 }
+   },
+
+   /* sRGB formats */
+   {
+      { GL_SRGB_EXT, GL_SRGB8_EXT, GL_SRGB_ALPHA_EXT, GL_SRGB8_ALPHA8_EXT, 0 },
+      { DEFAULT_SRGBA_FORMATS }
+   },
+   {
+      { GL_COMPRESSED_SRGB_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 0 },
+      { PIPE_FORMAT_DXT1_SRGB, DEFAULT_SRGBA_FORMATS }
+   },
+   {
+      { GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0 },
+      { PIPE_FORMAT_DXT1_SRGBA, 0 }
+   },
+   {
+      { GL_COMPRESSED_SRGB_ALPHA_EXT,
+        GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0 },
+      { PIPE_FORMAT_DXT3_SRGBA, DEFAULT_SRGBA_FORMATS }
+   },
+   {
+      { GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0 },
+      { PIPE_FORMAT_DXT5_SRGBA, 0 }
+   },
+   {
+      { GL_SLUMINANCE_ALPHA_EXT, GL_SLUMINANCE8_ALPHA8_EXT,
+        GL_COMPRESSED_SLUMINANCE_EXT, GL_COMPRESSED_SLUMINANCE_ALPHA_EXT, 0 },
+      { PIPE_FORMAT_L8A8_SRGB, DEFAULT_SRGBA_FORMATS }
+   },
+   {
+      { GL_SLUMINANCE_EXT, GL_SLUMINANCE8_EXT, 0 },
+      { PIPE_FORMAT_L8_SRGB, DEFAULT_SRGBA_FORMATS }
+   },
+
+   /* 16-bit float formats */
+   {
+      { GL_RGBA16F_ARB, 0 },
+      { PIPE_FORMAT_R16G16B16A16_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
+   },
+   {
+      { GL_RGB16F_ARB, 0 },
+      { PIPE_FORMAT_R16G16B16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
+        PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
+   },
+   {
+      { GL_LUMINANCE_ALPHA16F_ARB, 0 },
+      { PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
+        PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
+   },
+   {
+      { GL_ALPHA16F_ARB, 0 },
+      { PIPE_FORMAT_A16_FLOAT, PIPE_FORMAT_L16A16_FLOAT,
+        PIPE_FORMAT_A32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
+        PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
+   },
+   {
+      { GL_INTENSITY16F_ARB, 0 },
+      { PIPE_FORMAT_I16_FLOAT, PIPE_FORMAT_L16A16_FLOAT,
+        PIPE_FORMAT_I32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
+        PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
+   },
+   {
+      { GL_LUMINANCE16F_ARB, 0 },
+      { PIPE_FORMAT_L16_FLOAT, PIPE_FORMAT_L16A16_FLOAT,
+        PIPE_FORMAT_L32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
+        PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
+   },
+   {
+      { GL_R16F, 0 },
+      { PIPE_FORMAT_R16_FLOAT, PIPE_FORMAT_R16G16_FLOAT,
+        PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
+        PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
+   },
+   {
+      { GL_RG16F, 0 },
+      { PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
+        PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
+   },
+
+   /* 32-bit float formats */
+   {
+      { GL_RGBA32F_ARB, 0 },
+      { PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
+   },
+   {
+      { GL_RGB32F_ARB, 0 },
+      { PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT,
+        PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
+   },
+   {
+      { GL_LUMINANCE_ALPHA32F_ARB, 0 },
+      { PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT,
+        PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
+   },
+   {
+      { GL_ALPHA32F_ARB, 0 },
+      { PIPE_FORMAT_A32_FLOAT, PIPE_FORMAT_L32A32_FLOAT,
+        PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_A16_FLOAT,
+        PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
+   },
+   {
+      { GL_INTENSITY32F_ARB, 0 },
+      { PIPE_FORMAT_I32_FLOAT, PIPE_FORMAT_L32A32_FLOAT,
+        PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_I16_FLOAT,
+        PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
+   },
+   {
+      { GL_LUMINANCE32F_ARB, 0 },
+      { PIPE_FORMAT_L32_FLOAT, PIPE_FORMAT_L32A32_FLOAT,
+        PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_L16_FLOAT,
+        PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
+   },
+   {
+      { GL_R32F, 0 },
+      { PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R32G32_FLOAT,
+        PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_R16_FLOAT,
+        PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
+   },
+   {
+      { GL_RG32F, 0 },
+      { PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT,
+        PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
+   },
+
+   /* R, RG formats */
+   {
+      { GL_RED, GL_R8, 0 },
+      { PIPE_FORMAT_R8_UNORM, 0 }
+   },
+   {
+      { GL_RG, GL_RG8, 0 },
+      { PIPE_FORMAT_R8G8_UNORM, 0 }
+   },
+   {
+      { GL_R16, 0 },
+      { PIPE_FORMAT_R16_UNORM, 0 }
+   },
+   {
+      { GL_RG16, 0 },
+      { PIPE_FORMAT_R16G16_UNORM, 0 }
+   },
+
+   /* compressed R, RG formats */
+   {
+      { GL_COMPRESSED_RED, GL_COMPRESSED_RED_RGTC1, 0 },
+      { PIPE_FORMAT_RGTC1_UNORM, PIPE_FORMAT_R8_UNORM, 0 }
+   },
+   {
+      { GL_COMPRESSED_SIGNED_RED_RGTC1, 0 },
+      { PIPE_FORMAT_RGTC1_SNORM, 0 }
+   },
+   {
+      { GL_COMPRESSED_RG, GL_COMPRESSED_RG_RGTC2, 0 },
+      { PIPE_FORMAT_RGTC2_UNORM, PIPE_FORMAT_R8G8_UNORM, 0 }
+   },
+   {
+      { GL_COMPRESSED_SIGNED_RG_RGTC2, 0 },
+      { PIPE_FORMAT_RGTC2_SNORM, 0 }
+   },
+   {
+      { GL_COMPRESSED_LUMINANCE, GL_COMPRESSED_LUMINANCE_LATC1_EXT, 0 },
+      { PIPE_FORMAT_LATC1_UNORM, PIPE_FORMAT_L8_UNORM, 0 }
+   },
+   {
+      { GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT, 0 },
+      { PIPE_FORMAT_LATC1_SNORM, 0 }
+   },
+   {
+      { GL_COMPRESSED_LUMINANCE_ALPHA, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT,
+        GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0 },
+      { PIPE_FORMAT_LATC2_UNORM, PIPE_FORMAT_L8A8_UNORM, 0 }
+   },
+   {
+      { GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT, 0 },
+      { PIPE_FORMAT_LATC2_SNORM, 0 }
+   },
+
+   /* signed/unsigned integer formats.
+    * XXX Mesa only has formats for RGBA signed/unsigned integer formats.
+    * If/when new formats are added this code should be updated.
+    */
+   {
+      { GL_RED_INTEGER_EXT,
+        GL_GREEN_INTEGER_EXT,
+        GL_BLUE_INTEGER_EXT,
+        GL_ALPHA_INTEGER_EXT,
+        GL_RGB_INTEGER_EXT,
+        GL_RGBA_INTEGER_EXT,
+        GL_BGR_INTEGER_EXT,
+        GL_BGRA_INTEGER_EXT,
+        GL_LUMINANCE_INTEGER_EXT,
+        GL_LUMINANCE_ALPHA_INTEGER_EXT,
+        GL_RGBA8I_EXT,
+        GL_RGB8I_EXT,
+        GL_ALPHA8I_EXT,
+        GL_INTENSITY8I_EXT,
+        GL_LUMINANCE8I_EXT,
+        GL_LUMINANCE_ALPHA8I_EXT, 0 },
+      { PIPE_FORMAT_R8G8B8A8_SSCALED, 0 }
+   },
+   {
+      {
+         GL_RGBA16I_EXT,
+         GL_RGB16I_EXT,
+         GL_ALPHA16I_EXT,
+         GL_INTENSITY16I_EXT,
+         GL_LUMINANCE16I_EXT,
+         GL_LUMINANCE_ALPHA16I_EXT, 0 },
+      { PIPE_FORMAT_R16G16B16A16_SSCALED, 0 },
+   },
+   {
+      {
+         GL_RGBA32I_EXT,
+         GL_RGB32I_EXT,
+         GL_ALPHA32I_EXT,
+         GL_INTENSITY32I_EXT,
+         GL_LUMINANCE32I_EXT,
+         GL_LUMINANCE_ALPHA32I_EXT, 0 },
+      { PIPE_FORMAT_R32G32B32A32_SSCALED, 0 }
+   },
+   {
+      {
+         GL_RGBA8UI_EXT,
+         GL_RGB8UI_EXT,
+         GL_ALPHA8UI_EXT,
+         GL_INTENSITY8UI_EXT,
+         GL_LUMINANCE8UI_EXT,
+         GL_LUMINANCE_ALPHA8UI_EXT, 0 },
+      { PIPE_FORMAT_R8G8B8A8_USCALED, 0 }
+   },
+   {
+      {
+         GL_RGBA16UI_EXT,
+         GL_RGB16UI_EXT,
+         GL_ALPHA16UI_EXT,
+         GL_INTENSITY16UI_EXT,
+         GL_LUMINANCE16UI_EXT,
+         GL_LUMINANCE_ALPHA16UI_EXT, 0 },
+      { PIPE_FORMAT_R16G16B16A16_USCALED, 0 }
+   },
+   {
+      {
+         GL_RGBA32UI_EXT,
+         GL_RGB32UI_EXT,
+         GL_ALPHA32UI_EXT,
+         GL_INTENSITY32UI_EXT,
+         GL_LUMINANCE32UI_EXT,
+         GL_LUMINANCE_ALPHA32UI_EXT, 0 },
+      { PIPE_FORMAT_R32G32B32A32_USCALED, 0 }
+   },
+
+   /* signed normalized formats */
+   {
+      { GL_RED_SNORM, GL_R8_SNORM, 0 },
+      { PIPE_FORMAT_R8_SNORM, PIPE_FORMAT_R8G8_SNORM,
+        PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_R16_SNORM, 0 },
+      { PIPE_FORMAT_R16_SNORM,
+        PIPE_FORMAT_R16G16_SNORM,
+        PIPE_FORMAT_R16G16B16A16_SNORM,
+        PIPE_FORMAT_R8_SNORM,
+        PIPE_FORMAT_R8G8_SNORM,
+        PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_RG_SNORM, GL_RG8_SNORM, 0 },
+      { PIPE_FORMAT_R8G8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_RG16_SNORM, 0 },
+      { PIPE_FORMAT_R16G16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
+        PIPE_FORMAT_R8G8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_RGB_SNORM, GL_RGB8_SNORM, GL_RGBA_SNORM, GL_RGBA8_SNORM, 0 },
+      { PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_RGB16_SNORM, GL_RGBA16_SNORM, 0 },
+      { PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_ALPHA_SNORM, GL_ALPHA8_SNORM, 0 },
+      { PIPE_FORMAT_A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_ALPHA16_SNORM, 0 },
+      { PIPE_FORMAT_A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
+        PIPE_FORMAT_A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_LUMINANCE_SNORM, GL_LUMINANCE8_SNORM, 0 },
+      { PIPE_FORMAT_L8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_LUMINANCE16_SNORM, 0 },
+      { PIPE_FORMAT_L16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
+        PIPE_FORMAT_L8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_LUMINANCE_ALPHA_SNORM, GL_LUMINANCE8_ALPHA8_SNORM, 0 },
+      { PIPE_FORMAT_L8A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_LUMINANCE16_ALPHA16_SNORM, 0 },
+      { PIPE_FORMAT_L16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
+        PIPE_FORMAT_L8A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_INTENSITY_SNORM, GL_INTENSITY8_SNORM, 0 },
+      { PIPE_FORMAT_I8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   },
+   {
+      { GL_INTENSITY16_SNORM, 0 },
+      { PIPE_FORMAT_I16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
+        PIPE_FORMAT_I8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
+   }
+};
+
+
 /**
  * Return first supported format from the given list.
  */
 static enum pipe_format
 find_supported_format(struct pipe_screen *screen, 
                       const enum pipe_format formats[],
-                      uint num_formats,
                       enum pipe_texture_target target,
                       unsigned sample_count,
                       unsigned tex_usage)
 {
    uint i;
-   for (i = 0; i < num_formats; i++) {
+   for (i = 0; formats[i]; i++) {
       if (screen->is_format_supported(screen, formats[i], target,
                                       sample_count, tex_usage)) {
          return formats[i];
@@ -584,67 +1111,6 @@ find_supported_format(struct pipe_screen *screen,
 }
 
 
-/**
- * Find an RGBA format supported by the context/winsys.
- */
-static enum pipe_format
-default_rgba_format(struct pipe_screen *screen, 
-                    enum pipe_texture_target target,
-                    unsigned sample_count,
-                    unsigned tex_usage)
-{
-   static const enum pipe_format colorFormats[] = {
-      PIPE_FORMAT_B8G8R8A8_UNORM,
-      PIPE_FORMAT_A8R8G8B8_UNORM,
-      PIPE_FORMAT_A8B8G8R8_UNORM,
-      PIPE_FORMAT_B5G6R5_UNORM
-   };
-   return find_supported_format(screen, colorFormats, Elements(colorFormats),
-                                target, sample_count, tex_usage);
-}
-
-
-/**
- * Find an RGB format supported by the context/winsys.
- */
-static enum pipe_format
-default_rgb_format(struct pipe_screen *screen, 
-                   enum pipe_texture_target target,
-                   unsigned sample_count,
-                   unsigned tex_usage)
-{
-   static const enum pipe_format colorFormats[] = {
-      PIPE_FORMAT_B8G8R8X8_UNORM,
-      PIPE_FORMAT_X8R8G8B8_UNORM,
-      PIPE_FORMAT_X8B8G8R8_UNORM,
-      PIPE_FORMAT_B8G8R8A8_UNORM,
-      PIPE_FORMAT_A8R8G8B8_UNORM,
-      PIPE_FORMAT_A8B8G8R8_UNORM,
-      PIPE_FORMAT_B5G6R5_UNORM
-   };
-   return find_supported_format(screen, colorFormats, Elements(colorFormats),
-                                target, sample_count, tex_usage);
-}
-
-/**
- * Find an sRGBA format supported by the context/winsys.
- */
-static enum pipe_format
-default_srgba_format(struct pipe_screen *screen, 
-                    enum pipe_texture_target target,
-                    unsigned sample_count,
-                    unsigned tex_usage)
-{
-   static const enum pipe_format colorFormats[] = {
-      PIPE_FORMAT_B8G8R8A8_SRGB,
-      PIPE_FORMAT_A8R8G8B8_SRGB,
-      PIPE_FORMAT_A8B8G8R8_SRGB,
-   };
-   return find_supported_format(screen, colorFormats, Elements(colorFormats),
-                                target, sample_count, tex_usage);
-}
-
-
 /**
  * Given an OpenGL internalFormat value for a texture or surface, return
  * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match.
@@ -663,853 +1129,31 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
                  enum pipe_texture_target target, unsigned sample_count,
                  unsigned bindings)
 {
+   GET_CURRENT_CONTEXT(ctx); /* XXX this should be a function parameter */
+   int i, j;
 
-   switch (internalFormat) {
-   case GL_RGB10:
-   case GL_RGB10_A2:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_B10G10R10A2_UNORM,
-                                       target, sample_count, bindings))
-         return PIPE_FORMAT_B10G10R10A2_UNORM;
-      /* Pass through. */
-   case 4:
-   case GL_RGBA:
-   case GL_RGBA8:
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_BGRA:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_B8G8R8A8_UNORM,
-                                       target, sample_count, bindings))
-         return PIPE_FORMAT_B8G8R8A8_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case 3:
-   case GL_RGB:
-   case GL_RGB8:
-      return default_rgb_format( screen, target, sample_count, bindings);
-
-   case GL_RGB12:
-   case GL_RGB16:
-   case GL_RGBA12:
-   case GL_RGBA16:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_R16G16B16A16_UNORM,
-                                             target, sample_count, bindings))
-         return PIPE_FORMAT_R16G16B16A16_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_RGBA4:
-   case GL_RGBA2:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM,
-                                       target, sample_count, bindings))
-         return PIPE_FORMAT_B4G4R4A4_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_RGB5_A1:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
-                                       target, sample_count, bindings))
-         return PIPE_FORMAT_B5G5R5A1_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_R3_G3_B2:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_B2G3R3_UNORM,
-                                       target, sample_count, bindings))
-         return PIPE_FORMAT_B2G3R3_UNORM;
-      /* Pass through. */
-   case GL_RGB5:
-   case GL_RGB4:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_B5G6R5_UNORM,
-                                       target, sample_count, bindings))
-         return PIPE_FORMAT_B5G6R5_UNORM;
-      if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
-                                       target, sample_count, bindings))
-         return PIPE_FORMAT_B5G5R5A1_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_ALPHA12:
-   case GL_ALPHA16:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_A16_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_A16_UNORM;
-      /* Pass through. */
-   case GL_ALPHA:
-   case GL_ALPHA4:
-   case GL_ALPHA8:
-   case GL_COMPRESSED_ALPHA:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_A8_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_A8_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_LUMINANCE12:
-   case GL_LUMINANCE16:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_L16_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_L16_UNORM;
-      /* Pass through. */
-   case 1:
-   case GL_LUMINANCE:
-   case GL_LUMINANCE4:
-   case GL_LUMINANCE8:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_L8_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_LUMINANCE12_ALPHA4:
-   case GL_LUMINANCE12_ALPHA12:
-   case GL_LUMINANCE16_ALPHA16:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_L16A16_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_L16A16_UNORM;
-      /* Pass through. */
-   case 2:
-   case GL_LUMINANCE_ALPHA:
-   case GL_LUMINANCE6_ALPHA2:
-   case GL_LUMINANCE8_ALPHA8:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_L8A8_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_LUMINANCE4_ALPHA4:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_L4A4_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_L4A4_UNORM;
-      if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_L8A8_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_INTENSITY12:
-   case GL_INTENSITY16:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_I16_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_I16_UNORM;
-      /* Pass through. */
-   case GL_INTENSITY:
-   case GL_INTENSITY4:
-   case GL_INTENSITY8:
-   case GL_COMPRESSED_INTENSITY:
-      if (screen->is_format_supported( screen, PIPE_FORMAT_I8_UNORM, target,
-                                       sample_count, bindings))
-         return PIPE_FORMAT_I8_UNORM;
-      return default_rgba_format( screen, target, sample_count, bindings);
-
-   case GL_YCBCR_MESA:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, target,
-                                      sample_count, bindings)) {
-         return PIPE_FORMAT_UYVY;
-      }
-      if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, target,
-                                      sample_count, bindings)) {
-         return PIPE_FORMAT_YUYV;
-      }
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_RGB:
-      /* can only sample from compressed formats */
-      if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
-         return PIPE_FORMAT_NONE;
-      else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
-                                           target, sample_count, bindings))
-         return PIPE_FORMAT_DXT1_RGB;
-      else
-         return default_rgb_format(screen, target, sample_count, bindings);
-
-   case GL_COMPRESSED_RGBA:
-      /* can only sample from compressed formats */
-      if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
-         return PIPE_FORMAT_NONE;
-      else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
-                                           target, sample_count, bindings))
-         return PIPE_FORMAT_DXT3_RGBA;
-      else
-         return default_rgba_format(screen, target, sample_count, bindings);
-
-   case GL_RGB_S3TC:
-   case GL_RGB4_S3TC:
-   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
-                                      target, sample_count, bindings))
-         return PIPE_FORMAT_DXT1_RGB;
-      else
-         return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGBA,
-                                      target, sample_count, bindings))
-         return PIPE_FORMAT_DXT1_RGBA;
-      else
-         return PIPE_FORMAT_NONE;
-
-   case GL_RGBA_S3TC:
-   case GL_RGBA4_S3TC:
-   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
-                                      target, sample_count, bindings))
-         return PIPE_FORMAT_DXT3_RGBA;
-      else
-         return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
-                                      target, sample_count, bindings))
-         return PIPE_FORMAT_DXT5_RGBA;
-      else
-         return PIPE_FORMAT_NONE;
-
-#if 0
-   case GL_COMPRESSED_RGB_FXT1_3DFX:
-      return PIPE_FORMAT_RGB_FXT1;
-   case GL_COMPRESSED_RGBA_FXT1_3DFX:
-      return PIPE_FORMAT_RGB_FXT1;
-#endif
-
-   case GL_DEPTH_COMPONENT16:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_Z16_UNORM, target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_Z16_UNORM;
-      /* fall-through */
-   case GL_DEPTH_COMPONENT24:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
-                                      target, sample_count, bindings))
-         return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
-      if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
-                                      target, sample_count, bindings))
-         return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
-      /* fall-through */
-   case GL_DEPTH_COMPONENT32:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_Z32_UNORM, target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_Z32_UNORM;
-      /* fall-through */
-   case GL_DEPTH_COMPONENT:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_Z32_UNORM,
-            PIPE_FORMAT_Z24_UNORM_S8_USCALED,
-            PIPE_FORMAT_S8_USCALED_Z24_UNORM,
-            PIPE_FORMAT_Z16_UNORM
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-                                      target, sample_count, bindings);
-      }
-
-   case GL_STENCIL_INDEX:
-   case GL_STENCIL_INDEX1_EXT:
-   case GL_STENCIL_INDEX4_EXT:
-   case GL_STENCIL_INDEX8_EXT:
-   case GL_STENCIL_INDEX16_EXT:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_S8_USCALED,
-            PIPE_FORMAT_Z24_UNORM_S8_USCALED,
-            PIPE_FORMAT_S8_USCALED_Z24_UNORM
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-                                      target, sample_count, bindings);
-      }
-
-   case GL_DEPTH_STENCIL_EXT:
-   case GL_DEPTH24_STENCIL8_EXT:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_Z24_UNORM_S8_USCALED,
-            PIPE_FORMAT_S8_USCALED_Z24_UNORM
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-                                      target, sample_count, bindings);
-      }
-
-   case GL_SRGB_EXT:
-   case GL_SRGB8_EXT:
-   case GL_SRGB_ALPHA_EXT:
-   case GL_SRGB8_ALPHA8_EXT:
-      return default_srgba_format( screen, target, sample_count, bindings);
-
-   case GL_COMPRESSED_SRGB_EXT:
-   case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_SRGB, target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_DXT1_SRGB;
-      return default_srgba_format( screen, target, sample_count, bindings);
-
-   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
-      return PIPE_FORMAT_DXT1_SRGBA;
-
-   case GL_COMPRESSED_SRGB_ALPHA_EXT:
-   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_SRGBA, target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_DXT3_SRGBA;
-      return default_srgba_format( screen, target, sample_count, bindings);
-
-   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
-      return PIPE_FORMAT_DXT5_SRGBA;
-
-   case GL_SLUMINANCE_ALPHA_EXT:
-   case GL_SLUMINANCE8_ALPHA8_EXT:
-   case GL_COMPRESSED_SLUMINANCE_EXT:
-   case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_SRGB, target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_L8A8_SRGB;
-      return default_srgba_format( screen, target, sample_count, bindings);
-
-   case GL_SLUMINANCE_EXT:
-   case GL_SLUMINANCE8_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_L8_SRGB;
-      return default_srgba_format( screen, target, sample_count, bindings);
-
-   /* prefer formats in order of data size, choosing 16-bit ones if equal sized */
-   case GL_RGBA16F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_R16G16B16A16_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-                                      target, sample_count, bindings);
-      }
-   case GL_RGB16F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_R16G16B16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT,
-               PIPE_FORMAT_R32G32B32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-                                      target, sample_count, bindings);
-      }
-   case GL_LUMINANCE_ALPHA16F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_L16A16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT,
-               PIPE_FORMAT_L32A32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_ALPHA16F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_A16_FLOAT,
-               PIPE_FORMAT_L16A16_FLOAT,
-               PIPE_FORMAT_A32_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT,
-               PIPE_FORMAT_L32A32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_INTENSITY16F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_I16_FLOAT,
-               PIPE_FORMAT_L16A16_FLOAT,
-               PIPE_FORMAT_I32_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT,
-               PIPE_FORMAT_L32A32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_LUMINANCE16F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_L16_FLOAT,
-               PIPE_FORMAT_L16A16_FLOAT,
-               PIPE_FORMAT_L32_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT,
-               PIPE_FORMAT_L32A32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_R16F:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_R16_FLOAT,
-               PIPE_FORMAT_R16G16_FLOAT,
-               PIPE_FORMAT_R32_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT,
-               PIPE_FORMAT_R32G32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_RG16F:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_R16G16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT,
-               PIPE_FORMAT_R32G32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   /* try a 32-bit format if available, otherwise fallback to a 16-bit one */
-   case GL_RGBA32F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_R32G32B32A32_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-                                      target, sample_count, bindings);
-      }
-   case GL_RGB32F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_R32G32B32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-                                      target, sample_count, bindings);
-      }
-   case GL_LUMINANCE_ALPHA32F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_L32A32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT,
-               PIPE_FORMAT_L16A16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_ALPHA32F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_A32_FLOAT,
-               PIPE_FORMAT_L32A32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT,
-               PIPE_FORMAT_A16_FLOAT,
-               PIPE_FORMAT_L16A16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_INTENSITY32F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_I32_FLOAT,
-               PIPE_FORMAT_L32A32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT,
-               PIPE_FORMAT_I16_FLOAT,
-               PIPE_FORMAT_L16A16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_LUMINANCE32F_ARB:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_L32_FLOAT,
-               PIPE_FORMAT_L32A32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT,
-               PIPE_FORMAT_L16_FLOAT,
-               PIPE_FORMAT_L16A16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_R32F:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_R32_FLOAT,
-               PIPE_FORMAT_R32G32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT,
-               PIPE_FORMAT_R16_FLOAT,
-               PIPE_FORMAT_R16G16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-   case GL_RG32F:
-      {
-         static const enum pipe_format formats[] = {
-               PIPE_FORMAT_R32G32_FLOAT,
-               PIPE_FORMAT_R32G32B32A32_FLOAT,
-               PIPE_FORMAT_R16G16_FLOAT,
-               PIPE_FORMAT_R16G16B16A16_FLOAT
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_RED:
-   case GL_R8:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_R8_UNORM;
-      return PIPE_FORMAT_NONE;
-   case GL_RG:
-   case GL_RG8:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_R8G8_UNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_R16:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_R16_UNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_RG16:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_R16G16_UNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_RED:
-   case GL_COMPRESSED_RED_RGTC1:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_RGTC1_UNORM;
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_R8_UNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_SIGNED_RED_RGTC1:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_SNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_RGTC1_SNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_RG:
-   case GL_COMPRESSED_RG_RGTC2:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_RGTC2_UNORM;
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_R8G8_UNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_SIGNED_RG_RGTC2:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_SNORM, target,
-                                      sample_count, bindings))
-             return PIPE_FORMAT_RGTC2_SNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_LUMINANCE:
-   case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_UNORM, target,
-                                      sample_count, bindings))
-              return PIPE_FORMAT_LATC1_UNORM;
-      if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, target,
-                                      sample_count, bindings))
-              return PIPE_FORMAT_L8_UNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_SNORM, target,
-                                      sample_count, bindings))
-              return PIPE_FORMAT_LATC1_SNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_LUMINANCE_ALPHA:
-   case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
-   case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM, target,
-                                      sample_count, bindings))
-              return PIPE_FORMAT_LATC2_UNORM;
-      if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_UNORM, target,
-                                      sample_count, bindings))
-              return PIPE_FORMAT_L8A8_UNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_SNORM, target,
-                                      sample_count, bindings))
-              return PIPE_FORMAT_LATC2_SNORM;
-      return PIPE_FORMAT_NONE;
-
-   /* signed/unsigned integer formats.
-    * XXX Mesa only has formats for RGBA signed/unsigned integer formats.
-    * If/when new formats are added this code should be updated.
-    */
-   case GL_RED_INTEGER_EXT:
-   case GL_GREEN_INTEGER_EXT:
-   case GL_BLUE_INTEGER_EXT:
-   case GL_ALPHA_INTEGER_EXT:
-   case GL_RGB_INTEGER_EXT:
-   case GL_RGBA_INTEGER_EXT:
-   case GL_BGR_INTEGER_EXT:
-   case GL_BGRA_INTEGER_EXT:
-   case GL_LUMINANCE_INTEGER_EXT:
-   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
-      /* fall-through */
-   case GL_RGBA8I_EXT:
-   case GL_RGB8I_EXT:
-   case GL_ALPHA8I_EXT:
-   case GL_INTENSITY8I_EXT:
-   case GL_LUMINANCE8I_EXT:
-   case GL_LUMINANCE_ALPHA8I_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SSCALED,
-                                      target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_R8G8B8A8_SSCALED;
-      return PIPE_FORMAT_NONE;
-   case GL_RGBA16I_EXT:
-   case GL_RGB16I_EXT:
-   case GL_ALPHA16I_EXT:
-   case GL_INTENSITY16I_EXT:
-   case GL_LUMINANCE16I_EXT:
-   case GL_LUMINANCE_ALPHA16I_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_SSCALED,
-                                      target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_R16G16B16A16_SSCALED;
-      return PIPE_FORMAT_NONE;
-   case GL_RGBA32I_EXT:
-   case GL_RGB32I_EXT:
-   case GL_ALPHA32I_EXT:
-   case GL_INTENSITY32I_EXT:
-   case GL_LUMINANCE32I_EXT:
-   case GL_LUMINANCE_ALPHA32I_EXT:
-      /* xxx */
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_SSCALED,
-                                      target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_R32G32B32A32_SSCALED;
-      return PIPE_FORMAT_NONE;
-
-   case GL_RGBA8UI_EXT:
-   case GL_RGB8UI_EXT:
-   case GL_ALPHA8UI_EXT:
-   case GL_INTENSITY8UI_EXT:
-   case GL_LUMINANCE8UI_EXT:
-   case GL_LUMINANCE_ALPHA8UI_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_USCALED,
-                                      target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_R8G8B8A8_USCALED;
-      return PIPE_FORMAT_NONE;
-
-   case GL_RGBA16UI_EXT:
-   case GL_RGB16UI_EXT:
-   case GL_ALPHA16UI_EXT:
-   case GL_INTENSITY16UI_EXT:
-   case GL_LUMINANCE16UI_EXT:
-   case GL_LUMINANCE_ALPHA16UI_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_USCALED,
-                                      target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_R16G16B16A16_USCALED;
-      return PIPE_FORMAT_NONE;
-
-   case GL_RGBA32UI_EXT:
-   case GL_RGB32UI_EXT:
-   case GL_ALPHA32UI_EXT:
-   case GL_INTENSITY32UI_EXT:
-   case GL_LUMINANCE32UI_EXT:
-   case GL_LUMINANCE_ALPHA32UI_EXT:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_USCALED,
-                                      target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_R32G32B32A32_USCALED;
-      return PIPE_FORMAT_NONE;
-
-   /* signed normalized formats */
-   case GL_RED_SNORM:
-   case GL_R8_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_R8_SNORM,
-            PIPE_FORMAT_R8G8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_R16_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_R16_SNORM,
-            PIPE_FORMAT_R16G16_SNORM,
-            PIPE_FORMAT_R16G16B16A16_SNORM,
-            PIPE_FORMAT_R8_SNORM,
-            PIPE_FORMAT_R8G8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_RG_SNORM:
-   case GL_RG8_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_R8G8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_RG16_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_R16G16_SNORM,
-            PIPE_FORMAT_R16G16B16A16_SNORM,
-            PIPE_FORMAT_R8G8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_RGB_SNORM:
-   case GL_RGB8_SNORM:
-   case GL_RGBA_SNORM:
-   case GL_RGBA8_SNORM:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SNORM,
-                                      target,
-                                      sample_count, bindings))
-         return PIPE_FORMAT_R8G8B8A8_SNORM;
-      return PIPE_FORMAT_NONE;
-
-   case GL_RGB16_SNORM:
-   case GL_RGBA16_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_R16G16B16A16_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-
-   case GL_ALPHA_SNORM:
-   case GL_ALPHA8_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_A8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_ALPHA16_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_A16_SNORM,
-            PIPE_FORMAT_R16G16B16A16_SNORM,
-            PIPE_FORMAT_A8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_LUMINANCE_SNORM:
-   case GL_LUMINANCE8_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_L8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_LUMINANCE16_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_L16_SNORM,
-            PIPE_FORMAT_R16G16B16A16_SNORM,
-            PIPE_FORMAT_L8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_LUMINANCE_ALPHA_SNORM:
-   case GL_LUMINANCE8_ALPHA8_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_L8A8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_LUMINANCE16_ALPHA16_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_L16A16_SNORM,
-            PIPE_FORMAT_R16G16B16A16_SNORM,
-            PIPE_FORMAT_L8A8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_INTENSITY_SNORM:
-   case GL_INTENSITY8_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_I8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_INTENSITY16_SNORM:
-      {
-         static const enum pipe_format formats[] = {
-            PIPE_FORMAT_I16_SNORM,
-            PIPE_FORMAT_R16G16B16A16_SNORM,
-            PIPE_FORMAT_I8_SNORM,
-            PIPE_FORMAT_R8G8B8A8_SNORM,
-         };
-         return find_supported_format(screen, formats, Elements(formats),
-               target, sample_count, bindings);
-      }
-
-   case GL_RGB9_E5:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R9G9B9E5_FLOAT, target,
-                                      sample_count, bindings)) {
-         return PIPE_FORMAT_R9G9B9E5_FLOAT;
-      }
+   /* can't render to compressed formats at this time */
+   if (_mesa_is_compressed_format(ctx, internalFormat)
+       && (bindings & ~PIPE_BIND_SAMPLER_VIEW)) {
       return PIPE_FORMAT_NONE;
+   }
 
-   case GL_R11F_G11F_B10F:
-      if (screen->is_format_supported(screen, PIPE_FORMAT_R11G11B10_FLOAT, target,
-                                      sample_count, bindings)) {
-         return PIPE_FORMAT_R11G11B10_FLOAT;
+   /* search table for internalFormat */
+   for (i = 0; i < Elements(format_map); i++) {
+      const struct format_mapping *mapping = &format_map[i];
+      for (j = 0; mapping->glFormats[j]; j++) {
+         if (mapping->glFormats[j] == internalFormat) {
+            /* Found the desired internal format.  Find first pipe format
+             * which is supported by the driver.
+             */
+            return find_supported_format(screen, mapping->pipeFormats,
+                                         target, sample_count, bindings);
+         }
       }
-      return PIPE_FORMAT_NONE;
-
-   default:
-      return PIPE_FORMAT_NONE;
    }
+
+   _mesa_problem(NULL, "unhandled format!\n");
+   return PIPE_FORMAT_NONE;
 }