summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2009-09-02 10:38:32 -0600
committerBrian Paul <brianp@vmware.com>2009-09-02 10:38:32 -0600
commit489b5d9f50a3fc3f1539db5a4a6d6dedee1c8c6b (patch)
tree35a8192190ea8795235a3231e4c79fa1faf54489
parent4b08e7498230eac30eea1721f33994b30999acd4 (diff)
mesa: initial check-in of xRGB formats
-rw-r--r--src/mesa/main/texformat.c29
-rw-r--r--src/mesa/main/texformat.h2
-rw-r--r--src/mesa/main/texformat_tmp.h26
-rw-r--r--src/mesa/main/texstore.c15
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c67
-rw-r--r--src/mesa/state_tracker/st_format.c48
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: