r300g: allow unaligned vertex formats if the stride is dword-aligned
authorMarek Olšák <maraeo@gmail.com>
Sun, 25 Apr 2010 23:58:07 +0000 (01:58 +0200)
committerMarek Olšák <maraeo@gmail.com>
Mon, 26 Apr 2010 05:22:00 +0000 (07:22 +0200)
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_inlines.h

index 9eb8539a655220c7bff4f09d8557e000e588f8c4..e8171e949030e30d1ec10b4257671cce9b0ec2b4 100644 (file)
@@ -1271,6 +1271,7 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
 {
     struct r300_vertex_element_state *velems;
     unsigned i, size;
+    enum pipe_format *format;
 
     assert(count <= PIPE_MAX_ATTRIBS);
     velems = CALLOC_STRUCT(r300_vertex_element_state);
@@ -1281,13 +1282,46 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
         if (r300_screen(pipe->screen)->caps.has_tcl) {
             /* Check if the format is aligned to the size of DWORD. */
             for (i = 0; i < count; i++) {
-                size = util_format_get_blocksize(attribs[i].src_format);
+                format = &velems->velem[i].src_format;
+
+                /* Replace some formats with their aligned counterparts,
+                 * this is OK because we check for aligned strides too. */
+                /* XXX We need X instead of A in the format names. */
+                switch (*format) {
+                    case PIPE_FORMAT_R8G8B8_UNORM:
+                        *format = PIPE_FORMAT_R8G8B8X8_UNORM;
+                        continue;
+                    case PIPE_FORMAT_R8G8B8_SNORM:
+                        *format = PIPE_FORMAT_R8G8B8A8_SNORM;
+                        continue;
+                    case PIPE_FORMAT_R8G8B8_USCALED:
+                        *format = PIPE_FORMAT_R8G8B8A8_USCALED;
+                        continue;
+                    case PIPE_FORMAT_R8G8B8_SSCALED:
+                        *format = PIPE_FORMAT_R8G8B8A8_SSCALED;
+                        continue;
+                    case PIPE_FORMAT_R16G16B16_UNORM:
+                        *format = PIPE_FORMAT_R16G16B16A16_UNORM;
+                        continue;
+                    case PIPE_FORMAT_R16G16B16_SNORM:
+                        *format = PIPE_FORMAT_R16G16B16A16_SNORM;
+                        continue;
+                    case PIPE_FORMAT_R16G16B16_USCALED:
+                        *format = PIPE_FORMAT_R16G16B16A16_USCALED;
+                        continue;
+                    case PIPE_FORMAT_R16G16B16_SSCALED:
+                        *format = PIPE_FORMAT_R16G16B16A16_SSCALED;
+                        continue;
+                    default:;
+                }
+
+                size = util_format_get_blocksize(*format);
 
                 if (size % 4 != 0) {
                     /* XXX Shouldn't we align the format? */
                     fprintf(stderr, "r300_create_vertex_elements_state: "
                             "Unaligned format %s:%i isn't supported\n",
-                            util_format_name(attribs[i].src_format), size);
+                            util_format_name(*format), size);
                     assert(0);
                     abort();
                 }
index ca6fc650ed68a98dd94ae8f53b9a94ad89e01455..c2bff67ccb6bf70e3b937a2a3b1a5ac41f78e5eb 100644 (file)
@@ -443,6 +443,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
 static INLINE uint16_t
 r300_translate_vertex_data_swizzle(enum pipe_format format) {
     const struct util_format_description *desc = util_format_description(format);
+    unsigned i, swizzle = 0;
 
     assert(format);
 
@@ -452,11 +453,12 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) {
         return 0;
     }
 
-    return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
-            (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
-            (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
-            (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
-            (0xf << R300_WRITE_ENA_SHIFT));
+    for (i = 0; i < 4; i++) {
+        swizzle |=
+            MIN2(desc->swizzle[i], R300_SWIZZLE_SELECT_FP_ONE) << (3*i);
+    }
+
+    return swizzle | (0xf << R300_WRITE_ENA_SHIFT);
 }
 
 #endif /* R300_STATE_INLINES_H */