Kristian Høgsberg wrote:
Ok, I changed r100 to always use argb8888 instead of rgba8888 (at least on little endian, it is highly unlikely an app ever hits the memcopy path with rgba8888, and it can't do abgr8888).The problem is that while the hardware both argb8888 and rgba8888, the driver always only configures the hardware to use one of these. Which means that texture upload for argb8888 is just a memcpy, while rgba8888 upload has to swap. For implementing GLX_EXT_texture_from_pixmap, it just happens to choose the wrong format, so texture upload from an X pixmap always has to swap. Ideally, the driver should configure the hardware to use the right format so both cases reduce to memcpy, but the patch just swaps the slow and fast case so that the AIGLX texture_from_pixmap implementation hits the memcpy path.
Would the attached patch be useful for r200 and r300 or is it overkill for such a simple optimization? It will try to find a 8888 format so the memcopy path is hit. To do this it will use both _rev and normal formats on both little and big endian, which unfortunately means we now need two tx_table tables (though actually only 2 (respectively 4 on r300) entries differ from little to big endian). Note that on r300 an optimized chooseTextureFormatFunction could be used for other formats too (but the 8888 formats are probably by far the most used, save maybe compressed ones in games). The new chooseTextureFunction isn't used in some cases where it would be possible to hit the memcopy path in theory, for instance an app supplying rgba unsigned byte data, and requesting rgb internal format, I figured it's too unlikely to ever happen to be worth it. This is only tested on r200 / little endian (passes glean pixelFormats test), someone else would need to test r300 and / or big endian.
Roland
Index: r200/r200_tex.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_tex.c,v retrieving revision 1.20 diff -u -r1.20 r200_tex.c --- r200/r200_tex.c 7 Oct 2004 23:30:30 -0000 1.20 +++ r200/r200_tex.c 14 Sep 2006 11:40:59 -0000 @@ -305,6 +305,27 @@ return t; } +/* try to find a format which will only need a memcopy */ +static const struct gl_texture_format * +r200Choose8888TexFormat( GLenum srcFormat, GLenum srcType ) +{ + const GLuint ui = 1; + const GLubyte littleEndian = *((const GLubyte *) &ui); + + if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { + return &_mesa_texformat_rgba8888; + } + else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { + return &_mesa_texformat_rgba8888_rev; + } + else return _dri_texformat_argb8888; +} static const struct gl_texture_format * r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, @@ -332,7 +353,8 @@ case GL_UNSIGNED_SHORT_1_5_5_5_REV: return _dri_texformat_argb1555; default: - return do32bpt ? _dri_texformat_rgba8888 : _dri_texformat_argb4444; + return do32bpt ? + r200Choose8888TexFormat(format, type) : _dri_texformat_argb4444; } case 3: @@ -349,7 +371,7 @@ case GL_UNSIGNED_SHORT_5_6_5_REV: return _dri_texformat_rgb565; default: - return do32bpt ? _dri_texformat_rgba8888 : _dri_texformat_rgb565; + return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565; } case GL_RGBA8: @@ -357,7 +379,7 @@ case GL_RGBA12: case GL_RGBA16: return !force16bpt ? - _dri_texformat_rgba8888 : _dri_texformat_argb4444; + r200Choose8888TexFormat(format, type) : _dri_texformat_argb4444; case GL_RGBA4: case GL_RGBA2: @@ -370,7 +392,7 @@ case GL_RGB10: case GL_RGB12: case GL_RGB16: - return !force16bpt ? _dri_texformat_rgba8888 : _dri_texformat_rgb565; + return !force16bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565; case GL_RGB5: case GL_RGB4: Index: r200/r200_texmem.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_texmem.c,v retrieving revision 1.12 diff -u -r1.12 r200_texmem.c --- r200/r200_texmem.c 25 Aug 2005 03:38:07 -0000 1.12 +++ r200/r200_texmem.c 14 Sep 2006 11:41:00 -0000 @@ -374,6 +374,10 @@ tex.height = imageHeight; tex.width = imageWidth; tex.format = t->pp_txformat & R200_TXFORMAT_FORMAT_MASK; + if (tex.format == R200_TXFORMAT_ABGR8888) { + /* drm will refuse abgr8888 textures. */ + tex.format = R200_TXFORMAT_ARGB8888; + } tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1); tex.offset += tmp.x & ~1023; tmp.x = tmp.x % 1024; Index: r200/r200_texstate.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_texstate.c,v retrieving revision 1.25 diff -u -r1.25 r200_texstate.c --- r200/r200_texstate.c 13 Sep 2006 23:20:10 -0000 1.25 +++ r200/r200_texstate.c 14 Sep 2006 11:41:00 -0000 @@ -71,14 +71,14 @@ #define _INVALID(f) \ [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 } #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \ - && (tx_table[f].format != 0xffffffff) ) + && (tx_table_le[f].format != 0xffffffff) ) static const struct { GLuint format, filter; } -tx_table[] = +tx_table_be[] = { - _ALPHA(RGBA8888), + [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 }, _ALPHA_REV(RGBA8888), _ALPHA(ARGB8888), _ALPHA_REV(ARGB8888), @@ -105,6 +105,38 @@ _ALPHA(RGBA_DXT5), }; +static const struct { + GLuint format, filter; +} +tx_table_le[] = +{ + _ALPHA(RGBA8888), + [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 }, + _ALPHA(ARGB8888), + _ALPHA_REV(ARGB8888), + _INVALID(RGB888), + _COLOR(RGB565), + _COLOR_REV(RGB565), + _ALPHA(ARGB4444), + _ALPHA_REV(ARGB4444), + _ALPHA(ARGB1555), + _ALPHA_REV(ARGB1555), + _ALPHA(AL88), + _ALPHA_REV(AL88), + _ALPHA(A8), + _COLOR(L8), + _ALPHA(I8), + _INVALID(CI8), + _YUV(YCBCR), + _YUV(YCBCR_REV), + _INVALID(RGB_FXT1), + _INVALID(RGBA_FXT1), + _COLOR(RGB_DXT1), + _ALPHA(RGBA_DXT1), + _ALPHA(RGBA_DXT3), + _ALPHA(RGBA_DXT5), +}; + #undef _COLOR #undef _ALPHA #undef _INVALID @@ -129,6 +161,8 @@ GLint i, texelBytes; GLint numLevels; GLint log2Width, log2Height, log2Depth; + const GLuint ui = 1; + const GLubyte littleEndian = *((const GLubyte *) &ui); /* Set the hardware texture format */ @@ -138,8 +172,14 @@ t->pp_txfilter &= ~R200_YUV_TO_RGB; if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { - t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format; - t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter; + if (littleEndian) { + t->pp_txformat |= tx_table_le[ baseImage->TexFormat->MesaFormat ].format; + t->pp_txfilter |= tx_table_le[ baseImage->TexFormat->MesaFormat ].filter; + } + else { + t->pp_txformat |= tx_table_be[ baseImage->TexFormat->MesaFormat ].format; + t->pp_txfilter |= tx_table_be[ baseImage->TexFormat->MesaFormat ].filter; + } } else { _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); Index: r300/r300_tex.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_tex.c,v retrieving revision 1.23 diff -u -r1.23 r300_tex.c --- r300/r300_tex.c 29 Mar 2006 15:21:01 -0000 1.23 +++ r300/r300_tex.c 14 Sep 2006 11:41:01 -0000 @@ -297,6 +297,33 @@ return t; } +/* try to find a format which will only need a memcopy */ +static const struct gl_texture_format *r300Choose8888TexFormat( GLenum srcFormat, + GLenum srcType ) +{ + const GLuint ui = 1; + const GLubyte littleEndian = *((const GLubyte *) &ui); + + if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { + return &_mesa_texformat_rgba8888; + } + else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { + return &_mesa_texformat_rgba8888_rev; + } + else if (srcFormat == GL_BGRA && + ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || + srcType == GL_UNSIGNED_INT_8_8_8_8)) { + return &_mesa_texformat_argb8888_rev; + } + else return _dri_texformat_argb8888; +} + static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, GLint internalFormat, @@ -335,7 +362,7 @@ case GL_UNSIGNED_SHORT_1_5_5_5_REV: return _dri_texformat_argb1555; default: - return do32bpt ? _dri_texformat_rgba8888 : + return do32bpt ? r300Choose8888TexFormat(format, type) : _dri_texformat_argb4444; } @@ -353,7 +380,7 @@ case GL_UNSIGNED_SHORT_5_6_5_REV: return _dri_texformat_rgb565; default: - return do32bpt ? _dri_texformat_rgba8888 : + return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565; } @@ -362,7 +389,7 @@ case GL_RGBA12: case GL_RGBA16: return !force16bpt ? - _dri_texformat_rgba8888 : _dri_texformat_argb4444; + r300Choose8888TexFormat(format, type) : _dri_texformat_argb4444; case GL_RGBA4: case GL_RGBA2: @@ -375,7 +402,7 @@ case GL_RGB10: case GL_RGB12: case GL_RGB16: - return !force16bpt ? _dri_texformat_rgba8888 : + return !force16bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565; case GL_RGB5: Index: r300/r300_texstate.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_texstate.c,v retrieving revision 1.48 diff -u -r1.48 r300_texstate.c --- r300/r300_texstate.c 12 Sep 2006 18:34:43 -0000 1.48 +++ r300/r300_texstate.c 14 Sep 2006 11:41:01 -0000 @@ -51,14 +51,14 @@ #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \ || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \ (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \ - && tx_table[f].flag ) + && tx_table_le[f].flag ) #define _ASSIGN(entry, format) \ [ MESA_FORMAT_ ## entry ] = { format, 0, 1} static const struct { GLuint format, filter, flag; -} tx_table[] = { +} tx_table_be[] = { /* * Note that the _REV formats are the same as the non-REV formats. * This is because the REV and non-REV formats are identical as a @@ -68,9 +68,9 @@ * byte-swapping), the R300 sees the REV and non-REV formats * identically. -- paulus */ - _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)), + _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(X, W, Z, Y, W8Z8Y8X8)), _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)), - _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)), + _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)), _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)), _ASSIGN(RGB888, 0xffffffff), _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), @@ -106,6 +106,47 @@ _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)), }; +static const struct { + GLuint format, filter, flag; +} tx_table_le[] = { + _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)), + _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(X, W, Z, Y, W8Z8Y8X8)), + _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)), + _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)), + _ASSIGN(RGB888, 0xffffffff), + _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), + _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), + _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)), + _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)), + _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)), + _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)), + _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)), + _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)), + _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)), + _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)), + _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)), + _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)), + _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)), + _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE ), + _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE), + _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)), + _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)), + _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)), + _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)), + _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)), + _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)), + _ASSIGN(RGB_FLOAT32, 0xffffffff), + _ASSIGN(RGB_FLOAT16, 0xffffffff), + _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)), + _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)), + _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)), + _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)), + _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)), + _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)), + _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)), + _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)), + }; + #undef _ASSIGN @@ -130,15 +171,24 @@ GLint i, texelBytes; GLint numLevels; GLint log2Width, log2Height, log2Depth; + const GLuint ui = 1; + const GLubyte littleEndian = *((const GLubyte *) &ui); /* Set the hardware texture format */ - if (VALID_FORMAT(baseImage->TexFormat->MesaFormat) && - tx_table[baseImage->TexFormat->MesaFormat].flag) { - t->format = - tx_table[baseImage->TexFormat->MesaFormat].format; - t->filter |= - tx_table[baseImage->TexFormat->MesaFormat].filter; + if (VALID_FORMAT(baseImage->TexFormat->MesaFormat)) { + if (littleEndian) { + t->format = + tx_table_le[baseImage->TexFormat->MesaFormat].format; + t->filter |= + tx_table_le[baseImage->TexFormat->MesaFormat].filter; + } + else { + t->format = + tx_table_be[baseImage->TexFormat->MesaFormat].format; + t->filter |= + tx_table_be[baseImage->TexFormat->MesaFormat].filter; + } } else { _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mesa3d-dev