ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

teximage.c
Go to the documentation of this file.
00001 /*
00002  * mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00032 #include "glheader.h"
00033 #include "bufferobj.h"
00034 #include "context.h"
00035 #if FEATURE_convolve
00036 #include "convolve.h"
00037 #endif
00038 #include "fbobject.h"
00039 #include "framebuffer.h"
00040 #include "image.h"
00041 #include "imports.h"
00042 #include "macros.h"
00043 #include "state.h"
00044 #include "texcompress.h"
00045 #include "texformat.h"
00046 #include "teximage.h"
00047 #include "texstate.h"
00048 #include "texstore.h"
00049 #include "mtypes.h"
00050 
00051 
00056 void *
00057 _mesa_alloc_texmemory(GLsizei bytes)
00058 {
00059    return _mesa_align_malloc(bytes, 512);
00060 }
00061 
00062 
00066 void
00067 _mesa_free_texmemory(void *m)
00068 {
00069    _mesa_align_free(m);
00070 }
00071 
00072 
00073 
00074 
00075 #if 0
00076 static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img)
00077 {
00078 #if CHAN_TYPE != GL_UNSIGNED_BYTE
00079    _mesa_problem(NULL, "PrintTexture not supported");
00080 #else
00081    GLuint i, j, c;
00082    const GLubyte *data = (const GLubyte *) img->Data;
00083 
00084    if (!data) {
00085       _mesa_printf("No texture data\n");
00086       return;
00087    }
00088 
00089    switch (img->Format) {
00090       case GL_ALPHA:
00091       case GL_LUMINANCE:
00092       case GL_INTENSITY:
00093       case GL_COLOR_INDEX:
00094          c = 1;
00095          break;
00096       case GL_LUMINANCE_ALPHA:
00097          c = 2;
00098          break;
00099       case GL_RGB:
00100          c = 3;
00101          break;
00102       case GL_RGBA:
00103          c = 4;
00104          break;
00105       default:
00106          _mesa_problem(NULL, "error in PrintTexture\n");
00107          return;
00108    }
00109 
00110    for (i = 0; i < img->Height; i++) {
00111       for (j = 0; j < img->Width; j++) {
00112          if (c==1)
00113             _mesa_printf("%02x  ", data[0]);
00114          else if (c==2)
00115             _mesa_printf("%02x%02x  ", data[0], data[1]);
00116          else if (c==3)
00117             _mesa_printf("%02x%02x%02x  ", data[0], data[1], data[2]);
00118          else if (c==4)
00119             _mesa_printf("%02x%02x%02x%02x  ", data[0], data[1], data[2], data[3]);
00120          data += (img->RowStride - img->Width) * c;
00121       }
00122       /* XXX use img->ImageStride here */
00123       _mesa_printf("\n");
00124    }
00125 #endif
00126 }
00127 #endif
00128 
00129 
00130 /*
00131  * Compute floor(log_base_2(n)).
00132  * If n < 0 return -1.
00133  */
00134 static int
00135 logbase2( int n )
00136 {
00137    GLint i = 1;
00138    GLint log2 = 0;
00139 
00140    if (n < 0)
00141       return -1;
00142 
00143    if (n == 0)
00144       return 0;
00145 
00146    while ( n > i ) {
00147       i *= 2;
00148       log2++;
00149    }
00150    if (i != n) {
00151       return log2 - 1;
00152    }
00153    else {
00154       return log2;
00155    }
00156 }
00157 
00158 
00159 
00173 GLint
00174 _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
00175 {
00176    switch (internalFormat) {
00177       case GL_ALPHA:
00178       case GL_ALPHA4:
00179       case GL_ALPHA8:
00180       case GL_ALPHA12:
00181       case GL_ALPHA16:
00182          return GL_ALPHA;
00183       case 1:
00184       case GL_LUMINANCE:
00185       case GL_LUMINANCE4:
00186       case GL_LUMINANCE8:
00187       case GL_LUMINANCE12:
00188       case GL_LUMINANCE16:
00189          return GL_LUMINANCE;
00190       case 2:
00191       case GL_LUMINANCE_ALPHA:
00192       case GL_LUMINANCE4_ALPHA4:
00193       case GL_LUMINANCE6_ALPHA2:
00194       case GL_LUMINANCE8_ALPHA8:
00195       case GL_LUMINANCE12_ALPHA4:
00196       case GL_LUMINANCE12_ALPHA12:
00197       case GL_LUMINANCE16_ALPHA16:
00198          return GL_LUMINANCE_ALPHA;
00199       case GL_INTENSITY:
00200       case GL_INTENSITY4:
00201       case GL_INTENSITY8:
00202       case GL_INTENSITY12:
00203       case GL_INTENSITY16:
00204          return GL_INTENSITY;
00205       case 3:
00206       case GL_RGB:
00207       case GL_R3_G3_B2:
00208       case GL_RGB4:
00209       case GL_RGB5:
00210       case GL_RGB8:
00211       case GL_RGB10:
00212       case GL_RGB12:
00213       case GL_RGB16:
00214          return GL_RGB;
00215       case 4:
00216       case GL_RGBA:
00217       case GL_RGBA2:
00218       case GL_RGBA4:
00219       case GL_RGB5_A1:
00220       case GL_RGBA8:
00221       case GL_RGB10_A2:
00222       case GL_RGBA12:
00223       case GL_RGBA16:
00224          return GL_RGBA;
00225       default:
00226          ; /* fallthrough */
00227    }
00228 
00229    if (ctx->Extensions.EXT_paletted_texture) {
00230       switch (internalFormat) {
00231          case GL_COLOR_INDEX:
00232          case GL_COLOR_INDEX1_EXT:
00233          case GL_COLOR_INDEX2_EXT:
00234          case GL_COLOR_INDEX4_EXT:
00235          case GL_COLOR_INDEX8_EXT:
00236          case GL_COLOR_INDEX12_EXT:
00237          case GL_COLOR_INDEX16_EXT:
00238             return GL_COLOR_INDEX;
00239          default:
00240             ; /* fallthrough */
00241       }
00242    }
00243 
00244    if (ctx->Extensions.ARB_depth_texture) {
00245       switch (internalFormat) {
00246          case GL_DEPTH_COMPONENT:
00247          case GL_DEPTH_COMPONENT16:
00248          case GL_DEPTH_COMPONENT24:
00249          case GL_DEPTH_COMPONENT32:
00250             return GL_DEPTH_COMPONENT;
00251          default:
00252             ; /* fallthrough */
00253       }
00254    }
00255 
00256    if (ctx->Extensions.ARB_texture_compression) {
00257       switch (internalFormat) {
00258          case GL_COMPRESSED_ALPHA:
00259             return GL_ALPHA;
00260          case GL_COMPRESSED_LUMINANCE:
00261             return GL_LUMINANCE;
00262          case GL_COMPRESSED_LUMINANCE_ALPHA:
00263             return GL_LUMINANCE_ALPHA;
00264          case GL_COMPRESSED_INTENSITY:
00265             return GL_INTENSITY;
00266          case GL_COMPRESSED_RGB:
00267             return GL_RGB;
00268          case GL_COMPRESSED_RGBA:
00269             return GL_RGBA;
00270          default:
00271             ; /* fallthrough */
00272       }
00273    }
00274          
00275    if (ctx->Extensions.TDFX_texture_compression_FXT1) {
00276       switch (internalFormat) {
00277          case GL_COMPRESSED_RGB_FXT1_3DFX:
00278             return GL_RGB;
00279          case GL_COMPRESSED_RGBA_FXT1_3DFX:
00280             return GL_RGBA;
00281          default:
00282             ; /* fallthrough */
00283       }
00284    }
00285 
00286    if (ctx->Extensions.EXT_texture_compression_s3tc) {
00287       switch (internalFormat) {
00288          case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
00289             return GL_RGB;
00290          case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
00291          case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
00292          case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
00293             return GL_RGBA;
00294          default:
00295             ; /* fallthrough */
00296       }
00297    }
00298 
00299    if (ctx->Extensions.S3_s3tc) {
00300       switch (internalFormat) {
00301          case GL_RGB_S3TC:
00302          case GL_RGB4_S3TC:
00303             return GL_RGB;
00304          case GL_RGBA_S3TC:
00305          case GL_RGBA4_S3TC:
00306             return GL_RGBA;
00307          default:
00308             ; /* fallthrough */
00309       }
00310    }
00311 
00312    if (ctx->Extensions.MESA_ycbcr_texture) {
00313       if (internalFormat == GL_YCBCR_MESA)
00314          return GL_YCBCR_MESA;
00315    }
00316 
00317    if (ctx->Extensions.ARB_texture_float) {
00318       switch (internalFormat) {
00319          case GL_ALPHA16F_ARB:
00320          case GL_ALPHA32F_ARB:
00321             return GL_ALPHA;
00322          case GL_RGBA16F_ARB:
00323          case GL_RGBA32F_ARB:
00324             return GL_RGBA;
00325          case GL_RGB16F_ARB:
00326          case GL_RGB32F_ARB:
00327             return GL_RGB;
00328          case GL_INTENSITY16F_ARB:
00329          case GL_INTENSITY32F_ARB:
00330             return GL_INTENSITY;
00331          case GL_LUMINANCE16F_ARB:
00332          case GL_LUMINANCE32F_ARB:
00333             return GL_LUMINANCE;
00334          case GL_LUMINANCE_ALPHA16F_ARB:
00335          case GL_LUMINANCE_ALPHA32F_ARB:
00336             return GL_LUMINANCE_ALPHA;
00337          default:
00338             ; /* fallthrough */
00339       }
00340    }
00341 
00342    if (ctx->Extensions.EXT_packed_depth_stencil) {
00343       switch (internalFormat) {
00344          case GL_DEPTH_STENCIL_EXT:
00345          case GL_DEPTH24_STENCIL8_EXT:
00346             return GL_DEPTH_STENCIL_EXT;
00347          default:
00348             ; /* fallthrough */
00349       }
00350    }
00351 
00352 #if FEATURE_EXT_texture_sRGB
00353    if (ctx->Extensions.EXT_texture_sRGB) {
00354       switch (internalFormat) {
00355       case GL_SRGB_EXT:
00356       case GL_SRGB8_EXT:
00357       case GL_COMPRESSED_SRGB_EXT:
00358       case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
00359          return GL_RGB;
00360       case GL_SRGB_ALPHA_EXT:
00361       case GL_SRGB8_ALPHA8_EXT:
00362       case GL_COMPRESSED_SRGB_ALPHA_EXT:
00363       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
00364       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
00365       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
00366          return GL_RGBA;
00367       case GL_SLUMINANCE_ALPHA_EXT:
00368       case GL_SLUMINANCE8_ALPHA8_EXT:
00369       case GL_COMPRESSED_SLUMINANCE_EXT:
00370       case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
00371          return GL_LUMINANCE_ALPHA;
00372       case GL_SLUMINANCE_EXT:
00373       case GL_SLUMINANCE8_EXT:
00374          return GL_LUMINANCE;
00375       default:
00376             ; /* fallthrough */
00377       }
00378    }
00379 
00380 #endif /* FEATURE_EXT_texture_sRGB */
00381 
00382    return -1; /* error */
00383 }
00384 
00385 
00393 GLboolean
00394 _mesa_is_color_format(GLenum format)
00395 {
00396    switch (format) {
00397       case GL_RED:
00398       case GL_GREEN:
00399       case GL_BLUE:
00400       case GL_ALPHA:
00401       case GL_ALPHA4:
00402       case GL_ALPHA8:
00403       case GL_ALPHA12:
00404       case GL_ALPHA16:
00405       case 1:
00406       case GL_LUMINANCE:
00407       case GL_LUMINANCE4:
00408       case GL_LUMINANCE8:
00409       case GL_LUMINANCE12:
00410       case GL_LUMINANCE16:
00411       case 2:
00412       case GL_LUMINANCE_ALPHA:
00413       case GL_LUMINANCE4_ALPHA4:
00414       case GL_LUMINANCE6_ALPHA2:
00415       case GL_LUMINANCE8_ALPHA8:
00416       case GL_LUMINANCE12_ALPHA4:
00417       case GL_LUMINANCE12_ALPHA12:
00418       case GL_LUMINANCE16_ALPHA16:
00419       case GL_INTENSITY:
00420       case GL_INTENSITY4:
00421       case GL_INTENSITY8:
00422       case GL_INTENSITY12:
00423       case GL_INTENSITY16:
00424       case 3:
00425       case GL_RGB:
00426       case GL_BGR:
00427       case GL_R3_G3_B2:
00428       case GL_RGB4:
00429       case GL_RGB5:
00430       case GL_RGB8:
00431       case GL_RGB10:
00432       case GL_RGB12:
00433       case GL_RGB16:
00434       case 4:
00435       case GL_ABGR_EXT:
00436       case GL_RGBA:
00437       case GL_BGRA:
00438       case GL_RGBA2:
00439       case GL_RGBA4:
00440       case GL_RGB5_A1:
00441       case GL_RGBA8:
00442       case GL_RGB10_A2:
00443       case GL_RGBA12:
00444       case GL_RGBA16:
00445       /* float texture formats */
00446       case GL_ALPHA16F_ARB:
00447       case GL_ALPHA32F_ARB:
00448       case GL_LUMINANCE16F_ARB:
00449       case GL_LUMINANCE32F_ARB:
00450       case GL_LUMINANCE_ALPHA16F_ARB:
00451       case GL_LUMINANCE_ALPHA32F_ARB:
00452       case GL_INTENSITY16F_ARB:
00453       case GL_INTENSITY32F_ARB:
00454       case GL_RGB16F_ARB:
00455       case GL_RGB32F_ARB:
00456       case GL_RGBA16F_ARB:
00457       case GL_RGBA32F_ARB:
00458       /* compressed formats */
00459       case GL_COMPRESSED_ALPHA:
00460       case GL_COMPRESSED_LUMINANCE:
00461       case GL_COMPRESSED_LUMINANCE_ALPHA:
00462       case GL_COMPRESSED_INTENSITY:
00463       case GL_COMPRESSED_RGB:
00464       case GL_COMPRESSED_RGBA:
00465       case GL_RGB_S3TC:
00466       case GL_RGB4_S3TC:
00467       case GL_RGBA_S3TC:
00468       case GL_RGBA4_S3TC:
00469       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
00470       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
00471       case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
00472       case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
00473       case GL_COMPRESSED_RGB_FXT1_3DFX:
00474       case GL_COMPRESSED_RGBA_FXT1_3DFX:
00475 #if FEATURE_EXT_texture_sRGB
00476       case GL_SRGB_EXT:
00477       case GL_SRGB8_EXT:
00478       case GL_SRGB_ALPHA_EXT:
00479       case GL_SRGB8_ALPHA8_EXT:
00480       case GL_SLUMINANCE_ALPHA_EXT:
00481       case GL_SLUMINANCE8_ALPHA8_EXT:
00482       case GL_SLUMINANCE_EXT:
00483       case GL_SLUMINANCE8_EXT:
00484       case GL_COMPRESSED_SRGB_EXT:
00485       case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
00486       case GL_COMPRESSED_SRGB_ALPHA_EXT:
00487       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
00488       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
00489       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
00490       case GL_COMPRESSED_SLUMINANCE_EXT:
00491       case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
00492 #endif /* FEATURE_EXT_texture_sRGB */
00493          return GL_TRUE;
00494       case GL_YCBCR_MESA:  /* not considered to be RGB */
00495          /* fall-through */
00496       default:
00497          return GL_FALSE;
00498    }
00499 }
00500 
00501 
00505 static GLboolean
00506 is_index_format(GLenum format)
00507 {
00508    switch (format) {
00509       case GL_COLOR_INDEX:
00510       case GL_COLOR_INDEX1_EXT:
00511       case GL_COLOR_INDEX2_EXT:
00512       case GL_COLOR_INDEX4_EXT:
00513       case GL_COLOR_INDEX8_EXT:
00514       case GL_COLOR_INDEX12_EXT:
00515       case GL_COLOR_INDEX16_EXT:
00516          return GL_TRUE;
00517       default:
00518          return GL_FALSE;
00519    }
00520 }
00521 
00522 
00526 static GLboolean
00527 is_depth_format(GLenum format)
00528 {
00529    switch (format) {
00530       case GL_DEPTH_COMPONENT16:
00531       case GL_DEPTH_COMPONENT24:
00532       case GL_DEPTH_COMPONENT32:
00533       case GL_DEPTH_COMPONENT:
00534          return GL_TRUE;
00535       default:
00536          return GL_FALSE;
00537    }
00538 }
00539 
00540 
00544 static GLboolean
00545 is_ycbcr_format(GLenum format)
00546 {
00547    switch (format) {
00548       case GL_YCBCR_MESA:
00549          return GL_TRUE;
00550       default:
00551          return GL_FALSE;
00552    }
00553 }
00554 
00555 
00559 static GLboolean
00560 is_depthstencil_format(GLenum format)
00561 {
00562    switch (format) {
00563       case GL_DEPTH24_STENCIL8_EXT:
00564       case GL_DEPTH_STENCIL_EXT:
00565          return GL_TRUE;
00566       default:
00567          return GL_FALSE;
00568    }
00569 }
00570 
00571 
00572 
00584 static GLboolean
00585 is_compressed_format(GLcontext *ctx, GLenum internalFormat)
00586 {
00587    GLint supported[100]; /* 100 should be plenty */
00588    GLuint i, n;
00589 
00590    n = _mesa_get_compressed_formats(ctx, supported, GL_TRUE);
00591    ASSERT(n < 100);
00592    for (i = 0; i < n; i++) {
00593       if ((GLint) internalFormat == supported[i]) {
00594          return GL_TRUE;
00595       }
00596    }
00597    return GL_FALSE;
00598 }
00599 
00600 
00605 GLuint
00606 _mesa_tex_target_to_face(GLenum target)
00607 {
00608    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
00609        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
00610       return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
00611    else
00612       return 0;
00613 }
00614 
00615 
00616 
00628 void
00629 _mesa_set_tex_image(struct gl_texture_object *tObj,
00630                     GLenum target, GLint level,
00631                     struct gl_texture_image *texImage)
00632 {
00633    ASSERT(tObj);
00634    ASSERT(texImage);
00635    /* XXX simplify this with _mesa_tex_target_to_face() */
00636    switch (target) {
00637       case GL_TEXTURE_1D:
00638       case GL_TEXTURE_2D:
00639       case GL_TEXTURE_3D:
00640       case GL_TEXTURE_1D_ARRAY_EXT:
00641       case GL_TEXTURE_2D_ARRAY_EXT:
00642          tObj->Image[0][level] = texImage;
00643          break;
00644       case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00645       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00646       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00647       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00648       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00649       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00650          {
00651             GLuint face = ((GLuint) target - 
00652                            (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
00653             tObj->Image[face][level] = texImage;
00654          }
00655          break;
00656       case GL_TEXTURE_RECTANGLE_NV:
00657          ASSERT(level == 0);
00658          tObj->Image[0][level] = texImage;
00659          break;
00660       default:
00661          _mesa_problem(NULL, "bad target in _mesa_set_tex_image()");
00662          return;
00663    }
00664    /* Set the 'back' pointer */
00665    texImage->TexObject = tObj;
00666 }
00667 
00668 
00678 struct gl_texture_image *
00679 _mesa_new_texture_image( GLcontext *ctx )
00680 {
00681    (void) ctx;
00682    return CALLOC_STRUCT(gl_texture_image);
00683 }
00684 
00685 
00694 void
00695 _mesa_free_texture_image_data(GLcontext *ctx,
00696                               struct gl_texture_image *texImage)
00697 {
00698    (void) ctx;
00699 
00700    if (texImage->Data && !texImage->IsClientData) {
00701       /* free the old texture data */
00702       _mesa_free_texmemory(texImage->Data);
00703    }
00704 
00705    texImage->Data = NULL;
00706 }
00707 
00708 
00716 void
00717 _mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
00718 {
00719    /* Free texImage->Data and/or any other driver-specific texture
00720     * image storage.
00721     */
00722    ASSERT(ctx->Driver.FreeTexImageData);
00723    ctx->Driver.FreeTexImageData( ctx, texImage );
00724 
00725    ASSERT(texImage->Data == NULL);
00726    if (texImage->ImageOffsets)
00727       _mesa_free(texImage->ImageOffsets);
00728    _mesa_free(texImage);
00729 }
00730 
00731 
00739 GLboolean
00740 _mesa_is_proxy_texture(GLenum target)
00741 {
00742    return (target == GL_PROXY_TEXTURE_1D ||
00743            target == GL_PROXY_TEXTURE_2D ||
00744            target == GL_PROXY_TEXTURE_3D ||
00745            target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
00746            target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
00747            target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
00748            target == GL_PROXY_TEXTURE_2D_ARRAY_EXT);
00749 }
00750 
00751 
00763 struct gl_texture_object *
00764 _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
00765                         GLenum target)
00766 {
00767    switch (target) {
00768       case GL_TEXTURE_1D:
00769          return texUnit->CurrentTex[TEXTURE_1D_INDEX];
00770       case GL_PROXY_TEXTURE_1D:
00771          return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
00772       case GL_TEXTURE_2D:
00773          return texUnit->CurrentTex[TEXTURE_2D_INDEX];
00774       case GL_PROXY_TEXTURE_2D:
00775          return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
00776       case GL_TEXTURE_3D:
00777          return texUnit->CurrentTex[TEXTURE_3D_INDEX];
00778       case GL_PROXY_TEXTURE_3D:
00779          return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
00780       case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00781       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00782       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00783       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00784       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00785       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00786       case GL_TEXTURE_CUBE_MAP_ARB:
00787          return ctx->Extensions.ARB_texture_cube_map
00788                 ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL;
00789       case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
00790          return ctx->Extensions.ARB_texture_cube_map
00791                 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
00792       case GL_TEXTURE_RECTANGLE_NV:
00793          return ctx->Extensions.NV_texture_rectangle
00794                 ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL;
00795       case GL_PROXY_TEXTURE_RECTANGLE_NV:
00796          return ctx->Extensions.NV_texture_rectangle
00797                 ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
00798       case GL_TEXTURE_1D_ARRAY_EXT:
00799          return ctx->Extensions.MESA_texture_array
00800                 ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
00801       case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
00802          return ctx->Extensions.MESA_texture_array
00803                 ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
00804       case GL_TEXTURE_2D_ARRAY_EXT:
00805          return ctx->Extensions.MESA_texture_array
00806                 ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
00807       case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
00808          return ctx->Extensions.MESA_texture_array
00809                 ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
00810       default:
00811          _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
00812          return NULL;
00813    }
00814 }
00815 
00816 
00830 struct gl_texture_image *
00831 _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_object *texObj,
00832                GLenum target, GLint level)
00833 {
00834    ASSERT(texObj);
00835 
00836    if (level < 0 || level >= MAX_TEXTURE_LEVELS) 
00837       return NULL;
00838 
00839    /* XXX simplify this with _mesa_tex_target_to_face() */
00840    switch (target) {
00841       case GL_TEXTURE_1D:
00842       case GL_PROXY_TEXTURE_1D:
00843       case GL_TEXTURE_2D:
00844       case GL_PROXY_TEXTURE_2D:
00845       case GL_TEXTURE_3D:
00846       case GL_PROXY_TEXTURE_3D:
00847          return texObj->Image[0][level];
00848 
00849       case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00850       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00851       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00852       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00853       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00854       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 
00855          if (ctx->Extensions.ARB_texture_cube_map) {
00856         GLuint face = ((GLuint) target - 
00857                (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
00858             return texObj->Image[face][level];
00859      }
00860          else
00861             return NULL;
00862 
00863       case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
00864          if (ctx->Extensions.ARB_texture_cube_map)
00865             return texObj->Image[0][level];
00866          else
00867             return NULL;
00868 
00869       case GL_TEXTURE_RECTANGLE_NV:
00870       case GL_PROXY_TEXTURE_RECTANGLE_NV:
00871          if (ctx->Extensions.NV_texture_rectangle && level == 0) 
00872             return texObj->Image[0][level];
00873          else 
00874             return NULL;
00875 
00876       case GL_TEXTURE_1D_ARRAY_EXT:
00877       case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
00878       case GL_TEXTURE_2D_ARRAY_EXT:
00879       case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
00880          return (ctx->Extensions.MESA_texture_array)
00881             ? texObj->Image[0][level] : NULL;
00882 
00883       default:
00884          return NULL;
00885    }
00886 }
00887 
00888 
00894 struct gl_texture_image *
00895 _mesa_get_tex_image(GLcontext *ctx, struct gl_texture_object *texObj,
00896                     GLenum target, GLint level)
00897 {
00898    struct gl_texture_image *texImage;
00899 
00900    if (!texObj)
00901       return NULL;
00902    
00903    texImage = _mesa_select_tex_image(ctx, texObj, target, level);
00904    if (!texImage) {
00905       texImage = ctx->Driver.NewTextureImage(ctx);
00906       if (!texImage) {
00907          _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
00908          return NULL;
00909       }
00910 
00911       _mesa_set_tex_image(texObj, target, level, texImage);
00912    }
00913 
00914    return texImage;
00915 }
00916 
00917 
00924 struct gl_texture_image *
00925 _mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level)
00926 {
00927    struct gl_texture_image *texImage;
00928 
00929    if (level < 0 )
00930       return NULL;
00931 
00932    switch (target) {
00933    case GL_PROXY_TEXTURE_1D:
00934       if (level >= ctx->Const.MaxTextureLevels)
00935          return NULL;
00936       texImage = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level];
00937       if (!texImage) {
00938          texImage = ctx->Driver.NewTextureImage(ctx);
00939          if (!texImage) {
00940             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
00941             return NULL;
00942          }
00943          ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level] = texImage;
00944          /* Set the 'back' pointer */
00945          texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
00946       }
00947       return texImage;
00948    case GL_PROXY_TEXTURE_2D:
00949       if (level >= ctx->Const.MaxTextureLevels)
00950          return NULL;
00951       texImage = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level];
00952       if (!texImage) {
00953          texImage = ctx->Driver.NewTextureImage(ctx);
00954          if (!texImage) {
00955             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
00956             return NULL;
00957          }
00958          ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level] = texImage;
00959          /* Set the 'back' pointer */
00960          texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
00961       }
00962       return texImage;
00963    case GL_PROXY_TEXTURE_3D:
00964       if (level >= ctx->Const.Max3DTextureLevels)
00965          return NULL;
00966       texImage = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level];
00967       if (!texImage) {
00968          texImage = ctx->Driver.NewTextureImage(ctx);
00969          if (!texImage) {
00970             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
00971             return NULL;
00972          }
00973          ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level] = texImage;
00974          /* Set the 'back' pointer */
00975          texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
00976       }
00977       return texImage;
00978    case GL_PROXY_TEXTURE_CUBE_MAP:
00979       if (level >= ctx->Const.MaxCubeTextureLevels)
00980          return NULL;
00981       texImage = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level];
00982       if (!texImage) {
00983          texImage = ctx->Driver.NewTextureImage(ctx);
00984          if (!texImage) {
00985             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
00986             return NULL;
00987          }
00988          ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level] = texImage;
00989          /* Set the 'back' pointer */
00990          texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX];
00991       }
00992       return texImage;
00993    case GL_PROXY_TEXTURE_RECTANGLE_NV:
00994       if (level > 0)
00995          return NULL;
00996       texImage = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level];
00997       if (!texImage) {
00998          texImage = ctx->Driver.NewTextureImage(ctx);
00999          if (!texImage) {
01000             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
01001             return NULL;
01002          }
01003          ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level] = texImage;
01004          /* Set the 'back' pointer */
01005          texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX];
01006       }
01007       return texImage;
01008    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
01009       if (level >= ctx->Const.MaxTextureLevels)
01010          return NULL;
01011       texImage = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level];
01012       if (!texImage) {
01013          texImage = ctx->Driver.NewTextureImage(ctx);
01014          if (!texImage) {
01015             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
01016             return NULL;
01017          }
01018          ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level] = texImage;
01019          /* Set the 'back' pointer */
01020          texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX];
01021       }
01022       return texImage;
01023    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
01024       if (level >= ctx->Const.MaxTextureLevels)
01025          return NULL;
01026       texImage = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level];
01027       if (!texImage) {
01028          texImage = ctx->Driver.NewTextureImage(ctx);
01029          if (!texImage) {
01030             _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
01031             return NULL;
01032          }
01033          ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level] = texImage;
01034          /* Set the 'back' pointer */
01035          texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX];
01036       }
01037       return texImage;
01038    default:
01039       return NULL;
01040    }
01041 }
01042 
01043 
01055 GLint
01056 _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
01057 {
01058    switch (target) {
01059    case GL_TEXTURE_1D:
01060    case GL_PROXY_TEXTURE_1D:
01061    case GL_TEXTURE_2D:
01062    case GL_PROXY_TEXTURE_2D:
01063    case GL_TEXTURE_1D_ARRAY_EXT:
01064    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
01065    case GL_TEXTURE_2D_ARRAY_EXT:
01066    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
01067       return ctx->Const.MaxTextureLevels;
01068    case GL_TEXTURE_3D:
01069    case GL_PROXY_TEXTURE_3D:
01070       return ctx->Const.Max3DTextureLevels;
01071    case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01072    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01073    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01074    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01075    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01076    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01077    case GL_TEXTURE_CUBE_MAP_ARB:
01078    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
01079       return ctx->Const.MaxCubeTextureLevels;
01080    case GL_TEXTURE_RECTANGLE_NV:
01081    case GL_PROXY_TEXTURE_RECTANGLE_NV:
01082       return 1;
01083    default:
01084       return 0; /* bad target */
01085    }
01086 }
01087 
01088 
01089 
01090 #if 000 /* not used anymore */
01091 /*
01092  * glTexImage[123]D can accept a NULL image pointer.  In this case we
01093  * create a texture image with unspecified image contents per the OpenGL
01094  * spec.
01095  */
01096 static GLubyte *
01097 make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
01098 {
01099    const GLint components = _mesa_components_in_format(format);
01100    const GLint numPixels = width * height * depth;
01101    GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
01102 
01103 #ifdef DEBUG
01104    /*
01105     * Let's see if anyone finds this.  If glTexImage2D() is called with
01106     * a NULL image pointer then load the texture image with something
01107     * interesting instead of leaving it indeterminate.
01108     */
01109    if (data) {
01110       static const char message[8][32] = {
01111          "   X   X  XXXXX   XXX     X    ",
01112          "   XX XX  X      X   X   X X   ",
01113          "   X X X  X      X      X   X  ",
01114          "   X   X  XXXX    XXX   XXXXX  ",
01115          "   X   X  X          X  X   X  ",
01116          "   X   X  X      X   X  X   X  ",
01117          "   X   X  XXXXX   XXX   X   X  ",
01118          "                               "
01119       };
01120 
01121       GLubyte *imgPtr = data;
01122       GLint h, i, j, k;
01123       for (h = 0; h < depth; h++) {
01124          for (i = 0; i < height; i++) {
01125             GLint srcRow = 7 - (i % 8);
01126             for (j = 0; j < width; j++) {
01127                GLint srcCol = j % 32;
01128                GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
01129                for (k = 0; k < components; k++) {
01130                   *imgPtr++ = texel;
01131                }
01132             }
01133          }
01134       }
01135    }
01136 #endif
01137 
01138    return data;
01139 }
01140 #endif
01141 
01142 
01143 
01155 static void
01156 clear_teximage_fields(struct gl_texture_image *img)
01157 {
01158    ASSERT(img);
01159    img->_BaseFormat = 0;
01160    img->InternalFormat = 0;
01161    img->Border = 0;
01162    img->Width = 0;
01163    img->Height = 0;
01164    img->Depth = 0;
01165    img->RowStride = 0;
01166    if (img->ImageOffsets) {
01167       _mesa_free(img->ImageOffsets);
01168       img->ImageOffsets = NULL;
01169    }
01170    img->Width2 = 0;
01171    img->Height2 = 0;
01172    img->Depth2 = 0;
01173    img->WidthLog2 = 0;
01174    img->HeightLog2 = 0;
01175    img->DepthLog2 = 0;
01176    img->Data = NULL;
01177    img->TexFormat = &_mesa_null_texformat;
01178    img->FetchTexelc = NULL;
01179    img->FetchTexelf = NULL;
01180    img->IsCompressed = 0;
01181    img->CompressedSize = 0;
01182 }
01183 
01184 
01200 void
01201 _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
01202                            struct gl_texture_image *img,
01203                            GLsizei width, GLsizei height, GLsizei depth,
01204                            GLint border, GLenum internalFormat)
01205 {
01206    GLint i;
01207 
01208    ASSERT(img);
01209    ASSERT(width >= 0);
01210    ASSERT(height >= 0);
01211    ASSERT(depth >= 0);
01212 
01213    img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
01214    ASSERT(img->_BaseFormat > 0);
01215    img->InternalFormat = internalFormat;
01216    img->Border = border;
01217    img->Width = width;
01218    img->Height = height;
01219    img->Depth = depth;
01220    img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
01221    img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
01222    img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
01223    img->WidthLog2 = logbase2(img->Width2);
01224    if (height == 1)  /* 1-D texture */
01225       img->HeightLog2 = 0;
01226    else
01227       img->HeightLog2 = logbase2(img->Height2);
01228    if (depth == 1)   /* 2-D texture */
01229       img->DepthLog2 = 0;
01230    else
01231       img->DepthLog2 = logbase2(img->Depth2);
01232    img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
01233    img->IsCompressed = GL_FALSE;
01234    img->CompressedSize = 0;
01235 
01236    if ((width == 1 || _mesa_is_pow_two(img->Width2)) &&
01237        (height == 1 || _mesa_is_pow_two(img->Height2)) &&
01238        (depth == 1 || _mesa_is_pow_two(img->Depth2)))
01239       img->_IsPowerOfTwo = GL_TRUE;
01240    else
01241       img->_IsPowerOfTwo = GL_FALSE;
01242 
01243    /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */
01244    img->RowStride = width;
01245    /* Allocate the ImageOffsets array and initialize to typical values.
01246     * We allocate the array for 1D/2D textures too in order to avoid special-
01247     * case code in the texstore routines.
01248     */
01249    img->ImageOffsets = (GLuint *) _mesa_malloc(depth * sizeof(GLuint));
01250    for (i = 0; i < depth; i++) {
01251       img->ImageOffsets[i] = i * width * height;
01252    }
01253 
01254    /* Compute Width/Height/DepthScale for mipmap lod computation */
01255    if (target == GL_TEXTURE_RECTANGLE_NV) {
01256       /* scale = 1.0 since texture coords directly map to texels */
01257       img->WidthScale = 1.0;
01258       img->HeightScale = 1.0;
01259       img->DepthScale = 1.0;
01260    }
01261    else {
01262       img->WidthScale = (GLfloat) img->Width;
01263       img->HeightScale = (GLfloat) img->Height;
01264       img->DepthScale = (GLfloat) img->Depth;
01265    }
01266 }
01267 
01268 
01293 GLboolean
01294 _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
01295                           GLint internalFormat, GLenum format, GLenum type,
01296                           GLint width, GLint height, GLint depth, GLint border)
01297 {
01298    GLint maxSize;
01299 
01300    (void) internalFormat;
01301    (void) format;
01302    (void) type;
01303 
01304    switch (target) {
01305    case GL_PROXY_TEXTURE_1D:
01306       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
01307       if (width < 2 * border || width > 2 + maxSize ||
01308           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01309            width >0 && !_mesa_is_pow_two(width - 2 * border)) ||
01310           level >= ctx->Const.MaxTextureLevels) {
01311          /* bad width or level */
01312          return GL_FALSE;
01313       }
01314       return GL_TRUE;
01315    case GL_PROXY_TEXTURE_2D:
01316       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
01317       if (width < 2 * border || width > 2 + maxSize ||
01318           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01319            width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
01320           height < 2 * border || height > 2 + maxSize ||
01321           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01322            height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
01323           level >= ctx->Const.MaxTextureLevels) {
01324          /* bad width or height or level */
01325          return GL_FALSE;
01326       }
01327       return GL_TRUE;
01328    case GL_PROXY_TEXTURE_3D:
01329       maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
01330       if (width < 2 * border || width > 2 + maxSize ||
01331           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01332            width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
01333           height < 2 * border || height > 2 + maxSize ||
01334           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01335            height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
01336           depth < 2 * border || depth > 2 + maxSize ||
01337           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01338            depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) ||
01339           level >= ctx->Const.Max3DTextureLevels) {
01340          /* bad width or height or depth or level */
01341          return GL_FALSE;
01342       }
01343       return GL_TRUE;
01344    case GL_PROXY_TEXTURE_RECTANGLE_NV:
01345       if (width < 0 || width > ctx->Const.MaxTextureRectSize ||
01346           height < 0 || height > ctx->Const.MaxTextureRectSize ||
01347           level != 0) {
01348          /* bad width or height or level */
01349          return GL_FALSE;
01350       }
01351       return GL_TRUE;
01352    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
01353       maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
01354       if (width < 2 * border || width > 2 + maxSize ||
01355           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01356            width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
01357           height < 2 * border || height > 2 + maxSize ||
01358           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01359            height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
01360           level >= ctx->Const.MaxCubeTextureLevels) {
01361          /* bad width or height */
01362          return GL_FALSE;
01363       }
01364       return GL_TRUE;
01365    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
01366       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
01367       if (width < 2 * border || width > 2 + maxSize ||
01368           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01369            width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
01370           level >= ctx->Const.MaxTextureLevels) {
01371          /* bad width or level */
01372          return GL_FALSE;
01373       }
01374 
01375       if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) {
01376          return GL_FALSE;
01377       }
01378       return GL_TRUE;
01379    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
01380       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
01381       if (width < 2 * border || width > 2 + maxSize ||
01382           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01383            width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
01384           height < 2 * border || height > 2 + maxSize ||
01385           (!ctx->Extensions.ARB_texture_non_power_of_two &&
01386            height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
01387           level >= ctx->Const.MaxTextureLevels) {
01388          /* bad width or height or level */
01389          return GL_FALSE;
01390       }
01391       if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) {
01392          return GL_FALSE;
01393       }
01394       return GL_TRUE;
01395    default:
01396       _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
01397       return GL_FALSE;
01398    }
01399 }
01400 
01401 
01405 static GLboolean
01406 target_can_be_compressed(GLcontext *ctx, GLenum target)
01407 {
01408    return (((target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D))
01409            || ((ctx->Extensions.ARB_texture_cube_map &&
01410                 (target == GL_PROXY_TEXTURE_CUBE_MAP ||
01411                  (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
01412                   target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))))
01413            || ((ctx->Extensions.MESA_texture_array &&
01414                 ((target == GL_PROXY_TEXTURE_2D_ARRAY_EXT) ||
01415                  (target == GL_TEXTURE_2D_ARRAY_EXT)))));
01416 }
01417 
01418 
01440 static GLboolean
01441 texture_error_check( GLcontext *ctx, GLenum target,
01442                      GLint level, GLint internalFormat,
01443                      GLenum format, GLenum type,
01444                      GLuint dimensions,
01445                      GLint width, GLint height,
01446                      GLint depth, GLint border )
01447 {
01448    const GLboolean isProxy = _mesa_is_proxy_texture(target);
01449    GLboolean sizeOK = GL_TRUE;
01450    GLboolean colorFormat, indexFormat;
01451    GLenum proxy_target;
01452 
01453    /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
01454    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
01455       if (!isProxy) {
01456          _mesa_error(ctx, GL_INVALID_VALUE,
01457                      "glTexImage%dD(level=%d)", dimensions, level);
01458       }
01459       return GL_TRUE;
01460    }
01461 
01462    /* Check border */
01463    if (border < 0 || border > 1 ||
01464        ((target == GL_TEXTURE_RECTANGLE_NV ||
01465          target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
01466       if (!isProxy) {
01467          _mesa_error(ctx, GL_INVALID_VALUE,
01468                      "glTexImage%dD(border=%d)", dimensions, border);
01469       }
01470       return GL_TRUE;
01471    }
01472 
01473    if (width < 0 || height < 0 || depth < 0) {
01474       if (!isProxy) {
01475          _mesa_error(ctx, GL_INVALID_VALUE,
01476                      "glTexImage%dD(width, height or depth < 0)", dimensions);
01477       }
01478       return GL_TRUE;
01479    }
01480 
01481    /* Check target and call ctx->Driver.TestProxyTexImage() to check the
01482     * level, width, height and depth.
01483     */
01484    if (dimensions == 1) {
01485       if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
01486          proxy_target = GL_PROXY_TEXTURE_1D;
01487          height = 1;
01488          depth = 1;
01489       }
01490       else {
01491          _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
01492          return GL_TRUE;
01493       }
01494    }
01495    else if (dimensions == 2) {
01496       depth = 1;
01497       if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) {
01498          proxy_target = GL_PROXY_TEXTURE_2D;
01499       }
01500       else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
01501                (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
01502                 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
01503          if (!ctx->Extensions.ARB_texture_cube_map) {
01504             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
01505             return GL_TRUE;
01506          }
01507          proxy_target = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
01508          sizeOK = (width == height);
01509       }
01510       else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
01511                target == GL_TEXTURE_RECTANGLE_NV) {
01512          if (!ctx->Extensions.NV_texture_rectangle) {
01513             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
01514             return GL_TRUE;
01515          }
01516          proxy_target = GL_PROXY_TEXTURE_RECTANGLE_NV;
01517       }
01518       else if (target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
01519                target == GL_TEXTURE_1D_ARRAY_EXT) {
01520          proxy_target = GL_PROXY_TEXTURE_1D_ARRAY_EXT;
01521       }
01522       else {
01523          _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
01524          return GL_TRUE;
01525       }
01526    }
01527    else if (dimensions == 3) {
01528       if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) {
01529          proxy_target = GL_PROXY_TEXTURE_3D;
01530       }
01531       else if (target == GL_PROXY_TEXTURE_2D_ARRAY_EXT ||
01532                target == GL_TEXTURE_2D_ARRAY_EXT) {
01533          proxy_target = GL_PROXY_TEXTURE_2D_ARRAY_EXT;
01534       }
01535       else {
01536          _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
01537          return GL_TRUE;
01538       }
01539    }
01540    else {
01541       _mesa_problem( ctx, "bad dims in texture_error_check" );
01542       return GL_TRUE;
01543    }
01544 
01545    sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxy_target, level,
01546                                                     internalFormat, format,
01547                                                     type, width, height,
01548                                                     depth, border);
01549    if (!sizeOK) {
01550       if (!isProxy) {
01551          _mesa_error(ctx, GL_INVALID_VALUE,
01552                      "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
01553                      dimensions, level, width, height, depth);
01554       }
01555       return GL_TRUE;
01556    }
01557 
01558    /* Check internalFormat */
01559    if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
01560       if (!isProxy) {
01561          _mesa_error(ctx, GL_INVALID_VALUE,
01562                      "glTexImage%dD(internalFormat=0x%x)",
01563                      dimensions, internalFormat);
01564       }
01565       return GL_TRUE;
01566    }
01567 
01568    /* Check incoming image format and type */
01569    if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
01570       /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
01571        * is a type/format mismatch.  See 1.2 spec page 94, sec 3.6.4.
01572        */
01573       if (!isProxy) {
01574          _mesa_error(ctx, GL_INVALID_OPERATION,
01575                      "glTexImage%dD(format or type)", dimensions);
01576       }
01577       return GL_TRUE;
01578    }
01579 
01580    /* make sure internal format and format basically agree */
01581    colorFormat = _mesa_is_color_format(format);
01582    indexFormat = is_index_format(format);
01583    if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
01584        (is_index_format(internalFormat) && !indexFormat) ||
01585        (is_depth_format(internalFormat) != is_depth_format(format)) ||
01586        (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
01587        (is_depthstencil_format(internalFormat) != is_depthstencil_format(format))) {
01588       if (!isProxy)
01589          _mesa_error(ctx, GL_INVALID_OPERATION,
01590                      "glTexImage(internalFormat/format)");
01591       return GL_TRUE;
01592    }
01593 
01594    /* additional checks for ycbcr textures */
01595    if (internalFormat == GL_YCBCR_MESA) {
01596       ASSERT(ctx->Extensions.MESA_ycbcr_texture);
01597       if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
01598           type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
01599          char message[100];
01600          _mesa_sprintf(message,
01601                  "glTexImage%d(format/type YCBCR mismatch", dimensions);
01602          _mesa_error(ctx, GL_INVALID_ENUM, message);
01603          return GL_TRUE; /* error */
01604       }
01605       if (target != GL_TEXTURE_2D &&
01606           target != GL_PROXY_TEXTURE_2D &&
01607           target != GL_TEXTURE_RECTANGLE_NV &&
01608           target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
01609          if (!isProxy)
01610             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
01611          return GL_TRUE;
01612       }
01613       if (border != 0) {
01614          if (!isProxy) {
01615             char message[100];
01616             _mesa_sprintf(message,
01617                     "glTexImage%d(format=GL_YCBCR_MESA and border=%d)",
01618                     dimensions, border);
01619             _mesa_error(ctx, GL_INVALID_VALUE, message);
01620          }
01621          return GL_TRUE;
01622       }
01623    }
01624 
01625    /* additional checks for depth textures */
01626    if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
01627       /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */
01628       if (target != GL_TEXTURE_1D &&
01629           target != GL_PROXY_TEXTURE_1D &&
01630           target != GL_TEXTURE_2D &&
01631           target != GL_PROXY_TEXTURE_2D &&
01632           target != GL_TEXTURE_RECTANGLE_ARB &&
01633           target != GL_PROXY_TEXTURE_RECTANGLE_ARB) {
01634          if (!isProxy)
01635             _mesa_error(ctx, GL_INVALID_ENUM,
01636                         "glTexImage(target/internalFormat)");
01637          return GL_TRUE;
01638       }
01639    }
01640 
01641    /* additional checks for compressed textures */
01642    if (is_compressed_format(ctx, internalFormat)) {
01643       if (!target_can_be_compressed(ctx, target) && !isProxy) {
01644          _mesa_error(ctx, GL_INVALID_ENUM,
01645                      "glTexImage%d(target)", dimensions);
01646          return GL_TRUE;
01647       }
01648       if (border != 0) {
01649          if (!isProxy) {
01650             _mesa_error(ctx, GL_INVALID_OPERATION,
01651                         "glTexImage%D(border!=0)", dimensions);
01652          }
01653          return GL_TRUE;
01654       }
01655    }
01656 
01657    /* if we get here, the parameters are OK */
01658    return GL_FALSE;
01659 }
01660 
01661 
01684 static GLboolean
01685 subtexture_error_check( GLcontext *ctx, GLuint dimensions,
01686                         GLenum target, GLint level,
01687                         GLint xoffset, GLint yoffset, GLint zoffset,
01688                         GLint width, GLint height, GLint depth,
01689                         GLenum format, GLenum type )
01690 {
01691    /* Check target */
01692    if (dimensions == 1) {
01693       if (target != GL_TEXTURE_1D) {
01694          _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
01695          return GL_TRUE;
01696       }
01697    }
01698    else if (dimensions == 2) {
01699       if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
01700           target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
01701          if (!ctx->Extensions.ARB_texture_cube_map) {
01702             _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
01703             return GL_TRUE;
01704          }
01705       }
01706       else if (target == GL_TEXTURE_RECTANGLE_NV) {
01707          if (!ctx->Extensions.NV_texture_rectangle) {
01708             _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
01709             return GL_TRUE;
01710          }
01711       }
01712       else if (target == GL_TEXTURE_1D_ARRAY_EXT) {
01713         if (!ctx->Extensions.MESA_texture_array) {
01714            _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
01715            return GL_TRUE;
01716         }
01717       }
01718       else if (target != GL_TEXTURE_2D) {
01719          _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
01720          return GL_TRUE;
01721       }
01722    }
01723    else if (dimensions == 3) {
01724       if (target == GL_TEXTURE_2D_ARRAY_EXT) {
01725          if (!ctx->Extensions.MESA_texture_array) {
01726             _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
01727             return GL_TRUE;
01728          }
01729       }
01730       else if (target != GL_TEXTURE_3D) {
01731          _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
01732          return GL_TRUE;
01733       }
01734    }
01735    else {
01736       _mesa_problem( ctx, "invalid dims in texture_error_check" );
01737       return GL_TRUE;
01738    }
01739 
01740    /* Basic level check */
01741    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
01742       _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
01743       return GL_TRUE;
01744    }
01745 
01746    if (width < 0) {
01747       _mesa_error(ctx, GL_INVALID_VALUE,
01748                   "glTexSubImage%dD(width=%d)", dimensions, width);
01749       return GL_TRUE;
01750    }
01751    if (height < 0 && dimensions > 1) {
01752       _mesa_error(ctx, GL_INVALID_VALUE,
01753                   "glTexSubImage%dD(height=%d)", dimensions, height);
01754       return GL_TRUE;
01755    }
01756    if (depth < 0 && dimensions > 2) {
01757       _mesa_error(ctx, GL_INVALID_VALUE,
01758                   "glTexSubImage%dD(depth=%d)", dimensions, depth);
01759       return GL_TRUE;
01760    }
01761 
01762    if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
01763       _mesa_error(ctx, GL_INVALID_ENUM,
01764                   "glTexSubImage%dD(format or type)", dimensions);
01765       return GL_TRUE;
01766    }
01767 
01768    return GL_FALSE;
01769 }
01770 
01771 static GLboolean
01772 subtexture_error_check2( GLcontext *ctx, GLuint dimensions,
01773              GLenum target, GLint level,
01774              GLint xoffset, GLint yoffset, GLint zoffset,
01775              GLint width, GLint height, GLint depth,
01776              GLenum format, GLenum type,
01777              const struct gl_texture_image *destTex )
01778 {
01779    if (!destTex) {
01780       /* undefined image level */
01781       _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
01782       return GL_TRUE;
01783    }
01784 
01785    if (xoffset < -((GLint)destTex->Border)) {
01786       _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
01787                   dimensions);
01788       return GL_TRUE;
01789    }
01790    if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
01791       _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
01792                   dimensions);
01793       return GL_TRUE;
01794    }
01795    if (dimensions > 1) {
01796       if (yoffset < -((GLint)destTex->Border)) {
01797          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
01798                      dimensions);
01799          return GL_TRUE;
01800       }
01801       if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
01802          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
01803                      dimensions);
01804          return GL_TRUE;
01805       }
01806    }
01807    if (dimensions > 2) {
01808       if (zoffset < -((GLint)destTex->Border)) {
01809          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
01810          return GL_TRUE;
01811       }
01812       if (zoffset + depth  > (GLint) (destTex->Depth + destTex->Border)) {
01813          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
01814          return GL_TRUE;
01815       }
01816    }
01817 
01818 #if FEATURE_EXT_texture_sRGB
01819    if (destTex->InternalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT ||
01820        destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ||
01821        destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ||
01822        destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) {
01823       if ((width & 0x3) || (height & 0x3) ||
01824           (xoffset & 0x3) || (yoffset & 0x3))
01825          _mesa_error(ctx, GL_INVALID_OPERATION,
01826                      "glTexSubImage%dD(size or offset not multiple of 4)",
01827                      dimensions);
01828       return GL_TRUE;
01829    }
01830 #endif
01831 
01832    if (destTex->IsCompressed) {
01833       if (!target_can_be_compressed(ctx, target)) {
01834          _mesa_error(ctx, GL_INVALID_ENUM,
01835                      "glTexSubImage%D(target)", dimensions);
01836          return GL_TRUE;
01837       }
01838       /* offset must be multiple of 4 */
01839       if ((xoffset & 3) || (yoffset & 3)) {
01840          _mesa_error(ctx, GL_INVALID_OPERATION,
01841                      "glTexSubImage%D(xoffset or yoffset)", dimensions);
01842          return GL_TRUE;
01843       }
01844       /* size must be multiple of 4 or equal to whole texture size */
01845       if ((width & 3) && (GLuint) width != destTex->Width) {
01846          _mesa_error(ctx, GL_INVALID_OPERATION,
01847                      "glTexSubImage%D(width)", dimensions);
01848          return GL_TRUE;
01849       }         
01850       if ((height & 3) && (GLuint) height != destTex->Height) {
01851          _mesa_error(ctx, GL_INVALID_OPERATION,
01852                      "glTexSubImage%D(width)", dimensions);
01853          return GL_TRUE;
01854       }         
01855    }
01856 
01857    return GL_FALSE;
01858 }
01859 
01860 
01880 static GLboolean
01881 copytexture_error_check( GLcontext *ctx, GLuint dimensions,
01882                          GLenum target, GLint level, GLint internalFormat,
01883                          GLint width, GLint height, GLint border )
01884 {
01885    GLenum type;
01886    GLboolean sizeOK;
01887    GLint format;
01888 
01889    /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
01890    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
01891       _mesa_error(ctx, GL_INVALID_VALUE,
01892                   "glCopyTexImage%dD(level=%d)", dimensions, level);
01893       return GL_TRUE;
01894    }
01895 
01896    /* Check that the source buffer is complete */
01897    if (ctx->ReadBuffer->Name) {
01898       _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
01899       if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
01900          _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
01901                      "glCopyTexImage%dD(invalid readbuffer)", dimensions);
01902          return GL_TRUE;
01903       }
01904    }
01905 
01906    /* Check border */
01907    if (border < 0 || border > 1 ||
01908        ((target == GL_TEXTURE_RECTANGLE_NV ||
01909          target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
01910       return GL_TRUE;
01911    }
01912 
01913    format = _mesa_base_tex_format(ctx, internalFormat);
01914    if (format < 0) {
01915       _mesa_error(ctx, GL_INVALID_VALUE,
01916                   "glCopyTexImage%dD(internalFormat)", dimensions);
01917       return GL_TRUE;
01918    }
01919 
01920    /* NOTE: the format and type aren't really significant for
01921     * TestProxyTexImage().  Only the internalformat really matters.
01922    if (!_mesa_source_buffer_exists(ctx, format)) {
01923       _mesa_error(ctx, GL_INVALID_OPERATION,
01924                   "glCopyTexImage%dD(missing readbuffer)", dimensions);
01925       return GL_TRUE;
01926    }
01927 
01928     */
01929    type = GL_FLOAT;
01930 
01931    /* Check target and call ctx->Driver.TestProxyTexImage() to check the
01932     * level, width, height and depth.
01933     */
01934    if (dimensions == 1) {
01935       if (target == GL_TEXTURE_1D) {
01936          sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D,
01937                                                 level, internalFormat,
01938                                                 format, type,
01939                                                 width, 1, 1, border);
01940       }
01941       else {
01942          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
01943          return GL_TRUE;
01944       }
01945    }
01946    else if (dimensions == 2) {
01947       if (target == GL_TEXTURE_2D) {
01948          sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D,
01949                                                 level, internalFormat,
01950                                                 format, type,
01951                                                 width, height, 1, border);
01952       }
01953       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
01954                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
01955          if (!ctx->Extensions.ARB_texture_cube_map) {
01956             _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
01957             return GL_TRUE;
01958          }
01959          sizeOK = (width == height) &&
01960             ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB,
01961                                           level, internalFormat, format, type,
01962                                           width, height, 1, border);
01963       }
01964       else if (target == GL_TEXTURE_RECTANGLE_NV) {
01965          if (!ctx->Extensions.NV_texture_rectangle) {
01966             _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
01967             return GL_TRUE;
01968          }
01969          sizeOK = ctx->Driver.TestProxyTexImage(ctx,
01970                                                 GL_PROXY_TEXTURE_RECTANGLE_NV,
01971                                                 level, internalFormat,
01972                                                 format, type,
01973                                                 width, height, 1, border);
01974       }
01975       else if (target == GL_TEXTURE_1D_ARRAY_EXT) {
01976          if (!ctx->Extensions.MESA_texture_array) {
01977             _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)");
01978             return GL_TRUE;
01979          }
01980          sizeOK = ctx->Driver.TestProxyTexImage(ctx,
01981                                                 GL_PROXY_TEXTURE_1D_ARRAY_EXT,
01982                                                 level, internalFormat,
01983                                                 format, type,
01984                                                 width, height, 1, border);
01985       }
01986       else {
01987          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
01988          return GL_TRUE;
01989       }
01990    }
01991    else {
01992       _mesa_problem(ctx, "invalid dimensions in copytexture_error_check");
01993       return GL_TRUE;
01994    }
01995 
01996    if (!sizeOK) {
01997       if (dimensions == 1) {
01998          _mesa_error(ctx, GL_INVALID_VALUE,
01999                      "glCopyTexImage1D(width=%d)", width);
02000       }
02001       else {
02002          ASSERT(dimensions == 2);
02003          _mesa_error(ctx, GL_INVALID_VALUE,
02004                      "glCopyTexImage2D(width=%d, height=%d)", width, height);
02005       }
02006       return GL_TRUE;
02007    }
02008 
02009    if (is_compressed_format(ctx, internalFormat)) {
02010       if (!target_can_be_compressed(ctx, target)) {
02011          _mesa_error(ctx, GL_INVALID_ENUM,
02012                      "glCopyTexImage%d(target)", dimensions);
02013          return GL_TRUE;
02014       }
02015       if (border != 0) {
02016          _mesa_error(ctx, GL_INVALID_OPERATION,
02017                      "glCopyTexImage%D(border!=0)", dimensions);
02018          return GL_TRUE;
02019       }
02020    }
02021    else if (is_depth_format(internalFormat)) {
02022       /* make sure we have depth/stencil buffers */
02023       if (!ctx->ReadBuffer->_DepthBuffer) {
02024          _mesa_error(ctx, GL_INVALID_OPERATION,
02025                      "glCopyTexImage%D(no depth)", dimensions);
02026          return GL_TRUE;
02027       }
02028    }
02029    else if (is_depthstencil_format(internalFormat)) {
02030       /* make sure we have depth/stencil buffers */
02031       if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
02032          _mesa_error(ctx, GL_INVALID_OPERATION,
02033                      "glCopyTexImage%D(no depth/stencil buffer)", dimensions);
02034          return GL_TRUE;
02035       }
02036    }
02037 
02038    /* if we get here, the parameters are OK */
02039    return GL_FALSE;
02040 }
02041 
02042 
02055 static GLboolean
02056 copytexsubimage_error_check1( GLcontext *ctx, GLuint dimensions,
02057                               GLenum target, GLint level)
02058 {
02059    /* Check that the source buffer is complete */
02060    if (ctx->ReadBuffer->Name) {
02061       _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
02062       if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
02063          _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
02064                      "glCopyTexImage%dD(invalid readbuffer)", dimensions);
02065          return GL_TRUE;
02066       }
02067    }
02068 
02069    /* Check target */
02070    if (dimensions == 1) {
02071       if (target != GL_TEXTURE_1D) {
02072          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
02073          return GL_TRUE;
02074       }
02075    }
02076    else if (dimensions == 2) {
02077       if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
02078           target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
02079          if (!ctx->Extensions.ARB_texture_cube_map) {
02080             _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
02081             return GL_TRUE;
02082          }
02083       }
02084       else if (target == GL_TEXTURE_RECTANGLE_NV) {
02085          if (!ctx->Extensions.NV_texture_rectangle) {
02086             _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
02087             return GL_TRUE;
02088          }
02089       }
02090       else if (target == GL_TEXTURE_1D_ARRAY_EXT) {
02091          if (!ctx->Extensions.MESA_texture_array) {
02092             _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
02093             return GL_TRUE;
02094          }
02095       }
02096       else if (target != GL_TEXTURE_2D) {
02097          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
02098          return GL_TRUE;
02099       }
02100    }
02101    else if (dimensions == 3) {
02102       if (((target != GL_TEXTURE_2D_ARRAY_EXT) ||
02103        (!ctx->Extensions.MESA_texture_array))
02104       && (target != GL_TEXTURE_3D)) {
02105      _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
02106      return GL_TRUE;
02107       }
02108    }
02109 
02110    /* Check level */
02111    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
02112       _mesa_error(ctx, GL_INVALID_VALUE,
02113                   "glCopyTexSubImage%dD(level=%d)", dimensions, level);
02114       return GL_TRUE;
02115    }
02116 
02117    return GL_FALSE;
02118 }
02119 
02120 
02129 static GLboolean
02130 copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
02131                   GLenum target, GLint level,
02132                   GLint xoffset, GLint yoffset, GLint zoffset,
02133                   GLsizei width, GLsizei height,
02134                   const struct gl_texture_image *teximage )
02135 {
02136    /* check that dest tex image exists */
02137    if (!teximage) {
02138       _mesa_error(ctx, GL_INVALID_OPERATION,
02139                   "glCopyTexSubImage%dD(undefined texture level: %d)",
02140                   dimensions, level);
02141       return GL_TRUE;
02142    }
02143 
02144    /* Check size */
02145    if (width < 0) {
02146       _mesa_error(ctx, GL_INVALID_VALUE,
02147                   "glCopyTexSubImage%dD(width=%d)", dimensions, width);
02148       return GL_TRUE;
02149    }
02150    if (dimensions > 1 && height < 0) {
02151       _mesa_error(ctx, GL_INVALID_VALUE,
02152                   "glCopyTexSubImage%dD(height=%d)", dimensions, height);
02153       return GL_TRUE;
02154    }
02155 
02156    /* check x/y offsets */
02157    if (xoffset < -((GLint)teximage->Border)) {
02158       _mesa_error(ctx, GL_INVALID_VALUE,
02159                   "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
02160       return GL_TRUE;
02161    }
02162    if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
02163       _mesa_error(ctx, GL_INVALID_VALUE,
02164                   "glCopyTexSubImage%dD(xoffset+width)", dimensions);
02165       return GL_TRUE;
02166    }
02167    if (dimensions > 1) {
02168       if (yoffset < -((GLint)teximage->Border)) {
02169          _mesa_error(ctx, GL_INVALID_VALUE,
02170                      "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
02171          return GL_TRUE;
02172       }
02173       /* NOTE: we're adding the border here, not subtracting! */
02174       if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) {
02175          _mesa_error(ctx, GL_INVALID_VALUE,
02176                      "glCopyTexSubImage%dD(yoffset+height)", dimensions);
02177          return GL_TRUE;
02178       }
02179    }
02180 
02181    /* check z offset */
02182    if (dimensions > 2) {
02183       if (zoffset < -((GLint)teximage->Border)) {
02184          _mesa_error(ctx, GL_INVALID_VALUE,
02185                      "glCopyTexSubImage%dD(zoffset)", dimensions);
02186          return GL_TRUE;
02187       }
02188       if (zoffset > (GLint) (teximage->Depth + teximage->Border)) {
02189          _mesa_error(ctx, GL_INVALID_VALUE,
02190                      "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
02191          return GL_TRUE;
02192       }
02193    }
02194 
02195    if (teximage->IsCompressed) {
02196       if (!target_can_be_compressed(ctx, target)) {
02197          _mesa_error(ctx, GL_INVALID_ENUM,
02198                      "glCopyTexSubImage%d(target)", dimensions);
02199          return GL_TRUE;
02200       }
02201       /* offset must be multiple of 4 */
02202       if ((xoffset & 3) || (yoffset & 3)) {
02203          _mesa_error(ctx, GL_INVALID_VALUE,
02204                      "glCopyTexSubImage%D(xoffset or yoffset)", dimensions);
02205          return GL_TRUE;
02206       }
02207       /* size must be multiple of 4 */
02208       if ((width & 3) != 0 && (GLuint) width != teximage->Width) {
02209          _mesa_error(ctx, GL_INVALID_VALUE,
02210                      "glCopyTexSubImage%D(width)", dimensions);
02211          return GL_TRUE;
02212       }         
02213       if ((height & 3) != 0 && (GLuint) height != teximage->Height) {
02214          _mesa_error(ctx, GL_INVALID_VALUE,
02215                      "glCopyTexSubImage%D(height)", dimensions);
02216          return GL_TRUE;
02217       }         
02218    }
02219 
02220    if (teximage->InternalFormat == GL_YCBCR_MESA) {
02221       _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
02222       return GL_TRUE;
02223    }
02224 
02225    if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
02226       _mesa_error(ctx, GL_INVALID_OPERATION,
02227                   "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)",
02228                   dimensions, teximage->_BaseFormat);
02229       return GL_TRUE;
02230    }
02231 
02232    if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) {
02233       if (!ctx->ReadBuffer->_DepthBuffer) {
02234          _mesa_error(ctx, GL_INVALID_OPERATION,
02235                      "glCopyTexSubImage%D(no depth buffer)",
02236                      dimensions);
02237          return GL_TRUE;
02238       }
02239    }
02240    else if (teximage->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
02241       if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
02242          _mesa_error(ctx, GL_INVALID_OPERATION,
02243                      "glCopyTexSubImage%D(no depth/stencil buffer)",
02244                      dimensions);
02245          return GL_TRUE;
02246       }
02247    }
02248 
02249    /* if we get here, the parameters are OK */
02250    return GL_FALSE;
02251 }
02252 
02253 
02263 void GLAPIENTRY
02264 _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
02265                    GLenum type, GLvoid *pixels )
02266 {
02267    const struct gl_texture_unit *texUnit;
02268    struct gl_texture_object *texObj;
02269    struct gl_texture_image *texImage;
02270    GLint maxLevels = 0;
02271    GET_CURRENT_CONTEXT(ctx);
02272    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02273 
02274    texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
02275    texObj = _mesa_select_tex_object(ctx, texUnit, target);
02276    if (!texObj || _mesa_is_proxy_texture(target)) {
02277       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
02278       return;
02279    }
02280 
02281    maxLevels = _mesa_max_texture_levels(ctx, target);
02282    ASSERT(maxLevels > 0);  /* 0 indicates bad target, caught above */
02283 
02284    if (level < 0 || level >= maxLevels) {
02285       _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
02286       return;
02287    }
02288 
02289    if (_mesa_sizeof_packed_type(type) <= 0) {
02290       _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
02291       return;
02292    }
02293 
02294    if (_mesa_components_in_format(format) <= 0 ||
02295        format == GL_STENCIL_INDEX) {
02296       _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
02297       return;
02298    }
02299 
02300    if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
02301       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
02302       return;
02303    }
02304 
02305    if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
02306       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
02307       return;
02308    }
02309 
02310    if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
02311       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
02312       return;
02313    }
02314 
02315    if (!ctx->Extensions.EXT_packed_depth_stencil
02316        && is_depthstencil_format(format)) {
02317       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
02318       return;
02319    }
02320 
02321    _mesa_lock_texture(ctx, texObj);
02322    {
02323       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
02324       if (!texImage) {
02325      /* invalid mipmap level, not an error */
02326      goto out;
02327       }
02328 
02329 
02330       /* Make sure the requested image format is compatible with the
02331        * texture's format.  Note that a color index texture can be converted
02332        * to RGBA so that combo is allowed.
02333        */
02334       if (_mesa_is_color_format(format)
02335       && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
02336       && !is_index_format(texImage->TexFormat->BaseFormat)) {
02337      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
02338      goto out;
02339       }
02340       else if (is_index_format(format)
02341            && !is_index_format(texImage->TexFormat->BaseFormat)) {
02342      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
02343      goto out;
02344       }
02345       else if (is_depth_format(format)
02346            && !is_depth_format(texImage->TexFormat->BaseFormat)
02347            && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
02348      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
02349      goto out;
02350       }
02351       else if (is_ycbcr_format(format)
02352            && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
02353      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
02354      goto out;
02355       }
02356       else if (is_depthstencil_format(format)
02357            && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
02358      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
02359      goto out;
02360       }
02361 
02362       if (ctx->Pack.BufferObj->Name) {
02363      /* packing texture image into a PBO */
02364      const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
02365      if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
02366                     texImage->Height, texImage->Depth,
02367                     format, type, pixels)) {
02368         _mesa_error(ctx, GL_INVALID_OPERATION,
02369             "glGetTexImage(invalid PBO access)");
02370         goto out;
02371      }
02372       }
02373 
02374       /* typically, this will call _mesa_get_teximage() */
02375       ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
02376                   texObj, texImage);
02377 
02378    }
02379  out:
02380    _mesa_unlock_texture(ctx, texObj);
02381 }
02382 
02383 
02384 
02392 static void
02393 update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj,
02394                    GLuint face, GLuint level)
02395 {
02396    if (ctx->DrawBuffer->Name) {
02397       GLuint i;
02398       for (i = 0; i < BUFFER_COUNT; i++) {
02399          struct gl_renderbuffer_attachment *att = 
02400             ctx->DrawBuffer->Attachment + i;
02401          if (att->Type == GL_TEXTURE &&
02402              att->Texture == texObj &&
02403              att->TextureLevel == level &&
02404              att->CubeMapFace == face) {
02405             ASSERT(att->Texture->Image[att->CubeMapFace][att->TextureLevel]);
02406             /* Tell driver about the new renderbuffer texture */
02407             ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
02408          }
02409       }
02410    }
02411 }
02412 
02413 
02414 
02415 /*
02416  * Called from the API.  Note that width includes the border.
02417  */
02418 void GLAPIENTRY
02419 _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
02420                   GLsizei width, GLint border, GLenum format,
02421                   GLenum type, const GLvoid *pixels )
02422 {
02423    GLsizei postConvWidth = width;
02424    GET_CURRENT_CONTEXT(ctx);
02425    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02426 
02427 #if FEATURE_convolve
02428    if (_mesa_is_color_format(internalFormat)) {
02429       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
02430    }
02431 #endif
02432 
02433    if (target == GL_TEXTURE_1D) {
02434       /* non-proxy target */
02435       struct gl_texture_unit *texUnit;
02436       struct gl_texture_object *texObj;
02437       struct gl_texture_image *texImage;
02438       const GLuint face = _mesa_tex_target_to_face(target);
02439 
02440       if (texture_error_check(ctx, target, level, internalFormat,
02441                               format, type, 1, postConvWidth, 1, 1, border)) {
02442          return;   /* error was recorded */
02443       }
02444 
02445       if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
02446      _mesa_update_state(ctx);
02447 
02448       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
02449       texObj = _mesa_select_tex_object(ctx, texUnit, target);
02450       _mesa_lock_texture(ctx, texObj);
02451       {
02452      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
02453      if (!texImage) {
02454         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
02455         goto out;
02456      }
02457       
02458      if (texImage->Data) {
02459         ctx->Driver.FreeTexImageData( ctx, texImage );
02460      }
02461 
02462      ASSERT(texImage->Data == NULL);
02463 
02464      clear_teximage_fields(texImage); /* not really needed, but helpful */
02465      _mesa_init_teximage_fields(ctx, target, texImage,
02466                     postConvWidth, 1, 1,
02467                     border, internalFormat);
02468      
02469      ASSERT(ctx->Driver.TexImage1D);
02470 
02471      /* Give the texture to the driver!  <pixels> may be null! */
02472      (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
02473                    width, border, format, type, pixels,
02474                    &ctx->Unpack, texObj, texImage);
02475      
02476      ASSERT(texImage->TexFormat);
02477 
02478      update_fbo_texture(ctx, texObj, face, level);
02479      
02480      /* state update */
02481      texObj->_Complete = GL_FALSE;
02482      ctx->NewState |= _NEW_TEXTURE;
02483       }
02484    out:
02485       _mesa_unlock_texture(ctx, texObj);
02486    }
02487    else if (target == GL_PROXY_TEXTURE_1D) {
02488       /* Proxy texture: check for errors and update proxy state */
02489       struct gl_texture_image *texImage;
02490       texImage = _mesa_get_proxy_tex_image(ctx, target, level);
02491       if (texture_error_check(ctx, target, level, internalFormat,
02492                               format, type, 1, postConvWidth, 1, 1, border)) {
02493          /* when error, clear all proxy texture image parameters */
02494          if (texImage)
02495             clear_teximage_fields(texImage);
02496       }
02497       else {
02498          /* no error, set the tex image parameters */
02499          ASSERT(texImage);
02500          _mesa_init_teximage_fields(ctx, target, texImage,
02501                                     postConvWidth, 1, 1,
02502                                     border, internalFormat);
02503          texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
02504                                           internalFormat, format, type);
02505       }
02506    }
02507    else {
02508       _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
02509       return;
02510    }
02511 }
02512 
02513 
02514 void GLAPIENTRY
02515 _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
02516                   GLsizei width, GLsizei height, GLint border,
02517                   GLenum format, GLenum type,
02518                   const GLvoid *pixels )
02519 {
02520    GLsizei postConvWidth = width, postConvHeight = height;
02521    GET_CURRENT_CONTEXT(ctx);
02522    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02523 
02524 #if FEATURE_convolve
02525    if (_mesa_is_color_format(internalFormat)) {
02526       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
02527                      &postConvHeight);
02528    }
02529 #endif
02530 
02531    if (target == GL_TEXTURE_2D ||
02532        (ctx->Extensions.ARB_texture_cube_map &&
02533         target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
02534         target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) ||
02535        (ctx->Extensions.NV_texture_rectangle &&
02536         target == GL_TEXTURE_RECTANGLE_NV) ||
02537        (ctx->Extensions.MESA_texture_array &&
02538         target == GL_TEXTURE_1D_ARRAY_EXT)) {
02539       /* non-proxy target */
02540       struct gl_texture_unit *texUnit;
02541       struct gl_texture_object *texObj;
02542       struct gl_texture_image *texImage;
02543       const GLuint face = _mesa_tex_target_to_face(target);
02544 
02545       if (texture_error_check(ctx, target, level, internalFormat,
02546                               format, type, 2, postConvWidth, postConvHeight,
02547                               1, border)) {
02548          return;   /* error was recorded */
02549       }
02550 
02551       if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
02552      _mesa_update_state(ctx);
02553 
02554       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
02555       texObj = _mesa_select_tex_object(ctx, texUnit, target);
02556       _mesa_lock_texture(ctx, texObj);
02557       {
02558      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
02559      if (!texImage) {
02560         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
02561         goto out;
02562      }
02563      
02564      if (texImage->Data) {
02565         ctx->Driver.FreeTexImageData( ctx, texImage );
02566      }
02567      
02568      ASSERT(texImage->Data == NULL);
02569      clear_teximage_fields(texImage); /* not really needed, but helpful */
02570      _mesa_init_teximage_fields(ctx, target, texImage,
02571                     postConvWidth, postConvHeight, 1,
02572                     border, internalFormat);
02573      
02574      ASSERT(ctx->Driver.TexImage2D);
02575 
02576      /* Give the texture to the driver!  <pixels> may be null! */
02577      (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
02578                    width, height, border, format, type, pixels,
02579                    &ctx->Unpack, texObj, texImage);
02580      
02581      ASSERT(texImage->TexFormat);
02582 
02583      update_fbo_texture(ctx, texObj, face, level);
02584 
02585      /* state update */
02586      texObj->_Complete = GL_FALSE;
02587      ctx->NewState |= _NEW_TEXTURE;
02588       }
02589    out:
02590       _mesa_unlock_texture(ctx, texObj);
02591    }
02592    else if (target == GL_PROXY_TEXTURE_2D ||
02593             (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
02594              ctx->Extensions.ARB_texture_cube_map) ||
02595             (target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
02596              ctx->Extensions.NV_texture_rectangle) ||
02597             (ctx->Extensions.MESA_texture_array &&
02598              target == GL_PROXY_TEXTURE_1D_ARRAY_EXT)) {
02599       /* Proxy texture: check for errors and update proxy state */
02600       struct gl_texture_image *texImage;
02601       texImage = _mesa_get_proxy_tex_image(ctx, target, level);
02602       if (texture_error_check(ctx, target, level, internalFormat,
02603                               format, type, 2, postConvWidth, postConvHeight,
02604                               1, border)) {
02605          /* when error, clear all proxy texture image parameters */
02606          if (texImage)
02607             clear_teximage_fields(texImage);
02608       }
02609       else {
02610          /* no error, set the tex image parameters */
02611          _mesa_init_teximage_fields(ctx, target, texImage,
02612                                     postConvWidth, postConvHeight, 1,
02613                                     border, internalFormat);
02614          texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
02615                                           internalFormat, format, type);
02616       }
02617    }
02618    else {
02619       _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
02620       return;
02621    }
02622 }
02623 
02624 
02625 /*
02626  * Called by the API or display list executor.
02627  * Note that width and height include the border.
02628  */
02629 void GLAPIENTRY
02630 _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
02631                   GLsizei width, GLsizei height, GLsizei depth,
02632                   GLint border, GLenum format, GLenum type,
02633                   const GLvoid *pixels )
02634 {
02635    GET_CURRENT_CONTEXT(ctx);
02636    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02637 
02638    if (target == GL_TEXTURE_3D ||
02639        (ctx->Extensions.MESA_texture_array &&
02640         target == GL_TEXTURE_2D_ARRAY_EXT)) {
02641       /* non-proxy target */
02642       struct gl_texture_unit *texUnit;
02643       struct gl_texture_object *texObj;
02644       struct gl_texture_image *texImage;
02645       const GLuint face = _mesa_tex_target_to_face(target);
02646 
02647       if (texture_error_check(ctx, target, level, (GLint) internalFormat,
02648                               format, type, 3, width, height, depth, border)) {
02649          return;   /* error was recorded */
02650       }
02651 
02652       if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
02653      _mesa_update_state(ctx);
02654 
02655       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
02656       texObj = _mesa_select_tex_object(ctx, texUnit, target);
02657       _mesa_lock_texture(ctx, texObj);
02658       {
02659      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
02660      if (!texImage) {
02661         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
02662         goto out;
02663      }
02664      
02665      if (texImage->Data) {
02666         ctx->Driver.FreeTexImageData( ctx, texImage );
02667      }
02668      
02669      ASSERT(texImage->Data == NULL);
02670      clear_teximage_fields(texImage); /* not really needed, but helpful */
02671      _mesa_init_teximage_fields(ctx, target, texImage,
02672                     width, height, depth,
02673                     border, internalFormat);
02674 
02675      ASSERT(ctx->Driver.TexImage3D);
02676 
02677      /* Give the texture to the driver!  <pixels> may be null! */
02678      (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
02679                    width, height, depth, border, format, type,
02680                    pixels, &ctx->Unpack, texObj, texImage);
02681 
02682      ASSERT(texImage->TexFormat);
02683 
02684      update_fbo_texture(ctx, texObj, face, level);
02685 
02686      /* state update */
02687      texObj->_Complete = GL_FALSE;
02688      ctx->NewState |= _NEW_TEXTURE;
02689       }
02690    out:
02691       _mesa_unlock_texture(ctx, texObj);
02692    }
02693    else if (target == GL_PROXY_TEXTURE_3D ||
02694        (ctx->Extensions.MESA_texture_array &&
02695         target == GL_PROXY_TEXTURE_2D_ARRAY_EXT)) {
02696       /* Proxy texture: check for errors and update proxy state */
02697       struct gl_texture_image *texImage;
02698       texImage = _mesa_get_proxy_tex_image(ctx, target, level);
02699       if (texture_error_check(ctx, target, level, internalFormat,
02700                               format, type, 3, width, height, depth, border)) {
02701          /* when error, clear all proxy texture image parameters */
02702          if (texImage)
02703             clear_teximage_fields(texImage);
02704       }
02705       else {
02706          /* no error, set the tex image parameters */
02707          _mesa_init_teximage_fields(ctx, target, texImage, width, height,
02708                                     depth, border, internalFormat);
02709          texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
02710                                           internalFormat, format, type);
02711       }
02712    }
02713    else {
02714       _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
02715       return;
02716    }
02717 }
02718 
02719 
02720 void GLAPIENTRY
02721 _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
02722                      GLsizei width, GLsizei height, GLsizei depth,
02723                      GLint border, GLenum format, GLenum type,
02724                      const GLvoid *pixels )
02725 {
02726    _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
02727                     depth, border, format, type, pixels);
02728 }
02729 
02730 
02731 
02732 void GLAPIENTRY
02733 _mesa_TexSubImage1D( GLenum target, GLint level,
02734                      GLint xoffset, GLsizei width,
02735                      GLenum format, GLenum type,
02736                      const GLvoid *pixels )
02737 {
02738    GLsizei postConvWidth = width;
02739    struct gl_texture_unit *texUnit;
02740    struct gl_texture_object *texObj;
02741    struct gl_texture_image *texImage = NULL;
02742    GET_CURRENT_CONTEXT(ctx);
02743    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02744 
02745    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
02746       _mesa_update_state(ctx);
02747 
02748 #if FEATURE_convolve
02749    /* XXX should test internal format */
02750    if (_mesa_is_color_format(format)) {
02751       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
02752    }
02753 #endif
02754 
02755    if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
02756                    postConvWidth, 1, 1, format, type)) {
02757       return;   /* error was detected */
02758    }
02759 
02760 
02761    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
02762    texObj = _mesa_select_tex_object(ctx, texUnit, target);
02763    assert(texObj);
02764 
02765    _mesa_lock_texture(ctx, texObj);
02766    {
02767       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
02768 
02769       if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0,
02770                   postConvWidth, 1, 1, format, type, texImage)) {
02771      goto out;   /* error was detected */
02772       }
02773 
02774       if (width == 0)
02775      goto out;  /* no-op, not an error */
02776 
02777       /* If we have a border, xoffset=-1 is legal.  Bias by border width */
02778       xoffset += texImage->Border;
02779 
02780       ASSERT(ctx->Driver.TexSubImage1D);
02781       (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
02782                    format, type, pixels, &ctx->Unpack,
02783                    texObj, texImage);
02784       ctx->NewState |= _NEW_TEXTURE;
02785    }
02786  out:
02787    _mesa_unlock_texture(ctx, texObj);
02788 }
02789 
02790 
02791 void GLAPIENTRY
02792 _mesa_TexSubImage2D( GLenum target, GLint level,
02793                      GLint xoffset, GLint yoffset,
02794                      GLsizei width, GLsizei height,
02795                      GLenum format, GLenum type,
02796                      const GLvoid *pixels )
02797 {
02798    GLsizei postConvWidth = width, postConvHeight = height;
02799    struct gl_texture_unit *texUnit;
02800    struct gl_texture_object *texObj;
02801    struct gl_texture_image *texImage;
02802    GET_CURRENT_CONTEXT(ctx);
02803    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02804 
02805    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
02806       _mesa_update_state(ctx);
02807 
02808 #if FEATURE_convolve
02809    /* XXX should test internal format */
02810    if (_mesa_is_color_format(format)) {
02811       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
02812                                          &postConvHeight);
02813    }
02814 #endif
02815 
02816    if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
02817                   postConvWidth, postConvHeight, 1, format, type)) {
02818       return;   /* error was detected */
02819    }
02820 
02821    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
02822    texObj = _mesa_select_tex_object(ctx, texUnit, target);
02823    _mesa_lock_texture(ctx, texObj);
02824    {
02825       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
02826 
02827       if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
02828                   postConvWidth, postConvHeight, 1, format, type, 
02829                   texImage)) {
02830      goto out;   /* error was detected */
02831       }
02832 
02833       if (width == 0 || height == 0)
02834      goto out;  /* no-op, not an error */
02835 
02836       /* If we have a border, xoffset=-1 is legal.  Bias by border width */
02837       xoffset += texImage->Border;
02838       yoffset += texImage->Border;
02839       
02840       ASSERT(ctx->Driver.TexSubImage2D);
02841       (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset,
02842                    width, height, format, type, pixels,
02843                    &ctx->Unpack, texObj, texImage);
02844       ctx->NewState |= _NEW_TEXTURE;
02845    }
02846  out:
02847    _mesa_unlock_texture(ctx, texObj);
02848 }
02849 
02850 
02851 
02852 void GLAPIENTRY
02853 _mesa_TexSubImage3D( GLenum target, GLint level,
02854                      GLint xoffset, GLint yoffset, GLint zoffset,
02855                      GLsizei width, GLsizei height, GLsizei depth,
02856                      GLenum format, GLenum type,
02857                      const GLvoid *pixels )
02858 {
02859    struct gl_texture_unit *texUnit;
02860    struct gl_texture_object *texObj;
02861    struct gl_texture_image *texImage;
02862    GET_CURRENT_CONTEXT(ctx);
02863    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02864 
02865    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
02866       _mesa_update_state(ctx);
02867 
02868    if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
02869                               width, height, depth, format, type)) {
02870       return;   /* error was detected */
02871    }
02872 
02873    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
02874    texObj = _mesa_select_tex_object(ctx, texUnit, target);
02875 
02876    _mesa_lock_texture(ctx, texObj);
02877    {
02878       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
02879 
02880       if (subtexture_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset,
02881                   width, height, depth, format, type, texImage)) {
02882      goto out;   /* error was detected */
02883       }
02884 
02885       if (width == 0 || height == 0 || height == 0)
02886      goto out;  /* no-op, not an error */
02887 
02888       /* If we have a border, xoffset=-1 is legal.  Bias by border width */
02889       xoffset += texImage->Border;
02890       yoffset += texImage->Border;
02891       zoffset += texImage->Border;
02892 
02893       ASSERT(ctx->Driver.TexSubImage3D);
02894       (*ctx->Driver.TexSubImage3D)(ctx, target, level,
02895                    xoffset, yoffset, zoffset,
02896                    width, height, depth,
02897                    format, type, pixels,
02898                    &ctx->Unpack, texObj, texImage );
02899       ctx->NewState |= _NEW_TEXTURE;
02900    }
02901  out:
02902    _mesa_unlock_texture(ctx, texObj);
02903 }
02904 
02905 
02906 
02907 void GLAPIENTRY
02908 _mesa_CopyTexImage1D( GLenum target, GLint level,
02909                       GLenum internalFormat,
02910                       GLint x, GLint y,
02911                       GLsizei width, GLint border )
02912 {
02913    struct gl_texture_unit *texUnit;
02914    struct gl_texture_object *texObj;
02915    struct gl_texture_image *texImage;
02916    GLsizei postConvWidth = width;
02917    const GLuint face = _mesa_tex_target_to_face(target);
02918    GET_CURRENT_CONTEXT(ctx);
02919    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02920 
02921    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
02922       _mesa_update_state(ctx);
02923 
02924 #if FEATURE_convolve
02925    if (_mesa_is_color_format(internalFormat)) {
02926       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
02927    }
02928 #endif
02929 
02930    if (copytexture_error_check(ctx, 1, target, level, internalFormat,
02931                                postConvWidth, 1, border))
02932       return;
02933 
02934    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
02935    texObj = _mesa_select_tex_object(ctx, texUnit, target);
02936    _mesa_lock_texture(ctx, texObj);
02937    {
02938       texImage = _mesa_get_tex_image(ctx, texObj, target, level);
02939       if (!texImage) {
02940      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
02941      goto out;
02942       }
02943 
02944       if (texImage->Data) {
02945      ctx->Driver.FreeTexImageData( ctx, texImage );
02946       }
02947       
02948       ASSERT(texImage->Data == NULL);
02949 
02950       clear_teximage_fields(texImage); /* not really needed, but helpful */
02951       _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
02952                  border, internalFormat);
02953 
02954 
02955       ASSERT(ctx->Driver.CopyTexImage1D);
02956       (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat,
02957                     x, y, width, border);
02958 
02959       ASSERT(texImage->TexFormat);
02960 
02961       update_fbo_texture(ctx, texObj, face, level);
02962 
02963       /* state update */
02964       texObj->_Complete = GL_FALSE;
02965       ctx->NewState |= _NEW_TEXTURE;
02966    }
02967  out:
02968    _mesa_unlock_texture(ctx, texObj);
02969 }
02970 
02971 
02972 
02973 void GLAPIENTRY
02974 _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
02975                       GLint x, GLint y, GLsizei width, GLsizei height,
02976                       GLint border )
02977 {
02978    struct gl_texture_unit *texUnit;
02979    struct gl_texture_object *texObj;
02980    struct gl_texture_image *texImage;
02981    GLsizei postConvWidth = width, postConvHeight = height;
02982    const GLuint face = _mesa_tex_target_to_face(target);
02983    GET_CURRENT_CONTEXT(ctx);
02984    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
02985 
02986    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
02987       _mesa_update_state(ctx);
02988 
02989 #if FEATURE_convolve
02990    if (_mesa_is_color_format(internalFormat)) {
02991       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
02992                                          &postConvHeight);
02993    }
02994 #endif
02995 
02996    if (copytexture_error_check(ctx, 2, target, level, internalFormat,
02997                                postConvWidth, postConvHeight, border))
02998       return;
02999 
03000    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03001    texObj = _mesa_select_tex_object(ctx, texUnit, target);
03002 
03003    _mesa_lock_texture(ctx, texObj);
03004    {
03005       texImage = _mesa_get_tex_image(ctx, texObj, target, level);
03006 
03007       if (!texImage) {
03008      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
03009      goto out;
03010       }
03011       
03012       if (texImage->Data) {
03013      ctx->Driver.FreeTexImageData( ctx, texImage );
03014       }
03015       
03016       ASSERT(texImage->Data == NULL);
03017 
03018       clear_teximage_fields(texImage); /* not really needed, but helpful */
03019       _mesa_init_teximage_fields(ctx, target, texImage,
03020                  postConvWidth, postConvHeight, 1,
03021                  border, internalFormat);
03022       
03023       ASSERT(ctx->Driver.CopyTexImage2D);
03024       (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat,
03025                     x, y, width, height, border);
03026       
03027       ASSERT(texImage->TexFormat);
03028 
03029       update_fbo_texture(ctx, texObj, face, level);
03030 
03031       /* state update */
03032       texObj->_Complete = GL_FALSE;
03033       ctx->NewState |= _NEW_TEXTURE;
03034    }
03035  out:
03036    _mesa_unlock_texture(ctx, texObj);
03037 }
03038 
03039 
03040 void GLAPIENTRY
03041 _mesa_CopyTexSubImage1D( GLenum target, GLint level,
03042                          GLint xoffset, GLint x, GLint y, GLsizei width )
03043 {
03044    struct gl_texture_unit *texUnit;
03045    struct gl_texture_object *texObj;
03046    struct gl_texture_image *texImage;
03047    GLsizei postConvWidth = width;
03048    GLint yoffset = 0;
03049    GLsizei height = 1;
03050 
03051    GET_CURRENT_CONTEXT(ctx);
03052    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03053 
03054    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
03055       _mesa_update_state(ctx);
03056 
03057    if (copytexsubimage_error_check1(ctx, 1, target, level))
03058       return;
03059 
03060    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03061    texObj = _mesa_select_tex_object(ctx, texUnit, target);
03062 
03063    _mesa_lock_texture(ctx, texObj);
03064    {
03065       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03066 
03067 #if FEATURE_convolve
03068       if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
03069          _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
03070       }
03071 #endif
03072 
03073       if (copytexsubimage_error_check2(ctx, 1, target, level,
03074                        xoffset, 0, 0, postConvWidth, 1,
03075                        texImage))
03076      goto out;
03077       
03078 
03079       /* If we have a border, xoffset=-1 is legal.  Bias by border width */
03080       xoffset += texImage->Border;
03081 
03082       if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
03083                                      &width, &height)) {
03084          ASSERT(ctx->Driver.CopyTexSubImage1D);
03085          ctx->Driver.CopyTexSubImage1D(ctx, target, level,
03086                                        xoffset, x, y, width);
03087       }
03088 
03089       ctx->NewState |= _NEW_TEXTURE;
03090    }
03091  out:
03092    _mesa_unlock_texture(ctx, texObj);
03093 }
03094 
03095 
03096 
03097 void GLAPIENTRY
03098 _mesa_CopyTexSubImage2D( GLenum target, GLint level,
03099                          GLint xoffset, GLint yoffset,
03100                          GLint x, GLint y, GLsizei width, GLsizei height )
03101 {
03102    struct gl_texture_unit *texUnit;
03103    struct gl_texture_object *texObj;
03104    struct gl_texture_image *texImage;
03105    GLsizei postConvWidth = width, postConvHeight = height;
03106    GET_CURRENT_CONTEXT(ctx);
03107    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03108 
03109    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
03110       _mesa_update_state(ctx);
03111 
03112    if (copytexsubimage_error_check1(ctx, 2, target, level))
03113       return;
03114 
03115    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03116    texObj = _mesa_select_tex_object(ctx, texUnit, target);
03117 
03118    _mesa_lock_texture(ctx, texObj);
03119    {
03120       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03121 
03122 #if FEATURE_convolve
03123       if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
03124          _mesa_adjust_image_for_convolution(ctx, 2,
03125                                             &postConvWidth, &postConvHeight);
03126       }
03127 #endif
03128 
03129       if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
03130                        postConvWidth, postConvHeight, texImage))
03131      goto out;
03132 
03133       /* If we have a border, xoffset=-1 is legal.  Bias by border width */
03134       xoffset += texImage->Border;
03135       yoffset += texImage->Border;
03136 
03137       if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
03138                                      &width, &height)) {
03139          ASSERT(ctx->Driver.CopyTexSubImage2D);
03140          ctx->Driver.CopyTexSubImage2D(ctx, target, level,
03141                        xoffset, yoffset, x, y, width, height);
03142       }
03143 
03144       ctx->NewState |= _NEW_TEXTURE;
03145    }
03146  out:
03147    _mesa_unlock_texture(ctx, texObj);
03148 }
03149 
03150 
03151 
03152 void GLAPIENTRY
03153 _mesa_CopyTexSubImage3D( GLenum target, GLint level,
03154                          GLint xoffset, GLint yoffset, GLint zoffset,
03155                          GLint x, GLint y, GLsizei width, GLsizei height )
03156 {
03157    struct gl_texture_unit *texUnit;
03158    struct gl_texture_object *texObj;
03159    struct gl_texture_image *texImage;
03160    GLsizei postConvWidth = width, postConvHeight = height;
03161    GET_CURRENT_CONTEXT(ctx);
03162    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03163 
03164    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
03165       _mesa_update_state(ctx);
03166 
03167    if (copytexsubimage_error_check1(ctx, 3, target, level))
03168       return;
03169 
03170    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03171    texObj = _mesa_select_tex_object(ctx, texUnit, target);
03172 
03173    _mesa_lock_texture(ctx, texObj);
03174    {
03175       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03176 
03177 #if FEATURE_convolve
03178       if (texImage && _mesa_is_color_format(texImage->InternalFormat)) {
03179          _mesa_adjust_image_for_convolution(ctx, 2,
03180                                             &postConvWidth, &postConvHeight);
03181       }
03182 #endif
03183 
03184       if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset,
03185                        zoffset, postConvWidth, postConvHeight,
03186                        texImage))
03187      goto out;
03188 
03189       /* If we have a border, xoffset=-1 is legal.  Bias by border width */
03190       xoffset += texImage->Border;
03191       yoffset += texImage->Border;
03192       zoffset += texImage->Border;
03193       
03194       if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
03195                                      &width, &height)) {
03196          ASSERT(ctx->Driver.CopyTexSubImage3D);
03197          ctx->Driver.CopyTexSubImage3D(ctx, target, level,
03198                        xoffset, yoffset, zoffset,
03199                        x, y, width, height);
03200       }
03201 
03202       ctx->NewState |= _NEW_TEXTURE;
03203    }
03204  out:
03205    _mesa_unlock_texture(ctx, texObj);
03206 }
03207 
03208 
03209 
03210 
03211 /**********************************************************************/
03212 /******                   Compressed Textures                    ******/
03213 /**********************************************************************/
03214 
03215 
03220 static GLenum
03221 compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
03222                                GLenum target, GLint level,
03223                                GLenum internalFormat, GLsizei width,
03224                                GLsizei height, GLsizei depth, GLint border,
03225                                GLsizei imageSize)
03226 {
03227    GLint expectedSize, maxLevels = 0, maxTextureSize;
03228 
03229    if (dimensions == 1) {
03230       /* 1D compressed textures not allowed */
03231       return GL_INVALID_ENUM;
03232    }
03233    else if (dimensions == 2) {
03234       if (target == GL_PROXY_TEXTURE_2D) {
03235          maxLevels = ctx->Const.MaxTextureLevels;
03236       }
03237       else if (target == GL_TEXTURE_2D) {
03238          maxLevels = ctx->Const.MaxTextureLevels;
03239       }
03240       else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
03241          if (!ctx->Extensions.ARB_texture_cube_map)
03242             return GL_INVALID_ENUM; /*target*/
03243          maxLevels = ctx->Const.MaxCubeTextureLevels;
03244       }
03245       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
03246                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
03247          if (!ctx->Extensions.ARB_texture_cube_map)
03248             return GL_INVALID_ENUM; /*target*/
03249          maxLevels = ctx->Const.MaxCubeTextureLevels;
03250       }
03251       else {
03252          return GL_INVALID_ENUM; /*target*/
03253       }
03254    }
03255    else if (dimensions == 3) {
03256       /* 3D compressed textures not allowed */
03257       return GL_INVALID_ENUM;
03258    }
03259 
03260    maxTextureSize = 1 << (maxLevels - 1);
03261 
03262    /* This will detect any invalid internalFormat value */
03263    if (!is_compressed_format(ctx, internalFormat))
03264       return GL_INVALID_ENUM;
03265 
03266    /* This should really never fail */
03267    if (_mesa_base_tex_format(ctx, internalFormat) < 0)
03268       return GL_INVALID_ENUM;
03269 
03270    if (border != 0)
03271       return GL_INVALID_VALUE;
03272 
03273    /*
03274     * XXX We should probably use the proxy texture error check function here.
03275     */
03276    if (width < 1 || width > maxTextureSize ||
03277        (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width)))
03278       return GL_INVALID_VALUE;
03279 
03280    if ((height < 1 || height > maxTextureSize ||
03281        (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height)))
03282        && dimensions > 1)
03283       return GL_INVALID_VALUE;
03284 
03285    if ((depth < 1 || depth > maxTextureSize ||
03286        (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth)))
03287        && dimensions > 2)
03288       return GL_INVALID_VALUE;
03289 
03290    /* For cube map, width must equal height */
03291    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
03292        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height)
03293       return GL_INVALID_VALUE;
03294 
03295    if (level < 0 || level >= maxLevels)
03296       return GL_INVALID_VALUE;
03297 
03298    expectedSize = _mesa_compressed_texture_size_glenum(ctx, width, height,
03299                                                        depth, internalFormat);
03300    if (expectedSize != imageSize)
03301       return GL_INVALID_VALUE;
03302 
03303 #if FEATURE_EXT_texture_sRGB
03304    if ((internalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT ||
03305         internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ||
03306         internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ||
03307         internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT)
03308        && border != 0) {
03309       return GL_INVALID_OPERATION;
03310    }
03311 #endif
03312 
03313    return GL_NO_ERROR;
03314 }
03315 
03316 
03324 static GLenum
03325 compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
03326                                   GLenum target, GLint level,
03327                                   GLint xoffset, GLint yoffset, GLint zoffset,
03328                                   GLsizei width, GLsizei height, GLsizei depth,
03329                                   GLenum format, GLsizei imageSize)
03330 {
03331    GLint expectedSize, maxLevels = 0, maxTextureSize;
03332    (void) zoffset;
03333 
03334    if (dimensions == 1) {
03335       /* 1D compressed textures not allowed */
03336       return GL_INVALID_ENUM;
03337    }
03338    else if (dimensions == 2) {
03339       if (target == GL_PROXY_TEXTURE_2D) {
03340          maxLevels = ctx->Const.MaxTextureLevels;
03341       }
03342       else if (target == GL_TEXTURE_2D) {
03343          maxLevels = ctx->Const.MaxTextureLevels;
03344       }
03345       else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
03346          if (!ctx->Extensions.ARB_texture_cube_map)
03347             return GL_INVALID_ENUM; /*target*/
03348          maxLevels = ctx->Const.MaxCubeTextureLevels;
03349       }
03350       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
03351                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
03352          if (!ctx->Extensions.ARB_texture_cube_map)
03353             return GL_INVALID_ENUM; /*target*/
03354          maxLevels = ctx->Const.MaxCubeTextureLevels;
03355       }
03356       else {
03357          return GL_INVALID_ENUM; /*target*/
03358       }
03359    }
03360    else if (dimensions == 3) {
03361       /* 3D compressed textures not allowed */
03362       return GL_INVALID_ENUM;
03363    }
03364 
03365    maxTextureSize = 1 << (maxLevels - 1);
03366 
03367    /* this will catch any invalid compressed format token */
03368    if (!is_compressed_format(ctx, format))
03369       return GL_INVALID_ENUM;
03370 
03371    if (width < 1 || width > maxTextureSize)
03372       return GL_INVALID_VALUE;
03373 
03374    if ((height < 1 || height > maxTextureSize)
03375        && dimensions > 1)
03376       return GL_INVALID_VALUE;
03377 
03378    if (level < 0 || level >= maxLevels)
03379       return GL_INVALID_VALUE;
03380 
03381    /* XXX these tests are specific to the compressed format.
03382     * this code should be generalized in some way.
03383     */
03384    if ((xoffset & 3) != 0 || (yoffset & 3) != 0)
03385       return GL_INVALID_VALUE;
03386 
03387    if ((width & 3) != 0 && width != 2 && width != 1)
03388       return GL_INVALID_VALUE;
03389 
03390    if ((height & 3) != 0 && height != 2 && height != 1)
03391       return GL_INVALID_VALUE;
03392 
03393    expectedSize = _mesa_compressed_texture_size_glenum(ctx, width, height,
03394                                                        depth, format);
03395    if (expectedSize != imageSize)
03396       return GL_INVALID_VALUE;
03397 
03398    return GL_NO_ERROR;
03399 }
03400 
03401 
03402 
03403 void GLAPIENTRY
03404 _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
03405                               GLenum internalFormat, GLsizei width,
03406                               GLint border, GLsizei imageSize,
03407                               const GLvoid *data)
03408 {
03409    GET_CURRENT_CONTEXT(ctx);
03410    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03411 
03412    if (target == GL_TEXTURE_1D) {
03413       /* non-proxy target */
03414       struct gl_texture_unit *texUnit;
03415       struct gl_texture_object *texObj;
03416       struct gl_texture_image *texImage;
03417       GLenum error = compressed_texture_error_check(ctx, 1, target, level,
03418                                internalFormat, width, 1, 1, border, imageSize);
03419       if (error) {
03420          _mesa_error(ctx, error, "glCompressedTexImage1D");
03421          return;
03422       }
03423 
03424       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03425       texObj = _mesa_select_tex_object(ctx, texUnit, target);
03426 
03427       _mesa_lock_texture(ctx, texObj);
03428       {
03429      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
03430      if (!texImage) {
03431         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
03432         goto out;
03433      }
03434      
03435      if (texImage->Data) {
03436         ctx->Driver.FreeTexImageData( ctx, texImage );
03437      }
03438      ASSERT(texImage->Data == NULL);
03439 
03440      _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
03441                     border, internalFormat);
03442 
03443      ASSERT(ctx->Driver.CompressedTexImage1D);
03444      (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
03445                          internalFormat, width, border,
03446                          imageSize, data,
03447                          texObj, texImage);
03448 
03449      /* state update */
03450      texObj->_Complete = GL_FALSE;
03451      ctx->NewState |= _NEW_TEXTURE;
03452       }
03453    out:
03454       _mesa_unlock_texture(ctx, texObj);
03455    }
03456    else if (target == GL_PROXY_TEXTURE_1D) {
03457       /* Proxy texture: check for errors and update proxy state */
03458       GLenum error = compressed_texture_error_check(ctx, 1, target, level,
03459                                internalFormat, width, 1, 1, border, imageSize);
03460       if (!error) {
03461          ASSERT(ctx->Driver.TestProxyTexImage);
03462          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
03463                                              internalFormat, GL_NONE, GL_NONE,
03464                                              width, 1, 1, border);
03465       }
03466       if (error) {
03467          /* if error, clear all proxy texture image parameters */
03468          struct gl_texture_image *texImage;
03469          texImage = _mesa_get_proxy_tex_image(ctx, target, level);
03470          if (texImage)
03471             clear_teximage_fields(texImage);
03472       }
03473       else {
03474          /* store the teximage parameters */
03475          struct gl_texture_unit *texUnit;
03476          struct gl_texture_object *texObj;
03477          struct gl_texture_image *texImage;
03478          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03479      texObj = _mesa_select_tex_object(ctx, texUnit, target);
03480 
03481      _mesa_lock_texture(ctx, texObj);
03482      {
03483         texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03484         _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
03485                        border, internalFormat);
03486      }
03487      _mesa_unlock_texture(ctx, texObj);
03488       }
03489    }
03490    else {
03491       _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)");
03492       return;
03493    }
03494 }
03495 
03496 
03497 void GLAPIENTRY
03498 _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
03499                               GLenum internalFormat, GLsizei width,
03500                               GLsizei height, GLint border, GLsizei imageSize,
03501                               const GLvoid *data)
03502 {
03503    GET_CURRENT_CONTEXT(ctx);
03504    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03505 
03506    if (target == GL_TEXTURE_2D ||
03507        (ctx->Extensions.ARB_texture_cube_map &&
03508         target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
03509         target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
03510       /* non-proxy target */
03511       struct gl_texture_unit *texUnit;
03512       struct gl_texture_object *texObj;
03513       struct gl_texture_image *texImage;
03514       GLenum error = compressed_texture_error_check(ctx, 2, target, level,
03515                           internalFormat, width, height, 1, border, imageSize);
03516       if (error) {
03517          _mesa_error(ctx, error, "glCompressedTexImage2D");
03518          return;
03519       }
03520 
03521       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03522       texObj = _mesa_select_tex_object(ctx, texUnit, target);
03523 
03524       _mesa_lock_texture(ctx, texObj);
03525       {
03526      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
03527      if (!texImage) {
03528         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
03529         goto out;
03530      }
03531      
03532      if (texImage->Data) {
03533         ctx->Driver.FreeTexImageData( ctx, texImage );
03534      }
03535      ASSERT(texImage->Data == NULL);
03536 
03537      _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
03538                     border, internalFormat);
03539 
03540      ASSERT(ctx->Driver.CompressedTexImage2D);
03541      (*ctx->Driver.CompressedTexImage2D)(ctx, target, level,
03542                          internalFormat, width, height,
03543                          border, imageSize, data,
03544                          texObj, texImage);
03545      
03546      /* state update */
03547      texObj->_Complete = GL_FALSE;
03548      ctx->NewState |= _NEW_TEXTURE;
03549       }
03550    out:
03551       _mesa_unlock_texture(ctx, texObj);
03552    }
03553    else if (target == GL_PROXY_TEXTURE_2D ||
03554             (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
03555              ctx->Extensions.ARB_texture_cube_map)) {
03556       /* Proxy texture: check for errors and update proxy state */
03557       GLenum error = compressed_texture_error_check(ctx, 2, target, level,
03558                           internalFormat, width, height, 1, border, imageSize);
03559       if (!error) {
03560          ASSERT(ctx->Driver.TestProxyTexImage);
03561          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
03562                                               internalFormat, GL_NONE, GL_NONE,
03563                                               width, height, 1, border);
03564       }
03565       if (error) {
03566          /* if error, clear all proxy texture image parameters */
03567          struct gl_texture_image *texImage;
03568          texImage = _mesa_get_proxy_tex_image(ctx, target, level);
03569          if (texImage)
03570             clear_teximage_fields(texImage);
03571       }
03572       else {
03573          /* store the teximage parameters */
03574          struct gl_texture_unit *texUnit;
03575          struct gl_texture_object *texObj;
03576          struct gl_texture_image *texImage;
03577          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03578      texObj = _mesa_select_tex_object(ctx, texUnit, target);
03579 
03580      _mesa_lock_texture(ctx, texObj);
03581      {
03582         texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03583         _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
03584                        border, internalFormat);
03585      }
03586      _mesa_unlock_texture(ctx, texObj);
03587       }
03588    }
03589    else {
03590       _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)");
03591       return;
03592    }
03593 }
03594 
03595 
03596 void GLAPIENTRY
03597 _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
03598                               GLenum internalFormat, GLsizei width,
03599                               GLsizei height, GLsizei depth, GLint border,
03600                               GLsizei imageSize, const GLvoid *data)
03601 {
03602    GET_CURRENT_CONTEXT(ctx);
03603    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03604 
03605    if (target == GL_TEXTURE_3D) {
03606       /* non-proxy target */
03607       struct gl_texture_unit *texUnit;
03608       struct gl_texture_object *texObj;
03609       struct gl_texture_image *texImage;
03610       GLenum error = compressed_texture_error_check(ctx, 3, target, level,
03611                       internalFormat, width, height, depth, border, imageSize);
03612       if (error) {
03613          _mesa_error(ctx, error, "glCompressedTexImage3D");
03614          return;
03615       }
03616 
03617       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03618       texObj = _mesa_select_tex_object(ctx, texUnit, target);
03619       _mesa_lock_texture(ctx, texObj);
03620       {
03621      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
03622      if (!texImage) {
03623         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
03624         goto out;
03625      }
03626      
03627      if (texImage->Data) {
03628         ctx->Driver.FreeTexImageData( ctx, texImage );
03629      }
03630      ASSERT(texImage->Data == NULL);
03631 
03632      _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
03633                     border, internalFormat);
03634 
03635      ASSERT(ctx->Driver.CompressedTexImage3D);
03636      (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
03637                          internalFormat,
03638                          width, height, depth,
03639                          border, imageSize, data,
03640                          texObj, texImage);
03641      
03642      /* state update */
03643      texObj->_Complete = GL_FALSE;
03644      ctx->NewState |= _NEW_TEXTURE;
03645       }
03646    out:
03647       _mesa_unlock_texture(ctx, texObj);
03648    }
03649    else if (target == GL_PROXY_TEXTURE_3D) {
03650       /* Proxy texture: check for errors and update proxy state */
03651       GLenum error = compressed_texture_error_check(ctx, 3, target, level,
03652                       internalFormat, width, height, depth, border, imageSize);
03653       if (!error) {
03654          ASSERT(ctx->Driver.TestProxyTexImage);
03655          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
03656                                              internalFormat, GL_NONE, GL_NONE,
03657                                              width, height, depth, border);
03658       }
03659       if (error) {
03660          /* if error, clear all proxy texture image parameters */
03661          struct gl_texture_image *texImage;
03662          texImage = _mesa_get_proxy_tex_image(ctx, target, level);
03663          if (texImage)
03664             clear_teximage_fields(texImage);
03665       }
03666       else {
03667          /* store the teximage parameters */
03668          struct gl_texture_unit *texUnit;
03669          struct gl_texture_object *texObj;
03670          struct gl_texture_image *texImage;
03671          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03672      texObj = _mesa_select_tex_object(ctx, texUnit, target);
03673      _mesa_lock_texture(ctx, texObj);
03674      {
03675         texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03676         _mesa_init_teximage_fields(ctx, target, texImage, width, height,
03677                        depth, border, internalFormat);
03678      }
03679      _mesa_unlock_texture(ctx, texObj);
03680       }
03681    }
03682    else {
03683       _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)");
03684       return;
03685    }
03686 }
03687 
03688 
03689 void GLAPIENTRY
03690 _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
03691                                  GLsizei width, GLenum format,
03692                                  GLsizei imageSize, const GLvoid *data)
03693 {
03694    struct gl_texture_unit *texUnit;
03695    struct gl_texture_object *texObj;
03696    struct gl_texture_image *texImage;
03697    GLenum error;
03698    GET_CURRENT_CONTEXT(ctx);
03699    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03700 
03701    error = compressed_subtexture_error_check(ctx, 1, target, level,
03702                                              xoffset, 0, 0, /* pos */
03703                                              width, 1, 1,   /* size */
03704                                              format, imageSize);
03705    if (error) {
03706       _mesa_error(ctx, error, "glCompressedTexSubImage1D");
03707       return;
03708    }
03709 
03710    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03711    texObj = _mesa_select_tex_object(ctx, texUnit, target);
03712    _mesa_lock_texture(ctx, texObj);
03713    {
03714       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03715       assert(texImage);
03716 
03717       if ((GLint) format != texImage->InternalFormat) {
03718      _mesa_error(ctx, GL_INVALID_OPERATION,
03719              "glCompressedTexSubImage1D(format)");
03720      goto out;
03721       }
03722 
03723       if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) {
03724      _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)");
03725      goto out;
03726       }
03727       
03728       if (width == 0)
03729      goto out;  /* no-op, not an error */
03730 
03731       if (ctx->Driver.CompressedTexSubImage1D) {
03732      (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
03733                         xoffset, width,
03734                         format, imageSize, data,
03735                         texObj, texImage);
03736       }
03737       ctx->NewState |= _NEW_TEXTURE;
03738    }
03739  out:
03740    _mesa_unlock_texture(ctx, texObj);
03741 }
03742 
03743 
03744 void GLAPIENTRY
03745 _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
03746                                  GLint yoffset, GLsizei width, GLsizei height,
03747                                  GLenum format, GLsizei imageSize,
03748                                  const GLvoid *data)
03749 {
03750    struct gl_texture_unit *texUnit;
03751    struct gl_texture_object *texObj;
03752    struct gl_texture_image *texImage;
03753    GLenum error;
03754    GET_CURRENT_CONTEXT(ctx);
03755    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03756 
03757    error = compressed_subtexture_error_check(ctx, 2, target, level,
03758                                              xoffset, yoffset, 0, /* pos */
03759                                              width, height, 1,    /* size */
03760                                              format, imageSize);
03761    if (error) {
03762       /* XXX proxy target? */
03763       _mesa_error(ctx, error, "glCompressedTexSubImage2D");
03764       return;
03765    }
03766 
03767    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03768    texObj = _mesa_select_tex_object(ctx, texUnit, target);
03769    _mesa_lock_texture(ctx, texObj);
03770    {
03771       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03772       assert(texImage);
03773 
03774       if ((GLint) format != texImage->InternalFormat) {
03775      _mesa_error(ctx, GL_INVALID_OPERATION,
03776              "glCompressedTexSubImage2D(format)");
03777      goto out;
03778       }
03779 
03780       if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
03781       ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) {
03782      _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)");
03783      goto out;
03784       }
03785       
03786       if (width == 0 || height == 0)
03787      goto out;  /* no-op, not an error */
03788 
03789       if (ctx->Driver.CompressedTexSubImage2D) {
03790      (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
03791                         xoffset, yoffset, width, height,
03792                         format, imageSize, data,
03793                         texObj, texImage);
03794       }
03795       ctx->NewState |= _NEW_TEXTURE;
03796    }
03797  out:
03798    _mesa_unlock_texture(ctx, texObj);
03799 }
03800 
03801 
03802 void GLAPIENTRY
03803 _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
03804                                  GLint yoffset, GLint zoffset, GLsizei width,
03805                                  GLsizei height, GLsizei depth, GLenum format,
03806                                  GLsizei imageSize, const GLvoid *data)
03807 {
03808    struct gl_texture_unit *texUnit;
03809    struct gl_texture_object *texObj;
03810    struct gl_texture_image *texImage;
03811    GLenum error;
03812    GET_CURRENT_CONTEXT(ctx);
03813    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03814 
03815    error = compressed_subtexture_error_check(ctx, 3, target, level,
03816                                              xoffset, yoffset, zoffset,/*pos*/
03817                                              width, height, depth, /*size*/
03818                                              format, imageSize);
03819    if (error) {
03820       _mesa_error(ctx, error, "glCompressedTexSubImage3D");
03821       return;
03822    }
03823 
03824    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03825    texObj = _mesa_select_tex_object(ctx, texUnit, target);
03826    _mesa_lock_texture(ctx, texObj);
03827    {
03828       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03829       assert(texImage);
03830 
03831       if ((GLint) format != texImage->InternalFormat) {
03832      _mesa_error(ctx, GL_INVALID_OPERATION,
03833              "glCompressedTexSubImage3D(format)");
03834      goto out;
03835       }
03836 
03837       if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
03838       ((height == 1 || height == 2) && (GLuint) height != texImage->Height) ||
03839       ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) {
03840      _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)");
03841      goto out;
03842       }
03843       
03844       if (width == 0 || height == 0 || depth == 0)
03845      goto out;  /* no-op, not an error */
03846 
03847       if (ctx->Driver.CompressedTexSubImage3D) {
03848      (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
03849                         xoffset, yoffset, zoffset,
03850                         width, height, depth,
03851                         format, imageSize, data,
03852                         texObj, texImage);
03853       }
03854       ctx->NewState |= _NEW_TEXTURE;
03855    }
03856  out:
03857    _mesa_unlock_texture(ctx, texObj);
03858 }
03859 
03860 
03861 void GLAPIENTRY
03862 _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
03863 {
03864    const struct gl_texture_unit *texUnit;
03865    struct gl_texture_object *texObj;
03866    struct gl_texture_image *texImage;
03867    GLint maxLevels;
03868    GET_CURRENT_CONTEXT(ctx);
03869    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
03870 
03871    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
03872    texObj = _mesa_select_tex_object(ctx, texUnit, target);
03873    if (!texObj) {
03874       _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
03875       return;
03876    }
03877 
03878    maxLevels = _mesa_max_texture_levels(ctx, target);
03879    ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
03880 
03881    if (level < 0 || level >= maxLevels) {
03882       _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
03883       return;
03884    }
03885 
03886    if (_mesa_is_proxy_texture(target)) {
03887       _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
03888       return;
03889    }
03890 
03891    _mesa_lock_texture(ctx, texObj);
03892    {
03893       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
03894       if (texImage) {
03895          if (texImage->IsCompressed) {
03896             /* this typically calls _mesa_get_compressed_teximage() */
03897             ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
03898                                               texObj, texImage);
03899          }
03900          else {
03901             _mesa_error(ctx, GL_INVALID_OPERATION,
03902                         "glGetCompressedTexImageARB");
03903          }
03904       }
03905       else {
03906          /* probably invalid mipmap level */
03907          _mesa_error(ctx, GL_INVALID_VALUE,
03908                      "glGetCompressedTexImageARB(level)");
03909       }
03910    }
03911    _mesa_unlock_texture(ctx, texObj);
03912 }

Generated on Sat May 26 2012 04:19:14 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.