/*
* Mesa 3-D graphics library
- * Version: 7.5
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (c) 2008-2009 VMware, Inc.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/*
#include "bufferobj.h"
#include "colormac.h"
#include "format_pack.h"
+#include "format_utils.h"
#include "image.h"
#include "macros.h"
#include "mipmap.h"
-#include "mfeatures.h"
#include "mtypes.h"
#include "pack.h"
#include "pbo.h"
typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
-/**
- * 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,
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;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_INTEGER_EXT:
+ return IDX_LUMINANCE;
+ case GL_ALPHA:
+ case GL_ALPHA_INTEGER:
+ return IDX_ALPHA;
+ case GL_INTENSITY:
+ return IDX_INTENSITY;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+ return IDX_LUMINANCE_ALPHA;
+ case GL_RGB:
+ case GL_RGB_INTEGER:
+ return IDX_RGB;
+ case GL_RGBA:
+ case GL_RGBA_INTEGER:
+ return IDX_RGBA;
+ case GL_RED:
+ case GL_RED_INTEGER:
+ return IDX_RED;
+ case GL_GREEN:
+ return IDX_GREEN;
+ case GL_BLUE:
+ return IDX_BLUE;
+ case GL_BGR:
+ case GL_BGR_INTEGER:
+ return IDX_BGR;
+ case GL_BGRA:
+ case GL_BGRA_INTEGER:
+ return IDX_BGRA;
+ case GL_ABGR_EXT:
+ return IDX_ABGR;
+ case GL_RG:
+ case GL_RG_INTEGER:
+ return IDX_RG;
default:
- _mesa_problem(NULL, "Unexpected inFormat");
+ _mesa_problem(NULL, "Unexpected inFormat %s",
+ _mesa_lookup_enum_by_nr(value));
return 0;
}
}
}
-/**
- * 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;
- }
- }
-}
+static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE };
/**
static void
memcpy_texture(struct gl_context *ctx,
GLuint dimensions,
- gl_format dstFormat,
+ mesa_format dstFormat,
GLint dstRowStride,
GLubyte **dstSlices,
GLint srcWidth, GLint srcHeight, GLint srcDepth,
if (!tempImage)
return GL_FALSE;
+ /* This way we will use the RGB versions of the packing functions and it
+ * will work for both RGB and sRGB textures*/
+ dstFormat = _mesa_get_srgb_format_linear(dstFormat);
+
src = tempImage;
for (img = 0; img < srcDepth; img++) {
_mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
const GLuint depthScale = 0xffffffff;
GLenum dstType;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z32 ||
- dstFormat == MESA_FORMAT_Z32_FLOAT);
+ ASSERT(dstFormat == MESA_FORMAT_Z_UNORM32 ||
+ dstFormat == MESA_FORMAT_Z_FLOAT32);
ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
- if (dstFormat == MESA_FORMAT_Z32)
+ if (dstFormat == MESA_FORMAT_Z_UNORM32)
dstType = GL_UNSIGNED_INT;
else
dstType = GL_FLOAT;
- if (ctx->Pixel.DepthScale == 1.0f &&
- ctx->Pixel.DepthBias == 0.0f &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_DEPTH_COMPONENT &&
- srcFormat == GL_DEPTH_COMPONENT &&
- srcType == dstType) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
+ {
/* general path */
GLint img, row;
for (img = 0; img < srcDepth; img++) {
const GLuint depthScale = 0xffffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
+ ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
{
/* general path */
const GLuint depthScale = 0xffffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
+ ASSERT(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
{
/* general path */
{
const GLuint depthScale = 0xffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z16);
+ ASSERT(dstFormat == MESA_FORMAT_Z_UNORM16);
ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
- if (ctx->Pixel.DepthScale == 1.0f &&
- ctx->Pixel.DepthBias == 0.0f &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_DEPTH_COMPONENT &&
- srcFormat == GL_DEPTH_COMPONENT &&
- srcType == GL_UNSIGNED_SHORT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
+ {
/* general path */
GLint img, row;
for (img = 0; img < srcDepth; img++) {
static GLboolean
_mesa_texstore_rgb565(TEXSTORE_PARAMS)
{
- ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
- dstFormat == MESA_FORMAT_RGB565_REV);
+ 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 &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_RGB &&
- srcFormat == GL_RGB &&
- srcType == GL_UNSIGNED_BYTE &&
- dims == 2) {
+ 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 *srcUB = (const GLubyte *) src;
GLushort *dstUS = (GLushort *) dst;
/* check for byteswapped format */
- if (dstFormat == MESA_FORMAT_RGB565) {
+ 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;
dst += dstRowStride;
src += srcRowStride;
}
+ return GL_TRUE;
+ } else {
+ return GL_FALSE;
}
- 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_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
+ * 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_RGBA8888 ||
- dstFormat == MESA_FORMAT_RGBA8888_REV ||
- dstFormat == MESA_FORMAT_RGBX8888 ||
- dstFormat == MESA_FORMAT_RGBX8888_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
+ (void) ctx; (void) dims; (void) baseInternalFormat;
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else 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)) {
+ 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);
- GLubyte dstmap[4];
+ /* always just memcpy since no pixel transfer ops apply */
+ memcpy_texture(ctx, dims,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 ||
- dstFormat == MESA_FORMAT_RGBX8888)) ||
- (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV ||
- dstFormat == MESA_FORMAT_RGBX8888_REV))) {
- 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;
+ /* 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;
+ }
}
-
- _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_argb8888(TEXSTORE_PARAMS)
+_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
{
- const GLboolean littleEndian = _mesa_little_endian();
+ 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_ARGB8888 ||
- dstFormat == MESA_FORMAT_ARGB8888_REV ||
- dstFormat == MESA_FORMAT_XRGB8888 ||
- dstFormat == MESA_FORMAT_XRGB8888_REV );
- ASSERT(_mesa_get_format_bytes(dstFormat) == 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);
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path (big endian) */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- (dstFormat == MESA_FORMAT_ARGB8888 ||
- dstFormat == MESA_FORMAT_XRGB8888) &&
- 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;
- }
- }
+ if (!depth || !stencil) {
+ free(depth);
+ free(stencil);
+ return GL_FALSE;
}
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_ARGB8888 &&
- srcFormat == GL_LUMINANCE_ALPHA &&
- baseInternalFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_BYTE) {
- /* special case of storing LA -> ARGB8888 */
- int img, row, col;
- const GLint srcRowStride =
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- for (img = 0; img < srcDepth; img++) {
- const GLubyte *srcRow = (const GLubyte *)
- _mesa_image_address(dims, srcPacking, srcAddr, srcWidth,
- srcHeight, srcFormat, srcType, img, 0, 0);
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *d4 = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1];
- d4[col] = PACK_COLOR_8888(a, l, l, l);
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
+
+ /* 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 (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_ARGB8888 &&
- 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.
- */
- 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]);
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
+ else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
+ keepdepth = GL_TRUE;
}
- }
- }
- 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];
+ 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);
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
- (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
- (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
- (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
- dstmap[3] = 3; /* alpha */
- dstmap[2] = 0; /* red */
- dstmap[1] = 1; /* green */
- dstmap[0] = 2; /* blue */
- }
- else {
- assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
- (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
- (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
- (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
- 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;
-}
-
-
-static GLboolean
-_mesa_texstore_rgb888(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_RGB888);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGB &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else 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)) {
-
- GLubyte dstmap[4];
-
- /* 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);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_bgr888(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_BGR888);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGB &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else 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;
- }
- }
- }
- 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;
-}
-
-
-static GLboolean
-_mesa_texstore_argb4444(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
- dstFormat == MESA_FORMAT_ARGB4444_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-static GLboolean
-_mesa_texstore_rgba5551(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-static GLboolean
-_mesa_texstore_argb1555(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
- dstFormat == MESA_FORMAT_ARGB1555_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_argb2101010(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_ARGB2101010);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const 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];
- if (baseInternalFormat == GL_RGBA) {
- 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 if (baseInternalFormat == GL_RGB) {
- for (row = 0; row < srcHeight; row++) {
- GLuint *dstUI = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort r,g,b;
-
- 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(0xffff, r, g, b);
- src += 4;
- }
- dstRow += dstRowStride;
- }
- } else {
- ASSERT(0);
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
- */
-static GLboolean
-_mesa_texstore_unorm44(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_AL44);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
-
- {
- /* 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;
-}
-
-
-/**
- * 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_AL88 ||
- dstFormat == MESA_FORMAT_AL88_REV ||
- dstFormat == MESA_FORMAT_GR88 ||
- dstFormat == MESA_FORMAT_RG88);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- ((dstFormat == MESA_FORMAT_AL88 &&
- baseInternalFormat == GL_LUMINANCE_ALPHA &&
- srcFormat == GL_LUMINANCE_ALPHA) ||
- (dstFormat == MESA_FORMAT_GR88 &&
- baseInternalFormat == srcFormat)) &&
- srcType == GL_UNSIGNED_BYTE &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else 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_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
- if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
- (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
- dstmap[0] = 0;
- dstmap[1] = 3;
- }
- else {
- dstmap[0] = 3;
- dstmap[1] = 0;
- }
- }
- else {
- if ((littleEndian && dstFormat == MESA_FORMAT_GR88) ||
- (!littleEndian && dstFormat == MESA_FORMAT_RG88)) {
- dstmap[0] = 0;
- dstmap[1] = 1;
- }
- else {
- dstmap[0] = 1;
- dstmap[1] = 0;
- }
- }
- 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_AL88 ||
- dstFormat == MESA_FORMAT_GR88) {
- 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 GLboolean littleEndian = _mesa_little_endian();
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
- dstFormat == MESA_FORMAT_AL1616_REV ||
- dstFormat == MESA_FORMAT_RG1616 ||
- dstFormat == MESA_FORMAT_RG1616_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- ((dstFormat == MESA_FORMAT_AL1616 &&
- baseInternalFormat == GL_LUMINANCE_ALPHA &&
- srcFormat == GL_LUMINANCE_ALPHA) ||
- (dstFormat == MESA_FORMAT_RG1616 &&
- baseInternalFormat == srcFormat)) &&
- srcType == GL_UNSIGNED_SHORT &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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_AL1616 ||
- dstFormat == MESA_FORMAT_RG1616) {
- 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 GLboolean littleEndian = _mesa_little_endian();
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R16 ||
- dstFormat == MESA_FORMAT_A16 ||
- dstFormat == MESA_FORMAT_L16 ||
- dstFormat == MESA_FORMAT_I16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_UNSIGNED_SHORT &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_RGBA_16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 8);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_RGBA &&
- srcFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_SHORT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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, 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_SIGNED_RGB_16 ||
- dstFormat == MESA_FORMAT_SIGNED_RGBA_16);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_RGBA &&
- dstFormat == MESA_FORMAT_SIGNED_RGBA_16 &&
- srcFormat == GL_RGBA &&
- srcType == GL_SHORT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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_SIGNED_RGBA_16) {
- 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 {
- 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;
-}
-
-
-static GLboolean
-_mesa_texstore_rgb332(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_RGB332);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGB &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- 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_A8 ||
- dstFormat == MESA_FORMAT_L8 ||
- dstFormat == MESA_FORMAT_I8 ||
- dstFormat == MESA_FORMAT_R8);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_UNSIGNED_BYTE) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- 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:
- */
- if (dstFormat == MESA_FORMAT_A8) {
- 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 (!srcPacking->SwapBytes && srcType == GL_BYTE &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else 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_SIGNED_A8 ||
- dstFormat == MESA_FORMAT_SIGNED_L8 ||
- dstFormat == MESA_FORMAT_SIGNED_I8 ||
- dstFormat == MESA_FORMAT_SIGNED_R8);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_BYTE) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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 GLboolean littleEndian = _mesa_little_endian();
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 ||
- dstFormat == MESA_FORMAT_SIGNED_RG88_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_BYTE &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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++) {
- GLbyte *dst = dstRow;
- for (col = 0; col < srcWidth; col++) {
- dst[0] = FLOAT_TO_BYTE_TEX(src[0]);
- dst[1] = FLOAT_TO_BYTE_TEX(src[1]);
- src += 2;
- dst += 2;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-/* Texstore for signed R16, A16, L16, I16. */
-static GLboolean
-_mesa_texstore_snorm16(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_SIGNED_R16 ||
- dstFormat == MESA_FORMAT_SIGNED_A16 ||
- dstFormat == MESA_FORMAT_SIGNED_L16 ||
- dstFormat == MESA_FORMAT_SIGNED_I16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_SHORT &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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 GLboolean littleEndian = _mesa_little_endian();
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 ||
- dstFormat == MESA_FORMAT_SIGNED_GR1616);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_SHORT &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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 *dst = (GLshort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort l, a;
-
- UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
- UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
- dst[0] = l;
- dst[1] = a;
- src += 2;
- dst += 2;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-/**
- * Store a texture in MESA_FORMAT_SIGNED_RGBX8888.
- */
-static GLboolean
-_mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888);
- 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;
- 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;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-
-/**
- * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or
- * MESA_FORMAT_SIGNED_RGBA8888_REV
- */
-static GLboolean
-_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
- dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
- 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);
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const 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_SIGNED_RGBA8888) {
- 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;
+ 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);
- }
- 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;
-
- ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
- 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);
-
- if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f &&
- ctx->Pixel.DepthBias == 0.0f &&
- !srcPacking->SwapBytes) {
- /* simple path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
}
- else if (srcFormat == GL_DEPTH_COMPONENT ||
- srcFormat == GL_STENCIL_INDEX) {
- GLuint *depth = malloc(srcWidth * sizeof(GLuint));
- GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
-
- if (!depth || !stencil) {
- free(depth);
- free(stencil);
- return GL_FALSE;
- }
- /* In case we only upload depth we need to preserve the stencil */
- for (img = 0; img < srcDepth; img++) {
- GLuint *dstRow = (GLuint *) dstSlices[img];
- 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);
- }
+ free(depth);
+ free(stencil);
return GL_TRUE;
}
GLuint *depth;
GLubyte *stencil;
- ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
+ 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_UNSIGNED_INT_24_8_EXT ||
+ srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
depth = malloc(srcWidth * sizeof(GLuint));
stencil = malloc(srcWidth * sizeof(GLubyte));
static GLboolean
_mesa_texstore_s8(TEXSTORE_PARAMS)
{
- ASSERT(dstFormat == MESA_FORMAT_S8);
+ ASSERT(dstFormat == MESA_FORMAT_S_UINT8);
ASSERT(srcFormat == GL_STENCIL_INDEX);
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_UNSIGNED_BYTE) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
+ {
const GLint srcRowStride
= _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLint img, row;
}
-/**
- * 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)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- const GLint components = _mesa_components_in_format(baseFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
- dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
- dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
- dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
- dstFormat == MESA_FORMAT_INTENSITY_FLOAT32 ||
- dstFormat == MESA_FORMAT_R_FLOAT32 ||
- dstFormat == MESA_FORMAT_RG_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));
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- baseInternalFormat == baseFormat &&
- srcType == GL_FLOAT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- const GLint components = _mesa_components_in_format(baseFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
- dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
- dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
- dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
- dstFormat == MESA_FORMAT_INTENSITY_FLOAT16 ||
- dstFormat == MESA_FORMAT_R_FLOAT16 ||
- dstFormat == MESA_FORMAT_RG_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));
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- baseInternalFormat == baseFormat &&
- srcType == GL_HALF_FLOAT_ARB) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* 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)
+_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- const GLint components = _mesa_components_in_format(baseFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R_INT8 ||
- dstFormat == MESA_FORMAT_RG_INT8 ||
- dstFormat == MESA_FORMAT_RGB_INT8 ||
- dstFormat == MESA_FORMAT_RGBA_INT8 ||
- dstFormat == MESA_FORMAT_ALPHA_INT8 ||
- dstFormat == MESA_FORMAT_INTENSITY_INT8 ||
- dstFormat == MESA_FORMAT_LUMINANCE_INT8 ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8);
- 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));
-
- /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
- * to integer formats.
- */
- if (!srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_BYTE) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLuint *tempImage = make_temp_uint_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr,
- srcPacking);
- const GLuint *src = tempImage;
- GLint img, row;
- 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;
-}
-
+ GLint img, row;
+ const GLint srcRowStride
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
+ / sizeof(uint64_t);
-/* non-normalized, signed int16 */
-static GLboolean
-_mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- const GLint components = _mesa_components_in_format(baseFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R_INT16 ||
- dstFormat == MESA_FORMAT_RG_INT16 ||
- dstFormat == MESA_FORMAT_RGB_INT16 ||
- dstFormat == MESA_FORMAT_RGBA_INT16 ||
- dstFormat == MESA_FORMAT_ALPHA_INT16 ||
- dstFormat == MESA_FORMAT_LUMINANCE_INT16 ||
- dstFormat == MESA_FORMAT_INTENSITY_INT16 ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16);
- 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));
-
- /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
- * to integer formats.
- */
- if (!srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_SHORT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLuint *tempImage = make_temp_uint_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr,
- srcPacking);
- const GLuint *src = tempImage;
- GLint img, row;
- 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;
- }
- }
+ 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 ||
+ srcType == GL_UNSIGNED_INT_24_8 ||
+ srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
+ /* In case we only upload depth we need to preserve the stencil */
+ for (img = 0; img < srcDepth; img++) {
+ uint64_t *dstRow = (uint64_t *) dstSlices[img];
+ const uint64_t *src
+ = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
+ for (row = 0; row < srcHeight; row++) {
+ /* The unpack functions with:
+ * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
+ * only write their own dword, so the other dword (stencil
+ * or depth) is preserved. */
+ if (srcFormat != GL_STENCIL_INDEX)
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
+ dstRow, /* dst addr */
+ ~0U, srcType, src, srcPacking);
+ if (srcFormat != GL_DEPTH_COMPONENT)
+ _mesa_unpack_stencil_span(ctx, srcWidth,
+ GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
+ dstRow, /* dst addr */
+ srcType, src, srcPacking,
+ ctx->_ImageTransferState);
-/* non-normalized, signed int32 */
-static GLboolean
-_mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- const GLint components = _mesa_components_in_format(baseFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R_INT32 ||
- dstFormat == MESA_FORMAT_RG_INT32 ||
- dstFormat == MESA_FORMAT_RGB_INT32 ||
- dstFormat == MESA_FORMAT_RGBA_INT32 ||
- dstFormat == MESA_FORMAT_ALPHA_INT32 ||
- dstFormat == MESA_FORMAT_INTENSITY_INT32 ||
- dstFormat == MESA_FORMAT_LUMINANCE_INT32 ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32);
- 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));
-
- /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
- * to integer formats.
- */
- if (!srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_INT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLuint *tempImage = make_temp_uint_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr,
- srcPacking);
- const GLuint *src = tempImage;
- GLint img, row;
- 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;
- }
+ src += srcRowStride;
+ dstRow += dstRowStride / sizeof(uint64_t);
}
-
- free((void *) tempImage);
}
return GL_TRUE;
}
-
-/* non-normalized, unsigned int8 */
static GLboolean
-_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
+_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
{
const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- const GLint components = _mesa_components_in_format(baseFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
- dstFormat == MESA_FORMAT_RG_UINT8 ||
- dstFormat == MESA_FORMAT_RGB_UINT8 ||
- dstFormat == MESA_FORMAT_RGBA_UINT8 ||
- dstFormat == MESA_FORMAT_ALPHA_UINT8 ||
- dstFormat == MESA_FORMAT_INTENSITY_UINT8 ||
- dstFormat == MESA_FORMAT_LUMINANCE_UINT8 ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_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));
-
- /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
- * to integer formats.
- */
- if (!srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_UNSIGNED_BYTE) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
+
+ 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 *tempImage = make_temp_uint_image(ctx, dims,
+ baseInternalFormat,
+ baseFormat,
+ srcWidth, srcHeight,
+ srcDepth, srcFormat,
+ srcType, srcAddr,
+ srcPacking);
const GLuint *src = tempImage;
- GLint img, row;
+ 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++) {
- GLubyte *dstTexel = (GLubyte *) dstRow;
- GLint i;
+ GLuint *dstUI = (GLuint *) dstRow;
if (is_unsigned) {
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = (GLubyte) MIN2(src[i], 0xff);
+ 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 (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff);
+ 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;
- src += srcWidth * components;
}
}
-
free((void *) tempImage);
}
return GL_TRUE;
}
-
-/* non-normalized, unsigned int16 */
static GLboolean
-_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
+_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
{
const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- const GLint components = _mesa_components_in_format(baseFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
- dstFormat == MESA_FORMAT_RG_UINT16 ||
- dstFormat == MESA_FORMAT_RGB_UINT16 ||
- dstFormat == MESA_FORMAT_RGBA_UINT16 ||
- dstFormat == MESA_FORMAT_ALPHA_UINT16 ||
- dstFormat == MESA_FORMAT_INTENSITY_UINT16 ||
- dstFormat == MESA_FORMAT_LUMINANCE_UINT16 ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_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));
-
- /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
- * to integer formats.
- */
- if (!srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_UNSIGNED_SHORT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLuint *tempImage =
- make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- const GLuint *src = tempImage;
- GLint img, row;
- 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;
-}
+ ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT);
+ ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-/* non-normalized, unsigned int32 */
-static GLboolean
-_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- const GLint components = _mesa_components_in_format(baseFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
- dstFormat == MESA_FORMAT_RG_UINT32 ||
- dstFormat == MESA_FORMAT_RGB_UINT32 ||
- dstFormat == MESA_FORMAT_RGBA_UINT32 ||
- dstFormat == MESA_FORMAT_ALPHA_UINT32 ||
- dstFormat == MESA_FORMAT_INTENSITY_UINT32 ||
- dstFormat == MESA_FORMAT_LUMINANCE_UINT32 ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_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));
-
- /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
- * to integer formats.
- */
- if (!srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_UNSIGNED_INT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
+ {
/* general path */
- const GLuint *tempImage =
- make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
+ const GLuint *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);
- 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;
+ GLuint *dstUI = (GLuint *) dstRow;
if (is_unsigned) {
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = src[i];
+ 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 (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = MAX2((GLint) src[i], 0);
+ 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;
- src += srcWidth * components;
}
}
-
free((void *) tempImage);
}
return GL_TRUE;
static GLboolean
-_mesa_texstore_srgb8(TEXSTORE_PARAMS)
+texstore_depth_stencil(TEXSTORE_PARAMS)
{
- gl_format newDstFormat;
- GLboolean k;
-
- ASSERT(dstFormat == MESA_FORMAT_SRGB8);
-
- /* reuse normal rgb texstore code */
- newDstFormat = MESA_FORMAT_RGB888;
+ static StoreTexImageFunc table[MESA_FORMAT_COUNT];
+ static GLboolean initialized = GL_FALSE;
- k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
-}
+ if (!initialized) {
+ memset(table, 0, sizeof table);
+
+ 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;
+ initialized = GL_TRUE;
+ }
-static GLboolean
-_mesa_texstore_srgba8(TEXSTORE_PARAMS)
-{
- gl_format newDstFormat;
- GLboolean k;
-
- ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
-
- /* reuse normal rgba texstore code */
- newDstFormat = MESA_FORMAT_RGBA8888;
- k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
+ ASSERT(table[dstFormat]);
+ return table[dstFormat](ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
-
static GLboolean
-_mesa_texstore_sargb8(TEXSTORE_PARAMS)
+texstore_compressed(TEXSTORE_PARAMS)
{
- gl_format newDstFormat;
- GLboolean k;
-
- ASSERT(dstFormat == MESA_FORMAT_SARGB8);
-
- /* reuse normal rgba texstore code */
- newDstFormat = MESA_FORMAT_ARGB8888;
-
- k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
-}
-
+ static StoreTexImageFunc table[MESA_FORMAT_COUNT];
+ static GLboolean initialized = GL_FALSE;
-static GLboolean
-_mesa_texstore_sl8(TEXSTORE_PARAMS)
-{
- gl_format newDstFormat;
- GLboolean k;
+ if (!initialized) {
+ memset(table, 0, sizeof table);
- ASSERT(dstFormat == MESA_FORMAT_SL8);
+ 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_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
+ table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
+ table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
+ table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
+ 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_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;
+ table[MESA_FORMAT_RG_RGTC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
+ table[MESA_FORMAT_L_LATC1_UNORM] = _mesa_texstore_red_rgtc1;
+ table[MESA_FORMAT_L_LATC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
+ table[MESA_FORMAT_LA_LATC2_UNORM] = _mesa_texstore_rg_rgtc2;
+ table[MESA_FORMAT_LA_LATC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
+ table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
+ table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8;
+ table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8;
+ table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac;
+ table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac;
+ table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac;
+ table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac;
+ table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac;
+ table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac;
+ table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
+ _mesa_texstore_etc2_rgb8_punchthrough_alpha1;
+ table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
+ _mesa_texstore_etc2_srgb8_punchthrough_alpha1;
- newDstFormat = MESA_FORMAT_L8;
+ initialized = GL_TRUE;
+ }
- /* _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;
+ ASSERT(table[dstFormat]);
+ return table[dstFormat](ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
}
-
-static GLboolean
-_mesa_texstore_sla8(TEXSTORE_PARAMS)
+static void
+invert_swizzle(uint8_t dst[4], const uint8_t src[4])
{
- gl_format newDstFormat;
- GLboolean k;
+ int i, j;
- ASSERT(dstFormat == MESA_FORMAT_SLA8);
+ dst[0] = MESA_FORMAT_SWIZZLE_NONE;
+ dst[1] = MESA_FORMAT_SWIZZLE_NONE;
+ dst[2] = MESA_FORMAT_SWIZZLE_NONE;
+ dst[3] = MESA_FORMAT_SWIZZLE_NONE;
- /* reuse normal luminance/alpha texstore code */
- newDstFormat = MESA_FORMAT_AL88;
-
- k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
- newDstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType,
- srcAddr, srcPacking);
- return k;
+ for (i = 0; i < 4; ++i)
+ for (j = 0; j < 4; ++j)
+ if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE)
+ dst[i] = j;
}
+/** Store a texture by per-channel conversions and swizzling.
+ *
+ * This function attempts to perform a texstore operation by doing simple
+ * per-channel conversions and swizzling. This covers a huge chunk of the
+ * texture storage operations that anyone cares about. If this function is
+ * incapable of performing the operation, it bails and returns GL_FALSE.
+ */
static GLboolean
-_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
+texstore_swizzle(TEXSTORE_PARAMS)
{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT);
- ASSERT(baseInternalFormat == GL_RGB);
-
- if (!ctx->_ImageTransferState &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const 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_rgb9e5(&srcRow[col * 3]);
- }
- dstRow += dstRowStride;
- srcRow += srcWidth * 3;
- }
- }
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
+ srcFormat, srcType);
+ const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
+ srcWidth, srcHeight, srcFormat, srcType);
+ const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dims,
+ srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+ const int src_components = _mesa_components_in_format(srcFormat);
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
+ GLubyte swizzle[4], rgba2base[6], base2src[6], rgba2dst[4], dst2rgba[4];
+ const GLubyte *swap;
+ GLenum dst_type;
+ int dst_components;
+ bool is_array, normalized, need_swap;
+ GLint i, img, row;
+ const GLubyte *src_row;
+ GLubyte *dst_row;
-static GLboolean
-_mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+ is_array = _mesa_format_to_array(dstFormat, &dst_type, &dst_components,
+ rgba2dst, &normalized);
- ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT);
- ASSERT(baseInternalFormat == GL_RGB);
+ if (!is_array)
+ return GL_FALSE;
- if (!ctx->_ImageTransferState &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const 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)
+ switch (srcType) {
+ case GL_FLOAT:
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ /* If wa have to swap bytes in a multi-byte datatype, that means
+ * we're not doing an array conversion anymore */
+ if (srcPacking->SwapBytes)
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;
- }
- }
-
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8);
- ASSERT(srcFormat == GL_DEPTH_STENCIL ||
- srcFormat == GL_DEPTH_COMPONENT ||
- srcFormat == GL_STENCIL_INDEX);
- ASSERT(srcFormat != GL_DEPTH_STENCIL ||
- srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
-
- if (srcFormat == GL_DEPTH_STENCIL &&
- ctx->Pixel.DepthScale == 1.0f &&
- ctx->Pixel.DepthBias == 0.0f &&
- !srcPacking->SwapBytes) {
- /* simple path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
+ need_swap = false;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ need_swap = srcPacking->SwapBytes;
+ if (_mesa_little_endian())
+ need_swap = !need_swap;
+ srcType = GL_UNSIGNED_BYTE;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ need_swap = srcPacking->SwapBytes;
+ if (!_mesa_little_endian())
+ need_swap = !need_swap;
+ srcType = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ return GL_FALSE;
}
- else if (srcFormat == GL_DEPTH_COMPONENT ||
- srcFormat == GL_STENCIL_INDEX) {
- GLint img, row;
- const GLint srcRowStride
- = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
- / sizeof(uint64_t);
+ swap = need_swap ? map_3210 : map_identity;
- /* In case we only upload depth we need to preserve the stencil */
- for (img = 0; img < srcDepth; img++) {
- uint64_t *dstRow = (uint64_t *) dstSlices[img];
- const uint64_t *src
- = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- img, 0, 0);
- for (row = 0; row < srcHeight; row++) {
- /* The unpack functions with:
- * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
- * only write their own dword, so the other dword (stencil
- * or depth) is preserved. */
- if (srcFormat != GL_STENCIL_INDEX)
- _mesa_unpack_depth_span(ctx, srcWidth,
- GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
- dstRow, /* dst addr */
- ~0U, srcType, src, srcPacking);
-
- if (srcFormat != GL_DEPTH_COMPONENT)
- _mesa_unpack_stencil_span(ctx, srcWidth,
- GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
- dstRow, /* dst addr */
- srcType, src, srcPacking,
- ctx->_ImageTransferState);
+ compute_component_mapping(srcFormat, baseInternalFormat, base2src);
+ compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
+ invert_swizzle(dst2rgba, rgba2dst);
- src += srcRowStride;
- dstRow += dstRowStride / sizeof(uint64_t);
- }
- }
+ for (i = 0; i < 4; i++) {
+ if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)
+ swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;
+ else
+ swizzle[i] = swap[base2src[rgba2base[dst2rgba[i]]]];
}
- return GL_TRUE;
-}
-
-static GLboolean
-_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
- ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLuint *tempImage = make_temp_uint_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight,
- srcDepth, srcFormat,
- srcType, srcAddr,
- srcPacking);
- const GLuint *src = tempImage;
- GLint img, row, col;
- GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
+ /* Is it normalized? */
+ normalized |= !_mesa_is_enum_format_integer(srcFormat);
+ for (img = 0; img < srcDepth; img++) {
+ if (dstRowStride == srcWidth * dst_components &&
+ srcRowStride == srcWidth * src_components) {
+ _mesa_swizzle_and_convert(dstSlices[img], dst_type, dst_components,
+ srcImage, srcType, src_components,
+ swizzle, normalized, srcWidth * srcHeight);
+ } else {
+ src_row = srcImage;
+ dst_row = 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;
+ _mesa_swizzle_and_convert(dst_row, dst_type, dst_components,
+ src_row, srcType, src_components,
+ swizzle, normalized, srcWidth);
+ dst_row += dstRowStride;
+ src_row += srcRowStride;
}
}
- free((void *) tempImage);
+ srcImage += srcImageStride;
}
+
return GL_TRUE;
}
+
+/** Stores a texture by converting float and then to the texture format
+ *
+ * This function performs a texstore operation by converting to float,
+ * applying pixel transfer ops, and then converting to the texture's
+ * internal format using pixel store functions. This function will work
+ * for any rgb or srgb textore format.
+ */
static GLboolean
-_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
+texstore_via_float(TEXSTORE_PARAMS)
{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+ GLuint i, img, row;
+ const GLint src_stride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+ float *tmp_row;
+ bool need_convert;
+ uint8_t *src_row, *dst_row, map[4], rgba2base[6], base2rgba[6];
- ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
+ tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row));
+ if (!tmp_row)
+ return GL_FALSE;
+
+ /* The GL spec (4.0, compatibility profile) only specifies srgb
+ * conversion as something that is done in the sampler during the
+ * filtering process before the colors are handed to the shader.
+ * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec)
+ * does not list RGB <-> sRGB conversions anywhere. Therefore, we just
+ * treat sRGB formats the same as RGB formats for the purposes of
+ * texture upload and transfer ops.
+ */
+ dstFormat = _mesa_get_srgb_format_linear(dstFormat);
- if (baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
+ need_convert = false;
+ if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {
+ compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba);
+ compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
+ for (i = 0; i < 4; ++i) {
+ map[i] = base2rgba[rgba2base[i]];
+ if (map[i] != i)
+ need_convert = true;
+ }
}
- else {
- /* general path */
- const GLuint *tempImage = make_temp_uint_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight,
- srcDepth, srcFormat,
- srcType, srcAddr,
- srcPacking);
- const GLuint *src = tempImage;
- GLint img, row, col;
- GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *dstUI = (GLuint *) dstRow;
- if (is_unsigned) {
- for (col = 0; col < srcWidth; col++) {
- GLushort a,r,g,b;
- r = MIN2(src[RCOMP], 0x3ff);
- g = MIN2(src[GCOMP], 0x3ff);
- b = MIN2(src[BCOMP], 0x3ff);
- a = MIN2(src[ACOMP], 0x003);
- dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
- src += 4;
- }
- } else {
- for (col = 0; col < srcWidth; col++) {
- GLushort a,r,g,b;
- r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
- g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
- b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
- a = CLAMP((GLint) src[ACOMP], 0, 0x003);
- dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
- src += 4;
- }
- }
- dstRow += dstRowStride;
- }
+ for (img = 0; img < srcDepth; img++) {
+ dst_row = dstSlices[img];
+ src_row = _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, GL_RGBA, tmp_row,
+ srcFormat, srcType, src_row,
+ srcPacking, ctx->_ImageTransferState);
+ if (need_convert)
+ _mesa_swizzle_and_convert(tmp_row, GL_FLOAT, 4,
+ tmp_row, GL_FLOAT, 4,
+ map, false, srcWidth);
+ _mesa_pack_float_rgba_row(dstFormat, srcWidth,
+ (const GLfloat (*)[4])tmp_row,
+ dst_row);
+ dst_row += dstRowStride;
+ src_row += src_stride;
}
- free((void *) tempImage);
}
+
return GL_TRUE;
}
+/** Stores an integer rgba texture
+ *
+ * This function performs an integer texture storage operation by unpacking
+ * the texture to 32-bit integers, and repacking it into the internal
+ * format of the texture. This will work for any integer rgb texture
+ * storage operation.
+ */
static GLboolean
-_mesa_texstore_null(TEXSTORE_PARAMS)
+texstore_rgba_integer(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;
-}
+ GLuint i, img, row, *tmp_row;
+ GLenum dst_type, tmp_type;
+ const GLint src_stride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+ int num_dst_components;
+ bool is_array, normalized;
+ uint8_t *src_row, *dst_row;
+ uint8_t swizzle[4], rgba2base[6], base2rgba[6], rgba2dst[4], dst2rgba[4];
+ tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row));
+ if (!tmp_row)
+ return GL_FALSE;
-/**
- * Return the StoreTexImageFunc pointer to store an image in the given format.
- */
-static StoreTexImageFunc
-_mesa_get_texstore_func(gl_format format)
+ is_array = _mesa_format_to_array(dstFormat, &dst_type, &num_dst_components,
+ rgba2dst, &normalized);
+
+ assert(is_array && !normalized);
+
+ if (!is_array)
+ return GL_FALSE;
+
+ invert_swizzle(dst2rgba, rgba2dst);
+ compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba);
+ compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
+
+ for (i = 0; i < 4; ++i) {
+ if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)
+ swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;
+ else
+ swizzle[i] = base2rgba[rgba2base[dst2rgba[i]]];
+ }
+
+ if (_mesa_is_type_unsigned(srcType)) {
+ tmp_type = GL_UNSIGNED_INT;
+ } else {
+ tmp_type = GL_INT;
+ }
+
+ for (img = 0; img < srcDepth; img++) {
+ dst_row = dstSlices[img];
+ src_row = _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, GL_RGBA, tmp_row,
+ srcFormat, srcType, src_row, srcPacking);
+ _mesa_swizzle_and_convert(dst_row, dst_type, num_dst_components,
+ tmp_row, tmp_type, 4,
+ swizzle, false, srcWidth);
+ dst_row += dstRowStride;
+ src_row += src_stride;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean
+texstore_rgba(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_RGBA8888] = _mesa_texstore_rgba8888;
- table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888;
- table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888;
- table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888;
- table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888;
- table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888;
- table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888;
- table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888;
- table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888;
- table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888;
- table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565;
- table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565;
- table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444;
- table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444;
- table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551;
- table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555;
- table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555;
- table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44;
- table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88;
- table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88;
- table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616;
- table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616;
- table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332;
- table[MESA_FORMAT_A8] = _mesa_texstore_unorm8;
- table[MESA_FORMAT_A16] = _mesa_texstore_unorm16;
- table[MESA_FORMAT_L8] = _mesa_texstore_unorm8;
- table[MESA_FORMAT_L16] = _mesa_texstore_unorm16;
- table[MESA_FORMAT_I8] = _mesa_texstore_unorm8;
- table[MESA_FORMAT_I16] = _mesa_texstore_unorm16;
+ memset(table, 0, sizeof table);
+
+ table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565;
+ table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565;
table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
- table[MESA_FORMAT_R8] = _mesa_texstore_unorm8;
- table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88;
- table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88;
- table[MESA_FORMAT_R16] = _mesa_texstore_unorm16;
- table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616;
- table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616;
- table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010;
- table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8;
- table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24;
- table[MESA_FORMAT_Z16] = _mesa_texstore_z16;
- table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24;
- table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8;
- table[MESA_FORMAT_Z32] = _mesa_texstore_z32;
- table[MESA_FORMAT_S8] = _mesa_texstore_s8;
- table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8;
- table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8;
- table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8;
- table[MESA_FORMAT_SL8] = _mesa_texstore_sl8;
- table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8;
- 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_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
- table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
- table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
- table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
- 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_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
- table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32;
- table[MESA_FORMAT_INTENSITY_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_SIGNED_R8] = _mesa_texstore_snorm8;
- table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88;
- table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888;
- table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888;
- table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888;
- table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16;
- table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616;
- table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16;
- table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16;
- table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16;
- table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1;
- table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1;
- table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2;
- table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2;
- table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1;
- table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1;
- table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
- table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
- table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
- table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8;
- table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8;
- table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac;
- /* table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac; -- not implemented yet */
- /* table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac; -- not implemented yet */
- /* table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac; -- not implemented yet */
- /* table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac; -- not implemented yet */
- /* table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac; -- not implemented yet */
- /* table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
- _mesa_texstore_etc2_rgb8_punchthrough_alpha1; -- not implemented yet */
- /* table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
- _mesa_texstore_etc2_srgb8_punchthrough_alpha1; -- not implemented yet */
- table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
- table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
- table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
- table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8;
- table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16;
- table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16;
- table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616;
- table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16;
- table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5;
- table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
- table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32;
- table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8;
-
- table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
- table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
- table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
- table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32;
-
- table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8;
- table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16;
- table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32;
- table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32;
- table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32;
- table[MESA_FORMAT_RGBA_INT32] = _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_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
- table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint;
+
+ table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint;
+ table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint;
+
initialized = GL_TRUE;
}
- ASSERT(table[format]);
- return table[format];
+ if (table[dstFormat] && table[dstFormat](ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking)) {
+ return GL_TRUE;
+ }
+
+ if (texstore_swizzle(ctx, dims, baseInternalFormat,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking)) {
+ return GL_TRUE;
+ }
+
+ if (_mesa_is_format_integer(dstFormat)) {
+ return texstore_rgba_integer(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ } else if (_mesa_get_format_max_bits(dstFormat) <= 8 &&
+ !_mesa_is_format_signed(dstFormat)) {
+ return store_ubyte_texture(ctx, dims, baseInternalFormat,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking);
+ } else {
+ return texstore_via_float(ctx, dims, baseInternalFormat,
+ dstFormat, dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ }
+}
+
+GLboolean
+_mesa_texstore_needs_transfer_ops(struct gl_context *ctx,
+ GLenum baseInternalFormat,
+ mesa_format dstFormat)
+{
+ GLenum dstType;
+
+ /* There are different rules depending on the base format. */
+ switch (baseInternalFormat) {
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL:
+ return ctx->Pixel.DepthScale != 1.0f ||
+ ctx->Pixel.DepthBias != 0.0f;
+
+ case GL_STENCIL_INDEX:
+ return GL_FALSE;
+
+ default:
+ /* Color formats.
+ * Pixel transfer ops (scale, bias, table lookup) do not apply
+ * to integer formats.
+ */
+ dstType = _mesa_get_format_datatype(dstFormat);
+
+ return dstType != GL_INT && dstType != GL_UNSIGNED_INT &&
+ ctx->_ImageTransferState;
+ }
+}
+
+
+GLboolean
+_mesa_texstore_can_use_memcpy(struct gl_context *ctx,
+ GLenum baseInternalFormat, mesa_format dstFormat,
+ GLenum srcFormat, GLenum srcType,
+ const struct gl_pixelstore_attrib *srcPacking)
+{
+ if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
+ return GL_FALSE;
+ }
+
+ /* The base internal format and the base Mesa format must match. */
+ if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {
+ return GL_FALSE;
+ }
+
+ /* The Mesa format must match the input format and type. */
+ if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
+ srcPacking->SwapBytes)) {
+ 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_TRUE;
}
+static GLboolean
+_mesa_texstore_memcpy(TEXSTORE_PARAMS)
+{
+ if (!_mesa_texstore_can_use_memcpy(ctx, baseInternalFormat, dstFormat,
+ srcFormat, srcType, srcPacking)) {
+ return GL_FALSE;
+ }
+ memcpy_texture(ctx, dims,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ return GL_TRUE;
+}
/**
* Store user data into texture memory.
* Called via glTex[Sub]Image1/2/3D()
+ * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
*/
GLboolean
_mesa_texstore(TEXSTORE_PARAMS)
{
- StoreTexImageFunc storeImage;
- GLboolean success;
-
- storeImage = _mesa_get_texstore_func(dstFormat);
+ if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr, srcPacking)) {
+ return GL_TRUE;
+ }
- 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);
+ }
}
* \param texFormat the destination texture format
*/
static GLbitfield
-get_read_write_mode(GLenum userFormat, gl_format texFormat)
+get_read_write_mode(GLenum userFormat, mesa_format texFormat)
{
if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
&& _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_EXTERNAL_OES:
/* one image slice, nothing special needs to be done */
break;
case GL_TEXTURE_1D:
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()
struct gl_texture_image *texImage,
GLsizei imageSize, const GLvoid *data)
{
- /* only 2D compressed images are supported at this time */
- if (dims != 2) {
- _mesa_problem(ctx, "Unexpected glCompressedTexImage1D/3D call");
+ /* only 2D and 3D compressed images are supported at this time */
+ if (dims == 1) {
+ _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call");
return;
}
ASSERT(texImage);
ASSERT(texImage->Width > 0);
ASSERT(texImage->Height > 0);
- ASSERT(texImage->Depth == 1);
+ ASSERT(texImage->Depth > 0);
/* allocate storage for texture data */
if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims);
return;
}
}
+void
+_mesa_compute_compressed_pixelstore(GLuint dims, struct gl_texture_image *texImage,
+ GLsizei width, GLsizei height, GLsizei depth,
+ const struct gl_pixelstore_attrib *packing,
+ struct compressed_pixelstore *store)
+{
+ GLuint bw, bh;
+ const mesa_format texFormat = texImage->TexFormat;
+
+ _mesa_get_format_block_size(texFormat, &bw, &bh);
+
+ store->SkipBytes = 0;
+ store->TotalBytesPerRow = store->CopyBytesPerRow =
+ _mesa_format_row_stride(texFormat, width);
+ store->TotalRowsPerSlice = store->CopyRowsPerSlice =
+ (height + bh - 1) / bh;
+ store->CopySlices = depth;
+
+ 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;
+ }
+}
+
+
/**
* Fallback for Driver.CompressedTexSubImage()
*/
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 gl_format texFormat = texImage->TexFormat;
- GLuint bw, bh;
- if (dims != 2) {
- _mesa_problem(ctx, "Unexpected 1D/3D compressed texsubimage call");
+ 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, 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, imageSize, data,
+ data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data,
&ctx->Unpack,
- "glCompressedTexSubImage2D");
+ "glCompressedTexSubImage");
if (!data)
return;
- srcRowStride = _mesa_format_row_stride(texFormat, width);
- src = (const GLubyte *) data;
+ src = (const GLubyte *) data + store.SkipBytes;
- /* Map dest texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, 0,
- xoffset, yoffset, width, height,
- GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
- &dstMap, &dstRowStride);
+ for (slice = 0; slice < store.CopySlices; slice++) {
+ /* Map dest texture buffer */
+ ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset,
+ xoffset, yoffset, width, height,
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
+ &dstMap, &dstRowStride);
- if (dstMap) {
- bytesPerRow = srcRowStride; /* bytes per row of blocks */
- rows = (height + bh - 1) / bh; /* rows in blocks */
+ if (dstMap) {
- /* copy rows of blocks */
- for (i = 0; i < rows; i++) {
- memcpy(dstMap, src, bytesPerRow);
- dstMap += dstRowStride;
- src += srcRowStride;
- }
+ /* copy rows of blocks */
+ for (i = 0; i < store.CopyRowsPerSlice; i++) {
+ memcpy(dstMap, src, store.CopyBytesPerRow);
+ dstMap += dstRowStride;
+ src += store.TotalBytesPerRow;
+ }
- ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
- }
- else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
+ 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",
+ dims);
+ }
}
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);