teximage.c revision 9848e86af0c937a6f7609289ab2705c3535f378f
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Mesa 3-D graphics library
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * copy of this software and associated documentation files (the "Software"),
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * to deal in the Software without restriction, including without limitation
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * the rights to use, copy, modify, merge, publish, distribute, sublicense,
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * and/or sell copies of the Software, and to permit persons to whom the
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Software is furnished to do so, subject to the following conditions:
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * The above copyright notice and this permission notice shall be included
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * in all copies or substantial portions of the Software.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \file teximage.c
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Texture image-related functions.
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdbool.h>
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "glheader.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bufferobj.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "context.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "enums.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "fbobject.h"
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "framebuffer.h"
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hash.h"
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "image.h"
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "imports.h"
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "macros.h"
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "mfeatures.h"
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "state.h"
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "texcompress.h"
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "teximage.h"
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "texobj.h"
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "texstate.h"
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "texpal.h"
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "mtypes.h"
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "glformats.h"
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT.
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifndef GL_HALF_FLOAT_OES
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define GL_HALF_FLOAT_OES 0x8D61
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * State changes which we care about for glCopyTex[Sub]Image() calls.
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * In particular, we care about pixel transfer state and buffer state
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * (such as glReadBuffer to make sure we read from the right renderbuffer).
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL)
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Return the simple base format for a given internal texture format.
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param ctx GL context.
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param internalFormat the internal texture format token or 1, 2, 3, or 4.
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * This is the format which is used during texture application (i.e. the
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * texture format and env mode determine the arithmetic used.
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectGLint
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (internalFormat) {
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA:
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA4:
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA8:
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA12:
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA16:
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_ALPHA;
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case 1:
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE:
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE4:
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE8:
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE12:
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE16:
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE;
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case 2:
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE_ALPHA:
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE4_ALPHA4:
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE6_ALPHA2:
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE8_ALPHA8:
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE12_ALPHA4:
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE12_ALPHA12:
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE16_ALPHA16:
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE_ALPHA;
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY:
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY4:
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY8:
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY12:
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY16:
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_INTENSITY;
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case 3:
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB:
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R3_G3_B2:
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB4:
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB5:
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB8:
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB10:
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB12:
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB16:
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGB;
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case 4:
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA:
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA2:
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA4:
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB5_A1:
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA8:
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB10_A2:
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA12:
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA16:
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGBA;
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   /* GL_BGRA can be an internal format *only* in OpenGL ES (1.x or 2.0).
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (_mesa_is_gles(ctx)) {
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_BGRA:
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGBA;
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.ARB_ES2_compatibility) {
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGB565:
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGB;
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.ARB_depth_texture) {
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_DEPTH_COMPONENT:
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_DEPTH_COMPONENT16:
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_DEPTH_COMPONENT24:
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_DEPTH_COMPONENT32:
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_DEPTH_COMPONENT;
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (internalFormat) {
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_COMPRESSED_ALPHA:
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_ALPHA;
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_COMPRESSED_LUMINANCE:
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_LUMINANCE;
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_COMPRESSED_LUMINANCE_ALPHA:
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_LUMINANCE_ALPHA;
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_COMPRESSED_INTENSITY:
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_INTENSITY;
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_COMPRESSED_RGB:
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_RGB;
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_COMPRESSED_RGBA:
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_RGBA;
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      ; /* fallthrough */
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.TDFX_texture_compression_FXT1) {
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_COMPRESSED_RGB_FXT1_3DFX:
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGB;
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_COMPRESSED_RGBA_FXT1_3DFX:
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGBA;
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.EXT_texture_compression_s3tc) {
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGB;
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGBA;
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.S3_s3tc) {
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGB_S3TC:
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGB4_S3TC:
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGB;
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGBA_S3TC:
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGBA4_S3TC:
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGBA;
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.MESA_ycbcr_texture) {
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (internalFormat == GL_YCBCR_MESA)
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_YCBCR_MESA;
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.ARB_texture_float) {
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_ALPHA16F_ARB:
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_ALPHA32F_ARB:
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_ALPHA;
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGBA16F_ARB:
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGBA32F_ARB:
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGBA;
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGB16F_ARB:
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGB32F_ARB:
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGB;
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_INTENSITY16F_ARB:
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_INTENSITY32F_ARB:
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_INTENSITY;
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE16F_ARB:
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE32F_ARB:
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_LUMINANCE;
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE_ALPHA16F_ARB:
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE_ALPHA32F_ARB:
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_LUMINANCE_ALPHA;
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.ATI_envmap_bumpmap) {
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_DUDV_ATI:
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_DU8DV8_ATI:
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_DUDV_ATI;
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.EXT_texture_snorm) {
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RED_SNORM:
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_R8_SNORM:
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_R16_SNORM:
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RED;
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RG_SNORM:
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RG8_SNORM:
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RG16_SNORM:
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RG;
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGB_SNORM:
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGB8_SNORM:
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGB16_SNORM:
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGB;
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGBA_SNORM:
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGBA8_SNORM:
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_RGBA16_SNORM:
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_RGBA;
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_ALPHA_SNORM:
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_ALPHA8_SNORM:
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_ALPHA16_SNORM:
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_ALPHA;
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE_SNORM:
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE8_SNORM:
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE16_SNORM:
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_LUMINANCE;
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE_ALPHA_SNORM:
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE8_ALPHA8_SNORM:
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_LUMINANCE16_ALPHA16_SNORM:
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_LUMINANCE_ALPHA;
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_INTENSITY_SNORM:
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_INTENSITY8_SNORM:
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_INTENSITY16_SNORM:
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_INTENSITY;
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.EXT_packed_depth_stencil) {
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_DEPTH_STENCIL_EXT:
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         case GL_DEPTH24_STENCIL8_EXT:
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_DEPTH_STENCIL_EXT;
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         default:
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ; /* fallthrough */
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if FEATURE_EXT_texture_sRGB
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.EXT_texture_sRGB) {
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_SRGB_EXT:
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_SRGB8_EXT:
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SRGB_EXT:
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGB;
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_SRGB_ALPHA_EXT:
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_SRGB8_ALPHA8_EXT:
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SRGB_ALPHA_EXT:
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGBA;
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_SLUMINANCE_ALPHA_EXT:
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_SLUMINANCE8_ALPHA8_EXT:
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE_ALPHA;
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_SLUMINANCE_EXT:
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_SLUMINANCE8_EXT:
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SLUMINANCE_EXT:
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE;
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* FEATURE_EXT_texture_sRGB */
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Version >= 30 ||
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       ctx->Extensions.EXT_texture_integer) {
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA8UI_EXT:
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA16UI_EXT:
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA32UI_EXT:
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA8I_EXT:
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA16I_EXT:
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGBA32I_EXT:
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB10_A2UI:
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGBA;
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB8UI_EXT:
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB16UI_EXT:
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB32UI_EXT:
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB8I_EXT:
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB16I_EXT:
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB32I_EXT:
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGB;
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.EXT_texture_integer) {
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA8UI_EXT:
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA16UI_EXT:
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA32UI_EXT:
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA8I_EXT:
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA16I_EXT:
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ALPHA32I_EXT:
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_ALPHA;
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY8UI_EXT:
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY16UI_EXT:
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY32UI_EXT:
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY8I_EXT:
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY16I_EXT:
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_INTENSITY32I_EXT:
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_INTENSITY;
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE8UI_EXT:
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE16UI_EXT:
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE32UI_EXT:
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE8I_EXT:
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE16I_EXT:
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE32I_EXT:
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE;
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE_ALPHA8UI_EXT:
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE_ALPHA16UI_EXT:
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE_ALPHA32UI_EXT:
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE_ALPHA8I_EXT:
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE_ALPHA16I_EXT:
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_LUMINANCE_ALPHA32I_EXT:
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE_ALPHA;
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.ARB_texture_rg) {
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R16F:
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 /* R16F depends on both ARB_half_float_pixel and ARB_texture_float.
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	  */
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 if (!ctx->Extensions.ARB_half_float_pixel)
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	    break;
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 /* FALLTHROUGH */
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R32F:
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 if (!ctx->Extensions.ARB_texture_float)
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	    break;
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RED;
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R8I:
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R8UI:
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R16I:
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R16UI:
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R32I:
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R32UI:
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer)
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	    break;
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 /* FALLTHROUGH */
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R8:
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R16:
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RED:
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_RED:
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RED;
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG16F:
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 /* RG16F depends on both ARB_half_float_pixel and ARB_texture_float.
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	  */
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 if (!ctx->Extensions.ARB_half_float_pixel)
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	    break;
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 /* FALLTHROUGH */
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG32F:
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 if (!ctx->Extensions.ARB_texture_float)
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	    break;
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RG;
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG8I:
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG8UI:
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG16I:
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG16UI:
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG32I:
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG32UI:
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer)
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	    break;
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 /* FALLTHROUGH */
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG:
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG8:
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RG16:
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_RG:
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RG;
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.EXT_texture_shared_exponent) {
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_RGB9_E5_EXT:
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGB;
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.EXT_packed_float) {
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_R11F_G11F_B10F_EXT:
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGB;
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.ARB_depth_buffer_float) {
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_DEPTH_COMPONENT32F:
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_DEPTH_COMPONENT;
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_DEPTH32F_STENCIL8:
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_DEPTH_STENCIL;
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.ARB_texture_compression_rgtc) {
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_RED_RGTC1:
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SIGNED_RED_RGTC1:
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RED;
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_RG_RGTC2:
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SIGNED_RG_RGTC2:
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RG;
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.EXT_texture_compression_latc) {
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE;
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE_ALPHA;
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.ATI_texture_compression_3dc) {
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_LUMINANCE_ALPHA;
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) {
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_ETC1_RGB8_OES:
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_RGB;
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (ctx->API == API_OPENGLES) {
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      switch (internalFormat) {
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE4_RGB8_OES:
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE4_R5_G6_B5_OES:
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE8_RGB8_OES:
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE8_R5_G6_B5_OES:
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 return GL_RGB;
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE4_RGBA8_OES:
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE8_RGB5_A1_OES:
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE4_RGBA4_OES:
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE4_RGB5_A1_OES:
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE8_RGBA8_OES:
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PALETTE8_RGBA4_OES:
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	 return GL_RGBA;
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ; /* fallthrough */
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return -1; /* error */
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * For cube map faces, return a face index in [0,5].
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * For other targets return 0;
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectGLuint
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_tex_target_to_face(GLenum target)
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (_mesa_is_cube_face(target))
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   else
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return 0;
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Install gl_texture_image in a gl_texture_object according to the target
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * and level parameters.
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param tObj texture object.
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param target texture target.
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param level image level.
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param texImage texture image.
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectset_tex_image(struct gl_texture_object *tObj,
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              GLenum target, GLint level,
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              struct gl_texture_image *texImage)
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   const GLuint face = _mesa_tex_target_to_face(target);
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(tObj);
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(texImage);
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES)
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      assert(level == 0);
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   tObj->Image[face][level] = texImage;
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   /* Set the 'back' pointer */
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   texImage->TexObject = tObj;
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   texImage->Level = level;
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   texImage->Face = face;
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Allocate a texture image structure.
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Called via ctx->Driver.NewTextureImage() unless overriden by a device
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * driver.
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \return a pointer to gl_texture_image struct with all fields initialized to
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * zero.
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct gl_texture_image *
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_new_texture_image( struct gl_context *ctx )
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   (void) ctx;
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return CALLOC_STRUCT(gl_texture_image);
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Free a gl_texture_image and associated data.
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * This function is a fallback called via ctx->Driver.DeleteTextureImage().
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param texImage texture image.
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Free the texture image structure and the associated image data.
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_delete_texture_image(struct gl_context *ctx,
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                           struct gl_texture_image *texImage)
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   /* Free texImage->Data and/or any other driver-specific texture
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    * image storage.
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(ctx->Driver.FreeTextureImageBuffer);
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ctx->Driver.FreeTextureImageBuffer( ctx, texImage );
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   free(texImage);
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Test if a target is a proxy target.
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param target texture target.
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectGLboolean
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_is_proxy_texture(GLenum target)
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   /*
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    * NUM_TEXTURE_TARGETS should match number of terms below, except there's no
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   assert(NUM_TEXTURE_TARGETS == 7 + 2);
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return (target == GL_PROXY_TEXTURE_1D ||
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           target == GL_PROXY_TEXTURE_2D ||
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           target == GL_PROXY_TEXTURE_3D ||
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           target == GL_PROXY_TEXTURE_2D_ARRAY_EXT);
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Return the proxy target which corresponds to the given texture target
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic GLenum
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectget_proxy_target(GLenum target)
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (target) {
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_1D:
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D:
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_PROXY_TEXTURE_1D;
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D:
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D:
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_PROXY_TEXTURE_2D;
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_3D:
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_3D:
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_PROXY_TEXTURE_3D;
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_ARB:
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_PROXY_TEXTURE_CUBE_MAP_ARB;
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_RECTANGLE_NV:
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_RECTANGLE_NV:
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_PROXY_TEXTURE_RECTANGLE_NV;
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_1D_ARRAY_EXT:
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_PROXY_TEXTURE_1D_ARRAY_EXT;
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D_ARRAY_EXT:
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_PROXY_TEXTURE_2D_ARRAY_EXT;
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      _mesa_problem(NULL, "unexpected target in get_proxy_target()");
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return 0;
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Get the texture object that corresponds to the target of the given
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * texture unit.  The target should have already been checked for validity.
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param ctx GL context.
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param texUnit texture unit.
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param target texture target.
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \return pointer to the texture object on success, or NULL on failure.
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct gl_texture_object *
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_select_tex_object(struct gl_context *ctx,
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        const struct gl_texture_unit *texUnit,
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        GLenum target)
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   const GLboolean arrayTex = (ctx->Extensions.MESA_texture_array ||
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               ctx->Extensions.EXT_texture_array);
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (target) {
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_1D:
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return texUnit->CurrentTex[TEXTURE_1D_INDEX];
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PROXY_TEXTURE_1D:
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_2D:
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return texUnit->CurrentTex[TEXTURE_2D_INDEX];
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PROXY_TEXTURE_2D:
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_3D:
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return texUnit->CurrentTex[TEXTURE_3D_INDEX];
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PROXY_TEXTURE_3D:
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_CUBE_MAP_ARB:
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Extensions.ARB_texture_cube_map
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL;
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Extensions.ARB_texture_cube_map
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_RECTANGLE_NV:
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Extensions.NV_texture_rectangle
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL;
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PROXY_TEXTURE_RECTANGLE_NV:
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Extensions.NV_texture_rectangle
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_1D_ARRAY_EXT:
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_2D_ARRAY_EXT:
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_BUFFER:
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Extensions.ARB_texture_buffer_object
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ? texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL;
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      case GL_TEXTURE_EXTERNAL_OES:
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return ctx->Extensions.OES_EGL_image_external
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL;
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      default:
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Return pointer to texture object for given target on current texture unit.
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct gl_texture_object *
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target)
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return _mesa_select_tex_object(ctx, texUnit, target);
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Get a texture image pointer from a texture object, given a texture
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * target and mipmap level.  The target and level parameters should
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * have already been error-checked.
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param ctx GL context.
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param texObj texture unit.
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param target texture target.
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param level image level.
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \return pointer to the texture image structure, or NULL on failure.
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct gl_texture_image *
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_select_tex_image(struct gl_context *ctx,
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       const struct gl_texture_object *texObj,
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project		       GLenum target, GLint level)
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   const GLuint face = _mesa_tex_target_to_face(target);
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(texObj);
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(level >= 0);
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(level < MAX_TEXTURE_LEVELS);
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return texObj->Image[face][level];
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * it and install it.  Only return NULL if passed a bad parameter or run
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * out of memory.
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct gl_texture_image *
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    GLenum target, GLint level)
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   struct gl_texture_image *texImage;
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (!texObj)
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return NULL;
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   texImage = _mesa_select_tex_image(ctx, texObj, target, level);
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (!texImage) {
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texImage = ctx->Driver.NewTextureImage(ctx);
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (!texImage) {
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      set_tex_image(texObj, target, level, texImage);
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return texImage;
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Return pointer to the specified proxy texture image.
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Note that proxy textures are per-context, not per-texture unit.
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \return pointer to texture image or NULL if invalid target, invalid
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *         level, or out of memory.
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct gl_texture_image *
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
845d6750ef014c13bbfebc88a7b6789579b919e1becMike J. Chen   struct gl_texture_image *texImage;
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   GLuint texIndex;
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (level < 0)
8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return NULL;
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (target) {
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D:
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxTextureLevels)
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texIndex = TEXTURE_1D_INDEX;
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D:
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxTextureLevels)
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texIndex = TEXTURE_2D_INDEX;
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_3D:
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.Max3DTextureLevels)
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texIndex = TEXTURE_3D_INDEX;
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_CUBE_MAP:
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxCubeTextureLevels)
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texIndex = TEXTURE_CUBE_INDEX;
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_RECTANGLE_NV:
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level > 0)
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texIndex = TEXTURE_RECT_INDEX;
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxTextureLevels)
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texIndex = TEXTURE_1D_ARRAY_INDEX;
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxTextureLevels)
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texIndex = TEXTURE_2D_ARRAY_INDEX;
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return NULL;
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level];
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (!texImage) {
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texImage = ctx->Driver.NewTextureImage(ctx);
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (!texImage) {
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return NULL;
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage;
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      /* Set the 'back' pointer */
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      texImage->TexObject = ctx->Texture.ProxyTex[texIndex];
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return texImage;
9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Get the maximum number of allowed mipmap levels.
9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param ctx GL context.
9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param target texture target.
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \return the maximum number of allowed mipmap levels for the given
9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * texture target, or zero if passed a bad target.
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \sa gl_constants.
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectGLint
9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (target) {
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_1D:
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D:
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D:
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D:
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return ctx->Const.MaxTextureLevels;
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_3D:
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_3D:
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return ctx->Const.Max3DTextureLevels;
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP:
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return ctx->Extensions.ARB_texture_cube_map
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ? ctx->Const.MaxCubeTextureLevels : 0;
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_RECTANGLE_NV:
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_RECTANGLE_NV:
9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_1D_ARRAY_EXT:
9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D_ARRAY_EXT:
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return (ctx->Extensions.MESA_texture_array ||
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              ctx->Extensions.EXT_texture_array)
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ? ctx->Const.MaxTextureLevels : 0;
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_BUFFER:
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return _mesa_is_desktop_gl(ctx) &&
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         (ctx->Extensions.ARB_texture_buffer_object ||
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project          (ctx->Version >= 31)) ? 1 : 0;
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_EXTERNAL_OES:
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      /* fall-through */
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return 0; /* bad target */
9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Return number of dimensions per mipmap level for the given texture target.
9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectGLint
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_get_texture_dimensions(GLenum target)
9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (target) {
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_1D:
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D:
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return 1;
9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D:
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_RECTANGLE:
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP:
9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D:
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_RECTANGLE:
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_CUBE_MAP:
9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_1D_ARRAY:
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D_ARRAY:
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_EXTERNAL_OES:
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return 2;
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_3D:
9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_3D:
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D_ARRAY:
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D_ARRAY:
9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return 3;
9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_BUFFER:
9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      /* fall-through */
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    target);
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return 2;
9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if 000 /* not used anymore */
10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * glTexImage[123]D can accept a NULL image pointer.  In this case we
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * create a texture image with unspecified image contents per the OpenGL
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * spec.
10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic GLubyte *
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectmake_null_texture(GLint width, GLint height, GLint depth, GLenum format)
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   const GLint components = _mesa_components_in_format(format);
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   const GLint numPixels = width * height * depth;
10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifdef DEBUG
10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   /*
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    * Let's see if anyone finds this.  If glTexImage2D() is called with
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    * a NULL image pointer then load the texture image with something
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    * interesting instead of leaving it indeterminate.
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (data) {
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      static const char message[8][32] = {
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         "   X   X  XXXXX   XXX     X    ",
10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         "   XX XX  X      X   X   X X   ",
10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         "   X X X  X      X      X   X  ",
10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         "   X   X  XXXX    XXX   XXXXX  ",
10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         "   X   X  X          X  X   X  ",
10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         "   X   X  X      X   X  X   X  ",
10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         "   X   X  XXXXX   XXX   X   X  ",
10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         "                               "
10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      };
10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      GLubyte *imgPtr = data;
10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      GLint h, i, j, k;
10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      for (h = 0; h < depth; h++) {
10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         for (i = 0; i < height; i++) {
10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GLint srcRow = 7 - (i % 8);
10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (j = 0; j < width; j++) {
10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project               GLint srcCol = j % 32;
10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project               GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project               for (k = 0; k < components; k++) {
10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                  *imgPtr++ = texel;
10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project               }
10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         }
10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return data;
10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Set the size and format-related fields of a gl_texture_image struct
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * to zero.  This is used when a proxy texture test fails.
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectclear_teximage_fields(struct gl_texture_image *img)
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(img);
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->_BaseFormat = 0;
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->InternalFormat = 0;
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Border = 0;
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Width = 0;
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Height = 0;
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Depth = 0;
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Width2 = 0;
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Height2 = 0;
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Depth2 = 0;
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->WidthLog2 = 0;
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->HeightLog2 = 0;
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->DepthLog2 = 0;
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->TexFormat = MESA_FORMAT_NONE;
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Initialize basic fields of the gl_texture_image struct.
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param ctx GL context.
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param img texture image structure to be initialized.
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param width image width.
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param height image height.
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param depth image depth.
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param border image border.
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param internalFormat internal format.
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param format  the actual hardware format (one of MESA_FORMAT_*)
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Fills in the fields of \p img with the given information.
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Note: width, height and depth include the border.
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid
10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_init_teximage_fields(struct gl_context *ctx,
10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                           struct gl_texture_image *img,
11005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                           GLsizei width, GLsizei height, GLsizei depth,
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                           GLint border, GLenum internalFormat,
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                           gl_format format)
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   GLenum target;
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(img);
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(width >= 0);
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(height >= 0);
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(depth >= 0);
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   target = img->TexObject->Target;
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ASSERT(img->_BaseFormat > 0);
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->InternalFormat = internalFormat;
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Border = border;
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Width = width;
11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Height = height;
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Depth = depth;
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->WidthLog2 = _mesa_logbase2(img->Width2);
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch(target) {
11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_1D:
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_BUFFER:
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D:
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (height == 0)
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         img->Height2 = 0;
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      else
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         img->Height2 = 1;
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->HeightLog2 = 0;
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (depth == 0)
11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         img->Depth2 = 0;
11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      else
11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         img->Depth2 = 1;
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->DepthLog2 = 0;
11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_1D_ARRAY:
11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D_ARRAY:
11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->Height2 = height; /* no border */
11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->HeightLog2 = 0; /* not used */
11415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (depth == 0)
11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         img->Depth2 = 0;
11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      else
11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         img->Depth2 = 1;
11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->DepthLog2 = 0;
11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D:
11485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_RECTANGLE:
11495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP:
11505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
11515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
11525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
11535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
11545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
11555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
11565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_EXTERNAL_OES:
11575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D:
11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_RECTANGLE:
11595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_CUBE_MAP:
11605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
11615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->HeightLog2 = _mesa_logbase2(img->Height2);
11625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (depth == 0)
11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         img->Depth2 = 0;
11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      else
11655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         img->Depth2 = 1;
11665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->DepthLog2 = 0;
11675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
11685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D_ARRAY:
11695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D_ARRAY:
11705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
11715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->HeightLog2 = _mesa_logbase2(img->Height2);
11725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->Depth2 = depth; /* no border */
11735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->DepthLog2 = 0; /* not used */
11745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
11755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_3D:
11765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_3D:
11775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
11785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->HeightLog2 = _mesa_logbase2(img->Height2);
11795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
11805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      img->DepthLog2 = _mesa_logbase2(img->Depth2);
11815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      break;
11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()",
11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    target);
11855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
11865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
11885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   img->TexFormat = format;
11895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
11935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Free and clear fields of the gl_texture_image struct.
11945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
11955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param ctx GL context.
11965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param texImage texture image structure to be cleared.
11975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
11985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * After the call, \p texImage will have no data associated with it.  Its
11995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * fields are cleared so that its parent object will test incomplete.
12005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
12015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid
12025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_clear_texture_image(struct gl_context *ctx,
12035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          struct gl_texture_image *texImage)
12045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
12055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
12065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   clear_teximage_fields(texImage);
12075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
12085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
12115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * This is the fallback for Driver.TestProxyTexImage().  Test the texture
12125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * level, width, height and depth against the ctx->Const limits for textures.
12135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
12145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * A hardware driver might override this function if, for example, the
12155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * max 3D texture size is 512x512x64 (i.e. not a cube).
12165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
12175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Note that width, height, depth == 0 is not an error.  However, a
12185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * texture with zero width/height/depth will be considered "incomplete"
12195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * and texturing will effectively be disabled.
12205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
12215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param target  one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
12225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *                GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
12235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *                GL_PROXY_TEXTURE_CUBE_MAP_ARB.
12245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param level  as passed to glTexImage
12255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param internalFormat  as passed to glTexImage
12265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param format  as passed to glTexImage
12275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param type  as passed to glTexImage
12285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param width  as passed to glTexImage
12295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param height  as passed to glTexImage
12305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param depth  as passed to glTexImage
12315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \param border  as passed to glTexImage
12325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
12335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
12345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectGLboolean
12355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
12365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          GLint internalFormat, GLenum format, GLenum type,
12375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          GLint width, GLint height, GLint depth, GLint border)
12385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
12395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   GLint maxSize;
12405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   (void) internalFormat;
12425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   (void) format;
12435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   (void) type;
12445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (target) {
12465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D:
12475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
12485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (width < 2 * border || width > 2 * border + maxSize)
12495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxTextureLevels)
12515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
12535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
12545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
12555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
12565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE;
12575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D:
12595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
12605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (width < 2 * border || width > 2 * border + maxSize)
12615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (height < 2 * border || height > 2 * border + maxSize)
12635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxTextureLevels)
12655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
12675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
12685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
12695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
12705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
12715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
12725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE;
12735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_3D:
12755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
12765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (width < 2 * border || width > 2 * border + maxSize)
12775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (height < 2 * border || height > 2 * border + maxSize)
12795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (depth < 2 * border || depth > 2 * border + maxSize)
12815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.Max3DTextureLevels)
12835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
12855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
12865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
12875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
12885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
12895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border))
12905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
12915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
12925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE;
12935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_RECTANGLE_NV:
12955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      maxSize = ctx->Const.MaxTextureRectSize;
12965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (width < 0 || width > maxSize)
12975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
12985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (height < 0 || height > maxSize)
12995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level != 0)
13015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE;
13035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
13055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
13065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (width < 2 * border || width > 2 * border + maxSize)
13075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (height < 2 * border || height > 2 * border + maxSize)
13095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxCubeTextureLevels)
13115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
13135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
13145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
13155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
13165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
13175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
13185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE;
13195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
13215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
13225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (width < 2 * border || width > 2 * border + maxSize)
13235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (height < 1 || height > ctx->Const.MaxArrayTextureLayers)
13255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxTextureLevels)
13275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
13295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
13305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
13315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
13325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE;
13335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
13355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
13365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (width < 2 * border || width > 2 * border + maxSize)
13375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (height < 2 * border || height > 2 * border + maxSize)
13395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers)
13415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (level >= ctx->Const.MaxTextureLevels)
13435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         return GL_FALSE;
13445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
13455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
13465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
13475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
13485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return GL_FALSE;
13495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
13505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE;
13515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
13535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
13545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_FALSE;
13555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
13565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
13575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
13605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Check if the memory used by the texture would exceed the driver's limit.
13615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * This lets us support a max 3D texture size of 8K (for example) but
13625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * prevents allocating a full 8K x 8K x 8K texture.
13635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * XXX this could be rolled into the proxy texture size test (above) but
13645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * we don't have the actual texture internal format at that point.
13655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
13665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic GLboolean
13675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectlegal_texture_size(struct gl_context *ctx, gl_format format,
13685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   GLint width, GLint height, GLint depth)
13695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
13705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
13715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
13725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
13735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
13745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
13775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Return true if the format is only valid for glCompressedTexImage.
13785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
13795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic GLboolean
13805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectcompressedteximage_only_format(const struct gl_context *ctx, GLenum format)
13815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
13825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (format) {
13835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_ETC1_RGB8_OES:
13845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE;
13855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
13865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_FALSE;
13875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   }
13885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
13895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/**
13925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Helper function to determine whether a target and specific compression
13935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * format are supported.
13945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
13955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic GLboolean
13965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttarget_can_be_compressed(const struct gl_context *ctx, GLenum target,
13975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                         GLenum intFormat)
13985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
13995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   (void) intFormat;  /* not used yet */
14005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   switch (target) {
14025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D:
14035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D:
14045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return GL_TRUE; /* true for any compressed format so far */
14055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_CUBE_MAP:
14065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
14075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
14085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
14095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
14105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
14115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
14125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return ctx->Extensions.ARB_texture_cube_map;
14135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
14145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   case GL_TEXTURE_2D_ARRAY_EXT:
14155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      return (ctx->Extensions.MESA_texture_array ||
14165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              ctx->Extensions.EXT_texture_array);
14175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   default:
1418      return GL_FALSE;
1419   }
1420}
1421
1422
1423/**
1424 * Check if the given texture target value is legal for a
1425 * glTexImage1/2/3D call.
1426 */
1427static GLboolean
1428legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
1429{
1430   switch (dims) {
1431   case 1:
1432      switch (target) {
1433      case GL_TEXTURE_1D:
1434      case GL_PROXY_TEXTURE_1D:
1435         return _mesa_is_desktop_gl(ctx);
1436      default:
1437         return GL_FALSE;
1438      }
1439   case 2:
1440      switch (target) {
1441      case GL_TEXTURE_2D:
1442         return GL_TRUE;
1443      case GL_PROXY_TEXTURE_2D:
1444         return _mesa_is_desktop_gl(ctx);
1445      case GL_PROXY_TEXTURE_CUBE_MAP:
1446         return _mesa_is_desktop_gl(ctx)
1447            && ctx->Extensions.ARB_texture_cube_map;
1448      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1449      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1450      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1451      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1452      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1453      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1454         return ctx->Extensions.ARB_texture_cube_map;
1455      case GL_TEXTURE_RECTANGLE_NV:
1456      case GL_PROXY_TEXTURE_RECTANGLE_NV:
1457         return _mesa_is_desktop_gl(ctx)
1458            && ctx->Extensions.NV_texture_rectangle;
1459      case GL_TEXTURE_1D_ARRAY_EXT:
1460      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1461         return _mesa_is_desktop_gl(ctx)
1462            && (ctx->Extensions.MESA_texture_array ||
1463                ctx->Extensions.EXT_texture_array);
1464      default:
1465         return GL_FALSE;
1466      }
1467   case 3:
1468      switch (target) {
1469      case GL_TEXTURE_3D:
1470         return GL_TRUE;
1471      case GL_PROXY_TEXTURE_3D:
1472         return _mesa_is_desktop_gl(ctx);
1473      case GL_TEXTURE_2D_ARRAY_EXT:
1474         return (_mesa_is_desktop_gl(ctx)
1475                 && (ctx->Extensions.MESA_texture_array ||
1476                     ctx->Extensions.EXT_texture_array))
1477            || _mesa_is_gles3(ctx);
1478      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1479         return _mesa_is_desktop_gl(ctx)
1480            && (ctx->Extensions.MESA_texture_array ||
1481                ctx->Extensions.EXT_texture_array);
1482      default:
1483         return GL_FALSE;
1484      }
1485   default:
1486      _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
1487      return GL_FALSE;
1488   }
1489}
1490
1491
1492/**
1493 * Check if the given texture target value is legal for a
1494 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
1495 * The difference compared to legal_teximage_target() above is that
1496 * proxy targets are not supported.
1497 */
1498static GLboolean
1499legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
1500{
1501   switch (dims) {
1502   case 1:
1503      return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D;
1504   case 2:
1505      switch (target) {
1506      case GL_TEXTURE_2D:
1507         return GL_TRUE;
1508      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1509      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1510      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1511      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1512      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1513      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1514         return ctx->Extensions.ARB_texture_cube_map;
1515      case GL_TEXTURE_RECTANGLE_NV:
1516         return _mesa_is_desktop_gl(ctx)
1517            && ctx->Extensions.NV_texture_rectangle;
1518      case GL_TEXTURE_1D_ARRAY_EXT:
1519         return _mesa_is_desktop_gl(ctx)
1520            && (ctx->Extensions.MESA_texture_array ||
1521                ctx->Extensions.EXT_texture_array);
1522      default:
1523         return GL_FALSE;
1524      }
1525   case 3:
1526      switch (target) {
1527      case GL_TEXTURE_3D:
1528         return GL_TRUE;
1529      case GL_TEXTURE_2D_ARRAY_EXT:
1530         return (_mesa_is_desktop_gl(ctx)
1531                 && (ctx->Extensions.MESA_texture_array ||
1532                     ctx->Extensions.EXT_texture_array))
1533            || _mesa_is_gles3(ctx);
1534      default:
1535         return GL_FALSE;
1536      }
1537   default:
1538      _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
1539                    dims);
1540      return GL_FALSE;
1541   }
1542}
1543
1544
1545/**
1546 * Helper function to determine if a texture object is mutable (in terms
1547 * of GL_ARB_texture_storage).
1548 */
1549static GLboolean
1550mutable_tex_object(struct gl_context *ctx, GLenum target)
1551{
1552   if (ctx->Extensions.ARB_texture_storage) {
1553      struct gl_texture_object *texObj =
1554         _mesa_get_current_tex_object(ctx, target);
1555      return !texObj->Immutable;
1556   }
1557   return GL_TRUE;
1558}
1559
1560
1561GLenum
1562_mesa_es_error_check_format_and_type(GLenum format, GLenum type,
1563                                     unsigned dimensions)
1564{
1565   bool type_valid = true;
1566
1567   switch (format) {
1568   case GL_ALPHA:
1569   case GL_LUMINANCE:
1570   case GL_LUMINANCE_ALPHA:
1571      type_valid = (type == GL_UNSIGNED_BYTE
1572                    || type == GL_FLOAT
1573                    || type == GL_HALF_FLOAT_OES);
1574      break;
1575
1576   case GL_RGB:
1577      type_valid = (type == GL_UNSIGNED_BYTE
1578                    || type == GL_UNSIGNED_SHORT_5_6_5
1579                    || type == GL_FLOAT
1580                    || type == GL_HALF_FLOAT_OES);
1581      break;
1582
1583   case GL_RGBA:
1584      type_valid = (type == GL_UNSIGNED_BYTE
1585                    || type == GL_UNSIGNED_SHORT_4_4_4_4
1586                    || type == GL_UNSIGNED_SHORT_5_5_5_1
1587                    || type == GL_FLOAT
1588                    || type == GL_HALF_FLOAT_OES
1589                    || type == GL_UNSIGNED_INT_2_10_10_10_REV);
1590      break;
1591
1592   case GL_DEPTH_COMPONENT:
1593      /* This format is filtered against invalid dimensionalities elsewhere.
1594       */
1595      type_valid = (type == GL_UNSIGNED_SHORT
1596                    || type == GL_UNSIGNED_INT);
1597      break;
1598
1599   case GL_DEPTH_STENCIL:
1600      /* This format is filtered against invalid dimensionalities elsewhere.
1601       */
1602      type_valid = (type == GL_UNSIGNED_INT_24_8);
1603      break;
1604
1605   case GL_BGRA_EXT:
1606      type_valid = (type == GL_UNSIGNED_BYTE);
1607
1608      /* This feels like a bug in the EXT_texture_format_BGRA8888 spec, but
1609       * the format does not appear to be allowed for 3D textures in OpenGL
1610       * ES.
1611       */
1612      if (dimensions != 2)
1613         return GL_INVALID_VALUE;
1614
1615      break;
1616
1617   default:
1618      return GL_INVALID_VALUE;
1619   }
1620
1621   return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION;
1622}
1623
1624/**
1625 * Test the glTexImage[123]D() parameters for errors.
1626 *
1627 * \param ctx GL context.
1628 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1629 * \param target texture target given by the user.
1630 * \param level image level given by the user.
1631 * \param internalFormat internal format given by the user.
1632 * \param format pixel data format given by the user.
1633 * \param type pixel data type given by the user.
1634 * \param width image width given by the user.
1635 * \param height image height given by the user.
1636 * \param depth image depth given by the user.
1637 * \param border image border given by the user.
1638 *
1639 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1640 *
1641 * Verifies each of the parameters against the constants specified in
1642 * __struct gl_contextRec::Const and the supported extensions, and according
1643 * to the OpenGL specification.
1644 */
1645static GLboolean
1646texture_error_check( struct gl_context *ctx,
1647                     GLuint dimensions, GLenum target,
1648                     GLint level, GLint internalFormat,
1649                     GLenum format, GLenum type,
1650                     GLint width, GLint height,
1651                     GLint depth, GLint border )
1652{
1653   const GLenum proxyTarget = get_proxy_target(target);
1654   const GLboolean isProxy = target == proxyTarget;
1655   GLboolean sizeOK = GL_TRUE;
1656   GLboolean colorFormat;
1657   GLenum err;
1658
1659   /* Even though there are no color-index textures, we still have to support
1660    * uploading color-index data and remapping it to RGB via the
1661    * GL_PIXEL_MAP_I_TO_[RGBA] tables.
1662    */
1663   const GLboolean indexFormat = (format == GL_COLOR_INDEX);
1664
1665   /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1666   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1667      if (!isProxy) {
1668         _mesa_error(ctx, GL_INVALID_VALUE,
1669                     "glTexImage%dD(level=%d)", dimensions, level);
1670      }
1671      return GL_TRUE;
1672   }
1673
1674   /* Check border */
1675   if (border < 0 || border > 1 ||
1676       ((ctx->API != API_OPENGL ||
1677         target == GL_TEXTURE_RECTANGLE_NV ||
1678         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
1679      if (!isProxy) {
1680         _mesa_error(ctx, GL_INVALID_VALUE,
1681                     "glTexImage%dD(border=%d)", dimensions, border);
1682      }
1683      return GL_TRUE;
1684   }
1685
1686   if (width < 0 || height < 0 || depth < 0) {
1687      if (!isProxy) {
1688         _mesa_error(ctx, GL_INVALID_VALUE,
1689                     "glTexImage%dD(width, height or depth < 0)", dimensions);
1690      }
1691      return GL_TRUE;
1692   }
1693
1694   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1695    * combinations of format, internalFormat, and type that can be used.
1696    * Formats and types that require additional extensions (e.g., GL_FLOAT
1697    * requires GL_OES_texture_float) are filtered elsewhere.
1698    */
1699   if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
1700      if (format != internalFormat) {
1701         _mesa_error(ctx, GL_INVALID_OPERATION,
1702                     "glTexImage%dD(format = %s, internalFormat = %s)",
1703                     dimensions,
1704                     _mesa_lookup_enum_by_nr(format),
1705                     _mesa_lookup_enum_by_nr(internalFormat));
1706         return GL_TRUE;
1707      }
1708
1709      err = _mesa_es_error_check_format_and_type(format, type, dimensions);
1710      if (err != GL_NO_ERROR) {
1711         _mesa_error(ctx, err,
1712                     "glTexImage%dD(format = %s, type = %s)",
1713                     dimensions,
1714                     _mesa_lookup_enum_by_nr(format),
1715                     _mesa_lookup_enum_by_nr(type));
1716         return GL_TRUE;
1717      }
1718   }
1719
1720   /* Do this simple check before calling the TestProxyTexImage() function */
1721   if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
1722      sizeOK = (width == height);
1723   }
1724
1725   /*
1726    * Use the proxy texture driver hook to see if the size/level/etc are
1727    * legal.
1728    */
1729   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
1730                                                    internalFormat, format,
1731                                                    type, width, height,
1732                                                    depth, border);
1733   if (!sizeOK) {
1734      if (!isProxy) {
1735         _mesa_error(ctx, GL_INVALID_VALUE,
1736                     "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
1737                     dimensions, level, width, height, depth);
1738      }
1739      return GL_TRUE;
1740   }
1741
1742   /* Check internalFormat */
1743   if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
1744      if (!isProxy) {
1745         _mesa_error(ctx, GL_INVALID_VALUE,
1746                     "glTexImage%dD(internalFormat=%s)",
1747                     dimensions, _mesa_lookup_enum_by_nr(internalFormat));
1748      }
1749      return GL_TRUE;
1750   }
1751
1752   /* Check incoming image format and type */
1753   err = _mesa_error_check_format_and_type(ctx, format, type);
1754   if (err != GL_NO_ERROR) {
1755      if (!isProxy) {
1756         _mesa_error(ctx, err,
1757                     "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
1758                     dimensions, format, type);
1759      }
1760      return GL_TRUE;
1761   }
1762
1763   /* make sure internal format and format basically agree */
1764   colorFormat = _mesa_is_color_format(format);
1765   if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
1766       (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
1767       (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
1768       (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
1769       (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
1770      if (!isProxy)
1771         _mesa_error(ctx, GL_INVALID_OPERATION,
1772                     "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
1773                     dimensions, internalFormat, format);
1774      return GL_TRUE;
1775   }
1776
1777   /* additional checks for ycbcr textures */
1778   if (internalFormat == GL_YCBCR_MESA) {
1779      ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1780      if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
1781          type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
1782         char message[100];
1783         _mesa_snprintf(message, sizeof(message),
1784                        "glTexImage%dD(format/type YCBCR mismatch", dimensions);
1785         _mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
1786         return GL_TRUE; /* error */
1787      }
1788      if (target != GL_TEXTURE_2D &&
1789          target != GL_PROXY_TEXTURE_2D &&
1790          target != GL_TEXTURE_RECTANGLE_NV &&
1791          target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
1792         if (!isProxy)
1793            _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
1794         return GL_TRUE;
1795      }
1796      if (border != 0) {
1797         if (!isProxy) {
1798            char message[100];
1799            _mesa_snprintf(message, sizeof(message),
1800                           "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
1801                           dimensions, border);
1802            _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
1803         }
1804         return GL_TRUE;
1805      }
1806   }
1807
1808   /* additional checks for depth textures */
1809   if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
1810      /* Only 1D, 2D, rect, array and cube textures supported, not 3D
1811       * Cubemaps are only supported for GL version > 3.0 or with EXT_gpu_shader4 */
1812      if (target != GL_TEXTURE_1D &&
1813          target != GL_PROXY_TEXTURE_1D &&
1814          target != GL_TEXTURE_2D &&
1815          target != GL_PROXY_TEXTURE_2D &&
1816          target != GL_TEXTURE_1D_ARRAY &&
1817          target != GL_PROXY_TEXTURE_1D_ARRAY &&
1818          target != GL_TEXTURE_2D_ARRAY &&
1819          target != GL_PROXY_TEXTURE_2D_ARRAY &&
1820          target != GL_TEXTURE_RECTANGLE_ARB &&
1821          target != GL_PROXY_TEXTURE_RECTANGLE_ARB &&
1822         !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) &&
1823           (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))) {
1824         if (!isProxy)
1825            _mesa_error(ctx, GL_INVALID_ENUM,
1826                        "glTexImage(target/internalFormat)");
1827         return GL_TRUE;
1828      }
1829   }
1830
1831   /* additional checks for compressed textures */
1832   if (_mesa_is_compressed_format(ctx, internalFormat)) {
1833      if (!target_can_be_compressed(ctx, target, internalFormat)) {
1834         if (!isProxy)
1835            _mesa_error(ctx, GL_INVALID_ENUM,
1836                        "glTexImage%dD(target)", dimensions);
1837         return GL_TRUE;
1838      }
1839      if (compressedteximage_only_format(ctx, internalFormat)) {
1840         _mesa_error(ctx, GL_INVALID_OPERATION,
1841               "glTexImage%dD(no compression for format)", dimensions);
1842         return GL_TRUE;
1843      }
1844      if (border != 0) {
1845         if (!isProxy) {
1846            _mesa_error(ctx, GL_INVALID_OPERATION,
1847                        "glTexImage%dD(border!=0)", dimensions);
1848         }
1849         return GL_TRUE;
1850      }
1851   }
1852
1853   /* additional checks for integer textures */
1854   if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) &&
1855       (_mesa_is_enum_format_integer(format) !=
1856        _mesa_is_enum_format_integer(internalFormat))) {
1857      if (!isProxy) {
1858         _mesa_error(ctx, GL_INVALID_OPERATION,
1859                     "glTexImage%dD(integer/non-integer format mismatch)",
1860                     dimensions);
1861      }
1862      return GL_TRUE;
1863   }
1864
1865   if (!mutable_tex_object(ctx, target)) {
1866      _mesa_error(ctx, GL_INVALID_OPERATION,
1867                  "glTexImage%dD(immutable texture)", dimensions);
1868      return GL_TRUE;
1869   }
1870
1871   /* if we get here, the parameters are OK */
1872   return GL_FALSE;
1873}
1874
1875
1876/**
1877 * Test glTexSubImage[123]D() parameters for errors.
1878 *
1879 * \param ctx GL context.
1880 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1881 * \param target texture target given by the user.
1882 * \param level image level given by the user.
1883 * \param xoffset sub-image x offset given by the user.
1884 * \param yoffset sub-image y offset given by the user.
1885 * \param zoffset sub-image z offset given by the user.
1886 * \param format pixel data format given by the user.
1887 * \param type pixel data type given by the user.
1888 * \param width image width given by the user.
1889 * \param height image height given by the user.
1890 * \param depth image depth given by the user.
1891 *
1892 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1893 *
1894 * Verifies each of the parameters against the constants specified in
1895 * __struct gl_contextRec::Const and the supported extensions, and according
1896 * to the OpenGL specification.
1897 */
1898static GLboolean
1899subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
1900                        GLenum target, GLint level,
1901                        GLint xoffset, GLint yoffset, GLint zoffset,
1902                        GLint width, GLint height, GLint depth,
1903                        GLenum format, GLenum type )
1904{
1905   GLenum err;
1906
1907   /* Basic level check */
1908   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1909      _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
1910      return GL_TRUE;
1911   }
1912
1913   /* Check for negative sizes */
1914   if (width < 0) {
1915      _mesa_error(ctx, GL_INVALID_VALUE,
1916                  "glTexSubImage%dD(width=%d)", dimensions, width);
1917      return GL_TRUE;
1918   }
1919   if (height < 0 && dimensions > 1) {
1920      _mesa_error(ctx, GL_INVALID_VALUE,
1921                  "glTexSubImage%dD(height=%d)", dimensions, height);
1922      return GL_TRUE;
1923   }
1924   if (depth < 0 && dimensions > 2) {
1925      _mesa_error(ctx, GL_INVALID_VALUE,
1926                  "glTexSubImage%dD(depth=%d)", dimensions, depth);
1927      return GL_TRUE;
1928   }
1929
1930   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1931    * combinations of format and type that can be used.  Formats and types
1932    * that require additional extensions (e.g., GL_FLOAT requires
1933    * GL_OES_texture_float) are filtered elsewhere.
1934    */
1935   if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
1936      err = _mesa_es_error_check_format_and_type(format, type, dimensions);
1937      if (err != GL_NO_ERROR) {
1938         _mesa_error(ctx, err,
1939                     "glTexSubImage%dD(format = %s, type = %s)",
1940                     dimensions,
1941                     _mesa_lookup_enum_by_nr(format),
1942                     _mesa_lookup_enum_by_nr(type));
1943         return GL_TRUE;
1944      }
1945   }
1946
1947   err = _mesa_error_check_format_and_type(ctx, format, type);
1948   if (err != GL_NO_ERROR) {
1949      _mesa_error(ctx, err,
1950                  "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)",
1951                  dimensions, format, type);
1952      return GL_TRUE;
1953   }
1954
1955   return GL_FALSE;
1956}
1957
1958
1959/**
1960 * Do second part of glTexSubImage which depends on the destination texture.
1961 * \return GL_TRUE if error recorded, GL_FALSE otherwise
1962 */
1963static GLboolean
1964subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
1965			 GLenum target, GLint level,
1966			 GLint xoffset, GLint yoffset, GLint zoffset,
1967			 GLint width, GLint height, GLint depth,
1968			 GLenum format, GLenum type,
1969			 const struct gl_texture_image *destTex )
1970{
1971   if (!destTex) {
1972      /* undefined image level */
1973      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
1974      return GL_TRUE;
1975   }
1976
1977   if (xoffset < -((GLint)destTex->Border)) {
1978      _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
1979                  dimensions);
1980      return GL_TRUE;
1981   }
1982   if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
1983      _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
1984                  dimensions);
1985      return GL_TRUE;
1986   }
1987   if (dimensions > 1) {
1988      GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destTex->Border;
1989      if (yoffset < -yBorder) {
1990         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
1991                     dimensions);
1992         return GL_TRUE;
1993      }
1994      if (yoffset + height > (GLint) destTex->Height + yBorder) {
1995         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
1996                     dimensions);
1997         return GL_TRUE;
1998      }
1999   }
2000   if (dimensions > 2) {
2001      GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : destTex->Border;
2002      if (zoffset < -zBorder) {
2003         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
2004         return GL_TRUE;
2005      }
2006      if (zoffset + depth  > (GLint) destTex->Depth + zBorder) {
2007         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
2008         return GL_TRUE;
2009      }
2010   }
2011
2012   if (_mesa_is_format_compressed(destTex->TexFormat)) {
2013      GLuint bw, bh;
2014
2015      if (compressedteximage_only_format(ctx, destTex->InternalFormat)) {
2016         _mesa_error(ctx, GL_INVALID_OPERATION,
2017               "glTexSubImage%dD(no compression for format)", dimensions);
2018         return GL_TRUE;
2019      }
2020
2021      /* do tests which depend on compression block size */
2022      _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh);
2023
2024      /* offset must be multiple of block size */
2025      if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
2026         _mesa_error(ctx, GL_INVALID_OPERATION,
2027                     "glTexSubImage%dD(xoffset = %d, yoffset = %d)",
2028                     dimensions, xoffset, yoffset);
2029         return GL_TRUE;
2030      }
2031      /* size must be multiple of bw by bh or equal to whole texture size */
2032      if ((width % bw != 0) && (GLuint) width != destTex->Width) {
2033         _mesa_error(ctx, GL_INVALID_OPERATION,
2034                     "glTexSubImage%dD(width = %d)", dimensions, width);
2035         return GL_TRUE;
2036      }
2037      if ((height % bh != 0) && (GLuint) height != destTex->Height) {
2038         _mesa_error(ctx, GL_INVALID_OPERATION,
2039                     "glTexSubImage%dD(height = %d)", dimensions, height);
2040         return GL_TRUE;
2041      }
2042   }
2043
2044   if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
2045      /* both source and dest must be integer-valued, or neither */
2046      if (_mesa_is_format_integer_color(destTex->TexFormat) !=
2047          _mesa_is_enum_format_integer(format)) {
2048         _mesa_error(ctx, GL_INVALID_OPERATION,
2049                     "glTexSubImage%dD(integer/non-integer format mismatch)",
2050                     dimensions);
2051         return GL_TRUE;
2052      }
2053   }
2054
2055   return GL_FALSE;
2056}
2057
2058
2059/**
2060 * Test glCopyTexImage[12]D() parameters for errors.
2061 *
2062 * \param ctx GL context.
2063 * \param dimensions texture image dimensions (must be 1, 2 or 3).
2064 * \param target texture target given by the user.
2065 * \param level image level given by the user.
2066 * \param internalFormat internal format given by the user.
2067 * \param width image width given by the user.
2068 * \param height image height given by the user.
2069 * \param border texture border.
2070 *
2071 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2072 *
2073 * Verifies each of the parameters against the constants specified in
2074 * __struct gl_contextRec::Const and the supported extensions, and according
2075 * to the OpenGL specification.
2076 */
2077static GLboolean
2078copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
2079                         GLenum target, GLint level, GLint internalFormat,
2080                         GLint width, GLint height, GLint border )
2081{
2082   const GLenum proxyTarget = get_proxy_target(target);
2083   const GLenum type = GL_FLOAT;
2084   GLboolean sizeOK;
2085   GLint baseFormat;
2086
2087   /* check target */
2088   if (!legal_texsubimage_target(ctx, dimensions, target)) {
2089      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
2090                  dimensions, _mesa_lookup_enum_by_nr(target));
2091      return GL_TRUE;
2092   }
2093
2094   /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
2095   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
2096      _mesa_error(ctx, GL_INVALID_VALUE,
2097                  "glCopyTexImage%dD(level=%d)", dimensions, level);
2098      return GL_TRUE;
2099   }
2100
2101   /* Check that the source buffer is complete */
2102   if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
2103      if (ctx->ReadBuffer->_Status == 0) {
2104         _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2105      }
2106      if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2107         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2108                     "glCopyTexImage%dD(invalid readbuffer)", dimensions);
2109         return GL_TRUE;
2110      }
2111
2112      if (ctx->ReadBuffer->Visual.samples > 0) {
2113	 _mesa_error(ctx, GL_INVALID_OPERATION,
2114		     "glCopyTexImage%dD(multisample FBO)",
2115		     dimensions);
2116	 return GL_TRUE;
2117      }
2118   }
2119
2120   /* Check border */
2121   if (border < 0 || border > 1 ||
2122       ((ctx->API != API_OPENGL ||
2123         target == GL_TEXTURE_RECTANGLE_NV ||
2124         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
2125      _mesa_error(ctx, GL_INVALID_VALUE,
2126                  "glCopyTexImage%dD(border=%d)", dimensions, border);
2127      return GL_TRUE;
2128   }
2129
2130   baseFormat = _mesa_base_tex_format(ctx, internalFormat);
2131   if (baseFormat < 0) {
2132      _mesa_error(ctx, GL_INVALID_VALUE,
2133                  "glCopyTexImage%dD(internalFormat)", dimensions);
2134      return GL_TRUE;
2135   }
2136
2137   if (!_mesa_source_buffer_exists(ctx, baseFormat)) {
2138      _mesa_error(ctx, GL_INVALID_OPERATION,
2139                  "glCopyTexImage%dD(missing readbuffer)", dimensions);
2140      return GL_TRUE;
2141   }
2142
2143   /* From the EXT_texture_integer spec:
2144    *
2145    *     "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
2146    *      if the texture internalformat is an integer format and the read color
2147    *      buffer is not an integer format, or if the internalformat is not an
2148    *      integer format and the read color buffer is an integer format."
2149    */
2150   if (_mesa_is_color_format(internalFormat)) {
2151      struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
2152
2153      if (_mesa_is_enum_format_integer(rb->InternalFormat) !=
2154	  _mesa_is_enum_format_integer(internalFormat)) {
2155	 _mesa_error(ctx, GL_INVALID_OPERATION,
2156		     "glCopyTexImage%dD(integer vs non-integer)", dimensions);
2157	 return GL_TRUE;
2158      }
2159   }
2160
2161   /* Do size, level checking */
2162   sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
2163      ? (width == height) : 1;
2164
2165   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
2166                                                    internalFormat, baseFormat,
2167                                                    type, width, height,
2168                                                    1, border);
2169
2170   if (!sizeOK) {
2171      if (dimensions == 1) {
2172         _mesa_error(ctx, GL_INVALID_VALUE,
2173                     "glCopyTexImage1D(width=%d)", width);
2174      }
2175      else {
2176         ASSERT(dimensions == 2);
2177         _mesa_error(ctx, GL_INVALID_VALUE,
2178                     "glCopyTexImage2D(width=%d, height=%d)", width, height);
2179      }
2180      return GL_TRUE;
2181   }
2182
2183   if (_mesa_is_compressed_format(ctx, internalFormat)) {
2184      if (!target_can_be_compressed(ctx, target, internalFormat)) {
2185         _mesa_error(ctx, GL_INVALID_ENUM,
2186                     "glCopyTexImage%dD(target)", dimensions);
2187         return GL_TRUE;
2188      }
2189      if (compressedteximage_only_format(ctx, internalFormat)) {
2190         _mesa_error(ctx, GL_INVALID_OPERATION,
2191               "glCopyTexImage%dD(no compression for format)", dimensions);
2192         return GL_TRUE;
2193      }
2194      if (border != 0) {
2195         _mesa_error(ctx, GL_INVALID_OPERATION,
2196                     "glCopyTexImage%dD(border!=0)", dimensions);
2197         return GL_TRUE;
2198      }
2199   }
2200
2201   if (!mutable_tex_object(ctx, target)) {
2202      _mesa_error(ctx, GL_INVALID_OPERATION,
2203                  "glCopyTexImage%dD(immutable texture)", dimensions);
2204      return GL_TRUE;
2205   }
2206
2207   /* if we get here, the parameters are OK */
2208   return GL_FALSE;
2209}
2210
2211
2212/**
2213 * Test glCopyTexSubImage[12]D() parameters for errors.
2214 * Note that this is the first part of error checking.
2215 * See also copytexsubimage_error_check2() below for the second part.
2216 *
2217 * \param ctx GL context.
2218 * \param dimensions texture image dimensions (must be 1, 2 or 3).
2219 * \param target texture target given by the user.
2220 * \param level image level given by the user.
2221 *
2222 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2223 */
2224static GLboolean
2225copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
2226                              GLenum target, GLint level)
2227{
2228   /* Check that the source buffer is complete */
2229   if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
2230      if (ctx->ReadBuffer->_Status == 0) {
2231         _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2232      }
2233      if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2234         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2235                     "glCopyTexImage%dD(invalid readbuffer)", dimensions);
2236         return GL_TRUE;
2237      }
2238
2239      if (ctx->ReadBuffer->Visual.samples > 0) {
2240	 _mesa_error(ctx, GL_INVALID_OPERATION,
2241		     "glCopyTexSubImage%dD(multisample FBO)",
2242		     dimensions);
2243	 return GL_TRUE;
2244      }
2245   }
2246
2247   /* check target (proxies not allowed) */
2248   if (!legal_texsubimage_target(ctx, dimensions, target)) {
2249      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
2250                  dimensions, _mesa_lookup_enum_by_nr(target));
2251      return GL_TRUE;
2252   }
2253
2254   /* Check level */
2255   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
2256      _mesa_error(ctx, GL_INVALID_VALUE,
2257                  "glCopyTexSubImage%dD(level=%d)", dimensions, level);
2258      return GL_TRUE;
2259   }
2260
2261   return GL_FALSE;
2262}
2263
2264
2265/**
2266 * Second part of error checking for glCopyTexSubImage[12]D().
2267 * \param xoffset sub-image x offset given by the user.
2268 * \param yoffset sub-image y offset given by the user.
2269 * \param zoffset sub-image z offset given by the user.
2270 * \param width image width given by the user.
2271 * \param height image height given by the user.
2272 */
2273static GLboolean
2274copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
2275			      GLenum target, GLint level,
2276			      GLint xoffset, GLint yoffset, GLint zoffset,
2277			      GLsizei width, GLsizei height,
2278			      const struct gl_texture_image *teximage )
2279{
2280   /* check that dest tex image exists */
2281   if (!teximage) {
2282      _mesa_error(ctx, GL_INVALID_OPERATION,
2283                  "glCopyTexSubImage%dD(undefined texture level: %d)",
2284                  dimensions, level);
2285      return GL_TRUE;
2286   }
2287
2288   /* Check size */
2289   if (width < 0) {
2290      _mesa_error(ctx, GL_INVALID_VALUE,
2291                  "glCopyTexSubImage%dD(width=%d)", dimensions, width);
2292      return GL_TRUE;
2293   }
2294   if (dimensions > 1 && height < 0) {
2295      _mesa_error(ctx, GL_INVALID_VALUE,
2296                  "glCopyTexSubImage%dD(height=%d)", dimensions, height);
2297      return GL_TRUE;
2298   }
2299
2300   /* check x/y offsets */
2301   if (xoffset < -((GLint)teximage->Border)) {
2302      _mesa_error(ctx, GL_INVALID_VALUE,
2303                  "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
2304      return GL_TRUE;
2305   }
2306   if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
2307      _mesa_error(ctx, GL_INVALID_VALUE,
2308                  "glCopyTexSubImage%dD(xoffset+width)", dimensions);
2309      return GL_TRUE;
2310   }
2311   if (dimensions > 1) {
2312      GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : teximage->Border;
2313      if (yoffset < -yBorder) {
2314         _mesa_error(ctx, GL_INVALID_VALUE,
2315                     "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
2316         return GL_TRUE;
2317      }
2318      /* NOTE: we're adding the border here, not subtracting! */
2319      if (yoffset + height > (GLint) teximage->Height + yBorder) {
2320         _mesa_error(ctx, GL_INVALID_VALUE,
2321                     "glCopyTexSubImage%dD(yoffset+height)", dimensions);
2322         return GL_TRUE;
2323      }
2324   }
2325
2326   /* check z offset */
2327   if (dimensions > 2) {
2328      GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : teximage->Border;
2329      if (zoffset < -zBorder) {
2330         _mesa_error(ctx, GL_INVALID_VALUE,
2331                     "glCopyTexSubImage%dD(zoffset)", dimensions);
2332         return GL_TRUE;
2333      }
2334      if (zoffset > (GLint) teximage->Depth + zBorder) {
2335         _mesa_error(ctx, GL_INVALID_VALUE,
2336                     "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
2337         return GL_TRUE;
2338      }
2339   }
2340
2341   if (_mesa_is_format_compressed(teximage->TexFormat)) {
2342      if (compressedteximage_only_format(ctx, teximage->InternalFormat)) {
2343         _mesa_error(ctx, GL_INVALID_OPERATION,
2344               "glCopyTexSubImage%dD(no compression for format)", dimensions);
2345         return GL_TRUE;
2346      }
2347      /* offset must be multiple of 4 */
2348      if ((xoffset & 3) || (yoffset & 3)) {
2349         _mesa_error(ctx, GL_INVALID_VALUE,
2350                     "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions);
2351         return GL_TRUE;
2352      }
2353      /* size must be multiple of 4 */
2354      if ((width & 3) != 0 && (GLuint) width != teximage->Width) {
2355         _mesa_error(ctx, GL_INVALID_VALUE,
2356                     "glCopyTexSubImage%dD(width)", dimensions);
2357         return GL_TRUE;
2358      }
2359      if ((height & 3) != 0 && (GLuint) height != teximage->Height) {
2360         _mesa_error(ctx, GL_INVALID_VALUE,
2361                     "glCopyTexSubImage%dD(height)", dimensions);
2362         return GL_TRUE;
2363      }
2364   }
2365
2366   if (teximage->InternalFormat == GL_YCBCR_MESA) {
2367      _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
2368      return GL_TRUE;
2369   }
2370
2371   if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
2372      _mesa_error(ctx, GL_INVALID_OPERATION,
2373                  "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)",
2374                  dimensions, teximage->_BaseFormat);
2375      return GL_TRUE;
2376   }
2377
2378   /* From the EXT_texture_integer spec:
2379    *
2380    *     "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
2381    *      if the texture internalformat is an integer format and the read color
2382    *      buffer is not an integer format, or if the internalformat is not an
2383    *      integer format and the read color buffer is an integer format."
2384    */
2385   if (_mesa_is_color_format(teximage->InternalFormat)) {
2386      struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
2387
2388      if (_mesa_is_format_integer_color(rb->Format) !=
2389	  _mesa_is_format_integer_color(teximage->TexFormat)) {
2390	 _mesa_error(ctx, GL_INVALID_OPERATION,
2391		     "glCopyTexImage%dD(integer vs non-integer)", dimensions);
2392	 return GL_TRUE;
2393      }
2394   }
2395
2396   /* if we get here, the parameters are OK */
2397   return GL_FALSE;
2398}
2399
2400
2401/** Callback info for walking over FBO hash table */
2402struct cb_info
2403{
2404   struct gl_context *ctx;
2405   struct gl_texture_object *texObj;
2406   GLuint level, face;
2407};
2408
2409
2410/**
2411 * Check render to texture callback.  Called from _mesa_HashWalk().
2412 */
2413static void
2414check_rtt_cb(GLuint key, void *data, void *userData)
2415{
2416   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2417   const struct cb_info *info = (struct cb_info *) userData;
2418   struct gl_context *ctx = info->ctx;
2419   const struct gl_texture_object *texObj = info->texObj;
2420   const GLuint level = info->level, face = info->face;
2421
2422   /* If this is a user-created FBO */
2423   if (_mesa_is_user_fbo(fb)) {
2424      GLuint i;
2425      /* check if any of the FBO's attachments point to 'texObj' */
2426      for (i = 0; i < BUFFER_COUNT; i++) {
2427         struct gl_renderbuffer_attachment *att = fb->Attachment + i;
2428         if (att->Type == GL_TEXTURE &&
2429             att->Texture == texObj &&
2430             att->TextureLevel == level &&
2431             att->CubeMapFace == face) {
2432            ASSERT(_mesa_get_attachment_teximage(att));
2433            /* Tell driver about the new renderbuffer texture */
2434            ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
2435            /* Mark fb status as indeterminate to force re-validation */
2436            fb->_Status = 0;
2437         }
2438      }
2439   }
2440}
2441
2442
2443/**
2444 * When a texture image is specified we have to check if it's bound to
2445 * any framebuffer objects (render to texture) in order to detect changes
2446 * in size or format since that effects FBO completeness.
2447 * Any FBOs rendering into the texture must be re-validated.
2448 */
2449void
2450_mesa_update_fbo_texture(struct gl_context *ctx,
2451                         struct gl_texture_object *texObj,
2452                         GLuint face, GLuint level)
2453{
2454   /* Only check this texture if it's been marked as RenderToTexture */
2455   if (texObj->_RenderToTexture) {
2456      struct cb_info info;
2457      info.ctx = ctx;
2458      info.texObj = texObj;
2459      info.level = level;
2460      info.face = face;
2461      _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info);
2462   }
2463}
2464
2465
2466/**
2467 * If the texture object's GenerateMipmap flag is set and we've
2468 * changed the texture base level image, regenerate the rest of the
2469 * mipmap levels now.
2470 */
2471static inline void
2472check_gen_mipmap(struct gl_context *ctx, GLenum target,
2473                 struct gl_texture_object *texObj, GLint level)
2474{
2475   ASSERT(target != GL_TEXTURE_CUBE_MAP);
2476   if (texObj->GenerateMipmap &&
2477       level == texObj->BaseLevel &&
2478       level < texObj->MaxLevel) {
2479      ASSERT(ctx->Driver.GenerateMipmap);
2480      ctx->Driver.GenerateMipmap(ctx, target, texObj);
2481   }
2482}
2483
2484
2485/** Debug helper: override the user-requested internal format */
2486static GLenum
2487override_internal_format(GLenum internalFormat, GLint width, GLint height)
2488{
2489#if 0
2490   if (internalFormat == GL_RGBA16F_ARB ||
2491       internalFormat == GL_RGBA32F_ARB) {
2492      printf("Convert rgba float tex to int %d x %d\n", width, height);
2493      return GL_RGBA;
2494   }
2495   else if (internalFormat == GL_RGB16F_ARB ||
2496            internalFormat == GL_RGB32F_ARB) {
2497      printf("Convert rgb float tex to int %d x %d\n", width, height);
2498      return GL_RGB;
2499   }
2500   else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB ||
2501            internalFormat == GL_LUMINANCE_ALPHA32F_ARB) {
2502      printf("Convert luminance float tex to int %d x %d\n", width, height);
2503      return GL_LUMINANCE_ALPHA;
2504   }
2505   else if (internalFormat == GL_LUMINANCE16F_ARB ||
2506            internalFormat == GL_LUMINANCE32F_ARB) {
2507      printf("Convert luminance float tex to int %d x %d\n", width, height);
2508      return GL_LUMINANCE;
2509   }
2510   else if (internalFormat == GL_ALPHA16F_ARB ||
2511            internalFormat == GL_ALPHA32F_ARB) {
2512      printf("Convert luminance float tex to int %d x %d\n", width, height);
2513      return GL_ALPHA;
2514   }
2515   /*
2516   else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
2517      internalFormat = GL_RGBA;
2518   }
2519   */
2520   else {
2521      return internalFormat;
2522   }
2523#else
2524   return internalFormat;
2525#endif
2526}
2527
2528
2529/**
2530 * Choose the actual hardware format for a texture image.
2531 * Try to use the same format as the previous image level when possible.
2532 * Otherwise, ask the driver for the best format.
2533 * It's important to try to choose a consistant format for all levels
2534 * for efficient texture memory layout/allocation.  In particular, this
2535 * comes up during automatic mipmap generation.
2536 */
2537gl_format
2538_mesa_choose_texture_format(struct gl_context *ctx,
2539                            struct gl_texture_object *texObj,
2540                            GLenum target, GLint level,
2541                            GLenum internalFormat, GLenum format, GLenum type)
2542{
2543   gl_format f;
2544
2545   /* see if we've already chosen a format for the previous level */
2546   if (level > 0) {
2547      struct gl_texture_image *prevImage =
2548	 _mesa_select_tex_image(ctx, texObj, target, level - 1);
2549      /* See if the prev level is defined and has an internal format which
2550       * matches the new internal format.
2551       */
2552      if (prevImage &&
2553          prevImage->Width > 0 &&
2554          prevImage->InternalFormat == internalFormat) {
2555         /* use the same format */
2556         ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE);
2557         return prevImage->TexFormat;
2558      }
2559   }
2560
2561   /* choose format from scratch */
2562   f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
2563   ASSERT(f != MESA_FORMAT_NONE);
2564   return f;
2565}
2566
2567/**
2568 * Adjust pixel unpack params and image dimensions to strip off the
2569 * one-pixel texture border.
2570 *
2571 * Gallium and intel don't support texture borders.  They've seldem been used
2572 * and seldom been implemented correctly anyway.
2573 *
2574 * \param unpackNew returns the new pixel unpack parameters
2575 */
2576static void
2577strip_texture_border(GLenum target,
2578                     GLint *width, GLint *height, GLint *depth,
2579                     const struct gl_pixelstore_attrib *unpack,
2580                     struct gl_pixelstore_attrib *unpackNew)
2581{
2582   assert(width);
2583   assert(height);
2584   assert(depth);
2585
2586   *unpackNew = *unpack;
2587
2588   if (unpackNew->RowLength == 0)
2589      unpackNew->RowLength = *width;
2590
2591   if (unpackNew->ImageHeight == 0)
2592      unpackNew->ImageHeight = *height;
2593
2594   assert(*width >= 3);
2595   unpackNew->SkipPixels++;  /* skip the border */
2596   *width = *width - 2;      /* reduce the width by two border pixels */
2597
2598   /* The min height of a texture with a border is 3 */
2599   if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) {
2600      unpackNew->SkipRows++;  /* skip the border */
2601      *height = *height - 2;  /* reduce the height by two border pixels */
2602   }
2603
2604   if (*depth >= 3 && target != GL_TEXTURE_2D_ARRAY) {
2605      unpackNew->SkipImages++;  /* skip the border */
2606      *depth = *depth - 2;      /* reduce the depth by two border pixels */
2607   }
2608}
2609
2610/**
2611 * Common code to implement all the glTexImage1D/2D/3D functions.
2612 */
2613static void
2614teximage(struct gl_context *ctx, GLuint dims,
2615         GLenum target, GLint level, GLint internalFormat,
2616         GLsizei width, GLsizei height, GLsizei depth,
2617         GLint border, GLenum format, GLenum type,
2618         const GLvoid *pixels)
2619{
2620   GLboolean error;
2621   struct gl_pixelstore_attrib unpack_no_border;
2622   const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
2623
2624   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2625
2626   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2627      _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
2628                  dims,
2629                  _mesa_lookup_enum_by_nr(target), level,
2630                  _mesa_lookup_enum_by_nr(internalFormat),
2631                  width, height, depth, border,
2632                  _mesa_lookup_enum_by_nr(format),
2633                  _mesa_lookup_enum_by_nr(type), pixels);
2634
2635   internalFormat = override_internal_format(internalFormat, width, height);
2636
2637   /* target error checking */
2638   if (!legal_teximage_target(ctx, dims, target)) {
2639      _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
2640                  dims, _mesa_lookup_enum_by_nr(target));
2641      return;
2642   }
2643
2644   /* general error checking */
2645   error = texture_error_check(ctx, dims, target, level, internalFormat,
2646                               format, type, width, height, depth, border);
2647
2648   if (_mesa_is_proxy_texture(target)) {
2649      /* Proxy texture: just clear or set state depending on error checking */
2650      struct gl_texture_image *texImage =
2651         _mesa_get_proxy_tex_image(ctx, target, level);
2652
2653      if (error) {
2654         /* when error, clear all proxy texture image parameters */
2655         if (texImage)
2656            clear_teximage_fields(texImage);
2657      }
2658      else {
2659         /* no error, set the tex image parameters */
2660         struct gl_texture_object *texObj =
2661            _mesa_get_current_tex_object(ctx, target);
2662         gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
2663                                                           target, level,
2664                                                           internalFormat,
2665                                                           format, type);
2666
2667         if (legal_texture_size(ctx, texFormat, width, height, depth)) {
2668            _mesa_init_teximage_fields(ctx, texImage, width, height,
2669                                       depth, border, internalFormat,
2670                                       texFormat);
2671         }
2672         else if (texImage) {
2673            clear_teximage_fields(texImage);
2674         }
2675      }
2676   }
2677   else {
2678      /* non-proxy target */
2679      const GLuint face = _mesa_tex_target_to_face(target);
2680      struct gl_texture_object *texObj;
2681      struct gl_texture_image *texImage;
2682
2683      if (error) {
2684         return;   /* error was recorded */
2685      }
2686
2687      /* Allow a hardware driver to just strip out the border, to provide
2688       * reliable but slightly incorrect hardware rendering instead of
2689       * rarely-tested software fallback rendering.
2690       */
2691      if (border && ctx->Const.StripTextureBorder) {
2692	 strip_texture_border(target, &width, &height, &depth, unpack,
2693			      &unpack_no_border);
2694         border = 0;
2695	 unpack = &unpack_no_border;
2696      }
2697
2698      if (ctx->NewState & _NEW_PIXEL)
2699	 _mesa_update_state(ctx);
2700
2701      texObj = _mesa_get_current_tex_object(ctx, target);
2702
2703      _mesa_lock_texture(ctx, texObj);
2704      {
2705	 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
2706
2707	 if (!texImage) {
2708	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
2709	 }
2710         else {
2711            gl_format texFormat;
2712
2713            ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
2714
2715            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
2716                                                    internalFormat, format,
2717                                                    type);
2718
2719            if (legal_texture_size(ctx, texFormat, width, height, depth)) {
2720               _mesa_init_teximage_fields(ctx, texImage,
2721                                          width, height, depth,
2722                                          border, internalFormat, texFormat);
2723
2724               /* Give the texture to the driver.  <pixels> may be null. */
2725               ctx->Driver.TexImage(ctx, dims, texImage, format,
2726                                    type, pixels, unpack);
2727
2728               check_gen_mipmap(ctx, target, texObj, level);
2729
2730               _mesa_update_fbo_texture(ctx, texObj, face, level);
2731
2732               _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
2733            }
2734            else {
2735               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
2736            }
2737         }
2738      }
2739      _mesa_unlock_texture(ctx, texObj);
2740   }
2741}
2742
2743
2744/*
2745 * Called from the API.  Note that width includes the border.
2746 */
2747void GLAPIENTRY
2748_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
2749                  GLsizei width, GLint border, GLenum format,
2750                  GLenum type, const GLvoid *pixels )
2751{
2752   GET_CURRENT_CONTEXT(ctx);
2753   teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
2754            border, format, type, pixels);
2755}
2756
2757
2758void GLAPIENTRY
2759_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
2760                  GLsizei width, GLsizei height, GLint border,
2761                  GLenum format, GLenum type,
2762                  const GLvoid *pixels )
2763{
2764   GET_CURRENT_CONTEXT(ctx);
2765   teximage(ctx, 2, target, level, internalFormat, width, height, 1,
2766            border, format, type, pixels);
2767}
2768
2769
2770/*
2771 * Called by the API or display list executor.
2772 * Note that width and height include the border.
2773 */
2774void GLAPIENTRY
2775_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
2776                  GLsizei width, GLsizei height, GLsizei depth,
2777                  GLint border, GLenum format, GLenum type,
2778                  const GLvoid *pixels )
2779{
2780   GET_CURRENT_CONTEXT(ctx);
2781   teximage(ctx, 3, target, level, internalFormat, width, height, depth,
2782            border, format, type, pixels);
2783}
2784
2785
2786void GLAPIENTRY
2787_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
2788                     GLsizei width, GLsizei height, GLsizei depth,
2789                     GLint border, GLenum format, GLenum type,
2790                     const GLvoid *pixels )
2791{
2792   _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
2793                    depth, border, format, type, pixels);
2794}
2795
2796
2797#if FEATURE_OES_EGL_image
2798void GLAPIENTRY
2799_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
2800{
2801   struct gl_texture_object *texObj;
2802   struct gl_texture_image *texImage;
2803   bool valid_target;
2804   GET_CURRENT_CONTEXT(ctx);
2805   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2806
2807   switch (target) {
2808   case GL_TEXTURE_2D:
2809      valid_target = ctx->Extensions.OES_EGL_image;
2810      break;
2811   case GL_TEXTURE_EXTERNAL_OES:
2812      valid_target = ctx->Extensions.OES_EGL_image_external;
2813      break;
2814   default:
2815      valid_target = false;
2816      break;
2817   }
2818
2819   if (!valid_target) {
2820      _mesa_error(ctx, GL_INVALID_ENUM,
2821		  "glEGLImageTargetTexture2D(target=%d)", target);
2822      return;
2823   }
2824
2825   if (ctx->NewState & _NEW_PIXEL)
2826      _mesa_update_state(ctx);
2827
2828   texObj = _mesa_get_current_tex_object(ctx, target);
2829   _mesa_lock_texture(ctx, texObj);
2830
2831   if (texObj->Immutable) {
2832      _mesa_error(ctx, GL_INVALID_OPERATION,
2833		  "glEGLImageTargetTexture2D(texture is immutable)");
2834      _mesa_unlock_texture(ctx, texObj);
2835      return;
2836   }
2837
2838   texImage = _mesa_get_tex_image(ctx, texObj, target, 0);
2839   if (!texImage) {
2840      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D");
2841   } else {
2842      ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
2843
2844      ctx->Driver.EGLImageTargetTexture2D(ctx, target,
2845					  texObj, texImage, image);
2846
2847      _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
2848   }
2849   _mesa_unlock_texture(ctx, texObj);
2850
2851}
2852#endif
2853
2854
2855
2856/**
2857 * Implement all the glTexSubImage1/2/3D() functions.
2858 */
2859static void
2860texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
2861            GLint xoffset, GLint yoffset, GLint zoffset,
2862            GLsizei width, GLsizei height, GLsizei depth,
2863            GLenum format, GLenum type, const GLvoid *pixels )
2864{
2865   struct gl_texture_object *texObj;
2866   struct gl_texture_image *texImage;
2867
2868   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2869
2870   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2871      _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
2872                  dims,
2873                  _mesa_lookup_enum_by_nr(target), level,
2874                  xoffset, yoffset, zoffset, width, height, depth,
2875                  _mesa_lookup_enum_by_nr(format),
2876                  _mesa_lookup_enum_by_nr(type), pixels);
2877
2878   /* check target (proxies not allowed) */
2879   if (!legal_texsubimage_target(ctx, dims, target)) {
2880      _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
2881                  dims, _mesa_lookup_enum_by_nr(target));
2882      return;
2883   }
2884
2885   if (ctx->NewState & _NEW_PIXEL)
2886      _mesa_update_state(ctx);
2887
2888   if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset,
2889                              width, height, depth, format, type)) {
2890      return;   /* error was detected */
2891   }
2892
2893   texObj = _mesa_get_current_tex_object(ctx, target);
2894
2895   _mesa_lock_texture(ctx, texObj);
2896   {
2897      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
2898
2899      if (subtexture_error_check2(ctx, dims, target, level,
2900                                  xoffset, yoffset, zoffset,
2901				  width, height, depth,
2902                                  format, type, texImage)) {
2903         /* error was recorded */
2904      }
2905      else if (width > 0 && height > 0 && depth > 0) {
2906         /* If we have a border, offset=-1 is legal.  Bias by border width. */
2907         switch (dims) {
2908         case 3:
2909            if (target != GL_TEXTURE_2D_ARRAY)
2910               zoffset += texImage->Border;
2911            /* fall-through */
2912         case 2:
2913            if (target != GL_TEXTURE_1D_ARRAY)
2914               yoffset += texImage->Border;
2915            /* fall-through */
2916         case 1:
2917            xoffset += texImage->Border;
2918         }
2919
2920         ctx->Driver.TexSubImage(ctx, dims, texImage,
2921                                 xoffset, yoffset, zoffset,
2922                                 width, height, depth,
2923                                 format, type, pixels, &ctx->Unpack);
2924
2925         check_gen_mipmap(ctx, target, texObj, level);
2926
2927         ctx->NewState |= _NEW_TEXTURE;
2928      }
2929   }
2930   _mesa_unlock_texture(ctx, texObj);
2931}
2932
2933
2934void GLAPIENTRY
2935_mesa_TexSubImage1D( GLenum target, GLint level,
2936                     GLint xoffset, GLsizei width,
2937                     GLenum format, GLenum type,
2938                     const GLvoid *pixels )
2939{
2940   GET_CURRENT_CONTEXT(ctx);
2941   texsubimage(ctx, 1, target, level,
2942               xoffset, 0, 0,
2943               width, 1, 1,
2944               format, type, pixels);
2945}
2946
2947
2948void GLAPIENTRY
2949_mesa_TexSubImage2D( GLenum target, GLint level,
2950                     GLint xoffset, GLint yoffset,
2951                     GLsizei width, GLsizei height,
2952                     GLenum format, GLenum type,
2953                     const GLvoid *pixels )
2954{
2955   GET_CURRENT_CONTEXT(ctx);
2956   texsubimage(ctx, 2, target, level,
2957               xoffset, yoffset, 0,
2958               width, height, 1,
2959               format, type, pixels);
2960}
2961
2962
2963
2964void GLAPIENTRY
2965_mesa_TexSubImage3D( GLenum target, GLint level,
2966                     GLint xoffset, GLint yoffset, GLint zoffset,
2967                     GLsizei width, GLsizei height, GLsizei depth,
2968                     GLenum format, GLenum type,
2969                     const GLvoid *pixels )
2970{
2971   GET_CURRENT_CONTEXT(ctx);
2972   texsubimage(ctx, 3, target, level,
2973               xoffset, yoffset, zoffset,
2974               width, height, depth,
2975               format, type, pixels);
2976}
2977
2978
2979
2980/**
2981 * For glCopyTexSubImage, return the source renderbuffer to copy texel data
2982 * from.  This depends on whether the texture contains color or depth values.
2983 */
2984static struct gl_renderbuffer *
2985get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat)
2986{
2987   if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) {
2988      /* reading from depth/stencil buffer */
2989      return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
2990   }
2991   else {
2992      /* copying from color buffer */
2993      return ctx->ReadBuffer->_ColorReadBuffer;
2994   }
2995}
2996
2997
2998
2999/**
3000 * Implement the glCopyTexImage1/2D() functions.
3001 */
3002static void
3003copyteximage(struct gl_context *ctx, GLuint dims,
3004             GLenum target, GLint level, GLenum internalFormat,
3005             GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
3006{
3007   struct gl_texture_object *texObj;
3008   struct gl_texture_image *texImage;
3009   const GLuint face = _mesa_tex_target_to_face(target);
3010
3011   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3012
3013   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3014      _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
3015                  dims,
3016                  _mesa_lookup_enum_by_nr(target), level,
3017                  _mesa_lookup_enum_by_nr(internalFormat),
3018                  x, y, width, height, border);
3019
3020   if (ctx->NewState & NEW_COPY_TEX_STATE)
3021      _mesa_update_state(ctx);
3022
3023   if (copytexture_error_check(ctx, dims, target, level, internalFormat,
3024                               width, height, border))
3025      return;
3026
3027   texObj = _mesa_get_current_tex_object(ctx, target);
3028
3029   if (border && ctx->Const.StripTextureBorder) {
3030      x += border;
3031      width -= border * 2;
3032      if (dims == 2) {
3033	 y += border;
3034	 height -= border * 2;
3035      }
3036      border = 0;
3037   }
3038
3039   _mesa_lock_texture(ctx, texObj);
3040   {
3041      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
3042
3043      if (!texImage) {
3044	 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
3045      }
3046      else {
3047         /* choose actual hw format */
3048         gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
3049                                                           target, level,
3050                                                           internalFormat,
3051                                                           GL_NONE, GL_NONE);
3052
3053         if (legal_texture_size(ctx, texFormat, width, height, 1)) {
3054            GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0;
3055
3056            /* Free old texture image */
3057            ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
3058
3059            _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
3060                                       border, internalFormat, texFormat);
3061
3062            /* Allocate texture memory (no pixel data yet) */
3063            ctx->Driver.TexImage(ctx, dims, texImage,
3064                                 GL_NONE, GL_NONE,
3065                                 NULL, &ctx->Unpack);
3066
3067            if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
3068                                           &width, &height)) {
3069               struct gl_renderbuffer *srcRb =
3070                  get_copy_tex_image_source(ctx, texImage->TexFormat);
3071
3072               ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ,
3073                                           srcRb, srcX, srcY, width, height);
3074            }
3075
3076            check_gen_mipmap(ctx, target, texObj, level);
3077
3078            _mesa_update_fbo_texture(ctx, texObj, face, level);
3079
3080            _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
3081         }
3082         else {
3083            /* probably too large of image */
3084            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
3085         }
3086      }
3087   }
3088   _mesa_unlock_texture(ctx, texObj);
3089}
3090
3091
3092
3093void GLAPIENTRY
3094_mesa_CopyTexImage1D( GLenum target, GLint level,
3095                      GLenum internalFormat,
3096                      GLint x, GLint y,
3097                      GLsizei width, GLint border )
3098{
3099   GET_CURRENT_CONTEXT(ctx);
3100   copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
3101}
3102
3103
3104
3105void GLAPIENTRY
3106_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
3107                      GLint x, GLint y, GLsizei width, GLsizei height,
3108                      GLint border )
3109{
3110   GET_CURRENT_CONTEXT(ctx);
3111   copyteximage(ctx, 2, target, level, internalFormat,
3112                x, y, width, height, border);
3113}
3114
3115
3116
3117/**
3118 * Implementation for glCopyTexSubImage1/2/3D() functions.
3119 */
3120static void
3121copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
3122                GLint xoffset, GLint yoffset, GLint zoffset,
3123                GLint x, GLint y, GLsizei width, GLsizei height)
3124{
3125   struct gl_texture_object *texObj;
3126   struct gl_texture_image *texImage;
3127
3128   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3129
3130   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3131      _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n",
3132                  dims,
3133                  _mesa_lookup_enum_by_nr(target),
3134                  level, xoffset, yoffset, zoffset, x, y, width, height);
3135
3136   if (ctx->NewState & NEW_COPY_TEX_STATE)
3137      _mesa_update_state(ctx);
3138
3139   if (copytexsubimage_error_check1(ctx, dims, target, level))
3140      return;
3141
3142   texObj = _mesa_get_current_tex_object(ctx, target);
3143
3144   _mesa_lock_texture(ctx, texObj);
3145   {
3146      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
3147
3148      if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset,
3149				       zoffset, width, height, texImage)) {
3150         /* error was recored */
3151      }
3152      else {
3153         /* If we have a border, offset=-1 is legal.  Bias by border width. */
3154         switch (dims) {
3155         case 3:
3156            if (target != GL_TEXTURE_2D_ARRAY)
3157               zoffset += texImage->Border;
3158            /* fall-through */
3159         case 2:
3160            if (target != GL_TEXTURE_1D_ARRAY)
3161               yoffset += texImage->Border;
3162            /* fall-through */
3163         case 1:
3164            xoffset += texImage->Border;
3165         }
3166
3167         if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
3168                                        &width, &height)) {
3169            struct gl_renderbuffer *srcRb =
3170               get_copy_tex_image_source(ctx, texImage->TexFormat);
3171
3172            ctx->Driver.CopyTexSubImage(ctx, dims, texImage,
3173                                        xoffset, yoffset, zoffset,
3174                                        srcRb, x, y, width, height);
3175
3176            check_gen_mipmap(ctx, target, texObj, level);
3177
3178            ctx->NewState |= _NEW_TEXTURE;
3179         }
3180      }
3181   }
3182   _mesa_unlock_texture(ctx, texObj);
3183}
3184
3185
3186void GLAPIENTRY
3187_mesa_CopyTexSubImage1D( GLenum target, GLint level,
3188                         GLint xoffset, GLint x, GLint y, GLsizei width )
3189{
3190   GET_CURRENT_CONTEXT(ctx);
3191   copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1);
3192}
3193
3194
3195
3196void GLAPIENTRY
3197_mesa_CopyTexSubImage2D( GLenum target, GLint level,
3198                         GLint xoffset, GLint yoffset,
3199                         GLint x, GLint y, GLsizei width, GLsizei height )
3200{
3201   GET_CURRENT_CONTEXT(ctx);
3202   copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y,
3203                   width, height);
3204}
3205
3206
3207
3208void GLAPIENTRY
3209_mesa_CopyTexSubImage3D( GLenum target, GLint level,
3210                         GLint xoffset, GLint yoffset, GLint zoffset,
3211                         GLint x, GLint y, GLsizei width, GLsizei height )
3212{
3213   GET_CURRENT_CONTEXT(ctx);
3214   copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
3215                   x, y, width, height);
3216}
3217
3218
3219
3220
3221/**********************************************************************/
3222/******                   Compressed Textures                    ******/
3223/**********************************************************************/
3224
3225
3226/**
3227 * Return expected size of a compressed texture.
3228 */
3229static GLuint
3230compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
3231                    GLenum glformat)
3232{
3233   gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
3234   return _mesa_format_image_size(mesaFormat, width, height, depth);
3235}
3236
3237
3238/*
3239 * Return compressed texture block size, in pixels.
3240 */
3241static void
3242get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
3243{
3244   gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
3245   _mesa_get_format_block_size(mesaFormat, bw, bh);
3246}
3247
3248
3249/**
3250 * Error checking for glCompressedTexImage[123]D().
3251 * \param reason  returns reason for error, if any
3252 * \return error code or GL_NO_ERROR.
3253 */
3254static GLenum
3255compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
3256                               GLenum target, GLint level,
3257                               GLenum internalFormat, GLsizei width,
3258                               GLsizei height, GLsizei depth, GLint border,
3259                               GLsizei imageSize, char **reason)
3260{
3261   const GLenum proxyTarget = get_proxy_target(target);
3262   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
3263   GLint expectedSize;
3264   GLenum choose_format;
3265   GLenum choose_type;
3266   GLenum proxy_format;
3267
3268   *reason = ""; /* no error */
3269
3270   if (!target_can_be_compressed(ctx, target, internalFormat)) {
3271      *reason = "target";
3272      return GL_INVALID_ENUM;
3273   }
3274
3275   /* This will detect any invalid internalFormat value */
3276   if (!_mesa_is_compressed_format(ctx, internalFormat)) {
3277      *reason = "internalFormat";
3278      return GL_INVALID_ENUM;
3279   }
3280
3281   switch (internalFormat) {
3282#if FEATURE_ES
3283   case GL_PALETTE4_RGB8_OES:
3284   case GL_PALETTE4_RGBA8_OES:
3285   case GL_PALETTE4_R5_G6_B5_OES:
3286   case GL_PALETTE4_RGBA4_OES:
3287   case GL_PALETTE4_RGB5_A1_OES:
3288   case GL_PALETTE8_RGB8_OES:
3289   case GL_PALETTE8_RGBA8_OES:
3290   case GL_PALETTE8_R5_G6_B5_OES:
3291   case GL_PALETTE8_RGBA4_OES:
3292   case GL_PALETTE8_RGB5_A1_OES:
3293      _mesa_cpal_compressed_format_type(internalFormat, &choose_format,
3294					&choose_type);
3295      proxy_format = choose_format;
3296
3297      /* check level */
3298      if (level > 0 || level < -maxLevels) {
3299	 *reason = "level";
3300	 return GL_INVALID_VALUE;
3301      }
3302
3303      if (dimensions != 2) {
3304	 *reason = "compressed paletted textures must be 2D";
3305	 return GL_INVALID_OPERATION;
3306      }
3307
3308      /* Figure out the expected texture size (in bytes).  This will be
3309       * checked against the actual size later.
3310       */
3311      expectedSize = _mesa_cpal_compressed_size(level, internalFormat,
3312						width, height);
3313
3314      /* This is for the benefit of the TestProxyTexImage below.  It expects
3315       * level to be non-negative.  OES_compressed_paletted_texture uses a
3316       * weird mechanism where the level specified to glCompressedTexImage2D
3317       * is -(n-1) number of levels in the texture, and the data specifies the
3318       * complete mipmap stack.  This is done to ensure the palette is the
3319       * same for all levels.
3320       */
3321      level = -level;
3322      break;
3323#endif
3324
3325   default:
3326      choose_format = GL_NONE;
3327      choose_type = GL_NONE;
3328      proxy_format = internalFormat;
3329
3330      /* check level */
3331      if (level < 0 || level >= maxLevels) {
3332	 *reason = "level";
3333	 return GL_INVALID_VALUE;
3334      }
3335
3336      /* Figure out the expected texture size (in bytes).  This will be
3337       * checked against the actual size later.
3338       */
3339      expectedSize = compressed_tex_size(width, height, depth, internalFormat);
3340      break;
3341   }
3342
3343   /* This should really never fail */
3344   if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
3345      *reason = "internalFormat";
3346      return GL_INVALID_ENUM;
3347   }
3348
3349   /* No compressed formats support borders at this time */
3350   if (border != 0) {
3351      *reason = "border != 0";
3352      return GL_INVALID_VALUE;
3353   }
3354
3355   /* For cube map, width must equal height */
3356   if (_mesa_is_cube_face(target) && width != height) {
3357      *reason = "width != height";
3358      return GL_INVALID_VALUE;
3359   }
3360
3361   /* check image size against compression block size */
3362   {
3363      gl_format texFormat =
3364         ctx->Driver.ChooseTextureFormat(ctx, proxy_format,
3365					 choose_format, choose_type);
3366      GLuint bw, bh;
3367
3368      _mesa_get_format_block_size(texFormat, &bw, &bh);
3369      if ((width > bw && width % bw > 0) ||
3370          (height > bh && height % bh > 0)) {
3371         /*
3372          * Per GL_ARB_texture_compression:  GL_INVALID_OPERATION is
3373          * generated [...] if any parameter combinations are not
3374          * supported by the specific compressed internal format.
3375          */
3376         *reason = "invalid width or height for compression format";
3377         return GL_INVALID_OPERATION;
3378      }
3379   }
3380
3381   /* check image sizes */
3382   if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
3383				      proxy_format, choose_format,
3384				      choose_type,
3385				      width, height, depth, border)) {
3386      /* See error comment above */
3387      *reason = "invalid width, height or format";
3388      return GL_INVALID_OPERATION;
3389   }
3390
3391   /* check image size in bytes */
3392   if (expectedSize != imageSize) {
3393      /* Per GL_ARB_texture_compression:  GL_INVALID_VALUE is generated [...]
3394       * if <imageSize> is not consistent with the format, dimensions, and
3395       * contents of the specified image.
3396       */
3397      *reason = "imageSize inconsistant with width/height/format";
3398      return GL_INVALID_VALUE;
3399   }
3400
3401   if (!mutable_tex_object(ctx, target)) {
3402      *reason = "immutable texture";
3403      return GL_INVALID_OPERATION;
3404   }
3405
3406   return GL_NO_ERROR;
3407}
3408
3409
3410/**
3411 * Error checking for glCompressedTexSubImage[123]D().
3412 * \warning  There are some bad assumptions here about the size of compressed
3413 *           texture tiles (multiple of 4) used to test the validity of the
3414 *           offset and size parameters.
3415 * \return error code or GL_NO_ERROR.
3416 */
3417static GLenum
3418compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
3419                                  GLenum target, GLint level,
3420                                  GLint xoffset, GLint yoffset, GLint zoffset,
3421                                  GLsizei width, GLsizei height, GLsizei depth,
3422                                  GLenum format, GLsizei imageSize)
3423{
3424   GLint expectedSize, maxLevels = 0, maxTextureSize;
3425   GLuint bw, bh;
3426   (void) zoffset;
3427
3428   if (dimensions == 1) {
3429      /* 1D compressed textures not allowed */
3430      return GL_INVALID_ENUM;
3431   }
3432   else if (dimensions == 2) {
3433      if (target == GL_PROXY_TEXTURE_2D) {
3434         maxLevels = ctx->Const.MaxTextureLevels;
3435      }
3436      else if (target == GL_TEXTURE_2D) {
3437         maxLevels = ctx->Const.MaxTextureLevels;
3438      }
3439      else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
3440         if (!ctx->Extensions.ARB_texture_cube_map)
3441            return GL_INVALID_ENUM; /*target*/
3442         maxLevels = ctx->Const.MaxCubeTextureLevels;
3443      }
3444      else if (_mesa_is_cube_face(target)) {
3445         if (!ctx->Extensions.ARB_texture_cube_map)
3446            return GL_INVALID_ENUM; /*target*/
3447         maxLevels = ctx->Const.MaxCubeTextureLevels;
3448      }
3449      else {
3450         return GL_INVALID_ENUM; /*target*/
3451      }
3452   }
3453   else if (dimensions == 3) {
3454      /* 3D compressed textures not allowed */
3455      return GL_INVALID_ENUM;
3456   }
3457
3458   maxTextureSize = 1 << (maxLevels - 1);
3459
3460   /* this will catch any invalid compressed format token */
3461   if (!_mesa_is_compressed_format(ctx, format))
3462      return GL_INVALID_ENUM;
3463
3464   if (width < 1 || width > maxTextureSize)
3465      return GL_INVALID_VALUE;
3466
3467   if ((height < 1 || height > maxTextureSize)
3468       && dimensions > 1)
3469      return GL_INVALID_VALUE;
3470
3471   if (level < 0 || level >= maxLevels)
3472      return GL_INVALID_VALUE;
3473
3474   /*
3475    * do checks which depend on compression block size
3476    */
3477   get_compressed_block_size(format, &bw, &bh);
3478
3479   if ((xoffset % bw != 0) || (yoffset % bh != 0))
3480      return GL_INVALID_VALUE;
3481
3482   if ((width % bw != 0) && width != 2 && width != 1)
3483      return GL_INVALID_VALUE;
3484
3485   if ((height % bh != 0) && height != 2 && height != 1)
3486      return GL_INVALID_VALUE;
3487
3488   expectedSize = compressed_tex_size(width, height, depth, format);
3489   if (expectedSize != imageSize)
3490      return GL_INVALID_VALUE;
3491
3492   return GL_NO_ERROR;
3493}
3494
3495
3496/**
3497 * Do second part of glCompressedTexSubImage error checking.
3498 * \return GL_TRUE if error found, GL_FALSE otherwise.
3499 */
3500static GLboolean
3501compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
3502                                   GLsizei width, GLsizei height,
3503                                   GLsizei depth, GLenum format,
3504                                   struct gl_texture_image *texImage)
3505{
3506
3507   if ((GLint) format != texImage->InternalFormat) {
3508      _mesa_error(ctx, GL_INVALID_OPERATION,
3509                  "glCompressedTexSubImage%uD(format=0x%x)", dims, format);
3510      return GL_TRUE;
3511   }
3512
3513   if (compressedteximage_only_format(ctx, format)) {
3514      _mesa_error(ctx, GL_INVALID_OPERATION,
3515                  "glCompressedTexSubImage%uD(format=0x%x cannot be updated)"
3516                  , dims, format);
3517      return GL_TRUE;
3518   }
3519
3520   if (((width == 1 || width == 2) &&
3521        width != (GLsizei) texImage->Width) ||
3522       (width > (GLsizei) texImage->Width)) {
3523      _mesa_error(ctx, GL_INVALID_VALUE,
3524                  "glCompressedTexSubImage%uD(width=%d)", dims, width);
3525      return GL_TRUE;
3526   }
3527
3528   if (dims >= 2) {
3529      if (((height == 1 || height == 2) &&
3530           height != (GLsizei) texImage->Height) ||
3531          (height > (GLsizei) texImage->Height)) {
3532         _mesa_error(ctx, GL_INVALID_VALUE,
3533                     "glCompressedTexSubImage%uD(height=%d)", dims, height);
3534         return GL_TRUE;
3535      }
3536   }
3537
3538   if (dims >= 3) {
3539      if (((depth == 1 || depth == 2) &&
3540           depth != (GLsizei) texImage->Depth) ||
3541          (depth > (GLsizei) texImage->Depth)) {
3542         _mesa_error(ctx, GL_INVALID_VALUE,
3543                     "glCompressedTexSubImage%uD(depth=%d)", dims, depth);
3544         return GL_TRUE;
3545      }
3546   }
3547
3548   return GL_FALSE;
3549}
3550
3551
3552/**
3553 * Implementation of the glCompressedTexImage1/2/3D() functions.
3554 */
3555static void
3556compressedteximage(struct gl_context *ctx, GLuint dims,
3557                   GLenum target, GLint level,
3558                   GLenum internalFormat, GLsizei width,
3559                   GLsizei height, GLsizei depth, GLint border,
3560                   GLsizei imageSize, const GLvoid *data)
3561{
3562   GLenum error;
3563   char *reason = "";
3564
3565   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3566
3567   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3568      _mesa_debug(ctx,
3569                  "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n",
3570                  dims,
3571                  _mesa_lookup_enum_by_nr(target), level,
3572                  _mesa_lookup_enum_by_nr(internalFormat),
3573                  width, height, depth, border, imageSize, data);
3574
3575   /* check target */
3576   if (!legal_teximage_target(ctx, dims, target)) {
3577      _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)",
3578                  dims, _mesa_lookup_enum_by_nr(target));
3579      return;
3580   }
3581
3582   error = compressed_texture_error_check(ctx, dims, target, level,
3583                                          internalFormat, width, height, depth,
3584                                          border, imageSize, &reason);
3585
3586#if FEATURE_ES
3587   /* XXX this is kind of a hack */
3588   if (!error && dims == 2) {
3589      switch (internalFormat) {
3590      case GL_PALETTE4_RGB8_OES:
3591      case GL_PALETTE4_RGBA8_OES:
3592      case GL_PALETTE4_R5_G6_B5_OES:
3593      case GL_PALETTE4_RGBA4_OES:
3594      case GL_PALETTE4_RGB5_A1_OES:
3595      case GL_PALETTE8_RGB8_OES:
3596      case GL_PALETTE8_RGBA8_OES:
3597      case GL_PALETTE8_R5_G6_B5_OES:
3598      case GL_PALETTE8_RGBA4_OES:
3599      case GL_PALETTE8_RGB5_A1_OES:
3600         _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
3601                                          width, height, imageSize, data);
3602         return;
3603      }
3604   }
3605#endif
3606
3607   if (_mesa_is_proxy_texture(target)) {
3608      /* Proxy texture: just check for errors and update proxy state */
3609      struct gl_texture_image *texImage;
3610
3611      if (!error) {
3612         struct gl_texture_object *texObj =
3613            _mesa_get_current_tex_object(ctx, target);
3614         gl_format texFormat =
3615            _mesa_choose_texture_format(ctx, texObj, target, level,
3616                                        internalFormat, GL_NONE, GL_NONE);
3617         if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
3618            error = GL_OUT_OF_MEMORY;
3619         }
3620      }
3621
3622      texImage = _mesa_get_proxy_tex_image(ctx, target, level);
3623      if (texImage) {
3624         if (error) {
3625            /* if error, clear all proxy texture image parameters */
3626            clear_teximage_fields(texImage);
3627         }
3628         else {
3629            /* no error: store the teximage parameters */
3630            _mesa_init_teximage_fields(ctx, texImage, width, height,
3631                                       depth, border, internalFormat,
3632                                       MESA_FORMAT_NONE);
3633         }
3634      }
3635   }
3636   else {
3637      /* non-proxy target */
3638      struct gl_texture_object *texObj;
3639      struct gl_texture_image *texImage;
3640
3641      if (error) {
3642         _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason);
3643         return;
3644      }
3645
3646      texObj = _mesa_get_current_tex_object(ctx, target);
3647
3648      _mesa_lock_texture(ctx, texObj);
3649      {
3650	 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
3651	 if (!texImage) {
3652	    _mesa_error(ctx, GL_OUT_OF_MEMORY,
3653                        "glCompressedTexImage%uD", dims);
3654	 }
3655         else {
3656            gl_format texFormat;
3657
3658            ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
3659
3660            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
3661                                                    internalFormat, GL_NONE,
3662                                                    GL_NONE);
3663
3664            if (legal_texture_size(ctx, texFormat, width, height, depth)) {
3665               _mesa_init_teximage_fields(ctx, texImage,
3666                                          width, height, depth,
3667                                          border, internalFormat, texFormat);
3668
3669               ctx->Driver.CompressedTexImage(ctx, dims, texImage, imageSize,
3670                                              data);
3671
3672               check_gen_mipmap(ctx, target, texObj, level);
3673
3674               _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
3675            }
3676            else {
3677               _mesa_error(ctx, GL_OUT_OF_MEMORY,
3678                           "glCompressedTexImage%uD", dims);
3679            }
3680         }
3681      }
3682      _mesa_unlock_texture(ctx, texObj);
3683   }
3684}
3685
3686
3687void GLAPIENTRY
3688_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
3689                              GLenum internalFormat, GLsizei width,
3690                              GLint border, GLsizei imageSize,
3691                              const GLvoid *data)
3692{
3693   GET_CURRENT_CONTEXT(ctx);
3694   compressedteximage(ctx, 1, target, level, internalFormat,
3695                      width, 1, 1, border, imageSize, data);
3696}
3697
3698
3699void GLAPIENTRY
3700_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
3701                              GLenum internalFormat, GLsizei width,
3702                              GLsizei height, GLint border, GLsizei imageSize,
3703                              const GLvoid *data)
3704{
3705   GET_CURRENT_CONTEXT(ctx);
3706   compressedteximage(ctx, 2, target, level, internalFormat,
3707                      width, height, 1, border, imageSize, data);
3708}
3709
3710
3711void GLAPIENTRY
3712_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
3713                              GLenum internalFormat, GLsizei width,
3714                              GLsizei height, GLsizei depth, GLint border,
3715                              GLsizei imageSize, const GLvoid *data)
3716{
3717   GET_CURRENT_CONTEXT(ctx);
3718   compressedteximage(ctx, 3, target, level, internalFormat,
3719                      width, height, depth, border, imageSize, data);
3720}
3721
3722
3723/**
3724 * Common helper for glCompressedTexSubImage1/2/3D().
3725 */
3726static void
3727compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
3728                         GLint xoffset, GLint yoffset, GLint zoffset,
3729                         GLsizei width, GLsizei height, GLsizei depth,
3730                         GLenum format, GLsizei imageSize, const GLvoid *data)
3731{
3732   struct gl_texture_object *texObj;
3733   struct gl_texture_image *texImage;
3734   GLenum error;
3735   GET_CURRENT_CONTEXT(ctx);
3736   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3737
3738   error = compressed_subtexture_error_check(ctx, dims, target, level,
3739                                             xoffset, 0, 0, /* pos */
3740                                             width, height, depth,   /* size */
3741                                             format, imageSize);
3742   if (error) {
3743      _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims);
3744      return;
3745   }
3746
3747   texObj = _mesa_get_current_tex_object(ctx, target);
3748
3749   _mesa_lock_texture(ctx, texObj);
3750   {
3751      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
3752      assert(texImage);
3753
3754      if (compressed_subtexture_error_check2(ctx, dims, width, height, depth,
3755                                             format, texImage)) {
3756         /* error was recorded */
3757      }
3758      else if (width > 0 && height > 0 && depth > 0) {
3759         ctx->Driver.CompressedTexSubImage(ctx, dims, texImage,
3760                                           xoffset, yoffset, zoffset,
3761                                           width, height, depth,
3762                                           format, imageSize, data);
3763
3764         check_gen_mipmap(ctx, target, texObj, level);
3765
3766         ctx->NewState |= _NEW_TEXTURE;
3767      }
3768   }
3769   _mesa_unlock_texture(ctx, texObj);
3770}
3771
3772
3773void GLAPIENTRY
3774_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
3775                                 GLsizei width, GLenum format,
3776                                 GLsizei imageSize, const GLvoid *data)
3777{
3778   compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1,
3779                            format, imageSize, data);
3780}
3781
3782
3783void GLAPIENTRY
3784_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
3785                                 GLint yoffset, GLsizei width, GLsizei height,
3786                                 GLenum format, GLsizei imageSize,
3787                                 const GLvoid *data)
3788{
3789   compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0,
3790                            width, height, 1, format, imageSize, data);
3791}
3792
3793
3794void GLAPIENTRY
3795_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
3796                                 GLint yoffset, GLint zoffset, GLsizei width,
3797                                 GLsizei height, GLsizei depth, GLenum format,
3798                                 GLsizei imageSize, const GLvoid *data)
3799{
3800   compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset,
3801                            width, height, depth, format, imageSize, data);
3802}
3803
3804static gl_format
3805get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
3806{
3807   switch (internalFormat) {
3808   case GL_ALPHA8:
3809      return MESA_FORMAT_A8;
3810   case GL_ALPHA16:
3811      return MESA_FORMAT_A16;
3812   case GL_ALPHA16F_ARB:
3813      return MESA_FORMAT_ALPHA_FLOAT16;
3814   case GL_ALPHA32F_ARB:
3815      return MESA_FORMAT_ALPHA_FLOAT32;
3816   case GL_ALPHA8I_EXT:
3817      return MESA_FORMAT_ALPHA_INT8;
3818   case GL_ALPHA16I_EXT:
3819      return MESA_FORMAT_ALPHA_INT16;
3820   case GL_ALPHA32I_EXT:
3821      return MESA_FORMAT_ALPHA_INT32;
3822   case GL_ALPHA8UI_EXT:
3823      return MESA_FORMAT_ALPHA_UINT8;
3824   case GL_ALPHA16UI_EXT:
3825      return MESA_FORMAT_ALPHA_UINT16;
3826   case GL_ALPHA32UI_EXT:
3827      return MESA_FORMAT_ALPHA_UINT32;
3828   case GL_LUMINANCE8:
3829      return MESA_FORMAT_L8;
3830   case GL_LUMINANCE16:
3831      return MESA_FORMAT_L16;
3832   case GL_LUMINANCE16F_ARB:
3833      return MESA_FORMAT_LUMINANCE_FLOAT16;
3834   case GL_LUMINANCE32F_ARB:
3835      return MESA_FORMAT_LUMINANCE_FLOAT32;
3836   case GL_LUMINANCE8I_EXT:
3837      return MESA_FORMAT_LUMINANCE_INT8;
3838   case GL_LUMINANCE16I_EXT:
3839      return MESA_FORMAT_LUMINANCE_INT16;
3840   case GL_LUMINANCE32I_EXT:
3841      return MESA_FORMAT_LUMINANCE_INT32;
3842   case GL_LUMINANCE8UI_EXT:
3843      return MESA_FORMAT_LUMINANCE_UINT8;
3844   case GL_LUMINANCE16UI_EXT:
3845      return MESA_FORMAT_LUMINANCE_UINT16;
3846   case GL_LUMINANCE32UI_EXT:
3847      return MESA_FORMAT_LUMINANCE_UINT32;
3848   case GL_LUMINANCE8_ALPHA8:
3849      return MESA_FORMAT_AL88;
3850   case GL_LUMINANCE16_ALPHA16:
3851      return MESA_FORMAT_AL1616;
3852   case GL_LUMINANCE_ALPHA16F_ARB:
3853      return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
3854   case GL_LUMINANCE_ALPHA32F_ARB:
3855      return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
3856   case GL_LUMINANCE_ALPHA8I_EXT:
3857      return MESA_FORMAT_LUMINANCE_ALPHA_INT8;
3858   case GL_LUMINANCE_ALPHA16I_EXT:
3859      return MESA_FORMAT_LUMINANCE_ALPHA_INT8;
3860   case GL_LUMINANCE_ALPHA32I_EXT:
3861      return MESA_FORMAT_LUMINANCE_ALPHA_INT16;
3862   case GL_LUMINANCE_ALPHA8UI_EXT:
3863      return MESA_FORMAT_LUMINANCE_ALPHA_UINT8;
3864   case GL_LUMINANCE_ALPHA16UI_EXT:
3865      return MESA_FORMAT_LUMINANCE_ALPHA_UINT16;
3866   case GL_LUMINANCE_ALPHA32UI_EXT:
3867      return MESA_FORMAT_LUMINANCE_ALPHA_UINT32;
3868   case GL_INTENSITY8:
3869      return MESA_FORMAT_I8;
3870   case GL_INTENSITY16:
3871      return MESA_FORMAT_I16;
3872   case GL_INTENSITY16F_ARB:
3873      return MESA_FORMAT_INTENSITY_FLOAT16;
3874   case GL_INTENSITY32F_ARB:
3875      return MESA_FORMAT_INTENSITY_FLOAT32;
3876   case GL_INTENSITY8I_EXT:
3877      return MESA_FORMAT_INTENSITY_INT8;
3878   case GL_INTENSITY16I_EXT:
3879      return MESA_FORMAT_INTENSITY_INT16;
3880   case GL_INTENSITY32I_EXT:
3881      return MESA_FORMAT_INTENSITY_INT32;
3882   case GL_INTENSITY8UI_EXT:
3883      return MESA_FORMAT_INTENSITY_UINT8;
3884   case GL_INTENSITY16UI_EXT:
3885      return MESA_FORMAT_INTENSITY_UINT16;
3886   case GL_INTENSITY32UI_EXT:
3887      return MESA_FORMAT_INTENSITY_UINT32;
3888   case GL_RGBA8:
3889      return MESA_FORMAT_RGBA8888_REV;
3890   case GL_RGBA16:
3891      return MESA_FORMAT_RGBA_16;
3892   case GL_RGBA16F_ARB:
3893      return MESA_FORMAT_RGBA_FLOAT16;
3894   case GL_RGBA32F_ARB:
3895      return MESA_FORMAT_RGBA_FLOAT32;
3896   case GL_RGBA8I_EXT:
3897      return MESA_FORMAT_RGBA_INT8;
3898   case GL_RGBA16I_EXT:
3899      return MESA_FORMAT_RGBA_INT16;
3900   case GL_RGBA32I_EXT:
3901      return MESA_FORMAT_RGBA_INT32;
3902   case GL_RGBA8UI_EXT:
3903      return MESA_FORMAT_RGBA_UINT8;
3904   case GL_RGBA16UI_EXT:
3905      return MESA_FORMAT_RGBA_UINT16;
3906   case GL_RGBA32UI_EXT:
3907      return MESA_FORMAT_RGBA_UINT32;
3908
3909   case GL_RG8:
3910      return MESA_FORMAT_GR88;
3911   case GL_RG16:
3912      return MESA_FORMAT_RG1616;
3913   case GL_RG16F:
3914      return MESA_FORMAT_RG_FLOAT16;
3915   case GL_RG32F:
3916      return MESA_FORMAT_RG_FLOAT32;
3917   case GL_RG8I:
3918      return MESA_FORMAT_RG_INT8;
3919   case GL_RG16I:
3920      return MESA_FORMAT_RG_INT16;
3921   case GL_RG32I:
3922      return MESA_FORMAT_RG_INT32;
3923   case GL_RG8UI:
3924      return MESA_FORMAT_RG_UINT8;
3925   case GL_RG16UI:
3926      return MESA_FORMAT_RG_UINT16;
3927   case GL_RG32UI:
3928      return MESA_FORMAT_RG_UINT32;
3929
3930   case GL_R8:
3931      return MESA_FORMAT_R8;
3932   case GL_R16:
3933      return MESA_FORMAT_R16;
3934   case GL_R16F:
3935      return MESA_FORMAT_R_FLOAT16;
3936   case GL_R32F:
3937      return MESA_FORMAT_R_FLOAT32;
3938   case GL_R8I:
3939      return MESA_FORMAT_R_INT8;
3940   case GL_R16I:
3941      return MESA_FORMAT_R_INT16;
3942   case GL_R32I:
3943      return MESA_FORMAT_R_INT32;
3944   case GL_R8UI:
3945      return MESA_FORMAT_R_UINT8;
3946   case GL_R16UI:
3947      return MESA_FORMAT_R_UINT16;
3948   case GL_R32UI:
3949      return MESA_FORMAT_R_UINT32;
3950
3951   default:
3952      return MESA_FORMAT_NONE;
3953   }
3954}
3955
3956static gl_format
3957validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
3958{
3959   gl_format format = get_texbuffer_format(ctx, internalFormat);
3960   GLenum datatype;
3961
3962   if (format == MESA_FORMAT_NONE)
3963      return MESA_FORMAT_NONE;
3964
3965   datatype = _mesa_get_format_datatype(format);
3966   if (datatype == GL_FLOAT && !ctx->Extensions.ARB_texture_float)
3967      return MESA_FORMAT_NONE;
3968
3969   if (datatype == GL_HALF_FLOAT && !ctx->Extensions.ARB_half_float_pixel)
3970      return MESA_FORMAT_NONE;
3971
3972   /* The GL_ARB_texture_rg and GL_ARB_texture_buffer_object specs don't make
3973    * any mention of R/RG formats, but they appear in the GL 3.1 core
3974    * specification.
3975    */
3976   if (ctx->Version <= 30) {
3977      GLenum base_format = _mesa_get_format_base_format(format);
3978
3979      if (base_format == GL_R || base_format == GL_RG)
3980	 return MESA_FORMAT_NONE;
3981   }
3982   return format;
3983}
3984
3985
3986/** GL_ARB_texture_buffer_object */
3987void GLAPIENTRY
3988_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
3989{
3990   struct gl_texture_object *texObj;
3991   struct gl_buffer_object *bufObj;
3992   gl_format format;
3993
3994   GET_CURRENT_CONTEXT(ctx);
3995   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3996
3997   if (!ctx->Extensions.ARB_texture_buffer_object) {
3998      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer");
3999      return;
4000   }
4001
4002   if (target != GL_TEXTURE_BUFFER_ARB) {
4003      _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)");
4004      return;
4005   }
4006
4007   format = validate_texbuffer_format(ctx, internalFormat);
4008   if (format == MESA_FORMAT_NONE) {
4009      _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)",
4010                  internalFormat);
4011      return;
4012   }
4013
4014   bufObj = _mesa_lookup_bufferobj(ctx, buffer);
4015   if (buffer && !bufObj) {
4016      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer);
4017      return;
4018   }
4019
4020   texObj = _mesa_get_current_tex_object(ctx, target);
4021
4022   _mesa_lock_texture(ctx, texObj);
4023   {
4024      _mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj);
4025      texObj->BufferObjectFormat = internalFormat;
4026      texObj->_BufferObjectFormat = format;
4027   }
4028   _mesa_unlock_texture(ctx, texObj);
4029}
4030