1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version: 7.7 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (c) 2009 VMware, Inc. 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Code for glGetTexImage() and glGetCompressedTexImage(). 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glheader.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "bufferobj.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "enums.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "context.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "formats.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "format_unpack.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glformats.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "image.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "mfeatures.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "mtypes.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pack.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pbo.h" 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "texcompress.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "texgetimage.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "teximage.h" 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Can the given type represent negative values? 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLboolean 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtype_needs_clamping(GLenum type) 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (type) { 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_BYTE: 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_SHORT: 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_INT: 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FLOAT: 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_HALF_FLOAT_ARB: 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_UNSIGNED_INT_10F_11F_11F_REV: 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_UNSIGNED_INT_5_9_9_9_REV: 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glGetTexImage for depth/Z pixels. 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_tex_depth(struct gl_context *ctx, GLuint dimensions, 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum format, GLenum type, GLvoid *pixels, 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage) 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint width = texImage->Width; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint height = texImage->Height; 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint depth = texImage->Depth; 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint img, row; 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat *depthRow = (GLfloat *) malloc(width * sizeof(GLfloat)); 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!depthRow) { 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (img = 0; img < depth; img++) { 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *srcMap; 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint srcRowStride; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map src texture buffer */ 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapTextureImage(ctx, texImage, img, 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, width, height, GL_MAP_READ_BIT, 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &srcMap, &srcRowStride); 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcMap) { 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < height; row++) { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, height, format, type, 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org img, row, 0); 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte *src = srcMap + row * srcRowStride; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_unpack_float_z_row(texImage->TexFormat, width, src, depthRow); 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack); 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapTextureImage(ctx, texImage, img); 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(depthRow); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glGetTexImage for depth/stencil pixels. 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions, 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum format, GLenum type, GLvoid *pixels, 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage) 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint width = texImage->Width; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint height = texImage->Height; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint depth = texImage->Depth; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint img, row; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (img = 0; img < depth; img++) { 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *srcMap; 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint rowstride; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map src texture buffer */ 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapTextureImage(ctx, texImage, img, 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, width, height, GL_MAP_READ_BIT, 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &srcMap, &rowstride); 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcMap) { 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < height; row++) { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte *src = srcMap + row * rowstride; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, height, format, type, 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org img, row, 0); 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX Z24_S8 vs. S8_Z24??? */ 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(dest, src, width * sizeof(GLuint)); 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Pack.SwapBytes) { 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_swap4((GLuint *) dest, width); 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapTextureImage(ctx, texImage, img); 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glGetTexImage for YCbCr pixels. 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_tex_ycbcr(struct gl_context *ctx, GLuint dimensions, 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum format, GLenum type, GLvoid *pixels, 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage) 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint width = texImage->Width; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint height = texImage->Height; 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint depth = texImage->Depth; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint img, row; 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (img = 0; img < depth; img++) { 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *srcMap; 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint rowstride; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map src texture buffer */ 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapTextureImage(ctx, texImage, img, 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, width, height, GL_MAP_READ_BIT, 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &srcMap, &rowstride); 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcMap) { 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < height; row++) { 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte *src = srcMap + row * rowstride; 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, height, format, type, 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org img, row, 0); 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(dest, src, width * sizeof(GLushort)); 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* check for byte swapping */ 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((texImage->TexFormat == MESA_FORMAT_YCBCR 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) || 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (texImage->TexFormat == MESA_FORMAT_YCBCR_REV 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && type == GL_UNSIGNED_SHORT_8_8_MESA)) { 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ctx->Pack.SwapBytes) 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_swap2((GLushort *) dest, width); 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (ctx->Pack.SwapBytes) { 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_swap2((GLushort *) dest, width); 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapTextureImage(ctx, texImage, img); 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get a color texture image with decompression. 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions, 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum format, GLenum type, GLvoid *pixels, 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage, 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield transferOps) 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* don't want to apply sRGB -> RGB conversion here so override the format */ 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const gl_format texFormat = 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_get_srgb_format_linear(texImage->TexFormat); 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLenum baseFormat = _mesa_get_format_base_format(texFormat); 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLenum destBaseFormat = _mesa_base_tex_format(ctx, format); 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum rebaseFormat = GL_NONE; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint width = texImage->Width; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint height = texImage->Height; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint depth = texImage->Depth; 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat *tempImage, *srcRow; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint row; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Decompress into temp float buffer, then pack into user buffer */ 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tempImage = (GLfloat *) malloc(width * height * depth 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4 * sizeof(GLfloat)); 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!tempImage) { 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Decompress the texture image - results in 'tempImage' */ 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *srcMap; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint srcRowStride; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapTextureImage(ctx, texImage, 0, 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, width, height, 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_READ_BIT, 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &srcMap, &srcRowStride); 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcMap) { 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_decompress_image(texFormat, width, height, 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcMap, srcRowStride, tempImage); 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapTextureImage(ctx, texImage, 0); 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(tempImage); 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (baseFormat == GL_LUMINANCE || 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org baseFormat == GL_INTENSITY || 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org baseFormat == GL_LUMINANCE_ALPHA) { 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If a luminance (or intensity) texture is read back as RGB(A), the 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * returned value should be (L,0,0,1), not (L,L,L,1). Set rebaseFormat 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * here to get G=B=0. 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rebaseFormat = texImage->_BaseFormat; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((baseFormat == GL_RGBA || 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org baseFormat == GL_RGB || 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org baseFormat == GL_RG) && 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (destBaseFormat == GL_LUMINANCE || 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destBaseFormat == GL_LUMINANCE_ALPHA || 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destBaseFormat == GL_LUMINANCE_INTEGER_EXT || 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT)) { 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If we're reading back an RGB(A) texture as luminance then we need 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to return L=tex(R). Note, that's different from glReadPixels which 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * returns L=R+G+B. 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */ 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rebaseFormat) { 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_rebase_rgba_float(width * height, (GLfloat (*)[4]) tempImage, 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rebaseFormat); 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRow = tempImage; 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < height; row++) { 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, height, format, type, 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, row, 0); 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) srcRow, 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format, type, dest, &ctx->Pack, transferOps); 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRow += width * 4; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(tempImage); 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get an uncompressed color texture image. 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum format, GLenum type, GLvoid *pixels, 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage, 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield transferOps) 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* don't want to apply sRGB -> RGB conversion here so override the format */ 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const gl_format texFormat = 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_get_srgb_format_linear(texImage->TexFormat); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint width = texImage->Width; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLenum destBaseFormat = _mesa_base_tex_format(ctx, format); 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum rebaseFormat = GL_NONE; 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint height = texImage->Height; 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint depth = texImage->Depth; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint img, row; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat (*rgba)[4]; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint (*rgba_uint)[4]; 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLboolean tex_is_integer = _mesa_is_format_integer_color(texImage->TexFormat); 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLboolean tex_is_uint = _mesa_is_format_unsigned(texImage->TexFormat); 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Allocate buffer for one row of texels */ 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rgba = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat)); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rgba_uint = (GLuint (*)[4]) rgba; 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!rgba) { 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org depth = height; 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org height = 1; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (texImage->_BaseFormat == GL_LUMINANCE || 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->_BaseFormat == GL_INTENSITY || 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->_BaseFormat == GL_LUMINANCE_ALPHA) { 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If a luminance (or intensity) texture is read back as RGB(A), the 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * returned value should be (L,0,0,1), not (L,L,L,1). Set rebaseFormat 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * here to get G=B=0. 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rebaseFormat = texImage->_BaseFormat; 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((texImage->_BaseFormat == GL_RGBA || 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->_BaseFormat == GL_RGB || 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->_BaseFormat == GL_RG) && 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (destBaseFormat == GL_LUMINANCE || 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destBaseFormat == GL_LUMINANCE_ALPHA || 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destBaseFormat == GL_LUMINANCE_INTEGER_EXT || 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT)) { 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If we're reading back an RGB(A) texture as luminance then we need 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to return L=tex(R). Note, that's different from glReadPixels which 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * returns L=R+G+B. 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */ 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (img = 0; img < depth; img++) { 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *srcMap; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint rowstride; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map src texture buffer */ 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapTextureImage(ctx, texImage, img, 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, width, height, GL_MAP_READ_BIT, 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &srcMap, &rowstride); 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcMap) { 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < height; row++) { 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLubyte *src = srcMap + row * rowstride; 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, height, format, type, 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org img, row, 0); 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex_is_integer) { 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_unpack_uint_rgba_row(texFormat, width, src, rgba_uint); 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rebaseFormat) 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_rebase_rgba_uint(width, rgba_uint, rebaseFormat); 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex_is_uint) { 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_pack_rgba_span_from_uints(ctx, width, 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (GLuint (*)[4]) rgba_uint, 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format, type, dest); 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_pack_rgba_span_from_ints(ctx, width, 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (GLint (*)[4]) rgba_uint, 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format, type, dest); 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_unpack_rgba_row(texFormat, width, src, rgba); 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rebaseFormat) 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_rebase_rgba_float(width, rgba, rebaseFormat); 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format, type, dest, 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ctx->Pack, transferOps); 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Unmap the src texture buffer */ 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapTextureImage(ctx, texImage, img); 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(rgba); 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glGetTexImage for color formats (RGBA, RGB, alpha, LA, etc). 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compressed textures are handled here as well. 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_tex_rgba(struct gl_context *ctx, GLuint dimensions, 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum format, GLenum type, GLvoid *pixels, 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage) 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat); 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield transferOps = 0x0; 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* In general, clamping does not apply to glGetTexImage, except when 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the returned type of the image can't hold negative values. 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_needs_clamping(type)) { 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the returned image type can't have negative values */ 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dataType == GL_FLOAT || 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dataType == GL_SIGNED_NORMALIZED || 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format == GL_LUMINANCE || 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format == GL_LUMINANCE_ALPHA) { 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transferOps |= IMAGE_CLAMP_BIT; 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_format_compressed(texImage->TexFormat)) { 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_tex_rgba_compressed(ctx, dimensions, format, type, 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pixels, texImage, transferOps); 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_tex_rgba_uncompressed(ctx, dimensions, format, type, 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pixels, texImage, transferOps); 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Try to do glGetTexImage() with simple memcpy(). 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if done, GL_FALSE otherwise 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLvoid *pixels, 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage) 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLenum target = texImage->TexObject->Target; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLboolean memCopy = GL_FALSE; 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Check if we can use memcpy to copy from the hardware texture 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * format to the user's format/type. 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that GL's pixel transfer ops don't apply to glGetTexImage() 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (target == GL_TEXTURE_1D || 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target == GL_TEXTURE_2D || 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target == GL_TEXTURE_RECTANGLE || 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_is_cube_face(target)) { 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memCopy = _mesa_format_matches_format_and_type(texImage->TexFormat, 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format, type, 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pack.SwapBytes); 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (memCopy) { 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint bpp = _mesa_get_format_bytes(texImage->TexFormat); 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint bytesPerRow = texImage->Width * bpp; 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *dst = 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_image_address2d(&ctx->Pack, pixels, texImage->Width, 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Height, format, type, 0, 0); 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint dstRowStride = 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_image_row_stride(&ctx->Pack, texImage->Width, format, type); 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *src; 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint srcRowStride; 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map src texture buffer */ 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapTextureImage(ctx, texImage, 0, 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, texImage->Width, texImage->Height, 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_READ_BIT, &src, &srcRowStride); 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src) { 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (bytesPerRow == dstRowStride && bytesPerRow == srcRowStride) { 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(dst, src, bytesPerRow * texImage->Height); 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint row; 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < texImage->Height; row++) { 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(dst, src, bytesPerRow); 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst += dstRowStride; 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src += srcRowStride; 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* unmap src texture buffer */ 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapTextureImage(ctx, texImage, 0); 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return memCopy; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is the software fallback for Driver.GetTexImage(). 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All error checking will have been done before this routine is called. 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We'll call ctx->Driver.MapTextureImage() to access the data, then 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * unmap with ctx->Driver.UnmapTextureImage(). 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_get_teximage(struct gl_context *ctx, 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum format, GLenum type, GLvoid *pixels, 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage) 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint dimensions; 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (texImage->TexObject->Target) { 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_1D: 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dimensions = 1; 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_3D: 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dimensions = 3; 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dimensions = 2; 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map dest buffer, if PBO */ 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Packing texture image into a PBO. 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Map the (potentially) VRAM-based buffer into our process space so 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we can write into it with the code below. 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * A hardware driver might use a sophisticated blit to move the 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * texture data to the PBO if the PBO is in VRAM along with the texture. 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *buf = (GLubyte *) 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size, 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_WRITE_BIT, ctx->Pack.BufferObj); 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!buf) { 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* out of memory or other unexpected error */ 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage(map PBO failed)"); 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* <pixels> was an offset into the PBO. 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Now make it a real, client-side pointer inside the mapped region. 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pixels = ADD_POINTERS(buf, pixels); 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (get_tex_memcpy(ctx, format, type, pixels, texImage)) { 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* all done */ 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (format == GL_DEPTH_COMPONENT) { 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_tex_depth(ctx, dimensions, format, type, pixels, texImage); 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (format == GL_DEPTH_STENCIL_EXT) { 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_tex_depth_stencil(ctx, dimensions, format, type, pixels, texImage); 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (format == GL_YCBCR_MESA) { 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_tex_ycbcr(ctx, dimensions, format, type, pixels, texImage); 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_tex_rgba(ctx, dimensions, format, type, pixels, texImage); 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj); 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is the software fallback for Driver.GetCompressedTexImage(). 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All error checking will have been done before this routine is called. 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_get_compressed_teximage(struct gl_context *ctx, 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage, 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLvoid *img) 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint row_stride = 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_format_row_stride(texImage->TexFormat, texImage->Width); 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *src; 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint srcRowStride; 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* pack texture image into a PBO */ 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *buf = (GLubyte *) 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size, 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_WRITE_BIT, ctx->Pack.BufferObj); 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!buf) { 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* out of memory or other unexpected error */ 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetCompresssedTexImage(map PBO failed)"); 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org img = ADD_POINTERS(buf, img); 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map src texture buffer */ 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapTextureImage(ctx, texImage, 0, 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, texImage->Width, texImage->Height, 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_READ_BIT, &src, &srcRowStride); 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src) { 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no pixelstore or pixel transfer, but respect stride */ 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (row_stride == srcRowStride) { 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint size = _mesa_format_image_size(texImage->TexFormat, 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Width, 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Height, 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Depth); 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(img, src, size); 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint bw, bh; 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < (texImage->Height + bh - 1) / bh; i++) { 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy((GLubyte *)img + i * row_stride, 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (GLubyte *)src + i * srcRowStride, 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org row_stride); 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapTextureImage(ctx, texImage, 0); 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetCompresssedTexImage"); 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj); 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Validate the texture target enum supplied to glTexImage or 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glCompressedTexImage. 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglegal_getteximage_target(struct gl_context *ctx, GLenum target) 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (target) { 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_1D: 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_2D: 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_3D: 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ctx->Extensions.ARB_texture_cube_map; 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_RECTANGLE_NV: 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ctx->Extensions.NV_texture_rectangle; 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_1D_ARRAY_EXT: 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TEXTURE_2D_ARRAY_EXT: 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (ctx->Extensions.MESA_texture_array || 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Extensions.EXT_texture_array); 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do error checking for a glGetTexImage() call. 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if any error, GL_FALSE if no errors. 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggetteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum format, GLenum type, GLsizei clientMemSize, 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLvoid *pixels ) 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_object *texObj; 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage; 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint maxLevels = _mesa_max_texture_levels(ctx, target); 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum baseFormat, err; 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!legal_getteximage_target(ctx, target)) { 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target); 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(maxLevels != 0); 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (level < 0 || level >= maxLevels) { 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" ); 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org err = _mesa_error_check_format_and_type(ctx, format, type); 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (err != GL_NO_ERROR) { 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, err, "glGetTexImage(format/type)"); 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texObj = _mesa_get_current_tex_object(ctx, target); 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!texObj) { 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage = _mesa_select_tex_image(ctx, texObj, target, level); 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!texImage) { 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* non-existant texture image */ 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org baseFormat = _mesa_get_format_base_format(texImage->TexFormat); 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make sure the requested image format is compatible with the 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * texture's format. 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_color_format(format) 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !_mesa_is_color_format(baseFormat)) { 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (_mesa_is_depth_format(format) 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !_mesa_is_depth_format(baseFormat) 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !_mesa_is_depthstencil_format(baseFormat)) { 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (_mesa_is_ycbcr_format(format) 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !_mesa_is_ycbcr_format(baseFormat)) { 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (_mesa_is_depthstencil_format(format) 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !_mesa_is_depthstencil_format(baseFormat)) { 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (_mesa_is_dudv_format(format) 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !_mesa_is_dudv_format(baseFormat)) { 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Height, texImage->Depth, 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format, type, clientMemSize, pixels)) { 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetTexImage(out of bounds PBO access)"); 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetnTexImageARB(out of bounds access:" 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org " bufSize (%d) is too small)", clientMemSize); 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* PBO should not be mapped */ 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) { 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetTexImage(PBO is mapped)"); 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get texture image. Called by glGetTexImage. 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param target texture target. 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param level image level. 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param format pixel data format for returned image. 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type pixel data type for returned image. 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param bufSize size of the pixels data buffer. 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param pixels returned pixel data. 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GLAPIENTRY 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum type, GLsizei bufSize, GLvoid *pixels ) 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_object *texObj; 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage; 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_CURRENT_CONTEXT(ctx); 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (getteximage_error_check(ctx, target, level, format, type, 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bufSize, pixels)) { 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) { 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* not an error, do nothing */ 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texObj = _mesa_get_current_tex_object(ctx, target); 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage = _mesa_select_tex_image(ctx, texObj, target, level); 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_zero_size_texture(texImage)) 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(ctx, "glGetTexImage(tex %u) format = %s, w=%d, h=%d," 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org " dstFmt=0x%x, dstType=0x%x\n", 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texObj->Name, 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_get_format_name(texImage->TexFormat), 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Width, texImage->Height, 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format, type); 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_lock_texture(ctx, texObj); 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.GetTexImage(ctx, format, type, pixels, texImage); 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_unlock_texture(ctx, texObj); 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GLAPIENTRY 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_GetTexImage( GLenum target, GLint level, GLenum format, 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum type, GLvoid *pixels ) 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_GetnTexImageARB(target, level, format, type, INT_MAX, pixels); 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do error checking for a glGetCompressedTexImage() call. 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if any error, GL_FALSE if no errors. 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggetcompressedteximage_error_check(struct gl_context *ctx, GLenum target, 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint level, GLsizei clientMemSize, GLvoid *img) 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_object *texObj; 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage; 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLint maxLevels = _mesa_max_texture_levels(ctx, target); 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint compressedSize; 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!legal_getteximage_target(ctx, target)) { 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)", 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target); 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(maxLevels != 0); 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (level < 0 || level >= maxLevels) { 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_VALUE, 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetCompressedTexImageARB(bad level = %d)", level); 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texObj = _mesa_get_current_tex_object(ctx, target); 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!texObj) { 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)"); 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage = _mesa_select_tex_image(ctx, texObj, target, level); 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!texImage) { 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* probably invalid mipmap level */ 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_VALUE, 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetCompressedTexImageARB(level)"); 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!_mesa_is_format_compressed(texImage->TexFormat)) { 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetCompressedTexImageARB(texture is not compressed)"); 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compressedSize = _mesa_format_image_size(texImage->TexFormat, 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Width, 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Height, 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Depth); 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* do bounds checking on writing to client memory */ 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clientMemSize < compressedSize) { 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetnCompressedTexImageARB(out of bounds access:" 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org " bufSize (%d) is too small)", clientMemSize); 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* do bounds checking on PBO write */ 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((const GLubyte *) img + compressedSize > 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (const GLubyte *) ctx->Pack.BufferObj->Size) { 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetCompressedTexImage(out of bounds PBO access)"); 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* make sure PBO is not mapped */ 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) { 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetCompressedTexImage(PBO is mapped)"); 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GLAPIENTRY 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLvoid *img) 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_object *texObj; 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_texture_image *texImage; 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_CURRENT_CONTEXT(ctx); 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (getcompressedteximage_error_check(ctx, target, level, bufSize, img)) { 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !img) { 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* not an error, do nothing */ 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texObj = _mesa_get_current_tex_object(ctx, target); 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage = _mesa_select_tex_image(ctx, texObj, target, level); 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_zero_size_texture(texImage)) 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(ctx, 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glGetCompressedTexImage(tex %u) format = %s, w=%d, h=%d\n", 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texObj->Name, 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_get_format_name(texImage->TexFormat), 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texImage->Width, texImage->Height); 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_lock_texture(ctx, texObj); 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.GetCompressedTexImage(ctx, texImage, img); 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_unlock_texture(ctx, texObj); 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GLAPIENTRY 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_GetnCompressedTexImageARB(target, level, INT_MAX, img); 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 982