return;
}
- if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
- depth = height;
- height = 1;
- }
-
- assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint srcRowStride;
assert(type == GL_UNSIGNED_INT_24_8 ||
type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
- assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
{
GLint img, row;
- assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
}
}
+/**
+ * Depending on the base format involved we may need to apply a rebase
+ * transform (for example: if we download to a Luminance format we want
+ * G=0 and B=0).
+ */
+static bool
+teximage_needs_rebase(mesa_format texFormat, GLenum baseFormat,
+ bool is_compressed, uint8_t *rebaseSwizzle)
+{
+ bool needsRebase = false;
+
+ if (baseFormat == GL_LUMINANCE ||
+ baseFormat == GL_INTENSITY) {
+ needsRebase = true;
+ rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X;
+ rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
+ rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
+ rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_ONE;
+ } else if (baseFormat == GL_LUMINANCE_ALPHA) {
+ needsRebase = true;
+ rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X;
+ rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
+ rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
+ rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_W;
+ } else if (!is_compressed &&
+ (baseFormat != _mesa_get_format_base_format(texFormat))) {
+ needsRebase =
+ _mesa_compute_rgba2base2rgba_component_mapping(baseFormat,
+ rebaseSwizzle);
+ }
+
+ return needsRebase;
+}
+
/**
* Get a color texture image with decompression.
uint8_t rebaseSwizzle[4];
/* Decompress into temp float buffer, then pack into user buffer */
- tempImage = malloc(width * height * depth
- * 4 * sizeof(GLfloat));
+ tempImage = malloc(width * height * depth * 4 * sizeof(GLfloat));
if (!tempImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
return;
}
}
- /* Depending on the base format involved we may need to apply a rebase
- * transform (for example: if we download to a Luminance format we want
- * G=0 and B=0).
- */
- if (baseFormat == GL_LUMINANCE ||
- baseFormat == GL_INTENSITY) {
- needsRebase = true;
- rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X;
- rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
- rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
- rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_ONE;
- } else if (baseFormat == GL_LUMINANCE_ALPHA) {
- needsRebase = true;
- rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X;
- rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
- rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
- rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_W;
- } else {
- needsRebase = false;
- }
+ needsRebase = teximage_needs_rebase(texFormat, baseFormat, true,
+ rebaseSwizzle);
srcStride = 4 * width * sizeof(GLfloat);
dstStride = _mesa_image_row_stride(&ctx->Pack, width, format, type);
tempSlice, RGBA32_FLOAT, srcStride,
width, height,
needsRebase ? rebaseSwizzle : NULL);
+
+ /* Handle byte swapping if required */
+ if (ctx->Pack.SwapBytes) {
+ _mesa_swap_bytes_2d_image(format, type, &ctx->Pack,
+ width, height, dest, dest);
+ }
+
tempSlice += 4 * width * height;
}
bool needsRebase;
void *rgba = NULL;
- if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
- depth = height;
- height = 1;
- zoffset = yoffset;
- yoffset = 0;
- }
-
- /* Depending on the base format involved we may need to apply a rebase
- * transform (for example: if we download to a Luminance format we want
- * G=0 and B=0).
- */
- if (texImage->_BaseFormat == GL_LUMINANCE ||
- texImage->_BaseFormat == GL_INTENSITY) {
- needsRebase = true;
- rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X;
- rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
- rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
- rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_ONE;
- } else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
- needsRebase = true;
- rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X;
- rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
- rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
- rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_W;
- } else if (texImage->_BaseFormat !=
- _mesa_get_format_base_format(texFormat)) {
- needsRebase =
- _mesa_compute_rgba2base2rgba_component_mapping(texImage->_BaseFormat,
- rebaseSwizzle);
- } else {
- needsRebase = false;
- }
+ needsRebase = teximage_needs_rebase(texFormat, texImage->_BaseFormat, false,
+ rebaseSwizzle);
/* Describe the dst format */
dst_is_integer = _mesa_is_enum_format_integer(format);
*/
if (format == rgba_format) {
rgba = dest;
- } else if (rgba == NULL) { /* Allocate the RGBA buffer only once */
+ } else {
need_convert = true;
- rgba = malloc(height * rgba_stride);
- if (!rgba) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
- ctx->Driver.UnmapTextureImage(ctx, texImage, img);
- return;
+ if (rgba == NULL) { /* Allocate the RGBA buffer only once */
+ rgba = malloc(height * rgba_stride);
+ if (!rgba) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
+ ctx->Driver.UnmapTextureImage(ctx, texImage, img);
+ return;
+ }
}
}
do_swap:
/* Handle byte swapping if required */
- if (ctx->Pack.SwapBytes) {
- GLint swapSize = _mesa_sizeof_packed_type(type);
- if (swapSize == 2 || swapSize == 4) {
- int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize;
- assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0);
- if (swapSize == 2)
- _mesa_swap2((GLushort *) dest, width * height * swapsPerPixel);
- else if (swapSize == 4)
- _mesa_swap4((GLuint *) dest, width * height * swapsPerPixel);
- }
- }
+ if (ctx->Pack.SwapBytes)
+ _mesa_swap_bytes_2d_image(format, type, &ctx->Pack,
+ width, height, dest, dest);
/* Unmap the src texture buffer */
ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img);
}
done:
- if (rgba)
- free(rgba);
+ free(rgba);
}
texBaseFormat == texImage->_BaseFormat) {
memCopy = _mesa_format_matches_format_and_type(texImage->TexFormat,
format, type,
- ctx->Pack.SwapBytes);
+ ctx->Pack.SwapBytes, NULL);
}
if (depth > 1) {
if (src) {
if (bytesPerRow == dstRowStride && bytesPerRow == srcRowStride) {
- memcpy(dst, src, bytesPerRow * texImage->Height);
+ memcpy(dst, src, bytesPerRow * height);
}
else {
GLuint row;
pixels = ADD_POINTERS(buf, pixels);
}
+ /* for all array textures, the Z axis selects the layer */
+ if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
+ depth = height;
+ height = 1;
+ zoffset = yoffset;
+ yoffset = 0;
+ assert(zoffset + depth <= texImage->Height);
+ } else {
+ assert(zoffset + depth <= texImage->Depth);
+ }
+
if (get_tex_memcpy(ctx, xoffset, yoffset, zoffset, width, height, depth,
format, type, pixels, texImage)) {
/* all done */
* the targets from table 8.19 (for GetTexImage and GetnTexImage *only*),
* or TEXTURE_CUBE_MAP (for GetTextureImage *only*)." (Emphasis added.)
*/
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
return dsa ? GL_FALSE : ctx->Extensions.ARB_texture_cube_map;
case GL_TEXTURE_CUBE_MAP:
return dsa ? GL_TRUE : GL_FALSE;
/**
* Wrapper for _mesa_select_tex_image() which can handle target being
- * GL_TEXTURE_CUBE_MAP_ARB in which case we use zoffset to select a cube face.
+ * GL_TEXTURE_CUBE_MAP in which case we use zoffset to select a cube face.
* This can happen for glGetTextureImage and glGetTextureSubImage (DSA
* functions).
*/
const struct gl_texture_image *texImage;
int i;
- if (width == 0 || height == 0 || depth == 0) {
- /* Not an error, but nothing to do. Return 'true' so that the
- * caller simply returns.
- */
- return true;
- }
-
if (xoffset < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset = %d)", caller, xoffset);
return true;
"%s(1D, yoffset = %d)", caller, yoffset);
return true;
}
- if (height != 1) {
+ if (height > 1) {
_mesa_error(ctx, GL_INVALID_VALUE,
"%s(1D, height = %d)", caller, height);
return true;
"%s(zoffset = %d)", caller, zoffset);
return true;
}
- if (depth != 1) {
+ if (depth > 1) {
_mesa_error(ctx, GL_INVALID_VALUE,
"%s(depth = %d)", caller, depth);
return true;
/* Extra checks for compressed textures */
{
- GLuint bw, bh;
- _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
- if (bw > 1 || bh > 1) {
+ GLuint bw, bh, bd;
+ _mesa_get_format_block_size_3d(texImage->TexFormat, &bw, &bh, &bd);
+ if (bw > 1 || bh > 1 || bd > 1) {
/* offset must be multiple of block size */
if (xoffset % bw != 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
}
}
- /* The size must be a multiple of bw x bh, or we must be using a
+ if (zoffset % bd != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(zoffset = %d)", caller, zoffset);
+ return true;
+ }
+
+ /* The size must be a multiple of bw x bh x bd, or we must be using a
* offset+size that exactly hits the edge of the image.
*/
if ((width % bw != 0) &&
"%s(height = %d)", caller, height);
return true;
}
+
+ if ((depth % bd != 0) &&
+ (zoffset + depth != (GLint) texImage->Depth)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(depth = %d)", caller, depth);
+ return true;
+ }
}
}
+ if (width == 0 || height == 0 || depth == 0) {
+ /* Not an error, but nothing to do. Return 'true' so that the
+ * caller simply returns.
+ */
+ return true;
+ }
+
return false;
}
"%s(format=GL_STENCIL_INDEX)", caller);
return true;
}
+ else if (_mesa_is_stencil_format(format)
+ && !_mesa_is_depthstencil_format(baseFormat)
+ && !_mesa_is_stencil_format(baseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(format mismatch)", caller);
+ return true;
+ }
else if (_mesa_is_ycbcr_format(format)
&& !_mesa_is_ycbcr_format(baseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
return;
}
+ if (!legal_getteximage_target(ctx, texObj->Target, true)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s", caller);
+ return;
+ }
+
get_texture_image_dims(texObj, texObj->Target, level,
&width, &height, &depth);
return;
}
+ if (!legal_getteximage_target(ctx, texObj->Target, true)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(buffer/multisample texture)", caller);
+ return;
+ }
+
if (getteximage_error_check(ctx, texObj, texObj->Target, level,
xoffset, yoffset, zoffset, width, height, depth,
format, type, bufSize, pixels, caller)) {
{
GET_CURRENT_CONTEXT(ctx);
static const char *caller = "glGetCompressedTextureImage";
- struct gl_texture_object *texObj;
+ struct gl_texture_object *texObj = NULL;
texObj = _mesa_lookup_texture_err(ctx, texture, caller);
if (!texObj) {