* However, most device drivers will be able to use the fallback functions
* in this file. That is, most drivers will have the following bit of
* code:
- * ctx->Driver.TexImage1D = _mesa_store_teximage1d;
- * ctx->Driver.TexImage2D = _mesa_store_teximage2d;
- * ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ * ctx->Driver.TexImage = _mesa_store_teximage;
+ * ctx->Driver.TexSubImage = _mesa_store_texsubimage;
* etc...
*
* Texture image processing is actually kind of complicated. We have to do:
#include "teximage.h"
#include "texstore.h"
#include "enums.h"
+#include "glformats.h"
#include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
textureBaseFormat == GL_INTENSITY ||
textureBaseFormat == GL_DEPTH_COMPONENT);
- tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
+ tempImage = malloc(srcWidth * srcHeight * srcDepth
* components * sizeof(GLfloat));
if (!tempImage)
return NULL;
*/
ASSERT(texComponents >= logComponents);
- newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
+ newImage = malloc(srcWidth * srcHeight * srcDepth
* texComponents * sizeof(GLfloat));
if (!newImage) {
free(tempImage);
textureBaseFormat == GL_INTENSITY ||
textureBaseFormat == GL_ALPHA);
- tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
+ tempImage = malloc(srcWidth * srcHeight * srcDepth
* components * sizeof(GLuint));
if (!tempImage)
return NULL;
*/
ASSERT(texComponents >= logComponents);
- newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
+ newImage = malloc(srcWidth * srcHeight * srcDepth
* texComponents * sizeof(GLuint));
if (!newImage) {
free(tempImage);
textureBaseFormat == GL_INTENSITY);
/* unpack and transfer the source image */
- tempImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
+ tempImage = malloc(srcWidth * srcHeight * srcDepth
* components * sizeof(GLubyte));
if (!tempImage) {
return NULL;
*/
ASSERT(texComponents >= logComponents);
- newImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
+ newImage = malloc(srcWidth * srcHeight * srcDepth
* texComponents * sizeof(GLubyte));
if (!newImage) {
free(tempImage);
}
+/**
+ * General-case function for storing a color texture images with
+ * components that can be represented with ubytes. Example destination
+ * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
+ */
+static GLboolean
+store_ubyte_texture(TEXSTORE_PARAMS)
+{
+ const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
+ GLubyte *tempImage, *src;
+ GLint img;
+
+ tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
+ baseInternalFormat,
+ GL_RGBA,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ if (!tempImage)
+ return GL_FALSE;
+
+ src = tempImage;
+ for (img = 0; img < srcDepth; img++) {
+ _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
+ src, srcRowStride,
+ dstSlices[img], dstRowStride);
+ src += srcHeight * srcRowStride;
+ }
+ free(tempImage);
+
+ return GL_TRUE;
+}
+
+
+
/**
* Store a 32-bit integer or float depth component texture image.
}
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
srcPacking);
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
}
}
}
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == MESA_FORMAT_ARGB8888 &&
+ srcFormat == GL_LUMINANCE_ALPHA &&
+ baseInternalFormat == GL_RGBA &&
+ srcType == GL_UNSIGNED_BYTE) {
+ /* special case of storing LA -> ARGB8888 */
+ int img, row, col;
+ const GLint srcRowStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+ for (img = 0; img < srcDepth; img++) {
+ const GLubyte *srcRow = (const GLubyte *)
+ _mesa_image_address(dims, srcPacking, srcAddr, srcWidth,
+ srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstSlices[img];
+ for (row = 0; row < srcHeight; row++) {
+ GLuint *d4 = (GLuint *) dstRow;
+ for (col = 0; col < srcWidth; col++) {
+ GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1];
+ d4[col] = PACK_COLOR_8888(a, l, l, l);
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ }
+ }
else if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
dstFormat == MESA_FORMAT_ARGB8888 &&
srcPacking);
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
srcPacking);
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = (const GLubyte *) tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
srcPacking);
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = (const GLubyte *) tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
srcAddr, srcPacking);
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
srcAddr, srcPacking);
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src =tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
srcAddr, srcPacking);
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src =tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
srcAddr, srcPacking);
}
else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLint img;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free((void *) tempImage);
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
return GL_TRUE;
}
GLbyte *tempImage, *dst, *src;
GLint row;
- tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth
+ tempImage = malloc(srcWidth * srcHeight * srcDepth
* components * sizeof(GLbyte));
if (!tempImage)
return GL_FALSE;
}
else if (srcFormat == GL_DEPTH_COMPONENT ||
srcFormat == GL_STENCIL_INDEX) {
+ GLuint *depth = malloc(srcWidth * sizeof(GLuint));
+ GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
+
+ if (!depth || !stencil) {
+ free(depth);
+ free(stencil);
+ return GL_FALSE;
+ }
+
/* In case we only upload depth we need to preserve the stencil */
for (img = 0; img < srcDepth; img++) {
GLuint *dstRow = (GLuint *) dstSlices[img];
srcFormat, srcType,
img, 0, 0);
for (row = 0; row < srcHeight; row++) {
- GLuint depth[MAX_WIDTH];
- GLubyte stencil[MAX_WIDTH];
GLint i;
GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
dstRow += dstRowStride / sizeof(GLuint);
}
}
+
+ free(depth);
+ free(stencil);
}
return GL_TRUE;
}
const GLint srcRowStride
= _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLint img, row;
+ GLuint *depth;
+ GLubyte *stencil;
ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
srcType == GL_UNSIGNED_INT_24_8_EXT);
+ depth = malloc(srcWidth * sizeof(GLuint));
+ stencil = malloc(srcWidth * sizeof(GLubyte));
+
+ if (!depth || !stencil) {
+ free(depth);
+ free(stencil);
+ return GL_FALSE;
+ }
+
for (img = 0; img < srcDepth; img++) {
GLuint *dstRow = (GLuint *) dstSlices[img];
const GLubyte *src
srcFormat, srcType,
img, 0, 0);
for (row = 0; row < srcHeight; row++) {
- GLuint depth[MAX_WIDTH];
- GLubyte stencil[MAX_WIDTH];
GLint i;
GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
dstRow += dstRowStride / sizeof(GLuint);
}
}
+
+ free(depth);
+ free(stencil);
+
return GL_TRUE;
}
const GLint srcRowStride
= _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLint img, row;
-
+ GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
+
+ if (!stencil)
+ return GL_FALSE;
+
for (img = 0; img < srcDepth; img++) {
GLubyte *dstRow = dstSlices[img];
const GLubyte *src
srcFormat, srcType,
img, 0, 0);
for (row = 0; row < srcHeight; row++) {
- GLubyte stencil[MAX_WIDTH];
GLint i;
/* get the 8-bit stencil values */
}
}
+ free(stencil);
}
return GL_TRUE;
srcPacking);
const GLuint *src = tempImage;
GLint img, row;
+ GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
if (!tempImage)
return GL_FALSE;
for (img = 0; img < srcDepth; img++) {
for (row = 0; row < srcHeight; row++) {
GLbyte *dstTexel = (GLbyte *) dstRow;
GLint i;
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = (GLbyte) src[i];
+ if (is_unsigned) {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f);
+ }
+ } else {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f);
+ }
}
dstRow += dstRowStride;
src += srcWidth * components;
srcPacking);
const GLuint *src = tempImage;
GLint img, row;
+ GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
if (!tempImage)
return GL_FALSE;
for (img = 0; img < srcDepth; img++) {
for (row = 0; row < srcHeight; row++) {
GLshort *dstTexel = (GLshort *) dstRow;
GLint i;
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = (GLint) src[i];
+ if (is_unsigned) {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff);
+ }
+ } else {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff);
+ }
}
dstRow += dstRowStride;
src += srcWidth * components;
srcPacking);
const GLuint *src = tempImage;
GLint img, row;
+ GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
if (!tempImage)
return GL_FALSE;
for (img = 0; img < srcDepth; img++) {
for (row = 0; row < srcHeight; row++) {
GLint *dstTexel = (GLint *) dstRow;
GLint i;
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = (GLint) src[i];
+ if (is_unsigned) {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff);
+ }
+ } else {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLint) src[i];
+ }
}
dstRow += dstRowStride;
src += srcWidth * components;
srcFormat, srcType, srcAddr, srcPacking);
const GLuint *src = tempImage;
GLint img, row;
+ GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
if (!tempImage)
return GL_FALSE;
for (img = 0; img < srcDepth; img++) {
for (row = 0; row < srcHeight; row++) {
GLubyte *dstTexel = (GLubyte *) dstRow;
GLint i;
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff);
+ if (is_unsigned) {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLubyte) MIN2(src[i], 0xff);
+ }
+ } else {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff);
+ }
}
dstRow += dstRowStride;
src += srcWidth * components;
srcFormat, srcType, srcAddr, srcPacking);
const GLuint *src = tempImage;
GLint img, row;
+ GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
if (!tempImage)
return GL_FALSE;
for (img = 0; img < srcDepth; img++) {
for (row = 0; row < srcHeight; row++) {
GLushort *dstTexel = (GLushort *) dstRow;
GLint i;
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff);
+ if (is_unsigned) {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLushort) MIN2(src[i], 0xffff);
+ }
+ } else {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff);
+ }
}
dstRow += dstRowStride;
src += srcWidth * components;
srcWidth, srcHeight, srcDepth,
srcFormat, srcType, srcAddr, srcPacking);
const GLuint *src = tempImage;
+ GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
GLint img, row;
if (!tempImage)
return GL_FALSE;
for (row = 0; row < srcHeight; row++) {
GLuint *dstTexel = (GLuint *) dstRow;
GLint i;
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = src[i];
+ if (is_unsigned) {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = src[i];
+ }
+ } else {
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = MAX2((GLint) src[i], 0);
+ }
}
dstRow += dstRowStride;
src += srcWidth * components;
}
-
-
-#if FEATURE_EXT_texture_sRGB
static GLboolean
_mesa_texstore_srgb8(TEXSTORE_PARAMS)
{
return k;
}
-#else
-
-/* these are used only in texstore_funcs[] below */
-#define _mesa_texstore_srgb8 NULL
-#define _mesa_texstore_srgba8 NULL
-#define _mesa_texstore_sargb8 NULL
-#define _mesa_texstore_sl8 NULL
-#define _mesa_texstore_sla8 NULL
-
-#endif /* FEATURE_EXT_texture_sRGB */
-
static GLboolean
_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
{
srcPacking);
const GLuint *src = tempImage;
GLint img, row, col;
+ GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
if (!tempImage)
return GL_FALSE;
for (img = 0; img < srcDepth; img++) {
for (row = 0; row < srcHeight; row++) {
GLuint *dstUI = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort a,r,g,b;
- r = src[RCOMP];
- g = src[GCOMP];
- b = src[BCOMP];
- a = src[ACOMP];
- dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
- src += 4;
+ if (is_unsigned) {
+ for (col = 0; col < srcWidth; col++) {
+ GLushort a,r,g,b;
+ r = MIN2(src[RCOMP], 0x3ff);
+ g = MIN2(src[GCOMP], 0x3ff);
+ b = MIN2(src[BCOMP], 0x3ff);
+ a = MIN2(src[ACOMP], 0x003);
+ dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
+ src += 4;
+ }
+ } else {
+ for (col = 0; col < srcWidth; col++) {
+ GLushort a,r,g,b;
+ r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
+ g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
+ b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
+ a = CLAMP((GLint) src[ACOMP], 0, 0x003);
+ dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
+ src += 4;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ }
+ free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+static GLboolean
+_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
+{
+ const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+ ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT);
+ ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
+
+ if (baseInternalFormat == GL_RGBA &&
+ _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
+ srcPacking->SwapBytes)) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLuint *tempImage = make_temp_uint_image(ctx, dims,
+ baseInternalFormat,
+ baseFormat,
+ srcWidth, srcHeight,
+ srcDepth, srcFormat,
+ srcType, srcAddr,
+ srcPacking);
+ const GLuint *src = tempImage;
+ GLint img, row, col;
+ GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
+ if (!tempImage)
+ return GL_FALSE;
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstSlices[img];
+
+ for (row = 0; row < srcHeight; row++) {
+ GLuint *dstUI = (GLuint *) dstRow;
+ if (is_unsigned) {
+ for (col = 0; col < srcWidth; col++) {
+ GLushort a,r,g,b;
+ r = MIN2(src[RCOMP], 0x3ff);
+ g = MIN2(src[GCOMP], 0x3ff);
+ b = MIN2(src[BCOMP], 0x3ff);
+ a = MIN2(src[ACOMP], 0x003);
+ dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
+ src += 4;
+ }
+ } else {
+ for (col = 0; col < srcWidth; col++) {
+ GLushort a,r,g,b;
+ r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
+ g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
+ b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
+ a = CLAMP((GLint) src[ACOMP], 0, 0x003);
+ dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
+ src += 4;
+ }
}
dstRow += dstRowStride;
}
table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
+ table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint;
initialized = GL_TRUE;
}
/**
- * This is the fallback for Driver.TexImage1D().
+ * Fallback code for ctx->Driver.TexImage().
+ * Basically, allocate storage for the texture image, then copy the
+ * user's image into it.
*/
void
-_mesa_store_teximage1d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint internalFormat,
- GLint width, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing)
+_mesa_store_teximage(struct gl_context *ctx,
+ GLuint dims,
+ struct gl_texture_image *texImage,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing)
{
- if (width == 0)
- return;
+ assert(dims == 1 || dims == 2 || dims == 3);
- /* allocate storage for texture data */
- if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
- width, 1, 1)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
- return;
- }
-
- store_texsubimage(ctx, texImage,
- 0, 0, 0, width, 1, 1,
- format, type, pixels, packing, "glTexImage1D");
-}
-
-
-/**
- * This is the fallback for Driver.TexImage2D().
- */
-void
-_mesa_store_teximage2d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing)
-{
- if (width == 0 || height == 0)
- return;
-
- /* allocate storage for texture data */
- if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
- width, height, 1)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
- return;
- }
-
- store_texsubimage(ctx, texImage,
- 0, 0, 0, width, height, 1,
- format, type, pixels, packing, "glTexImage2D");
-}
-
-
-
-/**
- * This is the fallback for Driver.TexImage3D().
- */
-void
-_mesa_store_teximage3d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint internalFormat,
- GLint width, GLint height, GLint depth, GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing)
-{
- if (width == 0 || height == 0 || depth == 0)
+ if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
return;
/* allocate storage for texture data */
- if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
- width, height, depth)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+ if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
return;
}
store_texsubimage(ctx, texImage,
- 0, 0, 0, width, height, depth,
- format, type, pixels, packing, "glTexImage3D");
-}
-
-
-
-
-/*
- * This is the fallback for Driver.TexSubImage1D().
- */
-void
-_mesa_store_texsubimage1d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint xoffset, GLint width,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing)
-{
- store_texsubimage(ctx, texImage,
- xoffset, 0, 0, width, 1, 1,
- format, type, pixels, packing, "glTexSubImage1D");
-}
-
-
-
-/**
- * This is the fallback for Driver.TexSubImage2D().
- */
-void
-_mesa_store_texsubimage2d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint xoffset, GLint yoffset,
- GLint width, GLint height,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing)
-{
- store_texsubimage(ctx, texImage,
- xoffset, yoffset, 0, width, height, 1,
- format, type, pixels, packing, "glTexSubImage2D");
+ 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
+ format, type, pixels, packing, "glTexImage");
}
/*
- * This is the fallback for Driver.TexSubImage3D().
+ * Fallback for Driver.TexSubImage().
*/
void
-_mesa_store_texsubimage3d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint width, GLint height, GLint depth,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing)
+_mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_image *texImage,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing)
{
store_texsubimage(ctx, texImage,
xoffset, yoffset, zoffset, width, height, depth,
- format, type, pixels, packing, "glTexSubImage3D");
+ format, type, pixels, packing, "glTexSubImage");
}
-/*
- * Fallback for Driver.CompressedTexImage1D()
- */
-void
-_mesa_store_compressed_teximage1d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint internalFormat,
- GLint width, GLint border,
- GLsizei imageSize, const GLvoid *data)
-{
- /* no compressed 1D image formats at this time */
- (void) ctx;
- (void) internalFormat;
- (void) width; (void) border;
- (void) imageSize; (void) data;
- (void) texImage;
-}
-
-
-
/**
- * Fallback for Driver.CompressedTexImage2D()
+ * Fallback for Driver.CompressedTexImage()
*/
void
-_mesa_store_compressed_teximage2d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLsizei imageSize, const GLvoid *data)
+_mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_image *texImage,
+ GLsizei imageSize, const GLvoid *data)
{
+ /* only 2D compressed images are supported at this time */
+ if (dims != 2) {
+ _mesa_problem(ctx, "Unexpected glCompressedTexImage1D/3D call");
+ return;
+ }
+
/* This is pretty simple, because unlike the general texstore path we don't
* have to worry about the usual image unpacking or image transfer
* operations.
ASSERT(texImage->Depth == 1);
/* allocate storage for texture data */
- if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
- width, height, 1)) {
+ if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
return;
}
- _mesa_store_compressed_texsubimage2d(ctx, texImage,
- 0, 0,
- width, height,
- texImage->TexFormat,
- imageSize, data);
-}
-
-
-
-/*
- * Fallback for Driver.CompressedTexImage3D()
- */
-void
-_mesa_store_compressed_teximage3d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint internalFormat,
- GLint width, GLint height, GLint depth,
- GLint border,
- GLsizei imageSize, const GLvoid *data)
-{
- /* this space intentionally left blank */
- (void) ctx;
- (void) internalFormat;
- (void) width; (void) height; (void) depth;
- (void) border;
- (void) imageSize; (void) data;
- (void) texImage;
-}
-
-
-
-/**
- * Fallback for Driver.CompressedTexSubImage1D()
- */
-void
-_mesa_store_compressed_texsubimage1d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint xoffset, GLsizei width,
- GLenum format,
- GLsizei imageSize, const GLvoid *data)
-{
- /* there are no compressed 1D texture formats yet */
- (void) ctx;
- (void) xoffset; (void) width;
- (void) format;
- (void) imageSize; (void) data;
- (void) texImage;
+ _mesa_store_compressed_texsubimage(ctx, dims, texImage,
+ 0, 0, 0,
+ texImage->Width, texImage->Height, texImage->Depth,
+ texImage->TexFormat,
+ imageSize, data);
}
/**
- * Fallback for Driver.CompressedTexSubImage2D()
+ * Fallback for Driver.CompressedTexSubImage()
*/
void
-_mesa_store_compressed_texsubimage2d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format,
- GLsizei imageSize, const GLvoid *data)
+_mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_image *texImage,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data)
{
GLint bytesPerRow, dstRowStride, srcRowStride;
GLint i, rows;
const gl_format texFormat = texImage->TexFormat;
GLuint bw, bh;
+ if (dims != 2) {
+ _mesa_problem(ctx, "Unexpected 1D/3D compressed texsubimage call");
+ return;
+ }
+
_mesa_get_format_block_size(texFormat, &bw, &bh);
/* these should have been caught sooner */
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
}
-
-
-/**
- * Fallback for Driver.CompressedTexSubImage3D()
- */
-void
-_mesa_store_compressed_texsubimage3d(struct gl_context *ctx,
- struct gl_texture_image *texImage,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format,
- GLsizei imageSize, const GLvoid *data)
-{
- /* there are no compressed 3D texture formats yet */
- (void) ctx;
- (void) xoffset; (void) yoffset; (void) zoffset;
- (void) width; (void) height; (void) depth;
- (void) format;
- (void) imageSize; (void) data;
- (void) texImage;
-}