r600g: correctly report supported vertex formats
authorMarek Olšák <maraeo@gmail.com>
Mon, 7 Feb 2011 02:46:25 +0000 (03:46 +0100)
committerMarek Olšák <maraeo@gmail.com>
Mon, 7 Feb 2011 02:51:53 +0000 (03:51 +0100)
src/gallium/drivers/r600/eg_state_inlines.h
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_state_inlines.h

index 5a39d7c..ca00e61 100644 (file)
@@ -501,9 +501,4 @@ static INLINE boolean r600_is_zs_format_supported(enum pipe_format format)
        return r600_translate_dbformat(format) != ~0;
 }
 
-static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format)
-{
-       return r600_translate_colorformat(format) != ~0;
-}
-
 #endif
index 85ad0ee..04bbcf5 100644 (file)
@@ -440,9 +440,14 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
                retval |= PIPE_BIND_DEPTH_STENCIL;
        }
 
-       if ((usage & PIPE_BIND_VERTEX_BUFFER) &&
-           r600_is_vertex_format_supported(format))
-               retval |= PIPE_BIND_VERTEX_BUFFER;
+       if (usage & PIPE_BIND_VERTEX_BUFFER) {
+               struct r600_screen *rscreen = (struct r600_screen *)screen;
+               enum radeon_family family = r600_get_family(rscreen->radeon);
+
+               if (r600_is_vertex_format_supported(format, family)) {
+                       retval |= PIPE_BIND_VERTEX_BUFFER;
+               }
+       }
 
        if (usage & PIPE_BIND_TRANSFER_READ)
                retval |= PIPE_BIND_TRANSFER_READ;
index d5dabdc..f68bc84 100644 (file)
@@ -495,9 +495,37 @@ static INLINE boolean r600_is_zs_format_supported(enum pipe_format format)
        return r600_translate_dbformat(format) != ~0;
 }
 
-static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format)
+static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format,
+                                                     enum radeon_family family)
 {
-       return r600_translate_colorformat(format) != ~0;
+       unsigned i;
+       const struct util_format_description *desc = util_format_description(format);
+       if (!desc)
+               return FALSE;
+
+       /* Find the first non-VOID channel. */
+       for (i = 0; i < 4; i++) {
+               if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+                       break;
+               }
+       }
+       if (i == 4)
+               return FALSE;
+
+       /* No fixed, no double. */
+       if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
+           desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED ||
+           (desc->channel[i].size == 64 &&
+            desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))
+               return FALSE;
+
+       /* No scaled/norm formats with 32 bits per channel. */
+       if (desc->channel[i].size == 32 &&
+           (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
+            desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED))
+               return FALSE;
+
+       return TRUE;
 }
 
 #endif