From 52e591383bdce49cb46a1162aff9632c57e06504 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 26 Apr 2010 01:58:07 +0200 Subject: r300g: allow unaligned vertex formats if the stride is dword-aligned --- src/gallium/drivers/r300/r300_state.c | 38 +++++++++++++++++++++++++-- src/gallium/drivers/r300/r300_state_inlines.h | 12 +++++---- 2 files changed, 43 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 9eb8539a65..e8171e9490 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -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(); } diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index ca6fc650ed..c2bff67ccb 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -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 */ -- cgit v1.2.3