#include "glheader.h"
#include "bufferobj.h"
-#include "colormac.h"
#include "format_pack.h"
+#include "format_utils.h"
#include "image.h"
#include "macros.h"
#include "mipmap.h"
#include "texcompress_rgtc.h"
#include "texcompress_s3tc.h"
#include "texcompress_etc.h"
+#include "texcompress_bptc.h"
#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"
+#include "pixeltransfer.h"
+#include "util/format_rgb9e5.h"
+#include "util/format_r11g11b10f.h"
enum {
/**
- * Return GL_TRUE if the given image format is one that be converted
- * to another format by swizzling.
- */
-static GLboolean
-can_swizzle(GLenum logicalBaseFormat)
-{
- switch (logicalBaseFormat) {
- case GL_RGBA:
- case GL_RGB:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_BGR:
- case GL_BGRA:
- case GL_ABGR_EXT:
- case GL_RG:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-
-enum {
- IDX_LUMINANCE = 0,
- IDX_ALPHA,
- IDX_INTENSITY,
- IDX_LUMINANCE_ALPHA,
- IDX_RGB,
- IDX_RGBA,
- IDX_RED,
- IDX_GREEN,
- IDX_BLUE,
- IDX_BGR,
- IDX_BGRA,
- IDX_ABGR,
- IDX_RG,
- MAX_IDX
-};
-
-#define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
-#define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
-#define MAP3(x,y,z) MAP4(x, y, z, ZERO)
-#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
-
-
-static const struct {
- GLubyte format_idx;
- GLubyte to_rgba[6];
- GLubyte from_rgba[6];
-} mappings[MAX_IDX] =
-{
- {
- IDX_LUMINANCE,
- MAP4(0,0,0,ONE),
- MAP1(0)
- },
-
- {
- IDX_ALPHA,
- MAP4(ZERO, ZERO, ZERO, 0),
- MAP1(3)
- },
-
- {
- IDX_INTENSITY,
- MAP4(0, 0, 0, 0),
- MAP1(0),
- },
-
- {
- IDX_LUMINANCE_ALPHA,
- MAP4(0,0,0,1),
- MAP2(0,3)
- },
-
- {
- IDX_RGB,
- MAP4(0,1,2,ONE),
- MAP3(0,1,2)
- },
-
- {
- IDX_RGBA,
- MAP4(0,1,2,3),
- MAP4(0,1,2,3),
- },
-
- {
- IDX_RED,
- MAP4(0, ZERO, ZERO, ONE),
- MAP1(0),
- },
-
- {
- IDX_GREEN,
- MAP4(ZERO, 0, ZERO, ONE),
- MAP1(1),
- },
-
- {
- IDX_BLUE,
- MAP4(ZERO, ZERO, 0, ONE),
- MAP1(2),
- },
-
- {
- IDX_BGR,
- MAP4(2,1,0,ONE),
- MAP3(2,1,0)
- },
-
- {
- IDX_BGRA,
- MAP4(2,1,0,3),
- MAP4(2,1,0,3)
- },
-
- {
- IDX_ABGR,
- MAP4(3,2,1,0),
- MAP4(3,2,1,0)
- },
-
- {
- IDX_RG,
- MAP4(0, 1, ZERO, ONE),
- MAP2(0, 1)
- },
-};
-
-
-
-/**
- * Convert a GL image format enum to an IDX_* value (see above).
- */
-static int
-get_map_idx(GLenum value)
-{
- switch (value) {
- case GL_LUMINANCE: return IDX_LUMINANCE;
- case GL_ALPHA: return IDX_ALPHA;
- case GL_INTENSITY: return IDX_INTENSITY;
- case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
- case GL_RGB: return IDX_RGB;
- case GL_RGBA: return IDX_RGBA;
- case GL_RED: return IDX_RED;
- case GL_GREEN: return IDX_GREEN;
- case GL_BLUE: return IDX_BLUE;
- case GL_BGR: return IDX_BGR;
- case GL_BGRA: return IDX_BGRA;
- case GL_ABGR_EXT: return IDX_ABGR;
- case GL_RG: return IDX_RG;
- default:
- _mesa_problem(NULL, "Unexpected inFormat");
- return 0;
- }
-}
-
-
-/**
- * When promoting texture formats (see below) we need to compute the
- * mapping of dest components back to source components.
- * This function does that.
- * \param inFormat the incoming format of the texture
- * \param outFormat the final texture format
- * \return map[6] a full 6-component map
- */
-static void
-compute_component_mapping(GLenum inFormat, GLenum outFormat,
- GLubyte *map)
-{
- const int inFmt = get_map_idx(inFormat);
- const int outFmt = get_map_idx(outFormat);
- const GLubyte *in2rgba = mappings[inFmt].to_rgba;
- const GLubyte *rgba2out = mappings[outFmt].from_rgba;
- int i;
-
- for (i = 0; i < 4; i++)
- map[i] = in2rgba[rgba2out[i]];
-
- map[ZERO] = ZERO;
- map[ONE] = ONE;
-
-#if 0
- printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
- inFormat, _mesa_lookup_enum_by_nr(inFormat),
- outFormat, _mesa_lookup_enum_by_nr(outFormat),
- map[0],
- map[1],
- map[2],
- map[3],
- map[4],
- map[5]);
-#endif
-}
-
-
-/**
- * Make a temporary (color) texture image with GLfloat components.
- * Apply all needed pixel unpacking and pixel transfer operations.
- * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
- * Suppose the user specifies GL_LUMINANCE as the internal texture format
- * but the graphics hardware doesn't support luminance textures. So, we might
- * use an RGB hardware format instead.
- * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
- *
- * \param ctx the rendering context
- * \param dims image dimensions: 1, 2 or 3
- * \param logicalBaseFormat basic texture derived from the user's
- * internal texture format value
- * \param textureBaseFormat the actual basic format of the texture
- * \param srcWidth source image width
- * \param srcHeight source image height
- * \param srcDepth source image depth
- * \param srcFormat source image format
- * \param srcType source image type
- * \param srcAddr source image address
- * \param srcPacking source image pixel packing
- * \return resulting image with format = textureBaseFormat and type = GLfloat.
- */
-GLfloat *
-_mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
- GLenum logicalBaseFormat,
- GLenum textureBaseFormat,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking,
- GLbitfield transferOps)
-{
- GLfloat *tempImage;
- const GLint components = _mesa_components_in_format(logicalBaseFormat);
- const GLint srcStride =
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- GLfloat *dst;
- GLint img, row;
-
- ASSERT(dims >= 1 && dims <= 3);
-
- ASSERT(logicalBaseFormat == GL_RGBA ||
- logicalBaseFormat == GL_RGB ||
- logicalBaseFormat == GL_RG ||
- logicalBaseFormat == GL_RED ||
- logicalBaseFormat == GL_LUMINANCE_ALPHA ||
- logicalBaseFormat == GL_LUMINANCE ||
- logicalBaseFormat == GL_ALPHA ||
- logicalBaseFormat == GL_INTENSITY ||
- logicalBaseFormat == GL_DEPTH_COMPONENT);
-
- ASSERT(textureBaseFormat == GL_RGBA ||
- textureBaseFormat == GL_RGB ||
- textureBaseFormat == GL_RG ||
- textureBaseFormat == GL_RED ||
- textureBaseFormat == GL_LUMINANCE_ALPHA ||
- textureBaseFormat == GL_LUMINANCE ||
- textureBaseFormat == GL_ALPHA ||
- textureBaseFormat == GL_INTENSITY ||
- textureBaseFormat == GL_DEPTH_COMPONENT);
-
- tempImage = malloc(srcWidth * srcHeight * srcDepth
- * components * sizeof(GLfloat));
- if (!tempImage)
- return NULL;
-
- dst = tempImage;
- for (img = 0; img < srcDepth; img++) {
- const GLubyte *src
- = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- img, 0, 0);
- for (row = 0; row < srcHeight; row++) {
- _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
- dst, srcFormat, srcType, src,
- srcPacking, transferOps);
- dst += srcWidth * components;
- src += srcStride;
- }
- }
-
- if (logicalBaseFormat != textureBaseFormat) {
- /* more work */
- GLint texComponents = _mesa_components_in_format(textureBaseFormat);
- GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
- GLfloat *newImage;
- GLint i, n;
- GLubyte map[6];
-
- /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
- ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
- textureBaseFormat == GL_LUMINANCE_ALPHA);
-
- /* The actual texture format should have at least as many components
- * as the logical texture format.
- */
- ASSERT(texComponents >= logComponents);
-
- newImage = malloc(srcWidth * srcHeight * srcDepth
- * texComponents * sizeof(GLfloat));
- if (!newImage) {
- free(tempImage);
- return NULL;
- }
-
- compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
-
- n = srcWidth * srcHeight * srcDepth;
- for (i = 0; i < n; i++) {
- GLint k;
- for (k = 0; k < texComponents; k++) {
- GLint j = map[k];
- if (j == ZERO)
- newImage[i * texComponents + k] = 0.0F;
- else if (j == ONE)
- newImage[i * texComponents + k] = 1.0F;
- else
- newImage[i * texComponents + k] = tempImage[i * logComponents + j];
- }
- }
-
- free(tempImage);
- tempImage = newImage;
- }
-
- return tempImage;
-}
-
-
-/**
- * Make temporary image with uint pixel values. Used for unsigned
- * integer-valued textures.
+ * Teximage storage routine for when a simple memcpy will do.
+ * No pixel transfer operations or special texel encodings allowed.
+ * 1D, 2D and 3D images supported.
*/
-static GLuint *
-make_temp_uint_image(struct gl_context *ctx, GLuint dims,
- GLenum logicalBaseFormat,
- GLenum textureBaseFormat,
+void
+_mesa_memcpy_texture(struct gl_context *ctx,
+ GLuint dimensions,
+ mesa_format dstFormat,
+ GLint dstRowStride,
+ GLubyte **dstSlices,
GLint srcWidth, GLint srcHeight, GLint srcDepth,
GLenum srcFormat, GLenum srcType,
const GLvoid *srcAddr,
const struct gl_pixelstore_attrib *srcPacking)
-{
- GLuint *tempImage;
- const GLint components = _mesa_components_in_format(logicalBaseFormat);
- const GLint srcStride =
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- GLuint *dst;
- GLint img, row;
-
- ASSERT(dims >= 1 && dims <= 3);
-
- ASSERT(logicalBaseFormat == GL_RGBA ||
- logicalBaseFormat == GL_RGB ||
- logicalBaseFormat == GL_RG ||
- logicalBaseFormat == GL_RED ||
- logicalBaseFormat == GL_LUMINANCE_ALPHA ||
- logicalBaseFormat == GL_LUMINANCE ||
- logicalBaseFormat == GL_INTENSITY ||
- logicalBaseFormat == GL_ALPHA);
-
- ASSERT(textureBaseFormat == GL_RGBA ||
- textureBaseFormat == GL_RGB ||
- textureBaseFormat == GL_RG ||
- textureBaseFormat == GL_RED ||
- textureBaseFormat == GL_LUMINANCE_ALPHA ||
- textureBaseFormat == GL_LUMINANCE ||
- textureBaseFormat == GL_INTENSITY ||
- textureBaseFormat == GL_ALPHA);
-
- tempImage = malloc(srcWidth * srcHeight * srcDepth
- * components * sizeof(GLuint));
- if (!tempImage)
- return NULL;
-
- dst = tempImage;
- for (img = 0; img < srcDepth; img++) {
- const GLubyte *src
- = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- img, 0, 0);
- for (row = 0; row < srcHeight; row++) {
- _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
- dst, srcFormat, srcType, src,
- srcPacking);
- dst += srcWidth * components;
- src += srcStride;
- }
- }
-
- if (logicalBaseFormat != textureBaseFormat) {
- /* more work */
- GLint texComponents = _mesa_components_in_format(textureBaseFormat);
- GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
- GLuint *newImage;
- GLint i, n;
- GLubyte map[6];
-
- /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
- ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
- textureBaseFormat == GL_LUMINANCE_ALPHA);
-
- /* The actual texture format should have at least as many components
- * as the logical texture format.
- */
- ASSERT(texComponents >= logComponents);
-
- newImage = malloc(srcWidth * srcHeight * srcDepth
- * texComponents * sizeof(GLuint));
- if (!newImage) {
- free(tempImage);
- return NULL;
- }
-
- compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
-
- n = srcWidth * srcHeight * srcDepth;
- for (i = 0; i < n; i++) {
- GLint k;
- for (k = 0; k < texComponents; k++) {
- GLint j = map[k];
- if (j == ZERO)
- newImage[i * texComponents + k] = 0;
- else if (j == ONE)
- newImage[i * texComponents + k] = 1;
- else
- newImage[i * texComponents + k] = tempImage[i * logComponents + j];
- }
- }
-
- free(tempImage);
- tempImage = newImage;
- }
-
- return tempImage;
-}
-
-
-
-/**
- * Make a temporary (color) texture image with GLubyte components.
- * Apply all needed pixel unpacking and pixel transfer operations.
- * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
- * Suppose the user specifies GL_LUMINANCE as the internal texture format
- * but the graphics hardware doesn't support luminance textures. So, we might
- * use an RGB hardware format instead.
- * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
- *
- * \param ctx the rendering context
- * \param dims image dimensions: 1, 2 or 3
- * \param logicalBaseFormat basic texture derived from the user's
- * internal texture format value
- * \param textureBaseFormat the actual basic format of the texture
- * \param srcWidth source image width
- * \param srcHeight source image height
- * \param srcDepth source image depth
- * \param srcFormat source image format
- * \param srcType source image type
- * \param srcAddr source image address
- * \param srcPacking source image pixel packing
- * \return resulting image with format = textureBaseFormat and type = GLubyte.
- */
-GLubyte *
-_mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
- GLenum logicalBaseFormat,
- GLenum textureBaseFormat,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
-{
- GLuint transferOps = ctx->_ImageTransferState;
- const GLint components = _mesa_components_in_format(logicalBaseFormat);
- GLint img, row;
- GLubyte *tempImage, *dst;
-
- ASSERT(dims >= 1 && dims <= 3);
-
- ASSERT(logicalBaseFormat == GL_RGBA ||
- logicalBaseFormat == GL_RGB ||
- logicalBaseFormat == GL_RG ||
- logicalBaseFormat == GL_RED ||
- logicalBaseFormat == GL_LUMINANCE_ALPHA ||
- logicalBaseFormat == GL_LUMINANCE ||
- logicalBaseFormat == GL_ALPHA ||
- logicalBaseFormat == GL_INTENSITY);
-
- ASSERT(textureBaseFormat == GL_RGBA ||
- textureBaseFormat == GL_RGB ||
- textureBaseFormat == GL_RG ||
- textureBaseFormat == GL_RED ||
- textureBaseFormat == GL_LUMINANCE_ALPHA ||
- textureBaseFormat == GL_LUMINANCE ||
- textureBaseFormat == GL_ALPHA ||
- textureBaseFormat == GL_INTENSITY);
-
- /* unpack and transfer the source image */
- tempImage = malloc(srcWidth * srcHeight * srcDepth
- * components * sizeof(GLubyte));
- if (!tempImage) {
- return NULL;
- }
-
- dst = tempImage;
- for (img = 0; img < srcDepth; img++) {
- const GLint srcStride =
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- const GLubyte *src =
- (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- img, 0, 0);
- for (row = 0; row < srcHeight; row++) {
- _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
- srcFormat, srcType, src, srcPacking,
- transferOps);
- dst += srcWidth * components;
- src += srcStride;
- }
- }
-
- if (logicalBaseFormat != textureBaseFormat) {
- /* one more conversion step */
- GLint texComponents = _mesa_components_in_format(textureBaseFormat);
- GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
- GLubyte *newImage;
- GLint i, n;
- GLubyte map[6];
-
- /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
- ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
- textureBaseFormat == GL_LUMINANCE_ALPHA);
-
- /* The actual texture format should have at least as many components
- * as the logical texture format.
- */
- ASSERT(texComponents >= logComponents);
-
- newImage = malloc(srcWidth * srcHeight * srcDepth
- * texComponents * sizeof(GLubyte));
- if (!newImage) {
- free(tempImage);
- return NULL;
- }
-
- compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
-
- n = srcWidth * srcHeight * srcDepth;
- for (i = 0; i < n; i++) {
- GLint k;
- for (k = 0; k < texComponents; k++) {
- GLint j = map[k];
- if (j == ZERO)
- newImage[i * texComponents + k] = 0;
- else if (j == ONE)
- newImage[i * texComponents + k] = 255;
- else
- newImage[i * texComponents + k] = tempImage[i * logComponents + j];
- }
- }
-
- free(tempImage);
- tempImage = newImage;
- }
-
- return tempImage;
-}
-
-
-/**
- * Copy GLubyte pixels from <src> to <dst> with swizzling.
- * \param dst destination pixels
- * \param dstComponents number of color components in destination pixels
- * \param src source pixels
- * \param srcComponents number of color components in source pixels
- * \param map the swizzle mapping. map[X] says where to find the X component
- * in the source image's pixels. For example, if the source image
- * is GL_BGRA and X = red, map[0] yields 2.
- * \param count number of pixels to copy/swizzle.
- */
-static void
-swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
- GLuint srcComponents, const GLubyte *map, GLuint count)
-{
-#define SWZ_CPY(dst, src, count, dstComps, srcComps) \
- do { \
- GLuint i; \
- for (i = 0; i < count; i++) { \
- GLuint j; \
- if (srcComps == 4) { \
- COPY_4UBV(tmp, src); \
- } \
- else { \
- for (j = 0; j < srcComps; j++) { \
- tmp[j] = src[j]; \
- } \
- } \
- src += srcComps; \
- for (j = 0; j < dstComps; j++) { \
- dst[j] = tmp[map[j]]; \
- } \
- dst += dstComps; \
- } \
- } while (0)
-
- GLubyte tmp[6];
-
- tmp[ZERO] = 0x0;
- tmp[ONE] = 0xff;
-
- ASSERT(srcComponents <= 4);
- ASSERT(dstComponents <= 4);
-
- switch (dstComponents) {
- case 4:
- switch (srcComponents) {
- case 4:
- SWZ_CPY(dst, src, count, 4, 4);
- break;
- case 3:
- SWZ_CPY(dst, src, count, 4, 3);
- break;
- case 2:
- SWZ_CPY(dst, src, count, 4, 2);
- break;
- case 1:
- SWZ_CPY(dst, src, count, 4, 1);
- break;
- default:
- ;
- }
- break;
- case 3:
- switch (srcComponents) {
- case 4:
- SWZ_CPY(dst, src, count, 3, 4);
- break;
- case 3:
- SWZ_CPY(dst, src, count, 3, 3);
- break;
- case 2:
- SWZ_CPY(dst, src, count, 3, 2);
- break;
- case 1:
- SWZ_CPY(dst, src, count, 3, 1);
- break;
- default:
- ;
- }
- break;
- case 2:
- switch (srcComponents) {
- case 4:
- SWZ_CPY(dst, src, count, 2, 4);
- break;
- case 3:
- SWZ_CPY(dst, src, count, 2, 3);
- break;
- case 2:
- SWZ_CPY(dst, src, count, 2, 2);
- break;
- case 1:
- SWZ_CPY(dst, src, count, 2, 1);
- break;
- default:
- ;
- }
- break;
- case 1:
- switch (srcComponents) {
- case 4:
- SWZ_CPY(dst, src, count, 1, 4);
- break;
- case 3:
- SWZ_CPY(dst, src, count, 1, 3);
- break;
- case 2:
- SWZ_CPY(dst, src, count, 1, 2);
- break;
- case 1:
- SWZ_CPY(dst, src, count, 1, 1);
- break;
- default:
- ;
- }
- break;
- default:
- ;
- }
-#undef SWZ_CPY
-}
-
-
-
-static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
-static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
-
-
-/**
- * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
- * mapping array depending on endianness.
- */
-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:
- return _mesa_little_endian() ? map_3210 : map_identity;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- return _mesa_little_endian() ? map_identity : map_3210;
- default:
- return NULL;
- }
-}
-
-
-/**
- * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
- * mapping array depending on pixelstore byte swapping state.
- */
-static const GLubyte *
-byteswap_mapping( GLboolean swapBytes,
- GLenum srcType )
-{
- if (!swapBytes)
- return map_identity;
-
- switch (srcType) {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- return map_identity;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- return map_3210;
- default:
- return NULL;
- }
-}
-
-
-
-/**
- * Transfer a GLubyte texture image with component swizzling.
- */
-static void
-_mesa_swizzle_ubyte_image(struct gl_context *ctx,
- GLuint dimensions,
- GLenum srcFormat,
- GLenum srcType,
-
- GLenum baseInternalFormat,
-
- const GLubyte *rgba2dst,
- GLuint dstComponents,
-
- GLint dstRowStride,
- GLubyte **dstSlices,
-
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking )
-{
- GLint srcComponents = _mesa_components_in_format(srcFormat);
- const GLubyte *srctype2ubyte, *swap;
- GLubyte map[4], src2base[6], base2rgba[6];
- GLint i;
- const GLint srcRowStride =
- _mesa_image_row_stride(srcPacking, srcWidth,
- srcFormat, GL_UNSIGNED_BYTE);
- const GLint srcImageStride
- = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
- GL_UNSIGNED_BYTE);
- const GLubyte *srcImage
- = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
- srcWidth, srcHeight, srcFormat,
- GL_UNSIGNED_BYTE, 0, 0, 0);
-
- (void) ctx;
-
- /* Translate from src->baseInternal->GL_RGBA->dst. This will
- * correctly deal with RGBA->RGB->RGBA conversions where the final
- * A value must be 0xff regardless of the incoming alpha values.
- */
- compute_component_mapping(srcFormat, baseInternalFormat, src2base);
- compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
- swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
- srctype2ubyte = type_mapping(srcType);
-
-
- for (i = 0; i < 4; i++)
- map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
-
-/* printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
-
- if (srcComponents == dstComponents &&
- srcRowStride == dstRowStride &&
- srcRowStride == srcWidth * srcComponents &&
- dimensions < 3) {
- /* 1 and 2D images only */
- GLubyte *dstImage = dstSlices[0];
- swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
- srcWidth * srcHeight);
- }
- else {
- GLint img, row;
- for (img = 0; img < srcDepth; img++) {
- const GLubyte *srcRow = srcImage;
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- srcImage += srcImageStride;
- }
- }
-}
-
-
-/**
- * Teximage storage routine for when a simple memcpy will do.
- * No pixel transfer operations or special texel encodings allowed.
- * 1D, 2D and 3D images supported.
- */
-static void
-memcpy_texture(struct gl_context *ctx,
- GLuint dimensions,
- mesa_format dstFormat,
- GLint dstRowStride,
- GLubyte **dstSlices,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
{
const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
srcFormat, srcType);
}
-/**
- * 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.
*/
const GLuint depthScale = 0xffffffff;
GLenum dstType;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z_UNORM32 ||
+ assert(dstFormat == MESA_FORMAT_Z_UNORM32 ||
dstFormat == MESA_FORMAT_Z_FLOAT32);
- ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
+ assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
if (dstFormat == MESA_FORMAT_Z_UNORM32)
dstType = GL_UNSIGNED_INT;
const GLuint depthScale = 0xffffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
+ assert(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
{
/* general path */
const GLuint depthScale = 0xffffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
+ assert(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
{
/* general path */
{
const GLuint depthScale = 0xffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z_UNORM16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
+ assert(dstFormat == MESA_FORMAT_Z_UNORM16);
+ assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
{
/* general path */
/**
- * Store an rgb565 or rgb565_rev texture image.
- */
-static GLboolean
-_mesa_texstore_rgb565(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM ||
- dstFormat == MESA_FORMAT_R5G6B5_UNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_RGB &&
- srcFormat == GL_RGB &&
- srcType == GL_UNSIGNED_BYTE &&
- dims == 2) {
- /* do optimized tex store */
- const GLint srcRowStride =
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- GLubyte *dst = dstSlices[0];
- GLint row, col;
- for (row = 0; row < srcHeight; row++) {
- const GLubyte *srcUB = (const GLubyte *) src;
- GLushort *dstUS = (GLushort *) dst;
- /* check for byteswapped format */
- if (dstFormat == MESA_FORMAT_B5G6R5_UNORM) {
- for (col = 0; col < srcWidth; col++) {
- dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
- srcUB += 3;
- }
- }
- else {
- for (col = 0; col < srcWidth; col++) {
- dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
- srcUB += 3;
- }
- }
- dst += dstRowStride;
- src += srcRowStride;
- }
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store a texture in MESA_FORMAT_A8B8G8R8_UNORM or MESA_FORMAT_R8G8B8A8_UNORM.
+ * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
*/
static GLboolean
-_mesa_texstore_rgba8888(TEXSTORE_PARAMS)
+_mesa_texstore_ycbcr(TEXSTORE_PARAMS)
{
const GLboolean littleEndian = _mesa_little_endian();
- ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_UNORM ||
- dstFormat == MESA_FORMAT_R8G8B8A8_UNORM ||
- dstFormat == MESA_FORMAT_X8B8G8R8_UNORM ||
- dstFormat == MESA_FORMAT_R8G8B8X8_UNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- (srcType == GL_UNSIGNED_BYTE ||
- srcType == GL_UNSIGNED_INT_8_8_8_8 ||
- srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
-
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if ((littleEndian && (dstFormat == MESA_FORMAT_A8B8G8R8_UNORM ||
- dstFormat == MESA_FORMAT_X8B8G8R8_UNORM)) ||
- (!littleEndian && (dstFormat == MESA_FORMAT_R8G8B8A8_UNORM ||
- dstFormat == MESA_FORMAT_R8G8B8X8_UNORM))) {
- 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,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
+ (void) ctx; (void) dims; (void) baseInternalFormat;
+ assert((dstFormat == MESA_FORMAT_YCBCR) ||
+ (dstFormat == MESA_FORMAT_YCBCR_REV));
+ assert(_mesa_get_format_bytes(dstFormat) == 2);
+ assert(ctx->Extensions.MESA_ycbcr_texture);
+ assert(srcFormat == GL_YCBCR_MESA);
+ assert((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
+ (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
+ assert(baseInternalFormat == GL_YCBCR_MESA);
-static GLboolean
-_mesa_texstore_argb8888(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
+ /* always just memcpy since no pixel transfer ops apply */
+ _mesa_memcpy_texture(ctx, dims,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
- ASSERT(dstFormat == MESA_FORMAT_B8G8R8A8_UNORM ||
- dstFormat == MESA_FORMAT_A8R8G8B8_UNORM ||
- dstFormat == MESA_FORMAT_B8G8R8X8_UNORM ||
- dstFormat == MESA_FORMAT_X8R8G8B8_UNORM );
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- (dstFormat == MESA_FORMAT_B8G8R8A8_UNORM ||
- dstFormat == MESA_FORMAT_B8G8R8X8_UNORM) &&
- srcFormat == GL_RGB &&
- (baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB) &&
- srcType == GL_UNSIGNED_BYTE) {
- int 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 = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *d4 = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- d4[col] = PACK_COLOR_8888(0xff,
- srcRow[col * 3 + RCOMP],
- srcRow[col * 3 + GCOMP],
- srcRow[col * 3 + BCOMP]);
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- }
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_B8G8R8A8_UNORM &&
- 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_B8G8R8A8_UNORM &&
- srcFormat == GL_RGBA &&
- baseInternalFormat == GL_RGBA &&
- 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
- * are extremely sensitive to the characteristics of how the
- * source data is retrieved. By reordering the source reads to
- * be in-order, the speed of this operation increases by half.
- * Strangely the same isn't required for the RGB path, above.
- */
+ /* Check if we need byte swapping */
+ /* XXX the logic here _might_ be wrong */
+ if (srcPacking->SwapBytes ^
+ (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
+ (dstFormat == MESA_FORMAT_YCBCR_REV) ^
+ !littleEndian) {
+ GLint img, row;
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 = dstSlices[img];
for (row = 0; row < srcHeight; row++) {
- GLuint *d4 = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
- srcRow[col * 4 + RCOMP],
- srcRow[col * 4 + GCOMP],
- srcRow[col * 4 + BCOMP]);
- }
+ _mesa_swap2((GLushort *) dstRow, srcWidth);
dstRow += dstRowStride;
- srcRow += srcRowStride;
}
}
}
- else if (!ctx->_ImageTransferState &&
- (srcType == GL_UNSIGNED_BYTE ||
- srcType == GL_UNSIGNED_INT_8_8_8_8 ||
- srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
-
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if ((littleEndian && dstFormat == MESA_FORMAT_B8G8R8A8_UNORM) ||
- (littleEndian && dstFormat == MESA_FORMAT_B8G8R8X8_UNORM) ||
- (!littleEndian && dstFormat == MESA_FORMAT_A8R8G8B8_UNORM) ||
- (!littleEndian && dstFormat == MESA_FORMAT_X8R8G8B8_UNORM)) {
- dstmap[3] = 3; /* alpha */
- dstmap[2] = 0; /* red */
- dstmap[1] = 1; /* green */
- dstmap[0] = 2; /* blue */
- }
- else {
- assert((littleEndian && dstFormat == MESA_FORMAT_A8R8G8B8_UNORM) ||
- (!littleEndian && dstFormat == MESA_FORMAT_B8G8R8A8_UNORM) ||
- (littleEndian && dstFormat == MESA_FORMAT_X8R8G8B8_UNORM) ||
- (!littleEndian && dstFormat == MESA_FORMAT_B8G8R8X8_UNORM));
- dstmap[3] = 2;
- dstmap[2] = 1;
- dstmap[1] = 0;
- dstmap[0] = 3;
- }
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 4,
- dstRowStride,
- dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
return GL_TRUE;
}
+/**
+ * Store a combined depth/stencil texture image.
+ */
static GLboolean
-_mesa_texstore_rgb888(TEXSTORE_PARAMS)
+_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
{
- ASSERT(dstFormat == MESA_FORMAT_BGR_UNORM8);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- srcFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_BYTE) {
- /* extract RGB from RGBA */
- 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 = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- for (col = 0; col < srcWidth; col++) {
- dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
- dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
- dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- }
- }
- else if (!ctx->_ImageTransferState &&
- srcType == GL_UNSIGNED_BYTE &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
+ const GLuint depthScale = 0xffffff;
+ const GLint srcRowStride
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+ GLint img, row;
+ GLuint *depth = malloc(srcWidth * sizeof(GLuint));
+ GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
- GLubyte dstmap[4];
+ assert(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
+ assert(srcFormat == GL_DEPTH_STENCIL_EXT ||
+ srcFormat == GL_DEPTH_COMPONENT ||
+ srcFormat == GL_STENCIL_INDEX);
+ assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
+ srcType == GL_UNSIGNED_INT_24_8_EXT ||
+ srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- dstmap[0] = 2;
- dstmap[1] = 1;
- dstmap[2] = 0;
- dstmap[3] = ONE; /* ? */
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 3,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
+ if (!depth || !stencil) {
+ free(depth);
+ free(stencil);
+ return GL_FALSE;
}
- return GL_TRUE;
-}
+ /* In case we only upload depth we need to preserve the stencil */
+ for (img = 0; img < srcDepth; img++) {
+ GLuint *dstRow = (GLuint *) dstSlices[img];
+ const GLubyte *src
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
+ for (row = 0; row < srcHeight; row++) {
+ GLint i;
+ GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
-static GLboolean
-_mesa_texstore_bgr888(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_RGB_UNORM8);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- srcFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_BYTE) {
- /* extract BGR from RGBA */
- int 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 = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- for (col = 0; col < srcWidth; col++) {
- dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
- dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
- dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
+ if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
+ keepstencil = GL_TRUE;
+ }
+ else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
+ keepdepth = GL_TRUE;
}
- }
- }
- else if (!ctx->_ImageTransferState &&
- srcType == GL_UNSIGNED_BYTE &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
-
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- dstmap[0] = 0;
- dstmap[1] = 1;
- dstmap[2] = 2;
- dstmap[3] = ONE; /* ? */
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 3,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
+ if (keepdepth == GL_FALSE)
+ /* the 24 depth bits will be in the low position: */
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_UNSIGNED_INT, /* dst type */
+ keepstencil ? depth : dstRow, /* dst addr */
+ depthScale,
+ srcType, src, srcPacking);
-static GLboolean
-_mesa_texstore_argb2101010(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UNORM ||
- dstFormat == MESA_FORMAT_B10G10R10X2_UNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
+ if (keepstencil == GL_FALSE)
+ /* get the 8-bit stencil values */
+ _mesa_unpack_stencil_span(ctx, srcWidth,
+ GL_UNSIGNED_BYTE, /* dst type */
+ stencil, /* dst addr */
+ srcType, src, srcPacking,
+ ctx->_ImageTransferState);
- {
- /* general path */
- /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0
- * if the internal format is RGB. */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- if (baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB) {
- for (row = 0; row < srcHeight; row++) {
- GLuint *dstUI = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort a,r,g,b;
-
- UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
- dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b);
- src += 4;
- }
- dstRow += dstRowStride;
- }
- } else {
- ASSERT(0);
+ for (i = 0; i < srcWidth; i++) {
+ if (keepstencil)
+ dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
+ else
+ dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
}
+ src += srcRowStride;
+ dstRow += dstRowStride / sizeof(GLuint);
}
- free((void *) tempImage);
}
+
+ free(depth);
+ free(stencil);
return GL_TRUE;
}
/**
- * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
+ * Store a combined depth/stencil texture image.
*/
static GLboolean
-_mesa_texstore_unorm44(TEXSTORE_PARAMS)
+_mesa_texstore_s8_z24(TEXSTORE_PARAMS)
{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+ const GLuint depthScale = 0xffffff;
+ const GLint srcRowStride
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+ GLint img, row;
+ GLuint *depth;
+ GLubyte *stencil;
- ASSERT(dstFormat == MESA_FORMAT_L4A4_UNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
+ assert(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
+ assert(srcFormat == GL_DEPTH_STENCIL_EXT ||
+ srcFormat == GL_DEPTH_COMPONENT ||
+ srcFormat == GL_STENCIL_INDEX);
+ assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
+ srcType == GL_UNSIGNED_INT_24_8_EXT ||
+ srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
- {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLubyte *dstUS = (GLubyte *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- /* src[0] is luminance, src[1] is alpha */
- dstUS[col] = PACK_COLOR_44( src[1],
- src[0] );
- src += 2;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
+ depth = malloc(srcWidth * sizeof(GLuint));
+ stencil = malloc(srcWidth * sizeof(GLubyte));
+ if (!depth || !stencil) {
+ free(depth);
+ free(stencil);
+ return GL_FALSE;
+ }
-/**
- * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
- */
-static GLboolean
-_mesa_texstore_unorm88(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_L8A8_UNORM ||
- dstFormat == MESA_FORMAT_A8L8_UNORM ||
- dstFormat == MESA_FORMAT_R8G8_UNORM ||
- dstFormat == MESA_FORMAT_G8R8_UNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- littleEndian &&
- srcType == GL_UNSIGNED_BYTE &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if (dstFormat == MESA_FORMAT_L8A8_UNORM || dstFormat == MESA_FORMAT_A8L8_UNORM) {
- if ((littleEndian && dstFormat == MESA_FORMAT_L8A8_UNORM) ||
- (!littleEndian && dstFormat == MESA_FORMAT_A8L8_UNORM)) {
- dstmap[0] = 0;
- dstmap[1] = 3;
- }
- else {
- dstmap[0] = 3;
- dstmap[1] = 0;
- }
- }
- else {
- if ((littleEndian && dstFormat == MESA_FORMAT_R8G8_UNORM) ||
- (!littleEndian && dstFormat == MESA_FORMAT_G8R8_UNORM)) {
- dstmap[0] = 0;
- dstmap[1] = 1;
+ for (img = 0; img < srcDepth; img++) {
+ GLuint *dstRow = (GLuint *) dstSlices[img];
+ const GLubyte *src
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
+ for (row = 0; row < srcHeight; row++) {
+ GLint i;
+ GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
+
+ if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
+ keepstencil = GL_TRUE;
}
- else {
- dstmap[0] = 1;
- dstmap[1] = 0;
+ else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
+ keepdepth = GL_TRUE;
}
- }
- dstmap[2] = ZERO; /* ? */
- dstmap[3] = ONE; /* ? */
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 2,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLushort *dstUS = (GLushort *) dstRow;
- if (dstFormat == MESA_FORMAT_L8A8_UNORM ||
- dstFormat == MESA_FORMAT_R8G8_UNORM) {
- for (col = 0; col < srcWidth; col++) {
- /* src[0] is luminance (or R), src[1] is alpha (or G) */
- dstUS[col] = PACK_COLOR_88( src[1],
- src[0] );
- src += 2;
- }
- }
- else {
- for (col = 0; col < srcWidth; col++) {
- /* src[0] is luminance (or R), src[1] is alpha (or G) */
- dstUS[col] = PACK_COLOR_88_REV( src[1],
- src[0] );
- src += 2;
- }
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-/**
- * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
- */
-static GLboolean
-_mesa_texstore_unorm1616(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_L16A16_UNORM ||
- dstFormat == MESA_FORMAT_A16L16_UNORM ||
- dstFormat == MESA_FORMAT_R16G16_UNORM ||
- dstFormat == MESA_FORMAT_G16R16_UNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- 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 (dstFormat == MESA_FORMAT_L16A16_UNORM ||
- dstFormat == MESA_FORMAT_R16G16_UNORM) {
- for (col = 0; col < srcWidth; col++) {
- GLushort l, a;
-
- UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
- UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
- dstUI[col] = PACK_COLOR_1616(a, l);
- src += 2;
- }
- }
- else {
- for (col = 0; col < srcWidth; col++) {
- GLushort l, a;
-
- UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
- UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
- dstUI[col] = PACK_COLOR_1616_REV(a, l);
- src += 2;
- }
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/* Texstore for R16, A16, L16, I16. */
-static GLboolean
-_mesa_texstore_unorm16(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R_UNORM16 ||
- dstFormat == MESA_FORMAT_A_UNORM16 ||
- dstFormat == MESA_FORMAT_L_UNORM16 ||
- dstFormat == MESA_FORMAT_I_UNORM16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLushort *dstUS = (GLushort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort r;
-
- UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
- dstUS[col] = r;
- src += 1;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_rgba_16(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_RGBA_UNORM16 ||
- dstFormat == MESA_FORMAT_RGBX_UNORM16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 8);
-
- {
- /* general path */
- /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0
- * if the internal format is RGB. */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
-
- if (!tempImage)
- return GL_FALSE;
-
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLushort *dstUS = (GLushort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort r, g, b, a;
-
- UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
- UNCLAMPED_FLOAT_TO_USHORT(g, src[1]);
- UNCLAMPED_FLOAT_TO_USHORT(b, src[2]);
- UNCLAMPED_FLOAT_TO_USHORT(a, src[3]);
- dstUS[col*4+0] = r;
- dstUS[col*4+1] = g;
- dstUS[col*4+2] = b;
- dstUS[col*4+3] = a;
- src += 4;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_RGB_SNORM16 ||
- dstFormat == MESA_FORMAT_RGBA_SNORM16 ||
- dstFormat == MESA_FORMAT_RGBX_SNORM16);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2;
- GLint img, row, col;
-
- if (!tempImage)
- return GL_FALSE;
-
- /* Note: tempImage is always float[4] / RGBA. We convert to 1, 2,
- * 3 or 4 components/pixel here.
- */
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLshort *dstRowS = (GLshort *) dstRow;
- if (dstFormat == MESA_FORMAT_RGBA_SNORM16) {
- for (col = 0; col < srcWidth; col++) {
- GLuint c;
- for (c = 0; c < comps; c++) {
- GLshort p;
- UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]);
- dstRowS[col * comps + c] = p;
- }
- }
- dstRow += dstRowStride;
- src += 4 * srcWidth;
- }
- else if (dstFormat == MESA_FORMAT_RGBX_SNORM16) {
- for (col = 0; col < srcWidth; col++) {
- GLuint c;
-
- for (c = 0; c < 3; c++) {
- GLshort p;
- UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]);
- dstRowS[col * comps + c] = p;
- }
- dstRowS[col * comps + 3] = 32767;
- }
- dstRow += dstRowStride;
- src += 3 * srcWidth;
- }
- else {
- for (col = 0; col < srcWidth; col++) {
- GLuint c;
- for (c = 0; c < comps; c++) {
- GLshort p;
- UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]);
- dstRowS[col * comps + c] = p;
- }
- }
- dstRow += dstRowStride;
- src += 3 * srcWidth;
- }
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
- */
-static GLboolean
-_mesa_texstore_unorm8(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_A_UNORM8 ||
- dstFormat == MESA_FORMAT_L_UNORM8 ||
- dstFormat == MESA_FORMAT_I_UNORM8 ||
- dstFormat == MESA_FORMAT_R_UNORM8);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
-
- if (!ctx->_ImageTransferState &&
- srcType == GL_UNSIGNED_BYTE &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if (dstFormat == MESA_FORMAT_A_UNORM8) {
- dstmap[0] = 3;
- }
- else {
- dstmap[0] = 0;
- }
- dstmap[1] = ZERO; /* ? */
- dstmap[2] = ZERO; /* ? */
- dstmap[3] = ONE; /* ? */
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 1,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- for (col = 0; col < srcWidth; col++) {
- dstRow[col] = src[col];
- }
- dstRow += dstRowStride;
- src += srcWidth;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-
-/**
- * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
- */
-static GLboolean
-_mesa_texstore_ycbcr(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
-
- (void) ctx; (void) dims; (void) baseInternalFormat;
-
- ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
- (dstFormat == MESA_FORMAT_YCBCR_REV));
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
- ASSERT(ctx->Extensions.MESA_ycbcr_texture);
- ASSERT(srcFormat == GL_YCBCR_MESA);
- ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
- (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
- ASSERT(baseInternalFormat == GL_YCBCR_MESA);
-
- /* always just memcpy since no pixel transfer ops apply */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
-
- /* Check if we need byte swapping */
- /* XXX the logic here _might_ be wrong */
- if (srcPacking->SwapBytes ^
- (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
- (dstFormat == MESA_FORMAT_YCBCR_REV) ^
- !littleEndian) {
- GLint img, row;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- _mesa_swap2((GLushort *) dstRow, srcWidth);
- dstRow += dstRowStride;
- }
- }
- }
- return GL_TRUE;
-}
-
-static GLboolean
-_mesa_texstore_dudv8(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
- const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_DUDV8);
- ASSERT(texelBytes == 2);
- ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
- ASSERT((srcFormat == GL_DU8DV8_ATI) ||
- (srcFormat == GL_DUDV_ATI));
- ASSERT(baseInternalFormat == GL_DUDV_ATI);
-
- if (srcType == GL_BYTE) {
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if (littleEndian) {
- dstmap[0] = 0;
- dstmap[1] = 3;
- }
- else {
- dstmap[0] = 3;
- dstmap[1] = 0;
- }
- dstmap[2] = ZERO; /* ? */
- dstmap[3] = ONE; /* ? */
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- GL_LUMINANCE_ALPHA, /* hack */
- GL_UNSIGNED_BYTE, /* hack */
- GL_LUMINANCE_ALPHA, /* hack */
- dstmap, 2,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- /* general path - note this is defined for 2d textures only */
- const GLint components = _mesa_components_in_format(baseInternalFormat);
- const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
- srcFormat, srcType);
- GLbyte *tempImage, *dst, *src;
- GLint row;
-
- tempImage = malloc(srcWidth * srcHeight * srcDepth
- * components * sizeof(GLbyte));
- if (!tempImage)
- return GL_FALSE;
-
- src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- 0, 0, 0);
-
- dst = tempImage;
- for (row = 0; row < srcHeight; row++) {
- _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
- dst, srcFormat, srcType, src,
- srcPacking, 0);
- dst += srcWidth * components;
- src += srcStride;
- }
-
- src = tempImage;
- dst = (GLbyte *) dstSlices[0];
- for (row = 0; row < srcHeight; row++) {
- memcpy(dst, src, srcWidth * texelBytes);
- dst += dstRowStride;
- src += srcWidth * texelBytes;
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store a texture in a signed normalized 8-bit format.
- */
-static GLboolean
-_mesa_texstore_snorm8(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_A_SNORM8 ||
- dstFormat == MESA_FORMAT_L_SNORM8 ||
- dstFormat == MESA_FORMAT_I_SNORM8 ||
- dstFormat == MESA_FORMAT_R_SNORM8);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLbyte *dstRow = (GLbyte *) dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- for (col = 0; col < srcWidth; col++) {
- dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]);
- }
- dstRow += dstRowStride;
- src += srcWidth;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store a texture in a signed normalized two-channel 16-bit format.
- */
-static GLboolean
-_mesa_texstore_snorm88(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_L8A8_SNORM ||
- dstFormat == MESA_FORMAT_G8R8_SNORM ||
- dstFormat == MESA_FORMAT_R8G8_SNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLbyte *dstRow = (GLbyte *) dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLushort *dst = (GLushort *) dstRow;
-
- if (dstFormat == MESA_FORMAT_L8A8_SNORM ||
- dstFormat == MESA_FORMAT_R8G8_SNORM) {
- for (col = 0; col < srcWidth; col++) {
- GLubyte l = FLOAT_TO_BYTE_TEX(src[0]);
- GLubyte a = FLOAT_TO_BYTE_TEX(src[1]);
-
- dst[col] = PACK_COLOR_88_REV(l, a);
- src += 2;
- }
- } else {
- for (col = 0; col < srcWidth; col++) {
- GLubyte l = FLOAT_TO_BYTE_TEX(src[0]);
- GLubyte a = FLOAT_TO_BYTE_TEX(src[1]);
-
- dst[col] = PACK_COLOR_88(l, a);
- src += 2;
- }
- }
-
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-/* Texstore for signed R16, A16, L16, I16. */
-static GLboolean
-_mesa_texstore_snorm16(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R_SNORM16 ||
- dstFormat == MESA_FORMAT_A_SNORM16 ||
- dstFormat == MESA_FORMAT_L_SNORM16 ||
- dstFormat == MESA_FORMAT_I_SNORM16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLshort *dstUS = (GLshort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort r;
-
- UNCLAMPED_FLOAT_TO_SHORT(r, src[0]);
- dstUS[col] = r;
- src += 1;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-/**
- * Do texstore for 2-channel, 16-bit/channel, signed normalized formats.
- */
-static GLboolean
-_mesa_texstore_snorm1616(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_LA_SNORM16 ||
- dstFormat == MESA_FORMAT_G16R16_SNORM ||
- dstFormat == MESA_FORMAT_R16G16_SNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *dst = (GLuint *) dstRow;
-
- if (dstFormat == MESA_FORMAT_LA_SNORM16 ||
- dstFormat == MESA_FORMAT_R16G16_SNORM) {
- for (col = 0; col < srcWidth; col++) {
- GLushort l, a;
-
- UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
- UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
- dst[col] = PACK_COLOR_1616_REV(l, a);
- src += 2;
- }
- } else {
- for (col = 0; col < srcWidth; col++) {
- GLushort l, a;
-
- UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
- UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
- dst[col] = PACK_COLOR_1616_REV(l, a);
- src += 2;
- }
- }
-
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-/**
- * Store a texture in MESA_FORMAT_X8B8G8R8_SNORM or
- * MESA_FORMAT_R8G8B8X8_SNORM.
- */
-static GLboolean
-_mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_X8B8G8R8_SNORM ||
- dstFormat == MESA_FORMAT_R8G8B8X8_SNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *srcRow = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLbyte *dstRow = (GLbyte *) dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLbyte *dst = dstRow;
- if (dstFormat == MESA_FORMAT_X8B8G8R8_SNORM) {
- for (col = 0; col < srcWidth; col++) {
- dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
- dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
- dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
- dst[0] = 127;
- srcRow += 3;
- dst += 4;
- }
- }
- else {
- for (col = 0; col < srcWidth; col++) {
- dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
- dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
- dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
- dst[3] = 127;
- srcRow += 3;
- dst += 4;
- }
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-
-/**
- * Store a texture in MESA_FORMAT_A8B8G8R8_SNORM or
- * MESA_FORMAT_R8G8B8A8_SNORM
- */
-static GLboolean
-_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_SNORM ||
- dstFormat == MESA_FORMAT_R8G8B8A8_SNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *srcRow = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLbyte *dstRow = (GLbyte *) dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLbyte *dst = dstRow;
- if (dstFormat == MESA_FORMAT_A8B8G8R8_SNORM) {
- for (col = 0; col < srcWidth; col++) {
- dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
- dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
- dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
- dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
- srcRow += 4;
- dst += 4;
- }
- }
- else {
- for (col = 0; col < srcWidth; col++) {
- dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
- dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
- dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
- dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
- srcRow += 4;
- dst += 4;
- }
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store a combined depth/stencil texture image.
- */
-static GLboolean
-_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
-{
- const GLuint depthScale = 0xffffff;
- const GLint srcRowStride
- = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- GLint img, row;
- GLuint *depth = malloc(srcWidth * sizeof(GLuint));
- GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
-
- ASSERT(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
- ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
- srcFormat == GL_DEPTH_COMPONENT ||
- srcFormat == GL_STENCIL_INDEX);
- ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
- srcType == GL_UNSIGNED_INT_24_8_EXT ||
- srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
-
- 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];
- const GLubyte *src
- = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- img, 0, 0);
- for (row = 0; row < srcHeight; row++) {
- GLint i;
- GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
-
- if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
- keepstencil = GL_TRUE;
- }
- else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
- keepdepth = GL_TRUE;
- }
-
- if (keepdepth == GL_FALSE)
- /* the 24 depth bits will be in the low position: */
- _mesa_unpack_depth_span(ctx, srcWidth,
- GL_UNSIGNED_INT, /* dst type */
- keepstencil ? depth : dstRow, /* dst addr */
- depthScale,
- srcType, src, srcPacking);
-
- if (keepstencil == GL_FALSE)
- /* get the 8-bit stencil values */
- _mesa_unpack_stencil_span(ctx, srcWidth,
- GL_UNSIGNED_BYTE, /* dst type */
- stencil, /* dst addr */
- srcType, src, srcPacking,
- ctx->_ImageTransferState);
-
- for (i = 0; i < srcWidth; i++) {
- if (keepstencil)
- dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
- else
- dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
- }
- src += srcRowStride;
- dstRow += dstRowStride / sizeof(GLuint);
- }
- }
-
- free(depth);
- free(stencil);
- return GL_TRUE;
-}
-
-
-/**
- * Store a combined depth/stencil texture image.
- */
-static GLboolean
-_mesa_texstore_s8_z24(TEXSTORE_PARAMS)
-{
- const GLuint depthScale = 0xffffff;
- const GLint srcRowStride
- = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- GLint img, row;
- GLuint *depth;
- GLubyte *stencil;
-
- ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
- ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
- srcFormat == GL_DEPTH_COMPONENT ||
- srcFormat == GL_STENCIL_INDEX);
- ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
- srcType == GL_UNSIGNED_INT_24_8_EXT ||
- srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
-
- 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
- = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- img, 0, 0);
- for (row = 0; row < srcHeight; row++) {
- GLint i;
- GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
-
- if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
- keepstencil = GL_TRUE;
- }
- else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
- keepdepth = GL_TRUE;
- }
-
- if (keepdepth == GL_FALSE)
- /* the 24 depth bits will be in the low position: */
- _mesa_unpack_depth_span(ctx, srcWidth,
- GL_UNSIGNED_INT, /* dst type */
- keepstencil ? depth : dstRow, /* dst addr */
- depthScale,
- srcType, src, srcPacking);
-
- if (keepstencil == GL_FALSE)
- /* get the 8-bit stencil values */
- _mesa_unpack_stencil_span(ctx, srcWidth,
- GL_UNSIGNED_BYTE, /* dst type */
- stencil, /* dst addr */
- srcType, src, srcPacking,
- ctx->_ImageTransferState);
-
- /* merge stencil values into depth values */
- for (i = 0; i < srcWidth; i++) {
- if (keepstencil)
- dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
- else
- dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
-
- }
- src += srcRowStride;
- dstRow += dstRowStride / sizeof(GLuint);
- }
- }
-
- free(depth);
- free(stencil);
-
- return GL_TRUE;
-}
-
-
-/**
- * Store simple 8-bit/value stencil texture data.
- */
-static GLboolean
-_mesa_texstore_s8(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_S_UINT8);
- ASSERT(srcFormat == GL_STENCIL_INDEX);
-
- {
- 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
- = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- img, 0, 0);
- for (row = 0; row < srcHeight; row++) {
- GLint i;
-
- /* get the 8-bit stencil values */
- _mesa_unpack_stencil_span(ctx, srcWidth,
- GL_UNSIGNED_BYTE, /* dst type */
- stencil, /* dst addr */
- srcType, src, srcPacking,
- ctx->_ImageTransferState);
- /* merge stencil values into depth values */
- for (i = 0; i < srcWidth; i++)
- dstRow[i] = stencil[i];
-
- src += srcRowStride;
- dstRow += dstRowStride / sizeof(GLubyte);
- }
- }
-
- free(stencil);
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Store an image in any of the formats:
- * _mesa_texformat_rgba_float32
- * _mesa_texformat_rgb_float32
- * _mesa_texformat_alpha_float32
- * _mesa_texformat_luminance_float32
- * _mesa_texformat_luminance_alpha_float32
- * _mesa_texformat_intensity_float32
- */
-static GLboolean
-_mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
-{
- GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- GLint components = _mesa_components_in_format(baseFormat);
-
- /* this forces alpha to 1 in _mesa_make_temp_float_image */
- if (dstFormat == MESA_FORMAT_RGBX_FLOAT32) {
- baseFormat = GL_RGBA;
- components = 4;
- }
-
- ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
- dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
- dstFormat == MESA_FORMAT_A_FLOAT32 ||
- dstFormat == MESA_FORMAT_L_FLOAT32 ||
- dstFormat == MESA_FORMAT_LA_FLOAT32 ||
- dstFormat == MESA_FORMAT_I_FLOAT32 ||
- dstFormat == MESA_FORMAT_R_FLOAT32 ||
- dstFormat == MESA_FORMAT_RG_FLOAT32 ||
- dstFormat == MESA_FORMAT_RGBX_FLOAT32);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY ||
- baseInternalFormat == GL_RED ||
- baseInternalFormat == GL_RG);
- ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat));
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *srcRow = tempImage;
- GLint bytesPerRow;
- GLint img, row;
- if (!tempImage)
- return GL_FALSE;
- bytesPerRow = srcWidth * components * sizeof(GLfloat);
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- memcpy(dstRow, srcRow, bytesPerRow);
- dstRow += dstRowStride;
- srcRow += srcWidth * components;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-
-/**
- * As above, but store 16-bit floats.
- */
-static GLboolean
-_mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
-{
- GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- GLint components = _mesa_components_in_format(baseFormat);
-
- /* this forces alpha to 1 in _mesa_make_temp_float_image */
- if (dstFormat == MESA_FORMAT_RGBX_FLOAT16) {
- baseFormat = GL_RGBA;
- components = 4;
- }
-
- ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
- dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
- dstFormat == MESA_FORMAT_A_FLOAT16 ||
- dstFormat == MESA_FORMAT_L_FLOAT16 ||
- dstFormat == MESA_FORMAT_LA_FLOAT16 ||
- dstFormat == MESA_FORMAT_I_FLOAT16 ||
- dstFormat == MESA_FORMAT_R_FLOAT16 ||
- dstFormat == MESA_FORMAT_RG_FLOAT16 ||
- dstFormat == MESA_FORMAT_RGBX_FLOAT16);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY ||
- baseInternalFormat == GL_RED ||
- baseInternalFormat == GL_RG);
- ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB));
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
- GLint i;
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = _mesa_float_to_half(src[i]);
- }
- dstRow += dstRowStride;
- src += srcWidth * components;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/* non-normalized, signed int8 */
-static GLboolean
-_mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
-{
- GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- GLint components = _mesa_components_in_format(baseFormat);
-
- /* this forces alpha to 1 in make_temp_uint_image */
- if (dstFormat == MESA_FORMAT_RGBX_SINT8) {
- baseFormat = GL_RGBA;
- components = 4;
- }
-
- ASSERT(dstFormat == MESA_FORMAT_R_SINT8 ||
- dstFormat == MESA_FORMAT_RG_SINT8 ||
- dstFormat == MESA_FORMAT_RGB_SINT8 ||
- dstFormat == MESA_FORMAT_RGBA_SINT8 ||
- dstFormat == MESA_FORMAT_A_SINT8 ||
- dstFormat == MESA_FORMAT_I_SINT8 ||
- dstFormat == MESA_FORMAT_L_SINT8 ||
- dstFormat == MESA_FORMAT_LA_SINT8 ||
- dstFormat == MESA_FORMAT_RGBX_SINT8);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_RG ||
- baseInternalFormat == GL_RED ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY);
- ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte));
-
- {
- /* 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;
- 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++) {
- GLbyte *dstTexel = (GLbyte *) dstRow;
- GLint 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;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/* non-normalized, signed int16 */
-static GLboolean
-_mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
-{
- GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- GLint components = _mesa_components_in_format(baseFormat);
-
- /* this forces alpha to 1 in make_temp_uint_image */
- if (dstFormat == MESA_FORMAT_RGBX_SINT16) {
- baseFormat = GL_RGBA;
- components = 4;
- }
-
- ASSERT(dstFormat == MESA_FORMAT_R_SINT16 ||
- dstFormat == MESA_FORMAT_RG_SINT16 ||
- dstFormat == MESA_FORMAT_RGB_SINT16 ||
- dstFormat == MESA_FORMAT_RGBA_SINT16 ||
- dstFormat == MESA_FORMAT_A_SINT16 ||
- dstFormat == MESA_FORMAT_L_SINT16 ||
- dstFormat == MESA_FORMAT_I_SINT16 ||
- dstFormat == MESA_FORMAT_LA_SINT16 ||
- dstFormat == MESA_FORMAT_RGBX_SINT16);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_RG ||
- baseInternalFormat == GL_RED ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY);
- ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort));
-
- {
- /* 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;
- 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++) {
- GLshort *dstTexel = (GLshort *) dstRow;
- GLint 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;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/* non-normalized, signed int32 */
-static GLboolean
-_mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
-{
- GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- GLint components = _mesa_components_in_format(baseFormat);
-
- /* this forces alpha to 1 in make_temp_uint_image */
- if (dstFormat == MESA_FORMAT_RGBX_SINT32) {
- baseFormat = GL_RGBA;
- components = 4;
- }
-
- ASSERT(dstFormat == MESA_FORMAT_R_SINT32 ||
- dstFormat == MESA_FORMAT_RG_SINT32 ||
- dstFormat == MESA_FORMAT_RGB_SINT32 ||
- dstFormat == MESA_FORMAT_RGBA_SINT32 ||
- dstFormat == MESA_FORMAT_A_SINT32 ||
- dstFormat == MESA_FORMAT_I_SINT32 ||
- dstFormat == MESA_FORMAT_L_SINT32 ||
- dstFormat == MESA_FORMAT_LA_SINT32 ||
- dstFormat == MESA_FORMAT_RGBX_SINT32);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_RG ||
- baseInternalFormat == GL_RED ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY);
- ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint));
-
- {
- /* 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;
- 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++) {
- GLint *dstTexel = (GLint *) dstRow;
- GLint 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;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/* non-normalized, unsigned int8 */
-static GLboolean
-_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
-{
- GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- GLint components = _mesa_components_in_format(baseFormat);
-
- /* this forces alpha to 1 in make_temp_uint_image */
- if (dstFormat == MESA_FORMAT_RGBX_UINT8) {
- baseFormat = GL_RGBA;
- components = 4;
- }
-
- ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
- dstFormat == MESA_FORMAT_RG_UINT8 ||
- dstFormat == MESA_FORMAT_RGB_UINT8 ||
- dstFormat == MESA_FORMAT_RGBA_UINT8 ||
- dstFormat == MESA_FORMAT_A_UINT8 ||
- dstFormat == MESA_FORMAT_I_UINT8 ||
- dstFormat == MESA_FORMAT_L_UINT8 ||
- dstFormat == MESA_FORMAT_LA_UINT8 ||
- dstFormat == MESA_FORMAT_RGBX_UINT8);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_RG ||
- baseInternalFormat == GL_RED ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY);
- ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte));
-
- {
- /* 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;
- 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++) {
- GLubyte *dstTexel = (GLubyte *) dstRow;
- GLint i;
- 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;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/* non-normalized, unsigned int16 */
-static GLboolean
-_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
-{
- GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- GLint components = _mesa_components_in_format(baseFormat);
-
- /* this forces alpha to 1 in make_temp_uint_image */
- if (dstFormat == MESA_FORMAT_RGBX_UINT16) {
- baseFormat = GL_RGBA;
- components = 4;
- }
-
- ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
- dstFormat == MESA_FORMAT_RG_UINT16 ||
- dstFormat == MESA_FORMAT_RGB_UINT16 ||
- dstFormat == MESA_FORMAT_RGBA_UINT16 ||
- dstFormat == MESA_FORMAT_A_UINT16 ||
- dstFormat == MESA_FORMAT_I_UINT16 ||
- dstFormat == MESA_FORMAT_L_UINT16 ||
- dstFormat == MESA_FORMAT_LA_UINT16 ||
- dstFormat == MESA_FORMAT_RGBX_UINT16);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_RG ||
- baseInternalFormat == GL_RED ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY);
- ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort));
-
- {
- /* 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;
- 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++) {
- GLushort *dstTexel = (GLushort *) dstRow;
- GLint i;
- 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;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/* non-normalized, unsigned int32 */
-static GLboolean
-_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
-{
- GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- GLint components = _mesa_components_in_format(baseFormat);
-
- /* this forces alpha to 1 in make_temp_uint_image */
- if (dstFormat == MESA_FORMAT_RGBX_UINT32) {
- baseFormat = GL_RGBA;
- components = 4;
- }
-
- ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
- dstFormat == MESA_FORMAT_RG_UINT32 ||
- dstFormat == MESA_FORMAT_RGB_UINT32 ||
- dstFormat == MESA_FORMAT_RGBA_UINT32 ||
- dstFormat == MESA_FORMAT_A_UINT32 ||
- dstFormat == MESA_FORMAT_I_UINT32 ||
- dstFormat == MESA_FORMAT_L_UINT32 ||
- dstFormat == MESA_FORMAT_LA_UINT32 ||
- dstFormat == MESA_FORMAT_RGBX_UINT32);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_RG ||
- baseInternalFormat == GL_RED ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY);
- ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint));
-
- {
- /* general path */
- const GLuint *tempImage =
- make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
- 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 (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *dstTexel = (GLuint *) dstRow;
- GLint 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;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_srgb8(TEXSTORE_PARAMS)
-{
- mesa_format newDstFormat;
- GLboolean k;
-
- ASSERT(dstFormat == MESA_FORMAT_BGR_SRGB8);
-
- /* reuse normal rgb texstore code */
- newDstFormat = MESA_FORMAT_BGR_UNORM8;
-
- k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
-}
-
-
-static GLboolean
-_mesa_texstore_srgba8(TEXSTORE_PARAMS)
-{
- mesa_format newDstFormat;
- GLboolean k;
-
- ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_SRGB ||
- dstFormat == MESA_FORMAT_R8G8B8X8_SRGB ||
- dstFormat == MESA_FORMAT_R8G8B8A8_SRGB);
-
- newDstFormat = _mesa_get_srgb_format_linear(dstFormat);
-
- k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
-}
-
-
-static GLboolean
-_mesa_texstore_sargb8(TEXSTORE_PARAMS)
-{
- mesa_format newDstFormat;
- GLboolean k;
-
- assert(dstFormat == MESA_FORMAT_B8G8R8A8_SRGB ||
- dstFormat == MESA_FORMAT_B8G8R8X8_SRGB);
-
- newDstFormat = _mesa_get_srgb_format_linear(dstFormat);
-
- k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
-}
-
-
-static GLboolean
-_mesa_texstore_sl8(TEXSTORE_PARAMS)
-{
- mesa_format newDstFormat;
- GLboolean k;
-
- ASSERT(dstFormat == MESA_FORMAT_L_SRGB8);
-
- newDstFormat = MESA_FORMAT_L_UNORM8;
-
- /* _mesa_textore_a8 handles luminance8 too */
- k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
-}
+ if (keepdepth == GL_FALSE)
+ /* the 24 depth bits will be in the low position: */
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_UNSIGNED_INT, /* dst type */
+ keepstencil ? depth : dstRow, /* dst addr */
+ depthScale,
+ srcType, src, srcPacking);
+ if (keepstencil == GL_FALSE)
+ /* get the 8-bit stencil values */
+ _mesa_unpack_stencil_span(ctx, srcWidth,
+ GL_UNSIGNED_BYTE, /* dst type */
+ stencil, /* dst addr */
+ srcType, src, srcPacking,
+ ctx->_ImageTransferState);
-static GLboolean
-_mesa_texstore_sla8(TEXSTORE_PARAMS)
-{
- mesa_format newDstFormat;
- GLboolean k;
+ /* merge stencil values into depth values */
+ for (i = 0; i < srcWidth; i++) {
+ if (keepstencil)
+ dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
+ else
+ dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
- ASSERT(dstFormat == MESA_FORMAT_L8A8_SRGB);
+ }
+ src += srcRowStride;
+ dstRow += dstRowStride / sizeof(GLuint);
+ }
+ }
- /* reuse normal luminance/alpha texstore code */
- newDstFormat = MESA_FORMAT_L8A8_UNORM;
+ free(depth);
+ free(stencil);
- k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
+ return GL_TRUE;
}
+
+/**
+ * Store simple 8-bit/value stencil texture data.
+ */
static GLboolean
-_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
+_mesa_texstore_s8(TEXSTORE_PARAMS)
{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R9G9B9E5_FLOAT);
- ASSERT(baseInternalFormat == GL_RGB);
+ assert(dstFormat == MESA_FORMAT_S_UINT8);
+ assert(srcFormat == GL_STENCIL_INDEX);
{
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *srcRow = tempImage;
- GLint img, row, col;
- if (!tempImage)
+ 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
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
for (row = 0; row < srcHeight; row++) {
- GLuint *dstUI = (GLuint*)dstRow;
- for (col = 0; col < srcWidth; col++) {
- dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
- }
- dstRow += dstRowStride;
- srcRow += srcWidth * 3;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-static GLboolean
-_mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+ GLint i;
- ASSERT(dstFormat == MESA_FORMAT_R11G11B10_FLOAT);
- ASSERT(baseInternalFormat == GL_RGB);
+ /* get the 8-bit stencil values */
+ _mesa_unpack_stencil_span(ctx, srcWidth,
+ GL_UNSIGNED_BYTE, /* dst type */
+ stencil, /* dst addr */
+ srcType, src, srcPacking,
+ ctx->_ImageTransferState);
+ /* merge stencil values into depth values */
+ for (i = 0; i < srcWidth; i++)
+ dstRow[i] = stencil[i];
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *srcRow = tempImage;
- GLint img, row, col;
- 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;
- for (col = 0; col < srcWidth; col++) {
- dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]);
- }
- dstRow += dstRowStride;
- srcRow += srcWidth * 3;
+ src += srcRowStride;
+ dstRow += dstRowStride / sizeof(GLubyte);
}
}
- free((void *) tempImage);
+ free(stencil);
}
+
return GL_TRUE;
}
= _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
/ sizeof(uint64_t);
- ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
- ASSERT(srcFormat == GL_DEPTH_STENCIL ||
+ assert(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
+ assert(srcFormat == GL_DEPTH_STENCIL ||
srcFormat == GL_DEPTH_COMPONENT ||
srcFormat == GL_STENCIL_INDEX);
- ASSERT(srcFormat != GL_DEPTH_STENCIL ||
+ assert(srcFormat != GL_DEPTH_STENCIL ||
srcType == GL_UNSIGNED_INT_24_8 ||
srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
}
static GLboolean
-_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- {
- /* 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) | (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)
+texstore_depth_stencil(TEXSTORE_PARAMS)
{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+ static StoreTexImageFunc table[MESA_FORMAT_COUNT];
+ static GLboolean initialized = GL_FALSE;
- ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
+ if (!initialized) {
+ memset(table, 0, sizeof table);
- {
- /* 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];
+ table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8;
+ table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24;
+ table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16;
+ table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24;
+ table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8;
+ table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32;
+ table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8;
+ table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32;
+ table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8;
- 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;
- }
- }
- free((void *) tempImage);
+ initialized = GL_TRUE;
}
- return GL_TRUE;
-}
-static GLboolean
-_mesa_texstore_abgr2101010(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UNORM);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- 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;
- for (col = 0; col < srcWidth; col++) {
- GLushort a,r,g,b;
-
- UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
- dstUI[col] = PACK_COLOR_2101010_US(a, b, g, r);
- src += 4;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
+ assert(table[dstFormat]);
+ return table[dstFormat](ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
static GLboolean
-_mesa_texstore_null(TEXSTORE_PARAMS)
-{
- (void) ctx; (void) dims;
- (void) baseInternalFormat;
- (void) dstFormat;
- (void) dstRowStride; (void) dstSlices,
- (void) srcWidth; (void) srcHeight; (void) srcDepth;
- (void) srcFormat; (void) srcType;
- (void) srcAddr;
- (void) srcPacking;
-
- /* should never happen */
- _mesa_problem(NULL, "_mesa_texstore_null() is called");
- return GL_FALSE;
-}
-
-
-/**
- * Return the StoreTexImageFunc pointer to store an image in the given format.
- */
-static StoreTexImageFunc
-_mesa_get_texstore_func(mesa_format format)
+texstore_compressed(TEXSTORE_PARAMS)
{
static StoreTexImageFunc table[MESA_FORMAT_COUNT];
static GLboolean initialized = GL_FALSE;
if (!initialized) {
- table[MESA_FORMAT_NONE] = _mesa_texstore_null;
-
- table[MESA_FORMAT_A8B8G8R8_UNORM] = _mesa_texstore_rgba8888;
- table[MESA_FORMAT_R8G8B8A8_UNORM] = _mesa_texstore_rgba8888;
- table[MESA_FORMAT_B8G8R8A8_UNORM] = _mesa_texstore_argb8888;
- table[MESA_FORMAT_A8R8G8B8_UNORM] = _mesa_texstore_argb8888;
- table[MESA_FORMAT_X8B8G8R8_UNORM] = _mesa_texstore_rgba8888;
- table[MESA_FORMAT_R8G8B8X8_UNORM] = _mesa_texstore_rgba8888;
- table[MESA_FORMAT_B8G8R8X8_UNORM] = _mesa_texstore_argb8888;
- table[MESA_FORMAT_X8R8G8B8_UNORM] = _mesa_texstore_argb8888;
- table[MESA_FORMAT_BGR_UNORM8] = _mesa_texstore_rgb888;
- table[MESA_FORMAT_RGB_UNORM8] = _mesa_texstore_bgr888;
- table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565;
- table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565;
- table[MESA_FORMAT_B4G4R4A4_UNORM] = store_ubyte_texture;
- table[MESA_FORMAT_A4R4G4B4_UNORM] = store_ubyte_texture;
- table[MESA_FORMAT_A1B5G5R5_UNORM] = store_ubyte_texture;
- table[MESA_FORMAT_B5G5R5A1_UNORM] = store_ubyte_texture;
- table[MESA_FORMAT_A1R5G5B5_UNORM] = store_ubyte_texture;
- table[MESA_FORMAT_L4A4_UNORM] = _mesa_texstore_unorm44;
- table[MESA_FORMAT_L8A8_UNORM] = _mesa_texstore_unorm88;
- table[MESA_FORMAT_A8L8_UNORM] = _mesa_texstore_unorm88;
- table[MESA_FORMAT_L16A16_UNORM] = _mesa_texstore_unorm1616;
- table[MESA_FORMAT_A16L16_UNORM] = _mesa_texstore_unorm1616;
- table[MESA_FORMAT_B2G3R3_UNORM] = store_ubyte_texture;
- table[MESA_FORMAT_A_UNORM8] = _mesa_texstore_unorm8;
- table[MESA_FORMAT_A_UNORM16] = _mesa_texstore_unorm16;
- table[MESA_FORMAT_L_UNORM8] = _mesa_texstore_unorm8;
- table[MESA_FORMAT_L_UNORM16] = _mesa_texstore_unorm16;
- table[MESA_FORMAT_I_UNORM8] = _mesa_texstore_unorm8;
- table[MESA_FORMAT_I_UNORM16] = _mesa_texstore_unorm16;
- table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
- table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
- table[MESA_FORMAT_R_UNORM8] = _mesa_texstore_unorm8;
- table[MESA_FORMAT_R8G8_UNORM] = _mesa_texstore_unorm88;
- table[MESA_FORMAT_G8R8_UNORM] = _mesa_texstore_unorm88;
- table[MESA_FORMAT_R_UNORM16] = _mesa_texstore_unorm16;
- table[MESA_FORMAT_R16G16_UNORM] = _mesa_texstore_unorm1616;
- table[MESA_FORMAT_G16R16_UNORM] = _mesa_texstore_unorm1616;
- table[MESA_FORMAT_B10G10R10A2_UNORM] = _mesa_texstore_argb2101010;
- table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8;
- table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24;
- table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16;
- table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24;
- table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8;
- table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32;
- table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8;
- table[MESA_FORMAT_BGR_SRGB8] = _mesa_texstore_srgb8;
- table[MESA_FORMAT_A8B8G8R8_SRGB] = _mesa_texstore_srgba8;
- table[MESA_FORMAT_B8G8R8A8_SRGB] = _mesa_texstore_sargb8;
- table[MESA_FORMAT_L_SRGB8] = _mesa_texstore_sl8;
- table[MESA_FORMAT_L8A8_SRGB] = _mesa_texstore_sla8;
+ memset(table, 0, sizeof table);
+
table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
- table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_A_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_A_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_L_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_L_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_LA_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_LA_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_I_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_I_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8;
- table[MESA_FORMAT_R_SNORM8] = _mesa_texstore_snorm8;
- table[MESA_FORMAT_R8G8_SNORM] = _mesa_texstore_snorm88;
- table[MESA_FORMAT_X8B8G8R8_SNORM] = _mesa_texstore_signed_rgbx8888;
- table[MESA_FORMAT_A8B8G8R8_SNORM] = _mesa_texstore_signed_rgba8888;
- table[MESA_FORMAT_R8G8B8A8_SNORM] = _mesa_texstore_signed_rgba8888;
- table[MESA_FORMAT_R_SNORM16] = _mesa_texstore_snorm16;
- table[MESA_FORMAT_R16G16_SNORM] = _mesa_texstore_snorm1616;
- table[MESA_FORMAT_RGB_SNORM16] = _mesa_texstore_signed_rgba_16;
- table[MESA_FORMAT_RGBA_SNORM16] = _mesa_texstore_signed_rgba_16;
- table[MESA_FORMAT_RGBA_UNORM16] = _mesa_texstore_rgba_16;
table[MESA_FORMAT_R_RGTC1_UNORM] = _mesa_texstore_red_rgtc1;
table[MESA_FORMAT_R_RGTC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
table[MESA_FORMAT_RG_RGTC2_UNORM] = _mesa_texstore_rg_rgtc2;
_mesa_texstore_etc2_rgb8_punchthrough_alpha1;
table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
_mesa_texstore_etc2_srgb8_punchthrough_alpha1;
- table[MESA_FORMAT_A_SNORM8] = _mesa_texstore_snorm8;
- table[MESA_FORMAT_L_SNORM8] = _mesa_texstore_snorm8;
- table[MESA_FORMAT_L8A8_SNORM] = _mesa_texstore_snorm88;
- table[MESA_FORMAT_I_SNORM8] = _mesa_texstore_snorm8;
- table[MESA_FORMAT_A_SNORM16] = _mesa_texstore_snorm16;
- table[MESA_FORMAT_L_SNORM16] = _mesa_texstore_snorm16;
- table[MESA_FORMAT_LA_SNORM16] = _mesa_texstore_snorm1616;
- table[MESA_FORMAT_I_SNORM16] = _mesa_texstore_snorm16;
- table[MESA_FORMAT_R9G9B9E5_FLOAT] = _mesa_texstore_rgb9_e5;
- table[MESA_FORMAT_R11G11B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
- table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32;
- table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8;
- table[MESA_FORMAT_A_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_A_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_A_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_A_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_A_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_A_SINT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_I_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_I_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_I_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_I_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_I_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_I_SINT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_L_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_L_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_L_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_L_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_L_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_L_SINT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_LA_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_LA_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_LA_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_LA_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_LA_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_LA_SINT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_R_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_RG_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_RGB_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_RGBA_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_R_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_RG_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_RGB_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_RGBA_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_R_SINT32] = _mesa_texstore_rgba_int32;
- table[MESA_FORMAT_RG_SINT32] = _mesa_texstore_rgba_int32;
- table[MESA_FORMAT_RGB_SINT32] = _mesa_texstore_rgba_int32;
- table[MESA_FORMAT_RGBA_SINT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
-
- table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint;
- table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint;
-
- table[MESA_FORMAT_B4G4R4X4_UNORM] = store_ubyte_texture;
- table[MESA_FORMAT_B5G5R5X1_UNORM] = store_ubyte_texture;
- table[MESA_FORMAT_R8G8B8X8_SNORM] = _mesa_texstore_signed_rgbx8888;
- table[MESA_FORMAT_R8G8B8X8_SRGB] = _mesa_texstore_srgba8;
- table[MESA_FORMAT_R8G8B8A8_SRGB] = _mesa_texstore_srgba8;
- table[MESA_FORMAT_RGBX_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_RGBX_SINT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_B10G10R10X2_UNORM] = _mesa_texstore_argb2101010;
- table[MESA_FORMAT_RGBX_UNORM16] = _mesa_texstore_rgba_16;
- table[MESA_FORMAT_RGBX_SNORM16] = _mesa_texstore_signed_rgba_16;
- table[MESA_FORMAT_RGBX_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_RGBX_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_RGBX_SINT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_RGBX_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_RGBX_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_RGBX_SINT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_R10G10B10A2_UNORM] = _mesa_texstore_abgr2101010;
-
- table[MESA_FORMAT_G8R8_SNORM] = _mesa_texstore_snorm88;
- table[MESA_FORMAT_G16R16_SNORM] = _mesa_texstore_snorm1616;
-
- table[MESA_FORMAT_B8G8R8X8_SRGB] = _mesa_texstore_sargb8;
+ table[MESA_FORMAT_BPTC_RGBA_UNORM] =
+ _mesa_texstore_bptc_rgba_unorm;
+ table[MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM] =
+ _mesa_texstore_bptc_rgba_unorm;
+ table[MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT] =
+ _mesa_texstore_bptc_rgb_signed_float;
+ table[MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT] =
+ _mesa_texstore_bptc_rgb_unsigned_float;
initialized = GL_TRUE;
}
- ASSERT(table[format]);
- return table[format];
+ assert(table[dstFormat]);
+ return table[dstFormat](ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
+static GLboolean
+texstore_rgba(TEXSTORE_PARAMS)
+{
+ void *tempImage = NULL, *tempRGBA = NULL;
+ int srcRowStride, img;
+ GLubyte *src, *dst;
+ uint32_t srcMesaFormat;
+ uint8_t rebaseSwizzle[4];
+ bool needRebase;
+ bool transferOpsDone = false;
+
+ /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case
+ * and _mesa_format_convert does not support it. In this case the we only
+ * allow conversions between YCBCR formats and it is mostly a memcpy.
+ */
+ if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) {
+ return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ }
+
+ /* We have to deal with GL_COLOR_INDEX manually because
+ * _mesa_format_convert does not handle this format. So what we do here is
+ * convert it to RGBA ubyte first and then convert from that to dst as usual.
+ */
+ if (srcFormat == GL_COLOR_INDEX) {
+ /* Notice that this will already handle byte swapping if necessary */
+ tempImage =
+ _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims,
+ srcAddr, srcFormat, srcType,
+ srcWidth, srcHeight, srcDepth,
+ srcPacking,
+ ctx->_ImageTransferState);
+ if (!tempImage)
+ return GL_FALSE;
+
+ /* _mesa_unpack_color_index_to_rgba_ubyte has handled transferops
+ * if needed.
+ */
+ transferOpsDone = true;
+
+ /* Now we only have to adjust our src info for a conversion from
+ * the RGBA ubyte and then we continue as usual.
+ */
+ srcAddr = tempImage;
+ srcFormat = GL_RGBA;
+ srcType = GL_UNSIGNED_BYTE;
+ } else if (srcPacking->SwapBytes) {
+ /* We have to handle byte-swapping scenarios before calling
+ * _mesa_format_convert
+ */
+ GLint swapSize = _mesa_sizeof_packed_type(srcType);
+ if (swapSize == 2 || swapSize == 4) {
+ int imageStride = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, srcType);
+ int bufferSize = imageStride * srcDepth;
+ int layer;
+ const uint8_t *src;
+ uint8_t *dst;
+
+ tempImage = malloc(bufferSize);
+ if (!tempImage)
+ return GL_FALSE;
+ src = srcAddr;
+ dst = tempImage;
+ for (layer = 0; layer < srcDepth; layer++) {
+ _mesa_swap_bytes_2d_image(srcFormat, srcType,
+ srcPacking,
+ srcWidth, srcHeight,
+ dst, src);
+ src += imageStride;
+ dst += imageStride;
+ }
+ srcAddr = tempImage;
+ }
+ }
+
+ srcRowStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+
+ srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType);
+ dstFormat = _mesa_get_srgb_format_linear(dstFormat);
+
+ /* If we have transferOps then we need to convert to RGBA float first,
+ then apply transferOps, then do the conversion to dst
+ */
+ if (!transferOpsDone &&
+ _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
+ /* Allocate RGBA float image */
+ int elementCount = srcWidth * srcHeight * srcDepth;
+ tempRGBA = malloc(4 * elementCount * sizeof(float));
+ if (!tempRGBA) {
+ free(tempImage);
+ free(tempRGBA);
+ return GL_FALSE;
+ }
+
+ /* Convert from src to RGBA float */
+ src = (GLubyte *) srcAddr;
+ dst = (GLubyte *) tempRGBA;
+ for (img = 0; img < srcDepth; img++) {
+ _mesa_format_convert(dst, RGBA32_FLOAT, 4 * srcWidth * sizeof(float),
+ src, srcMesaFormat, srcRowStride,
+ srcWidth, srcHeight, NULL);
+ src += srcHeight * srcRowStride;
+ dst += srcHeight * 4 * srcWidth * sizeof(float);
+ }
+
+ /* Apply transferOps */
+ _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount,
+ (float(*)[4]) tempRGBA);
+
+ /* Now we have to adjust our src info for a conversion from
+ * the RGBA float image and then we continue as usual.
+ */
+ srcAddr = tempRGBA;
+ srcFormat = GL_RGBA;
+ srcType = GL_FLOAT;
+ srcRowStride = srcWidth * 4 * sizeof(float);
+ srcMesaFormat = RGBA32_FLOAT;
+ srcPacking = &ctx->DefaultPacking;
+ }
+
+ src = (GLubyte *)
+ _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
+ srcFormat, srcType, 0, 0, 0);
+
+ if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) {
+ needRebase =
+ _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat,
+ rebaseSwizzle);
+ } else {
+ needRebase = false;
+ }
+
+ for (img = 0; img < srcDepth; img++) {
+ _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride,
+ src, srcMesaFormat, srcRowStride,
+ srcWidth, srcHeight,
+ needRebase ? rebaseSwizzle : NULL);
+ src += srcHeight * srcRowStride;
+ }
+
+ free(tempImage);
+ free(tempRGBA);
+
+ return GL_TRUE;
+}
GLboolean
_mesa_texstore_needs_transfer_ops(struct gl_context *ctx,
/* The Mesa format must match the input format and type. */
if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
+ srcPacking->SwapBytes, NULL)) {
+ return GL_FALSE;
+ }
+
+ /* Depth texture data needs clamping in following cases:
+ * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0].
+ * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1].
+ *
+ * All the cases except one (float dstFormat with float srcType) are ruled
+ * out by _mesa_format_matches_format_and_type() check above. Handle the
+ * remaining case here.
+ */
+ if ((baseInternalFormat == GL_DEPTH_COMPONENT ||
+ baseInternalFormat == GL_DEPTH_STENCIL) &&
+ (srcType == GL_FLOAT ||
+ srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)) {
return GL_FALSE;
}
return GL_FALSE;
}
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
+ _mesa_memcpy_texture(ctx, dims,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
return GL_TRUE;
}
GLboolean
_mesa_texstore(TEXSTORE_PARAMS)
{
- StoreTexImageFunc storeImage;
- GLboolean success;
-
if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat,
dstFormat,
dstRowStride, dstSlices,
return GL_TRUE;
}
- storeImage = _mesa_get_texstore_func(dstFormat);
-
- success = storeImage(ctx, dims, baseInternalFormat,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- return success;
+ if (_mesa_is_depth_or_stencil_format(baseInternalFormat)) {
+ return texstore_depth_stencil(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
+ } else if (_mesa_is_format_compressed(dstFormat)) {
+ return texstore_compressed(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
+ } else {
+ return texstore_rgba(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
+ }
}
/* compute slice info (and do some sanity checks) */
switch (target) {
case GL_TEXTURE_2D:
+ case GL_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_EXTERNAL_OES:
srcImageStride = _mesa_image_row_stride(packing, width, format, type);
break;
case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
numSlices = depth;
sliceOffset = zoffset;
depth = 1;
format, type, pixels, packing, "glTexSubImage");
}
+static void
+clear_image_to_zero(GLubyte *dstMap, GLint dstRowStride,
+ GLsizei width, GLsizei height,
+ GLsizei clearValueSize)
+{
+ GLsizei y;
+
+ for (y = 0; y < height; y++) {
+ memset(dstMap, 0, clearValueSize * width);
+ dstMap += dstRowStride;
+ }
+}
+
+static void
+clear_image_to_value(GLubyte *dstMap, GLint dstRowStride,
+ GLsizei width, GLsizei height,
+ const GLvoid *clearValue,
+ GLsizei clearValueSize)
+{
+ GLsizei y, x;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ memcpy(dstMap, clearValue, clearValueSize);
+ dstMap += clearValueSize;
+ }
+ dstMap += dstRowStride - clearValueSize * width;
+ }
+}
+
+/*
+ * Fallback for Driver.ClearTexSubImage().
+ */
+void
+_mesa_store_cleartexsubimage(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ const GLvoid *clearValue)
+{
+ GLubyte *dstMap;
+ GLint dstRowStride;
+ GLsizeiptr clearValueSize;
+ GLsizei z;
+
+ clearValueSize = _mesa_get_format_bytes(texImage->TexFormat);
+
+ for (z = 0; z < depth; z++) {
+ ctx->Driver.MapTextureImage(ctx, texImage,
+ z + zoffset, xoffset, yoffset,
+ width, height,
+ GL_MAP_WRITE_BIT,
+ &dstMap, &dstRowStride);
+ if (dstMap == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearTex*Image");
+ return;
+ }
+
+ if (clearValue) {
+ clear_image_to_value(dstMap, dstRowStride,
+ width, height,
+ clearValue,
+ clearValueSize);
+ } else {
+ clear_image_to_zero(dstMap, dstRowStride,
+ width, height,
+ clearValueSize);
+ }
+
+ ctx->Driver.UnmapTextureImage(ctx, texImage, z + zoffset);
+ }
+}
/**
* Fallback for Driver.CompressedTexImage()
* have to worry about the usual image unpacking or image transfer
* operations.
*/
- ASSERT(texImage);
- ASSERT(texImage->Width > 0);
- ASSERT(texImage->Height > 0);
- ASSERT(texImage->Depth > 0);
+ assert(texImage);
+ assert(texImage->Width > 0);
+ assert(texImage->Height > 0);
+ assert(texImage->Depth > 0);
/* allocate storage for texture data */
if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
return;
}
- _mesa_store_compressed_texsubimage(ctx, dims, texImage,
- 0, 0, 0,
- texImage->Width, texImage->Height, texImage->Depth,
- texImage->TexFormat,
- imageSize, data);
+ ctx->Driver.CompressedTexSubImage(ctx, dims, texImage,
+ 0, 0, 0,
+ texImage->Width, texImage->Height, texImage->Depth,
+ texImage->TexFormat,
+ imageSize, data);
+}
+
+
+/**
+ * Compute compressed_pixelstore parameters for copying compressed
+ * texture data.
+ * \param dims number of texture image dimensions: 1, 2 or 3
+ * \param texFormat the compressed texture format
+ * \param width, height, depth size of image to copy
+ * \param packing pixelstore parameters describing user-space image packing
+ * \param store returns the compressed_pixelstore parameters
+ */
+void
+_mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat,
+ GLsizei width, GLsizei height,
+ GLsizei depth,
+ const struct gl_pixelstore_attrib *packing,
+ struct compressed_pixelstore *store)
+{
+ GLuint bw, bh, bd;
+
+ _mesa_get_format_block_size_3d(texFormat, &bw, &bh, &bd);
+
+ store->SkipBytes = 0;
+ store->TotalBytesPerRow = store->CopyBytesPerRow =
+ _mesa_format_row_stride(texFormat, width);
+ store->TotalRowsPerSlice = store->CopyRowsPerSlice =
+ (height + bh - 1) / bh;
+ store->CopySlices = (depth + bd - 1) / bd;
+
+ if (packing->CompressedBlockWidth &&
+ packing->CompressedBlockSize) {
+
+ bw = packing->CompressedBlockWidth;
+
+ if (packing->RowLength) {
+ store->TotalBytesPerRow = packing->CompressedBlockSize *
+ ((packing->RowLength + bw - 1) / bw);
+ }
+
+ store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw;
+ }
+
+ if (dims > 1 && packing->CompressedBlockHeight &&
+ packing->CompressedBlockSize) {
+
+ bh = packing->CompressedBlockHeight;
+
+ store->SkipBytes += packing->SkipRows * store->TotalBytesPerRow / bh;
+ store->CopyRowsPerSlice = (height + bh - 1) / bh; /* rows in blocks */
+
+ if (packing->ImageHeight) {
+ store->TotalRowsPerSlice = (packing->ImageHeight + bh - 1) / bh;
+ }
+ }
+
+ if (dims > 2 && packing->CompressedBlockDepth &&
+ packing->CompressedBlockSize) {
+
+ int bd = packing->CompressedBlockDepth;
+
+ store->SkipBytes += packing->SkipImages * store->TotalBytesPerRow *
+ store->TotalRowsPerSlice / bd;
+ }
}
GLenum format,
GLsizei imageSize, const GLvoid *data)
{
- GLint bytesPerRow, dstRowStride, srcRowStride;
- GLint i, rows;
+ struct compressed_pixelstore store;
+ GLint dstRowStride;
+ GLint i, slice;
GLubyte *dstMap;
const GLubyte *src;
- const mesa_format texFormat = texImage->TexFormat;
- GLuint bw, bh;
- GLint slice;
if (dims == 1) {
_mesa_problem(ctx, "Unexpected 1D compressed texsubimage call");
return;
}
- _mesa_get_format_block_size(texFormat, &bw, &bh);
+ _mesa_compute_compressed_pixelstore(dims, texImage->TexFormat,
+ width, height, depth,
+ &ctx->Unpack, &store);
/* get pointer to src pixels (may be in a pbo which we'll map here) */
data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data,
if (!data)
return;
- srcRowStride = _mesa_format_row_stride(texFormat, width);
- src = (const GLubyte *) data;
+ src = (const GLubyte *) data + store.SkipBytes;
- for (slice = 0; slice < depth; slice++) {
+ for (slice = 0; slice < store.CopySlices; slice++) {
/* Map dest texture buffer */
ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset,
xoffset, yoffset, width, height,
&dstMap, &dstRowStride);
if (dstMap) {
- bytesPerRow = srcRowStride; /* bytes per row of blocks */
- rows = (height + bh - 1) / bh; /* rows in blocks */
/* copy rows of blocks */
- for (i = 0; i < rows; i++) {
- memcpy(dstMap, src, bytesPerRow);
+ for (i = 0; i < store.CopyRowsPerSlice; i++) {
+ memcpy(dstMap, src, store.CopyBytesPerRow);
dstMap += dstRowStride;
- src += srcRowStride;
+ src += store.TotalBytesPerRow;
}
ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset);
+
+ /* advance to next slice */
+ src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",