From 62d4dfbfe3f7c452f3c182bfdb9270a2f20e3f2d Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 20 Sep 2006 19:11:56 +0000 Subject: [PATCH] try to use a 8888 texture format which will result in only a memcopy in mesa's texstore functions whenever possible for r200 and r300. r200 can use hw formats argb8888, rgba8888 and abgr8888 (or the opposite on big endian), r300 can use argb8888, bgra8888, rgba8888 and abgr8888 regardless of endian, as it supports free component swizzling. --- src/mesa/drivers/dri/r200/r200_tex.c | 30 ++++++++-- src/mesa/drivers/dri/r200/r200_texmem.c | 4 ++ src/mesa/drivers/dri/r200/r200_texstate.c | 50 ++++++++++++++-- src/mesa/drivers/dri/r300/r300_tex.c | 40 +++++++++++-- src/mesa/drivers/dri/r300/r300_texstate.c | 70 +++++++++++++++++++---- 5 files changed, 171 insertions(+), 23 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c index 3d259c2ca66..b3da8cd580b 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.c +++ b/src/mesa/drivers/dri/r200/r200_tex.c @@ -305,6 +305,27 @@ static r200TexObjPtr r200AllocTexObj( struct gl_texture_object *texObj ) 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 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, 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 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, 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 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, 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 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, 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: diff --git a/src/mesa/drivers/dri/r200/r200_texmem.c b/src/mesa/drivers/dri/r200/r200_texmem.c index 14ee8238ad8..28988c97556 100644 --- a/src/mesa/drivers/dri/r200/r200_texmem.c +++ b/src/mesa/drivers/dri/r200/r200_texmem.c @@ -374,6 +374,10 @@ static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t, 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; diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c index abb6af1b705..397b27ae52e 100644 --- a/src/mesa/drivers/dri/r200/r200_texstate.c +++ b/src/mesa/drivers/dri/r200/r200_texstate.c @@ -71,14 +71,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 @@ tx_table[] = _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 @@ static void r200SetTexImages( r200ContextPtr rmesa, 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 @@ static void r200SetTexImages( r200ContextPtr rmesa, 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__); diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index efa072c2651..6348ba1982a 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -297,6 +297,38 @@ static r300TexObjPtr r300AllocTexObj(struct gl_texture_object *texObj) 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 if (srcFormat == GL_BGRA && + ((srcType == GL_UNSIGNED_BYTE && littleEndian) || + srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { + return &_mesa_texformat_argb8888; + } + else return _dri_texformat_argb8888; +} + static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, GLint internalFormat, @@ -335,7 +367,7 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, 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 +385,7 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, 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 +394,7 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, 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 +407,7 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, 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: diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index c4a1bf01b4c..791427a6abe 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -51,14 +51,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 @@ static const struct { * 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(Z, Y, X, W, 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 @@ static const struct { _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(Z, Y, X, W, 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 @@ static void r300SetTexImages(r300ContextPtr rmesa, 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__); -- 2.30.2