diff options
author | Keith Whitwell <keithw@vmware.com> | 2009-09-02 10:38:32 -0600 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2009-09-02 10:38:32 -0600 |
commit | 489b5d9f50a3fc3f1539db5a4a6d6dedee1c8c6b (patch) | |
tree | 35a8192190ea8795235a3231e4c79fa1faf54489 | |
parent | 4b08e7498230eac30eea1721f33994b30999acd4 (diff) |
mesa: initial check-in of xRGB formats
-rw-r--r-- | src/mesa/main/texformat.c | 29 | ||||
-rw-r--r-- | src/mesa/main/texformat.h | 2 | ||||
-rw-r--r-- | src/mesa/main/texformat_tmp.h | 26 | ||||
-rw-r--r-- | src/mesa/main/texstore.c | 15 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 67 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_format.c | 48 |
6 files changed, 165 insertions, 22 deletions
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index c709004784..64c7d5fa26 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -874,6 +874,35 @@ const struct gl_texture_format _mesa_texformat_argb8888_rev = { store_texel_argb8888_rev /* StoreTexel */ }; + +/* A version of ARGB8888 where the hardware ignores the alpha + * component, meaning that mesa can be less careful about maintaining + * a 1.0 in that location in order to implement GL_RGB semantics. + */ +const struct gl_texture_format _mesa_texformat_xrgb8888 = { + MESA_FORMAT_XRGB8888, /* MesaFormat */ + GL_RGB, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 8, /* RedBits */ + 8, /* GreenBits */ + 8, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 0, /* StencilBits */ + 4, /* TexelBytes */ + _mesa_texstore_argb8888, /* StoreTexImageFunc */ + NULL, /* FetchTexel1D */ + NULL, /* FetchTexel2D */ + NULL, /* FetchTexel3D */ + fetch_texel_1d_f_xrgb8888, /* FetchTexel1Df */ + fetch_texel_2d_f_xrgb8888, /* FetchTexel2Df */ + fetch_texel_3d_f_xrgb8888, /* FetchTexel3Df */ + store_texel_xrgb8888 /* StoreTexel */ +}; + const struct gl_texture_format _mesa_texformat_rgb888 = { MESA_FORMAT_RGB888, /* MesaFormat */ GL_RGB, /* BaseFormat */ diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 5aa1d756cb..06ed7d3d66 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -66,6 +66,7 @@ enum _format { MESA_FORMAT_RGBA8888, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */ MESA_FORMAT_RGBA8888_REV, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR */ MESA_FORMAT_ARGB8888, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */ + MESA_FORMAT_XRGB8888, /* xxxx xxxx RRRR RRRR GGGG GGGG BBBB BBBB */ MESA_FORMAT_ARGB8888_REV, /* BBBB BBBB GGGG GGGG RRRR RRRR AAAA AAAA */ MESA_FORMAT_RGB888, /* RRRR RRRR GGGG GGGG BBBB BBBB */ MESA_FORMAT_BGR888, /* BBBB BBBB GGGG GGGG RRRR RRRR */ @@ -229,6 +230,7 @@ extern const struct gl_texture_format _mesa_texformat_signed_rgba8888_rev; /*@{*/ extern const struct gl_texture_format _mesa_texformat_rgba8888; extern const struct gl_texture_format _mesa_texformat_rgba8888_rev; +extern const struct gl_texture_format _mesa_texformat_xrgb8888; extern const struct gl_texture_format _mesa_texformat_argb8888; extern const struct gl_texture_format _mesa_texformat_argb8888_rev; extern const struct gl_texture_format _mesa_texformat_rgb888; diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h index eb160deff9..b8e18759b4 100644 --- a/src/mesa/main/texformat_tmp.h +++ b/src/mesa/main/texformat_tmp.h @@ -659,6 +659,31 @@ static void store_texel_argb8888(struct gl_texture_image *texImage, #endif + +/* MESA_FORMAT_XRGB8888 ******************************************************/ + +/* Fetch texel from 1D, 2D or 3D argb8888 texture, return 4 GLchans */ +static void FETCH(f_xrgb8888)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); + texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); + texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); + texel[BCOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); + texel[ACOMP] = 1.0f; +} + +#if DIM == 3 +static void store_texel_xrgb8888(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); + *dst = PACK_COLOR_8888(0xff, rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]); +} +#endif + + /* MESA_FORMAT_ARGB8888_REV **************************************************/ /* Fetch texel from 1D, 2D or 3D argb8888_rev texture, return 4 GLfloats */ @@ -709,6 +734,7 @@ static void store_texel_rgb888(struct gl_texture_image *texImage, #endif + /* MESA_FORMAT_BGR888 ********************************************************/ /* Fetch texel from 1D, 2D or 3D bgr888 texture, return 4 GLchans */ diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index a22db628d3..a01fdb0abb 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1486,12 +1486,14 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) const GLboolean littleEndian = _mesa_little_endian(); ASSERT(dstFormat == &_mesa_texformat_argb8888 || + dstFormat == &_mesa_texformat_xrgb8888 || dstFormat == &_mesa_texformat_argb8888_rev); ASSERT(dstFormat->TexelBytes == 4); if (!ctx->_ImageTransferState && !srcPacking->SwapBytes && - dstFormat == &_mesa_texformat_argb8888 && + (dstFormat == &_mesa_texformat_argb8888 || + dstFormat == &_mesa_texformat_xrgb8888) && baseInternalFormat == GL_RGBA && srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || @@ -1521,7 +1523,8 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) } else if (!ctx->_ImageTransferState && !srcPacking->SwapBytes && - dstFormat == &_mesa_texformat_argb8888 && + (dstFormat == &_mesa_texformat_argb8888 || + dstFormat == &_mesa_texformat_xrgb8888) && srcFormat == GL_RGB && (baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB) && @@ -1551,7 +1554,8 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) } else if (!ctx->_ImageTransferState && !srcPacking->SwapBytes && - dstFormat == &_mesa_texformat_argb8888 && + (dstFormat == &_mesa_texformat_argb8888 || + dstFormat == &_mesa_texformat_xrgb8888) && srcFormat == GL_RGBA && baseInternalFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) { @@ -1597,6 +1601,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) /* dstmap - how to swizzle from RGBA to dst format: */ if ((littleEndian && dstFormat == &_mesa_texformat_argb8888) || + (littleEndian && dstFormat == &_mesa_texformat_xrgb8888) || (!littleEndian && dstFormat == &_mesa_texformat_argb8888_rev)) { dstmap[3] = 3; /* alpha */ dstmap[2] = 0; /* red */ @@ -1605,6 +1610,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) } else { assert((littleEndian && dstFormat == &_mesa_texformat_argb8888_rev) || + (!littleEndian && dstFormat == &_mesa_texformat_xrgb8888) || (!littleEndian && dstFormat == &_mesa_texformat_argb8888)); dstmap[3] = 2; dstmap[2] = 1; @@ -1644,7 +1650,8 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) + dstXoffset * dstFormat->TexelBytes; for (row = 0; row < srcHeight; row++) { GLuint *dstUI = (GLuint *) dstRow; - if (dstFormat == &_mesa_texformat_argb8888) { + if (dstFormat == &_mesa_texformat_argb8888 || + dstFormat == &_mesa_texformat_xrgb8888) { for (col = 0; col < srcWidth; col++) { dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]), CHAN_TO_UBYTE(src[RCOMP]), diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 90a059ca69..b44b74c7ed 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1394,6 +1394,59 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, /** + * Check if it's OK to do a glCopyPixels from the src renderbuffer to the + * dest texture using a blit/render path. + * We have to be careful about the case where the dest texture was "promoted" + * from the user's requested format. For example, he requested GL_RGB but + * Mesa chose a GL_RGBA format. We need to ensure A=1 in that case when + * the src renderbuffer may have random A values. + * + * Note that there's an additional test to ask the gallium driver if it + * supports rendering to the dest format so this test isn't the final decider. + */ +static GLboolean +compatible_src_dst_formats(const struct gl_renderbuffer *src, + const struct gl_texture_image *dst) +{ + const GLenum srcFormat = src->_BaseFormat; + const GLenum dstLogicalFormat = dst->_BaseFormat; + const GLenum dstActualFormat = dst->TexFormat->BaseFormat; + + /* XXX we may need to add additional special cases here */ + + if (dstLogicalFormat == dstActualFormat) { + /* If dst is GL_RGB and implemented as GL_RGB, then don't have + * to worry about alpha values in the src data. + */ + return TRUE; + } + else if (srcFormat == dstLogicalFormat) { + /* Need to consider texture format promotion... */ + if (srcFormat == dstActualFormat) { + /* OK, everything's the same format */ + return GL_TRUE; + } + else if (srcFormat == GL_RGB && dstActualFormat == GL_RGBA) { + /* Copy RGB framebuffer data to GL_RGB texture which was + * promoted to GL_RGBA. A will correctly be set to 1. + */ + return GL_TRUE; + } + else { + return GL_FALSE; + } + } + else if (srcFormat == GL_DEPTH_STENCIL_EXT && + dstActualFormat == GL_DEPTH_COMPONENT) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + + +/** * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible. * Note that the region to copy has already been clipped so we know we * won't read from outside the source renderbuffer's bounds. @@ -1421,7 +1474,6 @@ st_copy_texsubimage(GLcontext *ctx, struct pipe_screen *screen = pipe->screen; enum pipe_format dest_format, src_format; GLboolean use_fallback = GL_TRUE; - GLboolean matching_base_formats; /* any rendering in progress must flushed before we grab the fb image */ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); @@ -1483,17 +1535,8 @@ st_copy_texsubimage(GLcontext *ctx, src_format = strb->surface->format; dest_format = stImage->pt->format; - /* - * Determine if the src framebuffer and dest texture have the same - * base format. We need this to detect a case such as the framebuffer - * being GL_RGBA but the texture being GL_RGB. If the actual hardware - * texture format stores RGBA we need to set A=1 (overriding the - * framebuffer's alpha values). We can't do that with the blit or - * textured-quad paths. - */ - matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat); - - if (matching_base_formats && ctx->_ImageTransferState == 0x0) { + if (ctx->_ImageTransferState == 0x0 && + compatible_src_dst_formats(&strb->Base, texImage)) { /* try potential hardware path */ struct pipe_surface *dest_surface = NULL; boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index dcb90a3107..5197f81216 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -228,6 +228,8 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat) { switch (mesaFormat) { /* fix this */ + case MESA_FORMAT_XRGB8888: + return PIPE_FORMAT_X8R8G8B8_UNORM; case MESA_FORMAT_ARGB8888_REV: case MESA_FORMAT_ARGB8888: return PIPE_FORMAT_A8R8G8B8_UNORM; @@ -317,6 +319,35 @@ default_rgba_format(struct pipe_screen *screen, return PIPE_FORMAT_NONE; } + + +/** + * Find an RGB format supported by the context/winsys. + */ +static enum pipe_format +default_rgb_format(struct pipe_screen *screen, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + static const enum pipe_format colorFormats[] = { + PIPE_FORMAT_R8G8B8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + /* PIPE_FORMAT_B8G8R8X8_UNORM, */ + /* PIPE_FORMAT_R8G8B8X8_UNORM, */ + PIPE_FORMAT_R5G6B5_UNORM, + }; + uint i; + for (i = 0; i < Elements(colorFormats); i++) { + if (screen->is_format_supported( screen, colorFormats[i], target, tex_usage, geom_flags )) { + return colorFormats[i]; + } + } + return default_rgba_format( screen, target, tex_usage, geom_flags ); +} + + + /** * Find an sRGBA format supported by the context/winsys. */ @@ -402,13 +433,14 @@ st_choose_format(struct pipe_context *pipe, GLenum internalFormat, case 4: case GL_RGBA: case GL_COMPRESSED_RGBA: - case 3: - case GL_RGB: - case GL_COMPRESSED_RGB: case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: return default_rgba_format( screen, target, tex_usage, geom_flags ); + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + return default_rgb_format( screen, target, tex_usage, geom_flags ); case GL_RGBA16: if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) return default_deep_rgba_format( screen, target, tex_usage, geom_flags ); @@ -430,7 +462,7 @@ st_choose_format(struct pipe_context *pipe, GLenum internalFormat, case GL_RGB10: case GL_RGB12: case GL_RGB16: - return default_rgba_format( screen, target, tex_usage, geom_flags ); + return default_rgb_format( screen, target, tex_usage, geom_flags ); case GL_RGB5: case GL_RGB4: @@ -439,7 +471,7 @@ st_choose_format(struct pipe_context *pipe, GLenum internalFormat, return PIPE_FORMAT_R5G6B5_UNORM; if (screen->is_format_supported( screen, PIPE_FORMAT_A1R5G5B5_UNORM, target, tex_usage, geom_flags )) return PIPE_FORMAT_A1R5G5B5_UNORM; - return default_rgba_format( screen, target, tex_usage, geom_flags ); + return default_rgb_format( screen, target, tex_usage, geom_flags ); case GL_ALPHA: case GL_ALPHA4: @@ -460,7 +492,7 @@ st_choose_format(struct pipe_context *pipe, GLenum internalFormat, case GL_COMPRESSED_LUMINANCE: if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target, tex_usage, geom_flags )) return PIPE_FORMAT_L8_UNORM; - return default_rgba_format( screen, target, tex_usage, geom_flags ); + return default_rgb_format( screen, target, tex_usage, geom_flags ); case 2: case GL_LUMINANCE_ALPHA: @@ -633,6 +665,10 @@ static const struct gl_texture_format * translate_gallium_format_to_mesa_format(enum pipe_format format) { switch (format) { + case PIPE_FORMAT_R8G8B8_UNORM: + return &_mesa_texformat_rgb888; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return &_mesa_texformat_xrgb8888; case PIPE_FORMAT_A8R8G8B8_UNORM: return &_mesa_texformat_argb8888; case PIPE_FORMAT_A1R5G5B5_UNORM: |