summaryrefslogtreecommitdiff
path: root/src/mesa/main
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@vmware.com>2009-03-27 19:39:52 +0100
committerRoland Scheidegger <sroland@vmware.com>2009-03-28 02:02:42 +0100
commitc6a6cc191813e8343a17b028146a34f193a6ce44 (patch)
treecb1ecd35ac15c9b2c0cf3740dbdc631c7622233a /src/mesa/main
parenta9bf5b5ccac2a75f1a2470d4910361e65b2d8eab (diff)
mesa: add new signed rgba texture format
This is a (partial) backport of the signed texture format support in OGL 3.1. Since it wasn't promoted from an existing extension roll our own.
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/colortab.c2
-rw-r--r--src/mesa/main/convolve.c6
-rw-r--r--src/mesa/main/extensions.c1
-rw-r--r--src/mesa/main/histogram.c2
-rw-r--r--src/mesa/main/image.c17
-rw-r--r--src/mesa/main/image.h2
-rw-r--r--src/mesa/main/macros.h22
-rw-r--r--src/mesa/main/mipmap.c111
-rw-r--r--src/mesa/main/mtypes.h1
-rw-r--r--src/mesa/main/texformat.c44
-rw-r--r--src/mesa/main/texformat.h4
-rw-r--r--src/mesa/main/texformat_tmp.h22
-rw-r--r--src/mesa/main/teximage.c13
-rw-r--r--src/mesa/main/texstore.c127
-rw-r--r--src/mesa/main/texstore.h1
15 files changed, 333 insertions, 42 deletions
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index bd9cf438b4..b05c0513aa 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -718,7 +718,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
}
_mesa_pack_rgba_span_float(ctx, table->Size, rgba,
- format, type, data, &ctx->Pack, 0x0);
+ format, type, data, &ctx->Pack, 0x0, GL_FALSE);
if (ctx->Pack.BufferObj->Name) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c
index 814c6a0a5a..63b652bf70 100644
--- a/src/mesa/main/convolve.c
+++ b/src/mesa/main/convolve.c
@@ -626,7 +626,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
row, 0);
GLfloat (*src)[4] = (GLfloat (*)[4]) (filter->Filter + row * filter->Width * 4);
_mesa_pack_rgba_span_float(ctx, filter->Width, src,
- format, type, dst, &ctx->Pack, 0x0);
+ format, type, dst, &ctx->Pack, 0x0, GL_FALSE);
}
if (ctx->Pack.BufferObj->Name) {
@@ -836,7 +836,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
format, type, 0);
_mesa_pack_rgba_span_float(ctx, filter->Width,
(GLfloat (*)[4]) filter->Filter,
- format, type, dst, &ctx->Pack, 0x0);
+ format, type, dst, &ctx->Pack, 0x0, GL_FALSE);
}
/* Column filter */
@@ -845,7 +845,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
format, type, 0);
GLfloat (*src)[4] = (GLfloat (*)[4]) (filter->Filter + colStart);
_mesa_pack_rgba_span_float(ctx, filter->Height, src,
- format, type, dst, &ctx->Pack, 0x0);
+ format, type, dst, &ctx->Pack, 0x0, GL_FALSE);
}
(void) span; /* unused at this time */
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 2d2bf51784..147d923e64 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -150,6 +150,7 @@ static const struct {
{ OFF, "GL_MESA_packed_depth_stencil", F(MESA_packed_depth_stencil) },
{ OFF, "GL_MESA_resize_buffers", F(MESA_resize_buffers) },
{ OFF, "GL_MESA_texture_array", F(MESA_texture_array) },
+ { OFF, "GL_MESA_texture_signed_rgba", F(MESA_texture_signed_rgba) },
{ OFF, "GL_MESA_ycbcr_texture", F(MESA_ycbcr_texture) },
{ ON, "GL_MESA_window_pos", F(ARB_window_pos) },
{ OFF, "GL_NV_blend_square", F(NV_blend_square) },
diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c
index 905c1ad830..febf8d99c4 100644
--- a/src/mesa/main/histogram.c
+++ b/src/mesa/main/histogram.c
@@ -684,7 +684,7 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F);
minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F);
_mesa_pack_rgba_span_float(ctx, 2, minmax,
- format, type, values, &ctx->Pack, 0x0);
+ format, type, values, &ctx->Pack, 0x0, GL_FALSE);
}
if (ctx->Pack.BufferObj->Name) {
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index fa3149d56d..44972ae8e2 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -1686,24 +1686,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
GLenum dstFormat, GLenum dstType,
GLvoid *dstAddr,
const struct gl_pixelstore_attrib *dstPacking,
- GLbitfield transferOps)
+ GLbitfield transferOps, GLboolean noClamp)
{
GLfloat luminance[MAX_WIDTH];
const GLint comps = _mesa_components_in_format(dstFormat);
GLuint i;
- /* clamping only applies to colors, not the dudv values, but still need
- it if converting to unsigned values (which doesn't make much sense) */
- if (dstFormat == GL_DUDV_ATI || dstFormat == GL_DU8DV8_ATI) {
- switch (dstType) {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT:
- case GL_UNSIGNED_INT:
- transferOps |= IMAGE_CLAMP_BIT;
- break;
- /* actually might want clamp to [-1,1] otherwise but shouldn't matter? */
- }
- }
- else if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
+
+ if ((!noClamp) && (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE)) {
/* need to clamp to [0, 1] */
transferOps |= IMAGE_CLAMP_BIT;
}
diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h
index b26c27e5a8..fb7a5c0e90 100644
--- a/src/mesa/main/image.h
+++ b/src/mesa/main/image.h
@@ -178,7 +178,7 @@ extern void
_mesa_pack_rgba_span_float( GLcontext *ctx, GLuint n, GLfloat rgba[][4],
GLenum dstFormat, GLenum dstType, GLvoid *dstAddr,
const struct gl_pixelstore_attrib *dstPacking,
- GLbitfield transferOps );
+ GLbitfield transferOps, GLboolean noClamp );
extern void
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
index bfd740870e..01d59dd42d 100644
--- a/src/mesa/main/macros.h
+++ b/src/mesa/main/macros.h
@@ -54,12 +54,20 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
#define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 )
+/** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0], texture/fb data */
+#define BYTE_TO_FLOAT_TEX(B) ((B) == -128 ? -1.0 : (B) * (1.0F/127.0F))
+
+/** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127], texture/fb data */
+#define FLOAT_TO_BYTE_TEX(X) ( (GLint) (127.0F * (X)) )
+
+
/** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */
#define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F))
/** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */
#define FLOAT_TO_USHORT(X) ((GLuint) ((X) * 65535.0))
+
/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
@@ -67,6 +75,13 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
#define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 )
+/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0], texture/fb data */
+#define SHORT_TO_FLOAT_TEX(S) ((S) == -32768 ? -1.0 : (S) * (1.0F/32767.0F))
+
+/** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767], texture/fb data */
+#define FLOAT_TO_SHORT_TEX(X) ( (GLint) (32767.0F * (X)) )
+
+
/** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0F))
@@ -85,6 +100,13 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) )
+/** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0], texture/fb data */
+#define INT_TO_FLOAT_TEX(I) ((I) == -2147483648 ? -1.0 : (I) * (1.0F/2147483647.0))
+
+/** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647], texture/fb data */
+#define FLOAT_TO_INT_TEX(X) ( (GLint) (2147483647.0F * (X)) )
+
+
#define BYTE_TO_UBYTE(b) ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b)))
#define SHORT_TO_UBYTE(s) ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)))
#define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8))
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 4a79430c34..7001211a13 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -86,6 +86,21 @@ bytes_per_pixel(GLenum datatype, GLuint comps)
rowD[j][e], rowD[k][e]); \
} while(0)
+#define FILTER_SUM_3D_SIGNED(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \
+ (Aj + Ak \
+ + Bj + Bk \
+ + Cj + Ck \
+ + Dj + Dk \
+ + 4) / 8
+
+#define FILTER_3D_SIGNED(e) \
+ do { \
+ dst[i][e] = FILTER_SUM_3D_SIGNED(rowA[j][e], rowA[k][e], \
+ rowB[j][e], rowB[k][e], \
+ rowC[j][e], rowC[k][e], \
+ rowD[j][e], rowD[k][e]); \
+ } while(0)
+
#define FILTER_F_3D(e) \
do { \
dst[i][e] = (rowA[j][e] + rowA[k][e] \
@@ -180,6 +195,53 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
}
}
+ if (datatype == GL_BYTE && comps == 4) {
+ GLuint i, j, k;
+ const GLbyte(*rowA)[4] = (const GLbyte(*)[4]) srcRowA;
+ const GLbyte(*rowB)[4] = (const GLbyte(*)[4]) srcRowB;
+ GLbyte(*dst)[4] = (GLbyte(*)[4]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
+ dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
+ dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
+ }
+ }
+ else if (datatype == GL_BYTE && comps == 3) {
+ GLuint i, j, k;
+ const GLbyte(*rowA)[3] = (const GLbyte(*)[3]) srcRowA;
+ const GLbyte(*rowB)[3] = (const GLbyte(*)[3]) srcRowB;
+ GLbyte(*dst)[3] = (GLbyte(*)[3]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
+ dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
+ }
+ }
+ else if (datatype == GL_BYTE && comps == 2) {
+ GLuint i, j, k;
+ const GLbyte(*rowA)[2] = (const GLbyte(*)[2]) srcRowA;
+ const GLbyte(*rowB)[2] = (const GLbyte(*)[2]) srcRowB;
+ GLbyte(*dst)[2] = (GLbyte(*)[2]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
+ }
+ }
+ else if (datatype == GL_BYTE && comps == 1) {
+ GLuint i, j, k;
+ const GLbyte *rowA = (const GLbyte *) srcRowA;
+ const GLbyte *rowB = (const GLbyte *) srcRowB;
+ GLbyte *dst = (GLbyte *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
+ }
+ }
+
else if (datatype == GL_UNSIGNED_SHORT && comps == 4) {
GLuint i, j, k;
const GLushort(*rowA)[4] = (const GLushort(*)[4]) srcRowA;
@@ -470,17 +532,6 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
dst[i] = (blue << 5) | (green << 2) | red;
}
}
- else if (datatype == GL_BYTE && comps == 2) {
- GLuint i, j, k;
- const GLbyte(*rowA)[2] = (const GLbyte(*)[2]) srcRowA;
- const GLbyte(*rowB)[2] = (const GLbyte(*)[2]) srcRowB;
- GLbyte(*dst)[2] = (GLbyte(*)[2]) dstRow;
- for (i = j = 0, k = k0; i < (GLuint) dstWidth;
- i++, j += colStride, k += colStride) {
- dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2;
- dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2;
- }
- }
else {
_mesa_problem(NULL, "bad format in do_row()");
}
@@ -555,6 +606,44 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth,
FILTER_3D(0);
}
}
+ if ((datatype == GL_BYTE) && (comps == 4)) {
+ DECLARE_ROW_POINTERS(GLbyte, 4);
+
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ FILTER_3D_SIGNED(0);
+ FILTER_3D_SIGNED(1);
+ FILTER_3D_SIGNED(2);
+ FILTER_3D_SIGNED(3);
+ }
+ }
+ else if ((datatype == GL_BYTE) && (comps == 3)) {
+ DECLARE_ROW_POINTERS(GLbyte, 3);
+
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ FILTER_3D_SIGNED(0);
+ FILTER_3D_SIGNED(1);
+ FILTER_3D_SIGNED(2);
+ }
+ }
+ else if ((datatype == GL_BYTE) && (comps == 2)) {
+ DECLARE_ROW_POINTERS(GLbyte, 2);
+
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ FILTER_3D_SIGNED(0);
+ FILTER_3D_SIGNED(1);
+ }
+ }
+ else if ((datatype == GL_BYTE) && (comps == 1)) {
+ DECLARE_ROW_POINTERS(GLbyte, 1);
+
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ FILTER_3D_SIGNED(0);
+ }
+ }
else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 4)) {
DECLARE_ROW_POINTERS(GLushort, 4);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 5293009454..a5d3be3543 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2503,6 +2503,7 @@ struct gl_extensions
GLboolean MESA_resize_buffers;
GLboolean MESA_ycbcr_texture;
GLboolean MESA_texture_array;
+ GLboolean MESA_texture_signed_rgba;
GLboolean NV_blend_square;
GLboolean NV_fragment_program;
GLboolean NV_light_max_exponent;
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index c372b49398..0ceaaf3ece 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -699,9 +699,7 @@ const struct gl_texture_format _mesa_texformat_intensity_float16 = {
const struct gl_texture_format _mesa_texformat_dudv8 = {
MESA_FORMAT_DUDV8, /* MesaFormat */
GL_DUDV_ATI, /* BaseFormat */
- /* FIXME: spec doesn't say since that parameter didn't exist then,
- but this should be something like SIGNED_NORMALIZED */
- GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ GL_SIGNED_NORMALIZED, /* DataType */
/* maybe should add dudvBits field, but spec seems to be
lacking the ability to query with GetTexLevelParameter anyway */
0, /* RedBits */
@@ -724,6 +722,30 @@ const struct gl_texture_format _mesa_texformat_dudv8 = {
NULL /* StoreTexel */
};
+const struct gl_texture_format _mesa_texformat_signed_rgba8888 = {
+ MESA_FORMAT_SIGNED_RGBA8888, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_SIGNED_NORMALIZED, /* DataType */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4, /* TexelBytes */
+ _mesa_texstore_signed_rgba8888, /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_signed_rgba8888, /* FetchTexel1Df */
+ fetch_texel_2d_signed_rgba8888, /* FetchTexel2Df */
+ fetch_texel_3d_signed_rgba8888, /* FetchTexel3Df */
+ store_texel_signed_rgba8888 /* StoreTexel */
+};
+
/*@}*/
@@ -1671,6 +1693,17 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
}
}
+ if (ctx->Extensions.MESA_texture_signed_rgba) {
+ switch (internalFormat) {
+ case GL_RGBA_SNORM:
+ case GL_RGBA8_SNORM:
+ return &_mesa_texformat_signed_rgba8888;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+
#if FEATURE_EXT_texture_sRGB
if (ctx->Extensions.EXT_texture_sRGB) {
switch (internalFormat) {
@@ -1820,6 +1853,11 @@ _mesa_format_to_type_and_comps(const struct gl_texture_format *format,
*comps = 2;
return;
+ case MESA_FORMAT_SIGNED_RGBA8888:
+ *datatype = GL_BYTE;
+ *comps = 4;
+ return;
+
#if FEATURE_EXT_texture_sRGB
case MESA_FORMAT_SRGB8:
*datatype = GL_UNSIGNED_BYTE;
diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h
index 7fa70ad4fe..3a08339adf 100644
--- a/src/mesa/main/texformat.h
+++ b/src/mesa/main/texformat.h
@@ -168,7 +168,8 @@ enum _format {
* \name Signed fixed point texture formats.
*/
/*@{*/
- MESA_FORMAT_DUDV8
+ MESA_FORMAT_DUDV8,
+ MESA_FORMAT_SIGNED_RGBA8888
/*@}*/
};
@@ -219,6 +220,7 @@ extern const struct gl_texture_format _mesa_texformat_intensity_float16;
/** Signed fixed point texture formats */
/*@{*/
extern const struct gl_texture_format _mesa_texformat_dudv8;
+extern const struct gl_texture_format _mesa_texformat_signed_rgba8888;
/*@}*/
/** \name Assorted hardware-friendly formats */
diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h
index 0f6a172ef0..604b1a744c 100644
--- a/src/mesa/main/texformat_tmp.h
+++ b/src/mesa/main/texformat_tmp.h
@@ -1321,6 +1321,28 @@ static void FETCH(dudv8)(const struct gl_texture_image *texImage,
texel[ACOMP] = 0;
}
+/* MESA_FORMAT_SIGNED_ARGB8888 ***********************************************/
+
+static void FETCH(signed_rgba8888)( 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] = BYTE_TO_FLOAT_TEX( (s >> 24) );
+ texel[GCOMP] = BYTE_TO_FLOAT_TEX( (s >> 16) & 0xff );
+ texel[BCOMP] = BYTE_TO_FLOAT_TEX( (s >> 8) & 0xff );
+ texel[ACOMP] = BYTE_TO_FLOAT_TEX( (s ) & 0xff );
+}
+
+#if DIM == 3
+static void store_texel_signed_rgba8888(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLbyte *rgba = (const GLbyte *) texel;
+ GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_8888(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP], rgba[ACOMP]);
+}
+#endif
+
/* MESA_FORMAT_YCBCR *********************************************************/
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 4f297738df..8c03c36c75 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -349,6 +349,15 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
}
}
+ if (ctx->Extensions.MESA_texture_signed_rgba) {
+ switch (internalFormat) {
+ case GL_RGBA_SNORM:
+ case GL_RGBA8_SNORM:
+ return GL_RGBA;
+ default:
+ ; /* fallthrough */
+ }
+ }
if (ctx->Extensions.EXT_packed_depth_stencil) {
switch (internalFormat) {
@@ -502,6 +511,10 @@ _mesa_is_color_format(GLenum format)
case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
#endif /* FEATURE_EXT_texture_sRGB */
return GL_TRUE;
+ /* signed texture formats */
+ case GL_RGBA_SNORM:
+ case GL_RGBA8_SNORM:
+ return GL_TRUE;
case GL_YCBCR_MESA: /* not considered to be RGB */
/* fall-through */
default:
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index cc3c6958c7..785fb50622 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -417,7 +417,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
(GLfloat (*)[4]) src,
logicalBaseFormat, GL_FLOAT,
dst, &ctx->DefaultPacking,
- postConvTransferOps);
+ postConvTransferOps, GL_FALSE);
src += convWidth * 4;
dst += convWidth * logComponents;
}
@@ -798,6 +798,7 @@ static const GLubyte *
type_mapping( GLenum srcType )
{
switch (srcType) {
+ case GL_BYTE:
case GL_UNSIGNED_BYTE:
return map_identity;
case GL_UNSIGNED_INT_8_8_8_8:
@@ -819,6 +820,7 @@ byteswap_mapping( GLboolean swapBytes,
return map_identity;
switch (srcType) {
+ case GL_BYTE:
case GL_UNSIGNED_BYTE:
return map_identity;
case GL_UNSIGNED_INT_8_8_8_8:
@@ -2561,6 +2563,99 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
return GL_TRUE;
}
+/**
+ * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
+ */
+GLboolean
+_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
+{
+ const GLboolean littleEndian = _mesa_little_endian();
+
+ ASSERT(dstFormat == &_mesa_texformat_signed_rgba8888);
+ ASSERT(dstFormat->TexelBytes == 4);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_signed_rgba8888 &&
+ baseInternalFormat == GL_RGBA &&
+ ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride,
+ dstImageOffsets,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ (srcType == GL_BYTE) &&
+ can_swizzle(baseInternalFormat) &&
+ can_swizzle(srcFormat)) {
+
+ GLubyte dstmap[4];
+
+ /* dstmap - how to swizzle from RGBA to dst format:
+ */
+ if (littleEndian && dstFormat == &_mesa_texformat_signed_rgba8888) {
+ dstmap[3] = 0;
+ dstmap[2] = 1;
+ dstmap[1] = 2;
+ dstmap[0] = 3;
+ }
+ else {
+ dstmap[3] = 3;
+ dstmap[2] = 2;
+ dstmap[1] = 1;
+ dstmap[0] = 0;
+ }
+
+ _mesa_swizzle_ubyte_image(ctx, dims,
+ srcFormat,
+ srcType,
+ baseInternalFormat,
+ dstmap, 4,
+ dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageOffsets,
+ srcWidth, srcHeight, srcDepth, srcAddr,
+ srcPacking);
+ }
+ else {
+ /* general path */
+ const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLfloat *srcRow = 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++) {
+ GLuint *dstUI = (GLuint *) dstRow;
+ if (dstFormat == &_mesa_texformat_signed_rgba8888) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
+ FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
+ FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
+ FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
+ srcRow += 4;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
/**
* Store a combined depth/stencil texture image.
@@ -3820,6 +3915,21 @@ linear_to_nonlinear(GLfloat cl)
#endif /* FEATURE_EXT_texture_sRGB */
+static INLINE GLboolean
+type_with_negative_values(GLenum type)
+{
+ switch (type) {
+ case GL_BYTE:
+ case GL_SHORT:
+ case GL_INT:
+ case GL_FLOAT:
+ case GL_HALF_FLOAT_ARB:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
/**
* This is the software fallback for Driver.GetTexImage().
* All error checking will have been done before this routine is called.
@@ -3962,7 +4072,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, transferOps /*image xfer ops*/);
+ &ctx->Pack, transferOps, GL_TRUE);
}
#endif /* FEATURE_EXT_texture_sRGB */
else {
@@ -3971,10 +4081,13 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
GLint col;
GLbitfield transferOps = 0x0;
- if (type == GL_FLOAT && texImage->TexFormat->BaseFormat != GL_DUDV_ATI &&
- ((ctx->Color.ClampReadColor == GL_TRUE) ||
- (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
- texImage->TexFormat->DataType != GL_FLOAT)))
+ /* clamp does not apply to GetTexImage (final conversion)?
+ Looks like we need clamp though when going from format containing
+ negative values to unsigned format */
+
+ if (!type_with_negative_values(type) &&
+ (texImage->TexFormat->DataType == GL_FLOAT ||
+ texImage->TexFormat->DataType == GL_SIGNED_NORMALIZED))
transferOps |= IMAGE_CLAMP_BIT;
for (col = 0; col < width; col++) {
@@ -4001,7 +4114,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, transferOps /*image xfer ops*/);
+ &ctx->Pack, transferOps, GL_TRUE);
} /* format */
} /* row */
} /* img */
diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h
index c9e639be4e..91cb64f377 100644
--- a/src/mesa/main/texstore.h
+++ b/src/mesa/main/texstore.h
@@ -79,6 +79,7 @@ extern GLboolean _mesa_texstore_sl8(TEXSTORE_PARAMS);
extern GLboolean _mesa_texstore_sla8(TEXSTORE_PARAMS);
#endif
extern GLboolean _mesa_texstore_dudv8(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS);
extern GLchan *
_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,