summaryrefslogtreecommitdiff
path: root/src/mesa/main/texstore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/texstore.c')
-rw-r--r--src/mesa/main/texstore.c297
1 files changed, 214 insertions, 83 deletions
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 0fd6a2daae..6360ca15f8 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 7.1
+ * Version: 7.3
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (c) 2008 VMware, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -1536,10 +1537,10 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
for (row = 0; row < srcHeight; row++) {
GLuint *d4 = (GLuint *) dstRow;
for (col = 0; col < srcWidth; col++) {
- d4[col] = ((0xff << 24) |
- (srcRow[col * 3 + RCOMP] << 16) |
- (srcRow[col * 3 + GCOMP] << 8) |
- (srcRow[col * 3 + BCOMP] << 0));
+ d4[col] = PACK_COLOR_8888(0xff,
+ srcRow[col * 3 + RCOMP],
+ srcRow[col * 3 + GCOMP],
+ srcRow[col * 3 + BCOMP]);
}
dstRow += dstRowStride;
srcRow += srcRowStride;
@@ -1551,8 +1552,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
dstFormat == &_mesa_texformat_argb8888 &&
srcFormat == GL_RGBA &&
baseInternalFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_BYTE &&
- littleEndian) {
+ srcType == GL_UNSIGNED_BYTE) {
/* same as above case, but src data has alpha too */
GLint img, row, col;
/* For some reason, streaming copies to write-combined regions
@@ -1573,39 +1573,10 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
for (row = 0; row < srcHeight; row++) {
GLuint *d4 = (GLuint *) dstRow;
for (col = 0; col < srcWidth; col++) {
- d4[col] = ((srcRow[col * 4 + ACOMP] << 24) |
- (srcRow[col * 4 + RCOMP] << 16) |
- (srcRow[col * 4 + GCOMP] << 8) |
- (srcRow[col * 4 + BCOMP] << 0));
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- }
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- dstFormat == &_mesa_texformat_argb8888 &&
- srcFormat == GL_RGBA &&
- baseInternalFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_BYTE) {
-
- GLint img, row, col;
- for (img = 0; img < srcDepth; img++) {
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
- GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
- GLubyte *dstRow = (GLubyte *) dstAddr
- + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
- + dstYoffset * dstRowStride
- + dstXoffset * dstFormat->TexelBytes;
- for (row = 0; row < srcHeight; row++) {
- for (col = 0; col < srcWidth; col++) {
- dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP];
- dstRow[col * 4 + 1] = srcRow[col * 4 + GCOMP];
- dstRow[col * 4 + 2] = srcRow[col * 4 + RCOMP];
- dstRow[col * 4 + 3] = srcRow[col * 4 + ACOMP];
+ d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
+ srcRow[col * 4 + RCOMP],
+ srcRow[col * 4 + GCOMP],
+ srcRow[col * 4 + BCOMP]);
}
dstRow += dstRowStride;
srcRow += srcRowStride;
@@ -1928,6 +1899,60 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
return GL_TRUE;
}
+GLboolean
+_mesa_texstore_rgba4444(TEXSTORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_rgba4444);
+ ASSERT(dstFormat->TexelBytes == 2);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_rgba4444 &&
+ baseInternalFormat == GL_RGBA &&
+ srcFormat == GL_RGBA &&
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4){
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride,
+ dstImageOffsets,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = (GLubyte *) dstAddr
+ + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (row = 0; row < srcHeight; row++) {
+ GLushort *dstUS = (GLushort *) dstRow;
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]),
+ CHAN_TO_UBYTE(src[ACOMP]) );
+ src += 4;
+ }
+ dstRow += dstRowStride;
+ }
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
GLboolean
_mesa_texstore_argb4444(TEXSTORE_PARAMS)
@@ -1996,7 +2021,60 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
return GL_TRUE;
}
+GLboolean
+_mesa_texstore_rgba5551(TEXSTORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_rgba5551);
+ ASSERT(dstFormat->TexelBytes == 2);
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_rgba5551 &&
+ baseInternalFormat == GL_RGBA &&
+ srcFormat == GL_RGBA &&
+ srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride,
+ dstImageOffsets,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src =tempImage;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = (GLubyte *) dstAddr
+ + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (row = 0; row < srcHeight; row++) {
+ GLushort *dstUS = (GLushort *) dstRow;
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]),
+ CHAN_TO_UBYTE(src[ACOMP]) );
+ src += 4;
+ }
+ dstRow += dstRowStride;
+ }
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
GLboolean
_mesa_texstore_argb1555(TEXSTORE_PARAMS)
@@ -2692,7 +2770,6 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
GLboolean
_mesa_texstore_srgb8(TEXSTORE_PARAMS)
{
- const GLboolean littleEndian = _mesa_little_endian();
const struct gl_texture_format *newDstFormat;
StoreTexImageFunc store;
GLboolean k;
@@ -2700,14 +2777,8 @@ _mesa_texstore_srgb8(TEXSTORE_PARAMS)
ASSERT(dstFormat == &_mesa_texformat_srgb8);
/* reuse normal rgb texstore code */
- if (littleEndian) {
- newDstFormat = &_mesa_texformat_bgr888;
- store = _mesa_texstore_bgr888;
- }
- else {
- newDstFormat = &_mesa_texformat_rgb888;
- store = _mesa_texstore_rgb888;
- }
+ newDstFormat = &_mesa_texformat_rgb888;
+ store = _mesa_texstore_rgb888;
k = store(ctx, dims, baseInternalFormat,
newDstFormat, dstAddr,
@@ -2723,17 +2794,13 @@ _mesa_texstore_srgb8(TEXSTORE_PARAMS)
GLboolean
_mesa_texstore_srgba8(TEXSTORE_PARAMS)
{
- const GLboolean littleEndian = _mesa_little_endian();
const struct gl_texture_format *newDstFormat;
GLboolean k;
ASSERT(dstFormat == &_mesa_texformat_srgba8);
/* reuse normal rgba texstore code */
- if (littleEndian)
- newDstFormat = &_mesa_texformat_rgba8888_rev;
- else
- newDstFormat = &_mesa_texformat_rgba8888;
+ newDstFormat = &_mesa_texformat_rgba8888;
k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
newDstFormat, dstAddr,
@@ -2747,6 +2814,28 @@ _mesa_texstore_srgba8(TEXSTORE_PARAMS)
GLboolean
+_mesa_texstore_sargb8(TEXSTORE_PARAMS)
+{
+ const struct gl_texture_format *newDstFormat;
+ GLboolean k;
+
+ ASSERT(dstFormat == &_mesa_texformat_sargb8);
+
+ /* reuse normal rgba texstore code */
+ newDstFormat = &_mesa_texformat_argb8888;
+
+ k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
+ newDstFormat, dstAddr,
+ dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageOffsets,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType,
+ srcAddr, srcPacking);
+ return k;
+}
+
+
+GLboolean
_mesa_texstore_sl8(TEXSTORE_PARAMS)
{
const struct gl_texture_format *newDstFormat;
@@ -2771,17 +2860,13 @@ _mesa_texstore_sl8(TEXSTORE_PARAMS)
GLboolean
_mesa_texstore_sla8(TEXSTORE_PARAMS)
{
- const GLboolean littleEndian = _mesa_little_endian();
const struct gl_texture_format *newDstFormat;
GLboolean k;
ASSERT(dstFormat == &_mesa_texformat_sla8);
/* reuse normal luminance/alpha texstore code */
- if (littleEndian)
- newDstFormat = &_mesa_texformat_al88;
- else
- newDstFormat = &_mesa_texformat_al88_rev;
+ newDstFormat = &_mesa_texformat_al88;
k = _mesa_texstore_al88(ctx, dims, baseInternalFormat,
newDstFormat, dstAddr,
@@ -3018,10 +3103,13 @@ choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
-/*
+/**
* This is the software fallback for Driver.TexImage1D()
* and Driver.CopyTexImage1D().
* \sa _mesa_store_teximage2d()
+ * Note that the width may not be the actual texture width since it may
+ * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
+ * have the actual texture size.
*/
void
_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
@@ -3032,21 +3120,16 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- GLint postConvWidth = width;
GLint sizeInBytes;
(void) border;
- if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
- _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
- }
-
choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
/* allocate memory */
if (texImage->IsCompressed)
sizeInBytes = texImage->CompressedSize;
else
- sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
+ sizeInBytes = texImage->Width * texImage->TexFormat->TexelBytes;
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
@@ -3106,15 +3189,9 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- GLint postConvWidth = width, postConvHeight = height;
GLint texelBytes, sizeInBytes;
(void) border;
- if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
- _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
- &postConvHeight);
- }
-
choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
texelBytes = texImage->TexFormat->TexelBytes;
@@ -3123,7 +3200,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
if (texImage->IsCompressed)
sizeInBytes = texImage->CompressedSize;
else
- sizeInBytes = postConvWidth * postConvHeight * texelBytes;
+ sizeInBytes = texImage->Width * texImage->Height * texelBytes;
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
@@ -3619,16 +3696,40 @@ is_srgb_teximage(const struct gl_texture_image *texImage)
switch (texImage->TexFormat->MesaFormat) {
case MESA_FORMAT_SRGB8:
case MESA_FORMAT_SRGBA8:
+ case MESA_FORMAT_SARGB8:
case MESA_FORMAT_SL8:
case MESA_FORMAT_SLA8:
+ case MESA_FORMAT_SRGB_DXT1:
+ case MESA_FORMAT_SRGBA_DXT1:
+ case MESA_FORMAT_SRGBA_DXT3:
+ case MESA_FORMAT_SRGBA_DXT5:
return GL_TRUE;
default:
return GL_FALSE;
}
}
-#endif /* FEATURE_EXT_texture_sRGB */
+/**
+ * Convert a float value from linear space to a
+ * non-linear sRGB value in [0, 255].
+ * Not terribly efficient.
+ */
+static INLINE GLfloat
+linear_to_nonlinear(GLfloat cl)
+{
+ /* can't have values outside [0, 1] */
+ GLfloat cs;
+ if (cl < 0.0031308) {
+ cs = 12.92 * cl;
+ }
+ else {
+ cs = 1.055 * _mesa_pow(cl, 0.41666) - 0.055;
+ }
+ return cs;
+}
+
+#endif /* FEATURE_EXT_texture_sRGB */
/**
* This is the software fallback for Driver.GetTexImage().
@@ -3745,18 +3846,48 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
}
#if FEATURE_EXT_texture_sRGB
else if (is_srgb_teximage(texImage)) {
- /* no pixel transfer and no non-linear to linear conversion */
- const GLint comps = texImage->TexFormat->TexelBytes;
- const GLint rowstride = comps * texImage->RowStride;
- MEMCPY(dest,
- (const GLubyte *) texImage->Data + row * rowstride,
- comps * width * sizeof(GLubyte));
+ /* special case this since need to backconvert values */
+ /* convert row to RGBA format */
+ GLfloat rgba[MAX_WIDTH][4];
+ GLint col;
+ GLbitfield transferOps = 0x0;
+
+ for (col = 0; col < width; col++) {
+ (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
+ if (texImage->TexFormat->BaseFormat == GL_LUMINANCE) {
+ rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
+ rgba[col][GCOMP] = 0.0;
+ rgba[col][BCOMP] = 0.0;
+ }
+ else if (texImage->TexFormat->BaseFormat == GL_LUMINANCE_ALPHA) {
+ rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
+ rgba[col][GCOMP] = 0.0;
+ rgba[col][BCOMP] = 0.0;
+ }
+ else if (texImage->TexFormat->BaseFormat == GL_RGB ||
+ texImage->TexFormat->BaseFormat == GL_RGBA) {
+ rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
+ rgba[col][GCOMP] = linear_to_nonlinear(rgba[col][GCOMP]);
+ rgba[col][BCOMP] = linear_to_nonlinear(rgba[col][BCOMP]);
+ }
+ }
+ _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
+ format, type, dest,
+ &ctx->Pack, transferOps /*image xfer ops*/);
}
#endif /* FEATURE_EXT_texture_sRGB */
else {
/* general case: convert row to RGBA format */
GLfloat rgba[MAX_WIDTH][4];
GLint col;
+ GLbitfield transferOps = 0x0;
+
+ if (type == GL_FLOAT &&
+ ((ctx->Color.ClampReadColor == GL_TRUE) ||
+ (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
+ texImage->TexFormat->DataType != GL_FLOAT)))
+ transferOps |= IMAGE_CLAMP_BIT;
+
for (col = 0; col < width; col++) {
(*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
if (texImage->TexFormat->BaseFormat == GL_ALPHA) {
@@ -3781,7 +3912,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
}
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
format, type, dest,
- &ctx->Pack, 0x0 /*image xfer ops*/);
+ &ctx->Pack, transferOps /*image xfer ops*/);
} /* format */
} /* row */
} /* img */
@@ -3802,8 +3933,8 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
void
_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
GLvoid *img,
- const struct gl_texture_object *texObj,
- const struct gl_texture_image *texImage)
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
{
GLuint size;