Mesa (master): r300g: add support for all missing non-FP sampler formats

Marek Olšák mareko at kemper.freedesktop.org
Thu Feb 18 05:37:47 UTC 2010


Module: Mesa
Branch: master
Commit: ca0e88ce9298516087825758dd97dd0636d9f19c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ca0e88ce9298516087825758dd97dd0636d9f19c

Author: Marek Olšák <maraeo at gmail.com>
Date:   Thu Feb 18 00:18:23 2010 +0100

r300g: add support for all missing non-FP sampler formats

The idea is to directly parse the format description in
r300_translate_texformat and return ~0 if the format is unsupported.

---

 src/gallium/drivers/r300/r300_screen.c        |   64 ++-----
 src/gallium/drivers/r300/r300_state_inlines.h |    1 -
 src/gallium/drivers/r300/r300_texture.h       |  293 +++++++++++++++++++------
 3 files changed, 234 insertions(+), 124 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index b892c08..5fa1ea0 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -210,6 +210,8 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
 {
     uint32_t retval = 0;
     boolean is_r500 = r300_screen(screen)->caps->is_r500;
+    boolean is_z24 = format == PIPE_FORMAT_Z24X8_UNORM ||
+                     format == PIPE_FORMAT_Z24S8_UNORM;
 
     if (target >= PIPE_MAX_TEXTURE_TYPES) {
         debug_printf("r300: Implementation error: Received bogus texture "
@@ -217,32 +219,18 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
         return FALSE;
     }
 
+    /* Check sampler format support. */
+    if ((usage & PIPE_TEXTURE_USAGE_SAMPLER) &&
+        (is_r500 || !is_z24) && /* Z24 cannot be sampled from on non-r5xx. */
+        r300_translate_texformat(format) != ~0) {
+        retval |= PIPE_TEXTURE_USAGE_SAMPLER;
+    }
+
     switch (format) {
         /* Supported formats. */
         /* Colorbuffer */
         case PIPE_FORMAT_A8_UNORM:
         case PIPE_FORMAT_L8_UNORM:
-            retval = usage &
-                (PIPE_TEXTURE_USAGE_RENDER_TARGET |
-                 PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
-                 PIPE_TEXTURE_USAGE_PRIMARY);
-            break;
-
-        /* Texture */
-        case PIPE_FORMAT_A8R8G8B8_SRGB:
-        case PIPE_FORMAT_R8G8B8A8_SRGB:
-        case PIPE_FORMAT_DXT1_RGB:
-        case PIPE_FORMAT_DXT1_RGBA:
-        case PIPE_FORMAT_DXT3_RGBA:
-        case PIPE_FORMAT_DXT5_RGBA:
-        case PIPE_FORMAT_YCBCR:
-        case PIPE_FORMAT_L8_SRGB:
-        case PIPE_FORMAT_A8L8_SRGB:
-        case PIPE_FORMAT_A8L8_UNORM:
-            retval = usage & PIPE_TEXTURE_USAGE_SAMPLER;
-            break;
-
-        /* Colorbuffer or texture */
         case PIPE_FORMAT_R5G6B5_UNORM:
         case PIPE_FORMAT_A1R5G5B5_UNORM:
         case PIPE_FORMAT_A4R4G4B4_UNORM:
@@ -251,47 +239,23 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
         case PIPE_FORMAT_R8G8B8A8_UNORM:
         case PIPE_FORMAT_R8G8B8X8_UNORM:
         case PIPE_FORMAT_I8_UNORM:
-            retval = usage &
+            retval |= usage &
                 (PIPE_TEXTURE_USAGE_RENDER_TARGET |
                  PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
-                 PIPE_TEXTURE_USAGE_PRIMARY |
-                 PIPE_TEXTURE_USAGE_SAMPLER);
+                 PIPE_TEXTURE_USAGE_PRIMARY);
             break;
 
-        /* Z buffer or texture */
+        /* ZS buffer */
         case PIPE_FORMAT_Z16_UNORM:
-            retval = usage &
-                (PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
-                 PIPE_TEXTURE_USAGE_SAMPLER);
-            break;
-
-        /* 24bit Z buffer can only be used as a texture on R500. */
         case PIPE_FORMAT_Z24X8_UNORM:
-        /* Z buffer with stencil or texture */
         case PIPE_FORMAT_Z24S8_UNORM:
-            retval = usage &
-                (PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
-                 (is_r500 ? PIPE_TEXTURE_USAGE_SAMPLER : 0));
+            retval = usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
             break;
 
-        /* Definitely unsupported formats. */
-        /* Non-usable Z buffer/stencil formats. */
-        case PIPE_FORMAT_Z32_UNORM:
-        case PIPE_FORMAT_S8Z24_UNORM:
-        case PIPE_FORMAT_X8Z24_UNORM:
-            SCREEN_DBG(r300_screen(screen), DBG_TEX,
-                       "r300: Note: Got unsupported format: %s in %s\n",
-                       util_format_name(format), __FUNCTION__);
-            return FALSE;
-
         /* XXX Add all remaining gallium-supported formats,
          * see util/u_format.csv. */
 
-        default:
-            /* Unknown format... */
-            debug_printf("r300: Warning: Got unknown format: %s in %s\n",
-                util_format_name(format), __FUNCTION__);
-            break;
+        default:;
     }
 
     /* If usage was a mask that contained multiple bits, and not all of them
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 6ee6cd0..a608392 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -338,7 +338,6 @@ static INLINE uint32_t r300_translate_colorformat(enum pipe_format format)
         case PIPE_FORMAT_A8_UNORM:
         case PIPE_FORMAT_I8_UNORM:
         case PIPE_FORMAT_L8_UNORM:
-        /* case PIPE_FORMAT_S8_UNORM: ??? */
             return R300_COLOR_FORMAT_I8;
         /* 16-bit buffers */
         case PIPE_FORMAT_R5G6B5_UNORM:
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index b9c3ab8..153f4ee 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -52,81 +52,228 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen,
  * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
 static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
 {
-    switch (format) {
-        /* X8 */
-        case PIPE_FORMAT_A8_UNORM:
-            return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8);
-        case PIPE_FORMAT_I8_UNORM:
-            return R300_EASY_TX_FORMAT(X, X, X, X, X8);
-        case PIPE_FORMAT_L8_UNORM:
-            return R300_EASY_TX_FORMAT(X, X, X, ONE, X8);
-        case PIPE_FORMAT_L8_SRGB:
-            return R300_EASY_TX_FORMAT(X, X, X, ONE, X8) |
-                R300_TX_FORMAT_GAMMA;
-        /* X16 */
-        case PIPE_FORMAT_A4R4G4B4_UNORM:
-            return R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4);
-        case PIPE_FORMAT_R16_UNORM:
-        case PIPE_FORMAT_Z16_UNORM:
-            return R300_EASY_TX_FORMAT(X, X, X, X, X16);
-        case PIPE_FORMAT_R16_SNORM:
-            return R300_EASY_TX_FORMAT(X, X, X, X, X16) |
-                R300_TX_FORMAT_SIGNED;
-        /* Z5Y6X5 */
-        case PIPE_FORMAT_R5G6B5_UNORM:
-            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
-        /* W1Z5Y5X5*/
-        case PIPE_FORMAT_A1R5G5B5_UNORM:
-            return R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5);
-        /* Y8X8 */
-        case PIPE_FORMAT_A8L8_UNORM:
-            return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8);
-        case PIPE_FORMAT_A8L8_SRGB:
-            return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) |
-                R300_TX_FORMAT_GAMMA;
-        /* W8Z8Y8X8 */
-        case PIPE_FORMAT_A8R8G8B8_UNORM:
-            return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
-        case PIPE_FORMAT_R8G8B8A8_UNORM:
-            return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8);
-        case PIPE_FORMAT_X8R8G8B8_UNORM:
-            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
-        case PIPE_FORMAT_R8G8B8X8_UNORM:
-            return R300_EASY_TX_FORMAT(Y, Z, ONE, X, W8Z8Y8X8);
-        case PIPE_FORMAT_A8R8G8B8_SRGB:
-            return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8) |
-                R300_TX_FORMAT_GAMMA;
-        case PIPE_FORMAT_R8G8B8A8_SRGB:
-            return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) |
-                R300_TX_FORMAT_GAMMA;
-        /* DXT1 */
-        case PIPE_FORMAT_DXT1_RGB:
-            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1);
-        case PIPE_FORMAT_DXT1_RGBA:
-            return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1);
-        /* DXT3 */
-        case PIPE_FORMAT_DXT3_RGBA:
-            return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3);
-        /* DXT5 */
-        case PIPE_FORMAT_DXT5_RGBA:
-            return R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5);
-        /* YVYU422 */
-        case PIPE_FORMAT_YCBCR:
-            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) |
-                R300_TX_FORMAT_YUV_TO_RGB;
-        /* W24_FP */
-        case PIPE_FORMAT_Z24S8_UNORM:
-        case PIPE_FORMAT_Z24X8_UNORM:
-            return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
-
-        default:
-            debug_printf("r300: Implementation error: "
-                "Got unsupported texture format %s in %s\n",
-                util_format_name(format), __FUNCTION__);
-            assert(0);
+    uint32_t result = 0;
+    const struct util_format_description *desc;
+    unsigned components = 0, i;
+    boolean uniform = TRUE;
+    const uint32_t swizzle_shift[4] = {
+        R300_TX_FORMAT_R_SHIFT,
+        R300_TX_FORMAT_G_SHIFT,
+        R300_TX_FORMAT_B_SHIFT,
+        R300_TX_FORMAT_A_SHIFT
+    };
+    const uint32_t sign_bit[4] = {
+        R300_TX_FORMAT_SIGNED_X,
+        R300_TX_FORMAT_SIGNED_Y,
+        R300_TX_FORMAT_SIGNED_Z,
+        R300_TX_FORMAT_SIGNED_W,
+    };
+
+    desc = util_format_description(format);
+
+    /* Colorspace (return non-RGB formats directly). */
+    switch (desc->colorspace) {
+        /* Depth stencil formats. */
+        case UTIL_FORMAT_COLORSPACE_ZS:
+            switch (format) {
+                case PIPE_FORMAT_Z16_UNORM:
+                    return R300_EASY_TX_FORMAT(X, X, X, X, X16);
+                case PIPE_FORMAT_Z24X8_UNORM:
+                case PIPE_FORMAT_Z24S8_UNORM:
+                    return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
+                default:
+                    return ~0; /* Unsupported. */
+            }
+
+        /* YUV formats. */
+        case UTIL_FORMAT_COLORSPACE_YUV:
+            result |= R300_TX_FORMAT_YUV_TO_RGB;
+
+            switch (format) {
+                case PIPE_FORMAT_YCBCR:
+                    return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
+                case PIPE_FORMAT_YCBCR_REV:
+                    return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
+                default:
+                    return ~0; /* Unsupported/unknown. */
+            }
+
+        /* Add gamma correction. */
+        case UTIL_FORMAT_COLORSPACE_SRGB:
+            result |= R300_TX_FORMAT_GAMMA;
             break;
+
+        default:;
+    }
+
+    /* Add swizzle. */
+    for (i = 0; i < 4; i++) {
+        switch (desc->swizzle[i]) {
+            case UTIL_FORMAT_SWIZZLE_X:
+            case UTIL_FORMAT_SWIZZLE_NONE:
+                result |= R300_TX_FORMAT_X << swizzle_shift[i];
+                break;
+            case UTIL_FORMAT_SWIZZLE_Y:
+                result |= R300_TX_FORMAT_Y << swizzle_shift[i];
+                break;
+            case UTIL_FORMAT_SWIZZLE_Z:
+                result |= R300_TX_FORMAT_Z << swizzle_shift[i];
+                break;
+            case UTIL_FORMAT_SWIZZLE_W:
+                result |= R300_TX_FORMAT_W << swizzle_shift[i];
+                break;
+            case UTIL_FORMAT_SWIZZLE_0:
+                result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
+                break;
+            case UTIL_FORMAT_SWIZZLE_1:
+                result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
+                break;
+            default:
+                return ~0; /* Unsupported. */
+        }
+    }
+
+    /* Compressed formats. */
+    if (desc->layout == UTIL_FORMAT_LAYOUT_DXT) {
+        switch (format) {
+            case PIPE_FORMAT_DXT1_RGB:
+            case PIPE_FORMAT_DXT1_RGBA:
+            case PIPE_FORMAT_DXT1_SRGB:
+            case PIPE_FORMAT_DXT1_SRGBA:
+                return R300_TX_FORMAT_DXT1 | result;
+            case PIPE_FORMAT_DXT3_RGBA:
+            case PIPE_FORMAT_DXT3_SRGBA:
+                return R300_TX_FORMAT_DXT3 | result;
+            case PIPE_FORMAT_DXT5_RGBA:
+            case PIPE_FORMAT_DXT5_SRGBA:
+                return R300_TX_FORMAT_DXT5 | result;
+            default:
+                return ~0; /* Unsupported/unknown. */
+        }
+    }
+
+    /* Get the number of components. */
+    for (i = 0; i < 4; i++) {
+        if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+            ++components;
+        }
+    }
+
+    /* Add sign. */
+    for (i = 0; i < components; i++) {
+        if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
+            result |= sign_bit[i];
+        }
     }
-    return 0;
+
+    /* See whether the components are of the same size. */
+    for (i = 1; i < components; i++) {
+        uniform = uniform && desc->channel[0].size == desc->channel[i].size;
+    }
+
+    /* Non-uniform formats. */
+    if (!uniform) {
+        switch (components) {
+            case 3:
+                if (desc->channel[0].size == 5 &&
+                    desc->channel[1].size == 6 &&
+                    desc->channel[2].size == 5) {
+                    return R300_TX_FORMAT_Z5Y6X5 | result;
+                }
+                if (desc->channel[0].size == 5 &&
+                    desc->channel[1].size == 5 &&
+                    desc->channel[2].size == 6) {
+                    return R300_TX_FORMAT_Z6Y5X5 | result;
+                }
+                return ~0; /* Unsupported/unknown. */
+
+            case 4:
+                if (desc->channel[0].size == 5 &&
+                    desc->channel[1].size == 5 &&
+                    desc->channel[2].size == 5 &&
+                    desc->channel[3].size == 1) {
+                    return R300_TX_FORMAT_W1Z5Y5X5 | result;
+                }
+                if (desc->channel[0].size == 10 &&
+                    desc->channel[1].size == 10 &&
+                    desc->channel[2].size == 10 &&
+                    desc->channel[3].size == 2) {
+                    return R300_TX_FORMAT_W2Z10Y10X10 | result;
+                }
+        }
+        return ~0; /* Unsupported/unknown. */
+    }
+
+    /* And finally, uniform formats. */
+    switch (desc->channel[0].type) {
+        case UTIL_FORMAT_TYPE_UNSIGNED:
+        case UTIL_FORMAT_TYPE_SIGNED:
+            if (!desc->channel[0].normalized) {
+                return ~0;
+            }
+
+            switch (desc->channel[0].size) {
+                case 4:
+                    switch (components) {
+                        case 2:
+                            return R300_TX_FORMAT_Y4X4 | result;
+                        case 4:
+                            return R300_TX_FORMAT_W4Z4Y4X4 | result;
+                    }
+                    return ~0;
+
+                case 8:
+                    switch (components) {
+                        case 1:
+                            return R300_TX_FORMAT_X8 | result;
+                        case 2:
+                            return R300_TX_FORMAT_Y8X8 | result;
+                        case 4:
+                            return R300_TX_FORMAT_W8Z8Y8X8 | result;
+                    }
+                    return ~0;
+
+                case 16:
+                    switch (components) {
+                        case 1:
+                            return R300_TX_FORMAT_X16 | result;
+                        case 2:
+                            return R300_TX_FORMAT_Y16X16 | result;
+                        case 4:
+                            return R300_TX_FORMAT_W16Z16Y16X16 | result;
+                    }
+            }
+            return ~0;
+
+/* XXX Enable float textures here. */
+#if 0
+        case UTIL_FORMAT_TYPE_FLOAT:
+            switch (desc->channel[0].size) {
+                case 16:
+                    switch (components) {
+                        case 1:
+                            return R300_TX_FORMAT_16F | result;
+                        case 2:
+                            return R300_TX_FORMAT_16F_16F | result;
+                        case 4:
+                            return R300_TX_FORMAT_16F_16F_16F_16F | result;
+                    }
+                    return ~0;
+
+                case 32:
+                    switch (components) {
+                        case 1:
+                            return R300_TX_FORMAT_32F | result;
+                        case 2:
+                            return R300_TX_FORMAT_32F_32F | result;
+                        case 4:
+                            return R300_TX_FORMAT_32F_32F_32F_32F | result;
+                    }
+            }
+#endif
+    }
+
+    return ~0; /* Unsupported/unknown. */
 }
 
 struct r300_video_surface




More information about the mesa-commit mailing list