*/
+#include "errors.h"
#include "glheader.h"
#include "bufferobj.h"
-#include "colormac.h"
#include "format_pack.h"
#include "format_utils.h"
#include "image.h"
#include "mtypes.h"
#include "pack.h"
#include "pbo.h"
-#include "imports.h"
+
#include "texcompress.h"
#include "texcompress_fxt1.h"
#include "texcompress_rgtc.h"
#include "enums.h"
#include "glformats.h"
#include "pixeltransfer.h"
-#include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
-#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
+#include "util/format_rgb9e5.h"
+#include "util/format_r11g11b10f.h"
enum {
- ZERO = 4,
+ ZERO = 4,
ONE = 5
};
* Texture image storage function.
*/
typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
-static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
-static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
-static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE };
/**
* No pixel transfer operations or special texel encodings allowed.
* 1D, 2D and 3D images supported.
*/
-static void
-memcpy_texture(struct gl_context *ctx,
- GLuint dimensions,
- mesa_format dstFormat,
- GLint dstRowStride,
- GLubyte **dstSlices,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
+void
+_mesa_memcpy_texture(struct gl_context *ctx,
+ GLuint dimensions,
+ mesa_format dstFormat,
+ GLint dstRowStride,
+ GLubyte **dstSlices,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking)
{
const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
srcFormat, srcType);
const GLuint depthScale = 0xffffffff;
GLenum dstType;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z_UNORM32 ||
+ assert(dstFormat == MESA_FORMAT_Z_UNORM32 ||
dstFormat == MESA_FORMAT_Z_FLOAT32);
- ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
+ assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
if (dstFormat == MESA_FORMAT_Z_UNORM32)
dstType = GL_UNSIGNED_INT;
const GLuint depthScale = 0xffffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
+ assert(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
{
/* general path */
const GLuint depthScale = 0xffffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
+ assert(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
{
/* general path */
{
const GLuint depthScale = 0xffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z_UNORM16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
+ assert(dstFormat == MESA_FORMAT_Z_UNORM16);
+ assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
{
/* general path */
static GLboolean
_mesa_texstore_ycbcr(TEXSTORE_PARAMS)
{
- const GLboolean littleEndian = _mesa_little_endian();
-
(void) ctx; (void) dims; (void) baseInternalFormat;
- ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
+ 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) ||
+ 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);
+ 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);
+ _mesa_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) {
+ !UTIL_ARCH_LITTLE_ENDIAN) {
GLint img, row;
for (img = 0; img < srcDepth; img++) {
GLubyte *dstRow = dstSlices[img];
GLuint *depth = malloc(srcWidth * sizeof(GLuint));
GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
- ASSERT(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
- ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
+ 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 ||
+ assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
srcType == GL_UNSIGNED_INT_24_8_EXT ||
srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
GLuint *depth;
GLubyte *stencil;
- ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
- ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
+ 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 ||
+ assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
srcType == GL_UNSIGNED_INT_24_8_EXT ||
srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
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);
+ = (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;
- }
+ GLint i;
+ GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
+
+ if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
+ keepstencil = GL_TRUE;
+ }
else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
- keepdepth = GL_TRUE;
- }
-
- if (keepdepth == GL_FALSE)
- /* the 24 depth bits will be in the low position: */
- _mesa_unpack_depth_span(ctx, srcWidth,
- GL_UNSIGNED_INT, /* dst type */
- keepstencil ? depth : dstRow, /* dst addr */
- depthScale,
- srcType, src, srcPacking);
-
- if (keepstencil == GL_FALSE)
- /* get the 8-bit stencil values */
- _mesa_unpack_stencil_span(ctx, srcWidth,
- GL_UNSIGNED_BYTE, /* dst type */
- stencil, /* dst addr */
- srcType, src, srcPacking,
- ctx->_ImageTransferState);
-
- /* merge stencil values into depth values */
- for (i = 0; i < srcWidth; i++) {
- if (keepstencil)
- dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
- else
- dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
-
- }
- src += srcRowStride;
- dstRow += dstRowStride / sizeof(GLuint);
+ keepdepth = GL_TRUE;
+ }
+
+ if (keepdepth == GL_FALSE)
+ /* the 24 depth bits will be in the low position: */
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_UNSIGNED_INT, /* dst type */
+ keepstencil ? depth : dstRow, /* dst addr */
+ depthScale,
+ srcType, src, srcPacking);
+
+ if (keepstencil == GL_FALSE)
+ /* get the 8-bit stencil values */
+ _mesa_unpack_stencil_span(ctx, srcWidth,
+ GL_UNSIGNED_BYTE, /* dst type */
+ stencil, /* dst addr */
+ srcType, src, srcPacking,
+ ctx->_ImageTransferState);
+
+ /* merge stencil values into depth values */
+ for (i = 0; i < srcWidth; i++) {
+ if (keepstencil)
+ dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
+ else
+ dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
+
+ }
+ src += srcRowStride;
+ dstRow += dstRowStride / sizeof(GLuint);
}
}
static GLboolean
_mesa_texstore_s8(TEXSTORE_PARAMS)
{
- ASSERT(dstFormat == MESA_FORMAT_S_UINT8);
- ASSERT(srcFormat == GL_STENCIL_INDEX);
+ assert(dstFormat == MESA_FORMAT_S_UINT8);
+ assert(srcFormat == GL_STENCIL_INDEX);
{
const GLint srcRowStride
- = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLint img, row;
GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
GLint img, row;
const GLint srcRowStride
= _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
- / sizeof(uint64_t);
+ / sizeof(int32_t);
- ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
- ASSERT(srcFormat == GL_DEPTH_STENCIL ||
+ assert(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
+ assert(srcFormat == GL_DEPTH_STENCIL ||
srcFormat == GL_DEPTH_COMPONENT ||
srcFormat == GL_STENCIL_INDEX);
- ASSERT(srcFormat != GL_DEPTH_STENCIL ||
+ assert(srcFormat != GL_DEPTH_STENCIL ||
srcType == GL_UNSIGNED_INT_24_8 ||
srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
/* 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,
+ const int32_t *src
+ = (const int32_t *) _mesa_image_address(dims, srcPacking, srcAddr,
srcWidth, srcHeight,
srcFormat, srcType,
img, 0, 0);
initialized = GL_TRUE;
}
- ASSERT(table[dstFormat]);
+ assert(table[dstFormat]);
return table[dstFormat](ctx, dims, baseInternalFormat,
dstFormat, dstRowStride, dstSlices,
srcWidth, srcHeight, srcDepth,
initialized = GL_TRUE;
}
- ASSERT(table[dstFormat]);
+ assert(table[dstFormat]);
return table[dstFormat](ctx, dims, baseInternalFormat,
dstFormat, dstRowStride, dstSlices,
srcWidth, srcHeight, srcDepth,
static GLboolean
texstore_rgba(TEXSTORE_PARAMS)
{
- void *tempImage = NULL, *tempRGBA = NULL;
- int srcRowStride, img;
+ void *tempImage = NULL;
+ int img;
GLubyte *src, *dst;
- uint32_t srcMesaFormat;
uint8_t rebaseSwizzle[4];
- bool needRebase;
bool transferOpsDone = false;
/* We have to handle MESA_FORMAT_YCBCR manually because it is a special case
*/
GLint swapSize = _mesa_sizeof_packed_type(srcType);
if (swapSize == 2 || swapSize == 4) {
- int components = _mesa_components_in_format(srcFormat);
- int elementCount = srcWidth * srcHeight * components;
- tempImage = malloc(elementCount * swapSize);
+ int imageStride = _mesa_image_image_stride(srcPacking, srcWidth,
+ srcHeight, srcFormat,
+ srcType);
+ int bufferSize = imageStride * srcDepth;
+ int layer;
+ const uint8_t *src;
+ uint8_t *dst;
+
+ tempImage = malloc(bufferSize);
if (!tempImage)
return GL_FALSE;
- if (swapSize == 2)
- _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, elementCount);
- else
- _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, elementCount);
+ src = srcAddr;
+ dst = tempImage;
+ for (layer = 0; layer < srcDepth; layer++) {
+ _mesa_swap_bytes_2d_image(srcFormat, srcType,
+ srcPacking,
+ srcWidth, srcHeight,
+ dst, src);
+ src += imageStride;
+ dst += imageStride;
+ }
srcAddr = tempImage;
}
}
- srcRowStride =
+ int srcRowStride =
_mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType);
+ uint32_t srcMesaFormat =
+ _mesa_format_from_format_and_type(srcFormat, srcType);
+
dstFormat = _mesa_get_srgb_format_linear(dstFormat);
/* If we have transferOps then we need to convert to RGBA float first,
then apply transferOps, then do the conversion to dst
*/
+ void *tempRGBA = NULL;
if (!transferOpsDone &&
_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
/* Allocate RGBA float image */
tempRGBA = malloc(4 * elementCount * sizeof(float));
if (!tempRGBA) {
free(tempImage);
- free(tempRGBA);
return GL_FALSE;
}
srcType = GL_FLOAT;
srcRowStride = srcWidth * 4 * sizeof(float);
srcMesaFormat = RGBA32_FLOAT;
+ srcPacking = &ctx->DefaultPacking;
}
src = (GLubyte *)
_mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
srcFormat, srcType, 0, 0, 0);
+ bool needRebase;
if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) {
needRebase =
_mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat,
/* The Mesa format must match the input format and type. */
if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
+ srcPacking->SwapBytes, NULL)) {
return GL_FALSE;
}
return GL_FALSE;
}
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
+ _mesa_memcpy_texture(ctx, dims,
+ dstFormat,
+ dstRowStride, dstSlices,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
return GL_TRUE;
}
+
+
/**
* Store user data into texture memory.
* Called via glTex[Sub]Image1/2/3D()
/* compute slice info (and do some sanity checks) */
switch (target) {
case GL_TEXTURE_2D:
+ case GL_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_EXTERNAL_OES:
srcImageStride = _mesa_image_row_stride(packing, width, format, type);
break;
case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
numSlices = depth;
sliceOffset = zoffset;
depth = 1;
format, type);
break;
default:
- _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
+ _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()",
+ target);
return;
}
* have to worry about the usual image unpacking or image transfer
* operations.
*/
- ASSERT(texImage);
- ASSERT(texImage->Width > 0);
- ASSERT(texImage->Height > 0);
- ASSERT(texImage->Depth > 0);
+ assert(texImage);
+ assert(texImage->Width > 0);
+ assert(texImage->Height > 0);
+ assert(texImage->Depth > 0);
/* allocate storage for texture data */
if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
return;
}
- _mesa_store_compressed_texsubimage(ctx, dims, texImage,
- 0, 0, 0,
- texImage->Width, texImage->Height, texImage->Depth,
- texImage->TexFormat,
- imageSize, data);
+ ctx->Driver.CompressedTexSubImage(ctx, dims, texImage,
+ 0, 0, 0,
+ texImage->Width, texImage->Height, texImage->Depth,
+ texImage->TexFormat,
+ imageSize, data);
}
const struct gl_pixelstore_attrib *packing,
struct compressed_pixelstore *store)
{
- GLuint bw, bh;
+ GLuint bw, bh, bd;
- _mesa_get_format_block_size(texFormat, &bw, &bh);
+ _mesa_get_format_block_size_3d(texFormat, &bw, &bh, &bd);
store->SkipBytes = 0;
store->TotalBytesPerRow = store->CopyBytesPerRow =
_mesa_format_row_stride(texFormat, width);
store->TotalRowsPerSlice = store->CopyRowsPerSlice =
(height + bh - 1) / bh;
- store->CopySlices = depth;
+ store->CopySlices = (depth + bd - 1) / bd;
if (packing->CompressedBlockWidth &&
packing->CompressedBlockSize) {
((packing->RowLength + bw - 1) / bw);
}
- store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw;
+ store->SkipBytes +=
+ packing->SkipPixels * packing->CompressedBlockSize / bw;
}
if (dims > 1 && packing->CompressedBlockHeight &&
if (dstMap) {
/* copy rows of blocks */
- for (i = 0; i < store.CopyRowsPerSlice; i++) {
- memcpy(dstMap, src, store.CopyBytesPerRow);
- dstMap += dstRowStride;
- src += store.TotalBytesPerRow;
+ if (dstRowStride == store.TotalBytesPerRow &&
+ dstRowStride == store.CopyBytesPerRow) {
+ memcpy(dstMap, src, store.CopyBytesPerRow * store.CopyRowsPerSlice);
+ src += store.CopyBytesPerRow * store.CopyRowsPerSlice;
+ }
+ else {
+ for (i = 0; i < store.CopyRowsPerSlice; i++) {
+ memcpy(dstMap, src, store.CopyBytesPerRow);
+ dstMap += dstRowStride;
+ src += store.TotalBytesPerRow;
+ }
}
ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset);
/* advance to next slice */
- src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);
+ src += store.TotalBytesPerRow * (store.TotalRowsPerSlice
+ - store.CopyRowsPerSlice);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",