home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / MesaDLL / teximage.cpp < prev    next >
C/C++ Source or Header  |  2002-10-30  |  100KB  |  2,939 lines

  1. /* $Id: teximage.c,v 1.124 2002/10/30 19:58:58 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. #include "glheader.h"
  28. #include "context.h"
  29. #include "convolve.h"
  30. #include "image.h"
  31. #include "imports.h"
  32. #include "macros.h"
  33. #include "mmath.h"
  34. #include "state.h"
  35. #include "texcompress.h"
  36. #include "texformat.h"
  37. #include "teximage.h"
  38. #include "texstate.h"
  39. #include "texstore.h"
  40. #include "mtypes.h"
  41.  
  42.  
  43. /*
  44.  * NOTES:
  45.  *
  46.  * Mesa's native texture datatype is GLchan.  Native formats are
  47.  * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
  48.  * and GL_COLOR_INDEX.
  49.  * Device drivers are free to implement any internal format they want.
  50.  */
  51.  
  52.  
  53. #if 0
  54. static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img)
  55. {
  56. #if CHAN_TYPE == GL_FLOAT
  57.    _mesa_problem(NULL, "PrintTexture doesn't support float channels");
  58. #else
  59.    GLuint i, j, c;
  60.    const GLchan *data = (const GLchan *) img->Data;
  61.  
  62.    if (!data) {
  63.       _mesa_printf("No texture data\n");
  64.       return;
  65.    }
  66.  
  67.    switch (img->Format) {
  68.       case GL_ALPHA:
  69.       case GL_LUMINANCE:
  70.       case GL_INTENSITY:
  71.       case GL_COLOR_INDEX:
  72.          c = 1;
  73.          break;
  74.       case GL_LUMINANCE_ALPHA:
  75.          c = 2;
  76.          break;
  77.       case GL_RGB:
  78.          c = 3;
  79.          break;
  80.       case GL_RGBA:
  81.          c = 4;
  82.          break;
  83.       default:
  84.          _mesa_problem(NULL, "error in PrintTexture\n");
  85.          return;
  86.    }
  87.  
  88.    for (i = 0; i < img->Height; i++) {
  89.       for (j = 0; j < img->Width; j++) {
  90.          if (c==1)
  91.             _mesa_printf("%02x  ", data[0]);
  92.          else if (c==2)
  93.             _mesa_printf("%02x%02x  ", data[0], data[1]);
  94.          else if (c==3)
  95.             _mesa_printf("%02x%02x%02x  ", data[0], data[1], data[2]);
  96.          else if (c==4)
  97.             _mesa_printf("%02x%02x%02x%02x  ", data[0], data[1], data[2], data[3]);
  98.          data += (img->RowStride - img->Width) * c;
  99.       }
  100.       _mesa_printf("\n");
  101.    }
  102. #endif
  103. }
  104. #endif
  105.  
  106.  
  107.  
  108. /*
  109.  * Compute log base 2 of n.
  110.  * If n isn't an exact power of two return -1.
  111.  * If n < 0 return -1.
  112.  */
  113. static int
  114. logbase2( int n )
  115. {
  116.    GLint i = 1;
  117.    GLint log2 = 0;
  118.  
  119.    if (n < 0) {
  120.       return -1;
  121.    }
  122.  
  123.    while ( n > i ) {
  124.       i *= 2;
  125.       log2++;
  126.    }
  127.    if (i != n) {
  128.       return -1;
  129.    }
  130.    else {
  131.       return log2;
  132.    }
  133. }
  134.  
  135.  
  136.  
  137. /*
  138.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  139.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  140.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
  141.  *
  142.  * This is the format which is used during texture application (i.e. the
  143.  * texture format and env mode determine the arithmetic used.
  144.  *
  145.  * Return -1 if invalid enum.
  146.  */
  147. GLint
  148. _mesa_base_tex_format( GLcontext *ctx, GLint format )
  149. {
  150.    /*
  151.     * Ask the driver for the base format, if it doesn't
  152.     * know, it will return -1;
  153.     */
  154.    switch (format) {
  155.       case GL_ALPHA:
  156.       case GL_ALPHA4:
  157.       case GL_ALPHA8:
  158.       case GL_ALPHA12:
  159.       case GL_ALPHA16:
  160.          return GL_ALPHA;
  161.       case 1:
  162.       case GL_LUMINANCE:
  163.       case GL_LUMINANCE4:
  164.       case GL_LUMINANCE8:
  165.       case GL_LUMINANCE12:
  166.       case GL_LUMINANCE16:
  167.          return GL_LUMINANCE;
  168.       case 2:
  169.       case GL_LUMINANCE_ALPHA:
  170.       case GL_LUMINANCE4_ALPHA4:
  171.       case GL_LUMINANCE6_ALPHA2:
  172.       case GL_LUMINANCE8_ALPHA8:
  173.       case GL_LUMINANCE12_ALPHA4:
  174.       case GL_LUMINANCE12_ALPHA12:
  175.       case GL_LUMINANCE16_ALPHA16:
  176.          return GL_LUMINANCE_ALPHA;
  177.       case GL_INTENSITY:
  178.       case GL_INTENSITY4:
  179.       case GL_INTENSITY8:
  180.       case GL_INTENSITY12:
  181.       case GL_INTENSITY16:
  182.          return GL_INTENSITY;
  183.       case 3:
  184.       case GL_RGB:
  185.       case GL_R3_G3_B2:
  186.       case GL_RGB4:
  187.       case GL_RGB5:
  188.       case GL_RGB8:
  189.       case GL_RGB10:
  190.       case GL_RGB12:
  191.       case GL_RGB16:
  192.          return GL_RGB;
  193.       case 4:
  194.       case GL_RGBA:
  195.       case GL_RGBA2:
  196.       case GL_RGBA4:
  197.       case GL_RGB5_A1:
  198.       case GL_RGBA8:
  199.       case GL_RGB10_A2:
  200.       case GL_RGBA12:
  201.       case GL_RGBA16:
  202.          return GL_RGBA;
  203.       case GL_COLOR_INDEX:
  204.       case GL_COLOR_INDEX1_EXT:
  205.       case GL_COLOR_INDEX2_EXT:
  206.       case GL_COLOR_INDEX4_EXT:
  207.       case GL_COLOR_INDEX8_EXT:
  208.       case GL_COLOR_INDEX12_EXT:
  209.       case GL_COLOR_INDEX16_EXT:
  210.          if (ctx->Extensions.EXT_paletted_texture)
  211.             return GL_COLOR_INDEX;
  212.          else
  213.             return -1;
  214.       case GL_DEPTH_COMPONENT:
  215.       case GL_DEPTH_COMPONENT16_SGIX:
  216.       case GL_DEPTH_COMPONENT24_SGIX:
  217.       case GL_DEPTH_COMPONENT32_SGIX:
  218.          if (ctx->Extensions.SGIX_depth_texture)
  219.             return GL_DEPTH_COMPONENT;
  220.          else
  221.             return -1;
  222.  
  223.       /* GL_ARB_texture_compression */
  224.       case GL_COMPRESSED_ALPHA:
  225.          if (ctx->Extensions.ARB_texture_compression)
  226.             return GL_ALPHA;
  227.          else
  228.             return -1;
  229.       case GL_COMPRESSED_LUMINANCE:
  230.          if (ctx->Extensions.ARB_texture_compression)
  231.             return GL_LUMINANCE;
  232.          else
  233.             return -1;
  234.       case GL_COMPRESSED_LUMINANCE_ALPHA:
  235.          if (ctx->Extensions.ARB_texture_compression)
  236.             return GL_LUMINANCE_ALPHA;
  237.          else
  238.             return -1;
  239.       case GL_COMPRESSED_INTENSITY:
  240.          if (ctx->Extensions.ARB_texture_compression)
  241.             return GL_INTENSITY;
  242.          else
  243.             return -1;
  244.       case GL_COMPRESSED_RGB:
  245.          if (ctx->Extensions.ARB_texture_compression)
  246.             return GL_RGB;
  247.          else
  248.             return -1;
  249.       case GL_COMPRESSED_RGBA:
  250.          if (ctx->Extensions.ARB_texture_compression)
  251.             return GL_RGBA;
  252.          else
  253.             return -1;
  254.       case GL_COMPRESSED_RGB_FXT1_3DFX:
  255.          if (ctx->Extensions.TDFX_texture_compression_FXT1)
  256.             return GL_RGB;
  257.          else
  258.             return -1;
  259.       case GL_COMPRESSED_RGBA_FXT1_3DFX:
  260.          if (ctx->Extensions.TDFX_texture_compression_FXT1)
  261.             return GL_RGBA;
  262.          else
  263.             return -1;
  264.  
  265.       case GL_YCBCR_MESA:
  266.          if (ctx->Extensions.MESA_ycbcr_texture)
  267.             return GL_YCBCR_MESA;
  268.          else
  269.             return -1;
  270.  
  271.       default:
  272.          return -1;  /* error */
  273.    }
  274. }
  275.  
  276.  
  277. /*
  278.  * Test if the given image format is a color/rgba format.  That is,
  279.  * not color index, depth, stencil, etc.
  280.  */
  281. static GLboolean
  282. is_color_format(GLenum format)
  283. {
  284.    switch (format) {
  285.       case GL_ALPHA:
  286.       case GL_ALPHA4:
  287.       case GL_ALPHA8:
  288.       case GL_ALPHA12:
  289.       case GL_ALPHA16:
  290.       case 1:
  291.       case GL_LUMINANCE:
  292.       case GL_LUMINANCE4:
  293.       case GL_LUMINANCE8:
  294.       case GL_LUMINANCE12:
  295.       case GL_LUMINANCE16:
  296.       case 2:
  297.       case GL_LUMINANCE_ALPHA:
  298.       case GL_LUMINANCE4_ALPHA4:
  299.       case GL_LUMINANCE6_ALPHA2:
  300.       case GL_LUMINANCE8_ALPHA8:
  301.       case GL_LUMINANCE12_ALPHA4:
  302.       case GL_LUMINANCE12_ALPHA12:
  303.       case GL_LUMINANCE16_ALPHA16:
  304.       case GL_INTENSITY:
  305.       case GL_INTENSITY4:
  306.       case GL_INTENSITY8:
  307.       case GL_INTENSITY12:
  308.       case GL_INTENSITY16:
  309.       case 3:
  310.       case GL_RGB:
  311.       case GL_R3_G3_B2:
  312.       case GL_RGB4:
  313.       case GL_RGB5:
  314.       case GL_RGB8:
  315.       case GL_RGB10:
  316.       case GL_RGB12:
  317.       case GL_RGB16:
  318.       case 4:
  319.       case GL_RGBA:
  320.       case GL_RGBA2:
  321.       case GL_RGBA4:
  322.       case GL_RGB5_A1:
  323.       case GL_RGBA8:
  324.       case GL_RGB10_A2:
  325.       case GL_RGBA12:
  326.       case GL_RGBA16:
  327.          return GL_TRUE;
  328.       case GL_YCBCR_MESA:  /* not considered to be RGB */
  329.       default:
  330.          return GL_FALSE;
  331.    }
  332. }
  333.  
  334.  
  335. static GLboolean
  336. is_index_format(GLenum format)
  337. {
  338.    switch (format) {
  339.       case GL_COLOR_INDEX:
  340.       case GL_COLOR_INDEX1_EXT:
  341.       case GL_COLOR_INDEX2_EXT:
  342.       case GL_COLOR_INDEX4_EXT:
  343.       case GL_COLOR_INDEX8_EXT:
  344.       case GL_COLOR_INDEX12_EXT:
  345.       case GL_COLOR_INDEX16_EXT:
  346.          return GL_TRUE;
  347.       default:
  348.          return GL_FALSE;
  349.    }
  350. }
  351.  
  352.  
  353. /**
  354.  * Return GL_TRUE if internalFormat is a supported compressed format,
  355.  * return GL_FALSE otherwise.
  356.  * \param - internalFormat - the internal format token provided by the user
  357.  */
  358. static GLboolean
  359. is_compressed_format(GLenum internalFormat)
  360. {
  361.    switch (internalFormat) {
  362.       case GL_COMPRESSED_RGB_FXT1_3DFX:
  363.       case GL_COMPRESSED_RGBA_FXT1_3DFX:
  364.          return GL_TRUE;
  365.       default:
  366.          return GL_FALSE;
  367.    }
  368. }
  369.  
  370.  
  371. /*
  372.  * Store a gl_texture_image pointer in a gl_texture_object structure
  373.  * according to the target and level parameters.
  374.  * This was basically prompted by the introduction of cube maps.
  375.  */
  376. void
  377. _mesa_set_tex_image(struct gl_texture_object *tObj,
  378.                     GLenum target, GLint level,
  379.                     struct gl_texture_image *texImage)
  380. {
  381.    ASSERT(tObj);
  382.    ASSERT(texImage);
  383.    switch (target) {
  384.       case GL_TEXTURE_1D:
  385.       case GL_TEXTURE_2D:
  386.       case GL_TEXTURE_3D:
  387.          tObj->Image[level] = texImage;
  388.          return;
  389.       case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
  390.          tObj->Image[level] = texImage;
  391.          return;
  392.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
  393.          tObj->NegX[level] = texImage;
  394.          return;
  395.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
  396.          tObj->PosY[level] = texImage;
  397.          return;
  398.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
  399.          tObj->NegY[level] = texImage;
  400.          return;
  401.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
  402.          tObj->PosZ[level] = texImage;
  403.          return;
  404.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
  405.          tObj->NegZ[level] = texImage;
  406.          return;
  407.       case GL_TEXTURE_RECTANGLE_NV:
  408.          ASSERT(level == 0);
  409.          tObj->Image[level] = texImage;
  410.          return;
  411.       default:
  412.          _mesa_problem(NULL, "bad target in _mesa_set_tex_image()");
  413.          return;
  414.    }
  415. }
  416.  
  417.  
  418.  
  419. /*
  420.  * Return new gl_texture_image struct with all fields initialized to zero.
  421.  */
  422. struct gl_texture_image *
  423. _mesa_alloc_texture_image( void )
  424. {
  425.    return CALLOC_STRUCT(gl_texture_image);
  426. }
  427.  
  428.  
  429.  
  430. void
  431. _mesa_free_texture_image( struct gl_texture_image *teximage )
  432. {
  433.    if (teximage->Data && !teximage->IsClientData) {
  434.       MESA_PBUFFER_FREE( teximage->Data );
  435.       teximage->Data = NULL;
  436.    }
  437.    FREE( teximage );
  438. }
  439.  
  440.  
  441. /*
  442.  * Return GL_TRUE if the target is a proxy target.
  443.  */
  444. static GLboolean
  445. is_proxy_target(GLenum target)
  446. {
  447.    return (target == GL_PROXY_TEXTURE_1D ||
  448.            target == GL_PROXY_TEXTURE_2D ||
  449.            target == GL_PROXY_TEXTURE_3D ||
  450.            target == GL_PROXY_TEXTURE_CUBE_MAP_ARB);
  451. }
  452.  
  453.  
  454. /*
  455.  * Given a texture unit and a texture target, return the corresponding
  456.  * texture object.
  457.  */
  458. struct gl_texture_object *
  459. _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
  460.                         GLenum target)
  461. {
  462.    switch (target) {
  463.       case GL_TEXTURE_1D:
  464.          return texUnit->Current1D;
  465.       case GL_PROXY_TEXTURE_1D:
  466.          return ctx->Texture.Proxy1D;
  467.       case GL_TEXTURE_2D:
  468.          return texUnit->Current2D;
  469.       case GL_PROXY_TEXTURE_2D:
  470.          return ctx->Texture.Proxy2D;
  471.       case GL_TEXTURE_3D:
  472.          return texUnit->Current3D;
  473.       case GL_PROXY_TEXTURE_3D:
  474.          return ctx->Texture.Proxy3D;
  475.       case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
  476.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
  477.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
  478.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
  479.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
  480.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
  481.       case GL_TEXTURE_CUBE_MAP_ARB:
  482.          return ctx->Extensions.ARB_texture_cube_map
  483.                 ? texUnit->CurrentCubeMap : NULL;
  484.       case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
  485.          return ctx->Extensions.ARB_texture_cube_map
  486.                 ? ctx->Texture.ProxyCubeMap : NULL;
  487.       case GL_TEXTURE_RECTANGLE_NV:
  488.          return ctx->Extensions.NV_texture_rectangle
  489.                 ? texUnit->CurrentRect : NULL;
  490.       case GL_PROXY_TEXTURE_RECTANGLE_NV:
  491.          return ctx->Extensions.NV_texture_rectangle
  492.                 ? ctx->Texture.ProxyRect : NULL;
  493.       default:
  494.          _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
  495.          return NULL;
  496.    }
  497. }
  498.  
  499.  
  500. /*
  501.  * Return the texture image struct which corresponds to target and level
  502.  * for the given texture unit.
  503.  */
  504. struct gl_texture_image *
  505. _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
  506.                        GLenum target, GLint level)
  507. {
  508.    ASSERT(texUnit);
  509.    ASSERT(level < MAX_TEXTURE_LEVELS);
  510.    switch (target) {
  511.       case GL_TEXTURE_1D:
  512.          return texUnit->Current1D->Image[level];
  513.       case GL_PROXY_TEXTURE_1D:
  514.          return ctx->Texture.Proxy1D->Image[level];
  515.       case GL_TEXTURE_2D:
  516.          return texUnit->Current2D->Image[level];
  517.       case GL_PROXY_TEXTURE_2D:
  518.          return ctx->Texture.Proxy2D->Image[level];
  519.       case GL_TEXTURE_3D:
  520.          return texUnit->Current3D->Image[level];
  521.       case GL_PROXY_TEXTURE_3D:
  522.          return ctx->Texture.Proxy3D->Image[level];
  523.       case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
  524.          if (ctx->Extensions.ARB_texture_cube_map)
  525.             return texUnit->CurrentCubeMap->Image[level];
  526.          else
  527.             return NULL;
  528.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
  529.          if (ctx->Extensions.ARB_texture_cube_map)
  530.             return texUnit->CurrentCubeMap->NegX[level];
  531.          else
  532.             return NULL;
  533.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
  534.          if (ctx->Extensions.ARB_texture_cube_map)
  535.             return texUnit->CurrentCubeMap->PosY[level];
  536.          else
  537.             return NULL;
  538.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
  539.          if (ctx->Extensions.ARB_texture_cube_map)
  540.             return texUnit->CurrentCubeMap->NegY[level];
  541.          else
  542.             return NULL;
  543.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
  544.          if (ctx->Extensions.ARB_texture_cube_map)
  545.             return texUnit->CurrentCubeMap->PosZ[level];
  546.          else
  547.             return NULL;
  548.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
  549.          if (ctx->Extensions.ARB_texture_cube_map)
  550.             return texUnit->CurrentCubeMap->NegZ[level];
  551.          else
  552.             return NULL;
  553.       case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
  554.          if (ctx->Extensions.ARB_texture_cube_map)
  555.             return ctx->Texture.ProxyCubeMap->Image[level];
  556.          else
  557.             return NULL;
  558.       case GL_TEXTURE_RECTANGLE_NV:
  559.          if (ctx->Extensions.NV_texture_rectangle) {
  560.             ASSERT(level == 0);
  561.             return texUnit->CurrentRect->Image[level];
  562.          }
  563.          else {
  564.             return NULL;
  565.          }
  566.       case GL_PROXY_TEXTURE_RECTANGLE_NV:
  567.          if (ctx->Extensions.NV_texture_rectangle) {
  568.             ASSERT(level == 0);
  569.             return ctx->Texture.ProxyRect->Image[level];
  570.          }
  571.          else {
  572.             return NULL;
  573.          }
  574.       default:
  575.          _mesa_problem(ctx, "bad target in _mesa_select_tex_image()");
  576.          return NULL;
  577.    }
  578. }
  579.  
  580.  
  581. /*
  582.  * Return the maximum number of allows mipmap levels for the given
  583.  * texture target.
  584.  */
  585. GLint
  586. _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
  587. {
  588.    switch (target) {
  589.    case GL_TEXTURE_1D:
  590.    case GL_PROXY_TEXTURE_1D:
  591.    case GL_TEXTURE_2D:
  592.    case GL_PROXY_TEXTURE_2D:
  593.       return ctx->Const.MaxTextureLevels;
  594.    case GL_TEXTURE_3D:
  595.    case GL_PROXY_TEXTURE_3D:
  596.       return ctx->Const.Max3DTextureLevels;
  597.    case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
  598.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
  599.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
  600.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
  601.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
  602.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
  603.    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
  604.       return ctx->Const.MaxCubeTextureLevels;
  605.       break;
  606.    case GL_TEXTURE_RECTANGLE_NV:
  607.    case GL_PROXY_TEXTURE_RECTANGLE_NV:
  608.       return 1;
  609.       break;
  610.    default:
  611.       return 0; /* bad target */
  612.    }
  613. }
  614.  
  615.  
  616.  
  617. #if 000 /* not used anymore */
  618. /*
  619.  * glTexImage[123]D can accept a NULL image pointer.  In this case we
  620.  * create a texture image with unspecified image contents per the OpenGL
  621.  * spec.
  622.  */
  623. static GLubyte *
  624. make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
  625. {
  626.    const GLint components = _mesa_components_in_format(format);
  627.    const GLint numPixels = width * height * depth;
  628.    GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
  629.  
  630. #ifdef DEBUG
  631.    /*
  632.     * Let's see if anyone finds this.  If glTexImage2D() is called with
  633.     * a NULL image pointer then load the texture image with something
  634.     * interesting instead of leaving it indeterminate.
  635.     */
  636.    if (data) {
  637.       static const char message[8][32] = {
  638.          "   X   X  XXXXX   XXX     X    ",
  639.          "   XX XX  X      X   X   X X   ",
  640.          "   X X X  X      X      X   X  ",
  641.          "   X   X  XXXX    XXX   XXXXX  ",
  642.          "   X   X  X          X  X   X  ",
  643.          "   X   X  X      X   X  X   X  ",
  644.          "   X   X  XXXXX   XXX   X   X  ",
  645.          "                               "
  646.       };
  647.  
  648.       GLubyte *imgPtr = data;
  649.       GLint h, i, j, k;
  650.       for (h = 0; h < depth; h++) {
  651.          for (i = 0; i < height; i++) {
  652.             GLint srcRow = 7 - (i % 8);
  653.             for (j = 0; j < width; j++) {
  654.                GLint srcCol = j % 32;
  655.                GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
  656.                for (k = 0; k < components; k++) {
  657.                   *imgPtr++ = texel;
  658.                }
  659.             }
  660.          }
  661.       }
  662.    }
  663. #endif
  664.  
  665.    return data;
  666. }
  667. #endif
  668.  
  669.  
  670.  
  671. /*
  672.  * Reset the fields of a gl_texture_image struct to zero.
  673.  * This is called when a proxy texture test fails, we set all the
  674.  * image members (except DriverData) to zero.
  675.  * It's also used in glTexImage[123]D as a safeguard to be sure all
  676.  * required fields get initialized properly by the Driver.TexImage[123]D
  677.  * functions.
  678.  */
  679. static void
  680. clear_teximage_fields(struct gl_texture_image *img)
  681. {
  682.    ASSERT(img);
  683.    img->Format = 0;
  684.    img->IntFormat = 0;
  685.    img->Border = 0;
  686.    img->Width = 0;
  687.    img->Height = 0;
  688.    img->Depth = 0;
  689.    img->RowStride = 0;
  690.    img->Width2 = 0;
  691.    img->Height2 = 0;
  692.    img->Depth2 = 0;
  693.    img->WidthLog2 = 0;
  694.    img->HeightLog2 = 0;
  695.    img->DepthLog2 = 0;
  696.    img->Data = NULL;
  697.    img->TexFormat = &_mesa_null_texformat;
  698.    img->FetchTexel = NULL;
  699.    img->IsCompressed = 0;
  700.    img->CompressedSize = 0;
  701. }
  702.  
  703.  
  704. /*
  705.  * Initialize basic fields of the gl_texture_image struct.
  706.  */
  707. void
  708. _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
  709.                            struct gl_texture_image *img,
  710.                            GLsizei width, GLsizei height, GLsizei depth,
  711.                            GLint border, GLenum internalFormat)
  712. {
  713.    ASSERT(img);
  714.    img->Format = _mesa_base_tex_format( ctx, internalFormat );
  715.    ASSERT(img->Format > 0);
  716.    img->IntFormat = internalFormat;
  717.    img->Border = border;
  718.    img->Width = width;
  719.    img->Height = height;
  720.    img->Depth = depth;
  721.    img->RowStride = width;
  722.    img->WidthLog2 = logbase2(width - 2 * border);
  723.    if (height == 1)  /* 1-D texture */
  724.       img->HeightLog2 = 0;
  725.    else
  726.       img->HeightLog2 = logbase2(height - 2 * border);
  727.    if (depth == 1)   /* 2-D texture */
  728.       img->DepthLog2 = 0;
  729.    else
  730.       img->DepthLog2 = logbase2(depth - 2 * border);
  731.    img->Width2 = 1 << img->WidthLog2;
  732.    img->Height2 = 1 << img->HeightLog2;
  733.    img->Depth2 = 1 << img->DepthLog2;
  734.    img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
  735.    img->IsCompressed = is_compressed_format(internalFormat);
  736.    if (img->IsCompressed)
  737.       img->CompressedSize = _mesa_compressed_texture_size(ctx, width, height,
  738.                                                        depth, internalFormat);
  739.    else
  740.       img->CompressedSize = 0;
  741.  
  742.    /* Compute Width/Height/DepthScale for mipmap lod computation */
  743.    if (target == GL_TEXTURE_RECTANGLE_NV) {
  744.       /* scale = 1.0 since texture coords directly map to texels */
  745.       img->WidthScale = 1.0;
  746.       img->HeightScale = 1.0;
  747.       img->DepthScale = 1.0;
  748.    }
  749.    else {
  750.       img->WidthScale = (GLfloat) img->Width;
  751.       img->HeightScale = (GLfloat) img->Height;
  752.       img->DepthScale = (GLfloat) img->Depth;
  753.    }
  754. }
  755.  
  756.  
  757.  
  758. /*
  759.  * Test glTexImage[123]D() parameters for errors.
  760.  * Input:
  761.  *         dimensions - must be 1 or 2 or 3
  762.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  763.  */
  764. static GLboolean
  765. texture_error_check( GLcontext *ctx, GLenum target,
  766.                      GLint level, GLint internalFormat,
  767.                      GLenum format, GLenum type,
  768.                      GLuint dimensions,
  769.                      GLint width, GLint height,
  770.                      GLint depth, GLint border )
  771. {
  772.    GLboolean isProxy;
  773.    GLint maxLevels = 0, maxTextureSize;
  774.  
  775.    if (dimensions == 1) {
  776.       if (target == GL_PROXY_TEXTURE_1D) {
  777.          isProxy = GL_TRUE;
  778.       }
  779.       else if (target == GL_TEXTURE_1D) {
  780.          isProxy = GL_FALSE;
  781.       }
  782.       else {
  783.          _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
  784.          return GL_TRUE;
  785.       }
  786.       maxLevels = ctx->Const.MaxTextureLevels;
  787.    }
  788.    else if (dimensions == 2) {
  789.       if (target == GL_PROXY_TEXTURE_2D) {
  790.          isProxy = GL_TRUE;
  791.          maxLevels = ctx->Const.MaxTextureLevels;
  792.       }
  793.       else if (target == GL_TEXTURE_2D) {
  794.          isProxy = GL_FALSE;
  795.          maxLevels = ctx->Const.MaxTextureLevels;
  796.       }
  797.       else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
  798.          if (!ctx->Extensions.ARB_texture_cube_map) {
  799.             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
  800.             return GL_TRUE;
  801.          }
  802.          isProxy = GL_TRUE;
  803.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  804.       }
  805.       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  806.                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  807.          if (!ctx->Extensions.ARB_texture_cube_map) {
  808.             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
  809.             return GL_TRUE;
  810.          }
  811.          isProxy = GL_FALSE;
  812.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  813.       }
  814.       else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
  815.          if (!ctx->Extensions.NV_texture_rectangle) {
  816.             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
  817.             return GL_TRUE;
  818.          }
  819.          isProxy = GL_TRUE;
  820.          maxLevels = 1;
  821.       }
  822.       else if (target == GL_TEXTURE_RECTANGLE_NV) {
  823.          if (!ctx->Extensions.NV_texture_rectangle) {
  824.             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
  825.             return GL_TRUE;
  826.          }
  827.          isProxy = GL_FALSE;
  828.          maxLevels = 1;
  829.       }
  830.       else {
  831.          _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
  832.          return GL_TRUE;
  833.       }
  834.    }
  835.    else if (dimensions == 3) {
  836.       if (target == GL_PROXY_TEXTURE_3D) {
  837.          isProxy = GL_TRUE;
  838.       }
  839.       else if (target == GL_TEXTURE_3D) {
  840.          isProxy = GL_FALSE;
  841.       }
  842.       else {
  843.          _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
  844.          return GL_TRUE;
  845.       }
  846.       maxLevels = ctx->Const.Max3DTextureLevels;
  847.    }
  848.    else {
  849.       _mesa_problem( ctx, "bad dims in texture_error_check" );
  850.       return GL_TRUE;
  851.    }
  852.  
  853.    ASSERT(maxLevels > 0);
  854.    maxTextureSize = 1 << (maxLevels - 1);
  855.  
  856.    /* Border */
  857.    if (border != 0 && border != 1) {
  858.       if (!isProxy) {
  859.          _mesa_error(ctx, GL_INVALID_VALUE,
  860.                      "glTexImage%dD(border=%d)", dimensions, border);
  861.       }
  862.       return GL_TRUE;
  863.    }
  864.    if ((target == GL_TEXTURE_RECTANGLE_NV ||
  865.         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0) {
  866.       return GL_TRUE;
  867.    }
  868.  
  869.    /* Width */
  870.    if (target == GL_TEXTURE_RECTANGLE_NV ||
  871.        target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
  872.       if (width < 1 || width > ctx->Const.MaxTextureRectSize) {
  873.          if (!isProxy) {
  874.             _mesa_error(ctx, GL_INVALID_VALUE,
  875.                         "glTexImage%dD(width=%d)", dimensions, width);
  876.          }
  877.          return GL_TRUE;
  878.       }
  879.    }
  880.    else if (width < 2 * border || width > 2 + maxTextureSize
  881.        || logbase2( width - 2 * border ) < 0) {
  882.       if (!isProxy) {
  883.          _mesa_error(ctx, GL_INVALID_VALUE,
  884.                      "glTexImage%dD(width=%d)", dimensions, width);
  885.       }
  886.       return GL_TRUE;
  887.    }
  888.  
  889.    /* Height */
  890.    if (target == GL_TEXTURE_RECTANGLE_NV ||
  891.        target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
  892.       if (height < 1 || height > ctx->Const.MaxTextureRectSize) {
  893.          if (!isProxy) {
  894.             _mesa_error(ctx, GL_INVALID_VALUE,
  895.                         "glTexImage%dD(height=%d)", dimensions, height);
  896.          }
  897.          return GL_TRUE;
  898.       }
  899.    }
  900.    else if (dimensions >= 2) {
  901.       if (height < 2 * border || height > 2 + maxTextureSize
  902.           || logbase2( height - 2 * border ) < 0) {
  903.          if (!isProxy) {
  904.             _mesa_error(ctx, GL_INVALID_VALUE,
  905.                         "glTexImage%dD(height=%d)", dimensions, height);
  906.          }
  907.          return GL_TRUE;
  908.       }
  909.    }
  910.  
  911.    /* For cube map, width must equal height */
  912.    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  913.        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  914.       if (width != height) {
  915.          if (!isProxy) {
  916.             _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)");
  917.          }
  918.          return GL_TRUE;
  919.       }
  920.    }
  921.  
  922.    /* Depth */
  923.    if (dimensions >= 3) {
  924.       if (depth < 2 * border || depth > 2 + maxTextureSize
  925.           || logbase2( depth - 2 * border ) < 0) {
  926.          if (!isProxy) {
  927.             _mesa_error( ctx, GL_INVALID_VALUE,
  928.                          "glTexImage3D(depth=%d)", depth );
  929.          }
  930.          return GL_TRUE;
  931.       }
  932.    }
  933.  
  934.    /* Level */
  935.    if (target == GL_TEXTURE_RECTANGLE_NV ||
  936.        target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
  937.       if (level != 0) {
  938.          if (!isProxy) {
  939.             _mesa_error(ctx, GL_INVALID_VALUE,
  940.                         "glTexImage2D(level=%d)", level);
  941.          }
  942.          return GL_TRUE;
  943.       }
  944.    }
  945.    else if (level < 0 || level >= maxLevels) {
  946.       if (!isProxy) {
  947.          _mesa_error(ctx, GL_INVALID_VALUE,
  948.                      "glTexImage%dD(level=%d)", dimensions, level);
  949.       }
  950.       return GL_TRUE;
  951.    }
  952.  
  953.    /* For cube map, width must equal height */
  954.    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  955.        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  956.       if (width != height) {
  957.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)");
  958.          return GL_TRUE;
  959.       }
  960.    }
  961.  
  962.    if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
  963.       if (!isProxy) {
  964.          _mesa_error(ctx, GL_INVALID_VALUE,
  965.                      "glTexImage%dD(internalFormat=0x%x)",
  966.                      dimensions, internalFormat);
  967.       }
  968.       return GL_TRUE;
  969.    }
  970.  
  971.    if (!_mesa_is_legal_format_and_type(format, type)) {
  972.       /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
  973.        * is a type/format mismatch.  See 1.2 spec page 94, sec 3.6.4.
  974.        */
  975.       if (!isProxy) {
  976.          _mesa_error(ctx, GL_INVALID_OPERATION,
  977.                      "glTexImage%dD(format or type)", dimensions);
  978.       }
  979.       return GL_TRUE;
  980.    }
  981.  
  982.    if (format == GL_YCBCR_MESA || internalFormat == GL_YCBCR_MESA) {
  983.       ASSERT(ctx->Extensions.MESA_ycbcr_texture);
  984.       if (format != GL_YCBCR_MESA ||
  985.           internalFormat != GL_YCBCR_MESA ||
  986.           (type != GL_UNSIGNED_SHORT_8_8_MESA &&
  987.           type != GL_UNSIGNED_SHORT_8_8_REV_MESA)) {
  988.          char message[100];
  989.          _mesa_sprintf(message,
  990.                  "glTexImage%d(format/type/internalFormat YCBCR mismatch",
  991.                  dimensions);
  992.          _mesa_error(ctx, GL_INVALID_ENUM, message);
  993.          return GL_TRUE; /* error */
  994.       }
  995.       if (target != GL_TEXTURE_2D &&
  996.           target != GL_PROXY_TEXTURE_2D &&
  997.           target != GL_TEXTURE_RECTANGLE_NV &&
  998.           target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
  999.          if (!isProxy)
  1000.             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
  1001.          return GL_TRUE;
  1002.       }
  1003.       if (border != 0) {
  1004.          if (!isProxy) {
  1005.             char message[100];
  1006.             _mesa_sprintf(message,
  1007.                     "glTexImage%d(format=GL_YCBCR_MESA and border=%d)",
  1008.                     dimensions, border);
  1009.             _mesa_error(ctx, GL_INVALID_VALUE, message);
  1010.          }
  1011.          return GL_TRUE;
  1012.       }
  1013.    }
  1014.  
  1015.    if (is_compressed_format(internalFormat)) {
  1016.       if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
  1017.          /* OK */
  1018.       }
  1019.       else if (ctx->Extensions.ARB_texture_cube_map &&
  1020.                (target == GL_PROXY_TEXTURE_CUBE_MAP ||
  1021.                 (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
  1022.                  target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) {
  1023.          /* OK */
  1024.       }
  1025.       else {
  1026.          if (!isProxy) {
  1027.             _mesa_error(ctx, GL_INVALID_ENUM,
  1028.                         "glTexImage%d(target)", dimensions);
  1029.             return GL_TRUE;
  1030.          }
  1031.       }
  1032.       if (border != 0) {
  1033.          if (!isProxy) {
  1034.             _mesa_error(ctx, GL_INVALID_OPERATION,
  1035.                         "glTexImage%D(border!=0)", dimensions);
  1036.          }
  1037.          return GL_TRUE;
  1038.       }
  1039.    }
  1040.  
  1041.    /* if we get here, the parameters are OK */
  1042.    return GL_FALSE;
  1043. }
  1044.  
  1045.  
  1046.  
  1047. /*
  1048.  * Test glTexSubImage[123]D() parameters for errors.
  1049.  * Input:
  1050.  *         dimensions - must be 1 or 2 or 3
  1051.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  1052.  */
  1053. static GLboolean
  1054. subtexture_error_check( GLcontext *ctx, GLuint dimensions,
  1055.                         GLenum target, GLint level,
  1056.                         GLint xoffset, GLint yoffset, GLint zoffset,
  1057.                         GLint width, GLint height, GLint depth,
  1058.                         GLenum format, GLenum type )
  1059. {
  1060.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1061.    struct gl_texture_image *destTex;
  1062.    GLint maxLevels = 0;
  1063.  
  1064.    if (dimensions == 1) {
  1065.       if (target == GL_TEXTURE_1D) {
  1066.          maxLevels = ctx->Const.MaxTextureLevels;
  1067.       }
  1068.       else {
  1069.          _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
  1070.          return GL_TRUE;
  1071.       }
  1072.    }
  1073.    else if (dimensions == 2) {
  1074.       if (ctx->Extensions.ARB_texture_cube_map &&
  1075.           target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  1076.           target <=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  1077.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  1078.       }
  1079.       else if (ctx->Extensions.NV_texture_rectangle &&
  1080.                target == GL_TEXTURE_RECTANGLE_NV) {
  1081.          maxLevels = 1;
  1082.       }
  1083.       else if (target == GL_TEXTURE_2D) {
  1084.          maxLevels = ctx->Const.MaxTextureLevels;
  1085.       }
  1086.       else {
  1087.          _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
  1088.          return GL_TRUE;
  1089.       }
  1090.    }
  1091.    else if (dimensions == 3) {
  1092.       if (target == GL_TEXTURE_3D) {
  1093.          maxLevels = ctx->Const.Max3DTextureLevels;
  1094.       }
  1095.       else {
  1096.          _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
  1097.          return GL_TRUE;
  1098.       }
  1099.    }
  1100.    else {
  1101.       _mesa_problem( ctx, "bad dims in texture_error_check" );
  1102.       return GL_TRUE;
  1103.    }
  1104.  
  1105.    ASSERT(maxLevels > 0);
  1106.  
  1107.    if (level < 0 || level >= maxLevels) {
  1108.       _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
  1109.       return GL_TRUE;
  1110.    }
  1111.  
  1112.    if (width < 0) {
  1113.       _mesa_error(ctx, GL_INVALID_VALUE,
  1114.                   "glTexSubImage%dD(width=%d)", dimensions, width);
  1115.       return GL_TRUE;
  1116.    }
  1117.    if (height < 0 && dimensions > 1) {
  1118.       _mesa_error(ctx, GL_INVALID_VALUE,
  1119.                   "glTexSubImage%dD(height=%d)", dimensions, height);
  1120.       return GL_TRUE;
  1121.    }
  1122.    if (depth < 0 && dimensions > 2) {
  1123.       _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(depth=%d)", dimensions, depth);
  1124.       return GL_TRUE;
  1125.    }
  1126.  
  1127.    destTex = _mesa_select_tex_image(ctx, texUnit, target, level);
  1128.  
  1129.    if (!destTex) {
  1130.       _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage2D");
  1131.       return GL_TRUE;
  1132.    }
  1133.  
  1134.    if (xoffset < -((GLint)destTex->Border)) {
  1135.       _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset)");
  1136.       return GL_TRUE;
  1137.    }
  1138.    if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
  1139.       _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset+width)");
  1140.       return GL_TRUE;
  1141.    }
  1142.    if (dimensions > 1) {
  1143.       if (yoffset < -((GLint)destTex->Border)) {
  1144.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset)");
  1145.          return GL_TRUE;
  1146.       }
  1147.       if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
  1148.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset+height)");
  1149.          return GL_TRUE;
  1150.       }
  1151.    }
  1152.    if (dimensions > 2) {
  1153.       if (zoffset < -((GLint)destTex->Border)) {
  1154.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
  1155.          return GL_TRUE;
  1156.       }
  1157.       if (zoffset + depth  > (GLint) (destTex->Depth + destTex->Border)) {
  1158.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
  1159.          return GL_TRUE;
  1160.       }
  1161.    }
  1162.  
  1163.    if (!_mesa_is_legal_format_and_type(format, type)) {
  1164.       _mesa_error(ctx, GL_INVALID_ENUM,
  1165.                   "glTexSubImage%dD(format or type)", dimensions);
  1166.       return GL_TRUE;
  1167.    }
  1168.  
  1169.    if (destTex->IsCompressed) {
  1170.       const struct gl_texture_unit *texUnit;
  1171.       const struct gl_texture_object *texObj;
  1172.       const struct gl_texture_image *texImage;
  1173.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1174.       texObj = _mesa_select_tex_object(ctx, texUnit, target);
  1175.       texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1176.  
  1177.       if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
  1178.          /* OK */
  1179.       }
  1180.       else if (ctx->Extensions.ARB_texture_cube_map &&
  1181.                (target == GL_PROXY_TEXTURE_CUBE_MAP ||
  1182.                 (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
  1183.                  target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) {
  1184.          /* OK */
  1185.       }
  1186.       else {
  1187.          _mesa_error(ctx, GL_INVALID_ENUM,
  1188.                      "glTexSubImage%D(target)", dimensions);
  1189.          return GL_TRUE;
  1190.       }
  1191.       /* offset must be multiple of 4 */
  1192.       if ((xoffset & 3) || (yoffset & 3)) {
  1193.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1194.                      "glTexSubImage%D(xoffset or yoffset)", dimensions);
  1195.          return GL_TRUE;
  1196.       }
  1197.       /* size must be multiple of 4 or equal to whole texture size */
  1198.       if ((width & 3) && (GLuint) width != texImage->Width) {
  1199.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1200.                      "glTexSubImage%D(width)", dimensions);
  1201.          return GL_TRUE;
  1202.       }         
  1203.       if ((height & 3) && (GLuint) height != texImage->Height) {
  1204.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1205.                      "glTexSubImage%D(width)", dimensions);
  1206.          return GL_TRUE;
  1207.       }         
  1208.    }
  1209.  
  1210.    return GL_FALSE;
  1211. }
  1212.  
  1213.  
  1214. /*
  1215.  * Test glCopyTexImage[12]D() parameters for errors.
  1216.  * Input:  dimensions - must be 1 or 2 or 3
  1217.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  1218.  */
  1219. static GLboolean
  1220. copytexture_error_check( GLcontext *ctx, GLuint dimensions,
  1221.                          GLenum target, GLint level, GLint internalFormat,
  1222.                          GLint width, GLint height, GLint border )
  1223. {
  1224.    GLint maxLevels = 0, maxTextureSize;
  1225.  
  1226.    if (dimensions == 1) {
  1227.       if (target != GL_TEXTURE_1D) {
  1228.          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
  1229.          return GL_TRUE;
  1230.       }
  1231.       maxLevels = ctx->Const.MaxTextureLevels;
  1232.    }
  1233.    else if (dimensions == 2) {
  1234.       if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  1235.           target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  1236.          if (!ctx->Extensions.ARB_texture_cube_map) {
  1237.             _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
  1238.             return GL_TRUE;
  1239.          }
  1240.       }
  1241.       else if (target == GL_TEXTURE_RECTANGLE_NV) {
  1242.          if (!ctx->Extensions.NV_texture_rectangle) {
  1243.             _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
  1244.             return GL_TRUE;
  1245.          }
  1246.       }
  1247.       else if (target != GL_TEXTURE_2D) {
  1248.          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
  1249.          return GL_TRUE;
  1250.       }
  1251.       if (target == GL_TEXTURE_2D)
  1252.          maxLevels = ctx->Const.MaxTextureLevels;
  1253.       else if (target == GL_TEXTURE_RECTANGLE_NV)
  1254.          maxLevels = 1;
  1255.       else
  1256.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  1257.    }
  1258.  
  1259.    ASSERT(maxLevels > 0);
  1260.    maxTextureSize = 1 << (maxLevels - 1);
  1261.  
  1262.    /* Border */
  1263.    if (border != 0 && border != 1) {
  1264.       _mesa_error(ctx, GL_INVALID_VALUE,
  1265.                   "glCopyTexImage%dD(border)", dimensions);
  1266.       return GL_TRUE;
  1267.    }
  1268.  
  1269.    /* Width */
  1270.    if (width < 2 * border || width > 2 + maxTextureSize
  1271.        || logbase2( width - 2 * border ) < 0) {
  1272.       _mesa_error(ctx, GL_INVALID_VALUE,
  1273.                   "glCopyTexImage%dD(width=%d)", dimensions, width);
  1274.       return GL_TRUE;
  1275.    }
  1276.  
  1277.    /* Height */
  1278.    if (dimensions >= 2) {
  1279.       if (height < 2 * border || height > 2 + maxTextureSize
  1280.           || logbase2( height - 2 * border ) < 0) {
  1281.          _mesa_error(ctx, GL_INVALID_VALUE,
  1282.                      "glCopyTexImage%dD(height=%d)", dimensions, height);
  1283.          return GL_TRUE;
  1284.       }
  1285.    }
  1286.  
  1287.    /* For cube map, width must equal height */
  1288.    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  1289.        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  1290.       if (width != height) {
  1291.          _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width != height)");
  1292.          return GL_TRUE;
  1293.       }
  1294.    }
  1295.  
  1296.    /* Level */
  1297.    if (level < 0 || level >= maxLevels) {
  1298.       _mesa_error(ctx, GL_INVALID_VALUE,
  1299.                   "glCopyTexImage%dD(level=%d)", dimensions, level);
  1300.       return GL_TRUE;
  1301.    }
  1302.  
  1303.    if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
  1304.       _mesa_error(ctx, GL_INVALID_VALUE,
  1305.                   "glCopyTexImage%dD(internalFormat)", dimensions);
  1306.       return GL_TRUE;
  1307.    }
  1308.  
  1309.    if (is_compressed_format(internalFormat)) {
  1310.       if (target != GL_TEXTURE_2D) {
  1311.          _mesa_error(ctx, GL_INVALID_ENUM,
  1312.                      "glCopyTexImage%d(target)", dimensions);
  1313.          return GL_TRUE;
  1314.       }
  1315.       if (border != 0) {
  1316.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1317.                      "glCopyTexImage%D(border!=0)", dimensions);
  1318.          return GL_TRUE;
  1319.       }
  1320.    }
  1321.  
  1322.    /* if we get here, the parameters are OK */
  1323.    return GL_FALSE;
  1324. }
  1325.  
  1326.  
  1327. static GLboolean
  1328. copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
  1329.                              GLenum target, GLint level,
  1330.                              GLint xoffset, GLint yoffset, GLint zoffset,
  1331.                              GLsizei width, GLsizei height )
  1332. {
  1333.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1334.    struct gl_texture_image *teximage;
  1335.    GLint maxLevels = 0;
  1336.  
  1337.    if (dimensions == 1) {
  1338.       if (target != GL_TEXTURE_1D) {
  1339.          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
  1340.          return GL_TRUE;
  1341.       }
  1342.       maxLevels = ctx->Const.MaxTextureLevels;
  1343.    }
  1344.    else if (dimensions == 2) {
  1345.       if (ctx->Extensions.ARB_texture_cube_map) {
  1346.          if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB ||
  1347.               target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) &&
  1348.              target != GL_TEXTURE_2D) {
  1349.             _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
  1350.             return GL_TRUE;
  1351.          }
  1352.       }
  1353.       else if (target != GL_TEXTURE_2D) {
  1354.          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
  1355.          return GL_TRUE;
  1356.       }
  1357.       if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D)
  1358.          maxLevels = ctx->Const.MaxTextureLevels;
  1359.       else
  1360.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  1361.    }
  1362.    else if (dimensions == 3) {
  1363.       if (target != GL_TEXTURE_3D) {
  1364.          _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
  1365.          return GL_TRUE;
  1366.       }
  1367.       maxLevels = ctx->Const.Max3DTextureLevels;
  1368.    }
  1369.  
  1370.    ASSERT(maxLevels > 0);
  1371.  
  1372.    if (level < 0 || level >= maxLevels) {
  1373.       _mesa_error(ctx, GL_INVALID_VALUE,
  1374.                   "glCopyTexSubImage%dD(level=%d)", dimensions, level);
  1375.       return GL_TRUE;
  1376.    }
  1377.  
  1378.    if (width < 0) {
  1379.       _mesa_error(ctx, GL_INVALID_VALUE,
  1380.                   "glCopyTexSubImage%dD(width=%d)", dimensions, width);
  1381.       return GL_TRUE;
  1382.    }
  1383.    if (dimensions > 1 && height < 0) {
  1384.       _mesa_error(ctx, GL_INVALID_VALUE,
  1385.                   "glCopyTexSubImage%dD(height=%d)", dimensions, height);
  1386.       return GL_TRUE;
  1387.    }
  1388.  
  1389.    teximage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1390.    if (!teximage) {
  1391.       _mesa_error(ctx, GL_INVALID_OPERATION,
  1392.                   "glCopyTexSubImage%dD(undefined texture level: %d)",
  1393.                   dimensions, level);
  1394.       return GL_TRUE;
  1395.    }
  1396.  
  1397.    if (xoffset < -((GLint)teximage->Border)) {
  1398.       _mesa_error(ctx, GL_INVALID_VALUE,
  1399.                   "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
  1400.       return GL_TRUE;
  1401.    }
  1402.    if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
  1403.       _mesa_error(ctx, GL_INVALID_VALUE,
  1404.                   "glCopyTexSubImage%dD(xoffset+width)", dimensions);
  1405.       return GL_TRUE;
  1406.    }
  1407.    if (dimensions > 1) {
  1408.       if (yoffset < -((GLint)teximage->Border)) {
  1409.          _mesa_error(ctx, GL_INVALID_VALUE,
  1410.                      "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
  1411.          return GL_TRUE;
  1412.       }
  1413.       /* NOTE: we're adding the border here, not subtracting! */
  1414.       if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) {
  1415.          _mesa_error(ctx, GL_INVALID_VALUE,
  1416.                      "glCopyTexSubImage%dD(yoffset+height)", dimensions);
  1417.          return GL_TRUE;
  1418.       }
  1419.    }
  1420.  
  1421.    if (dimensions > 2) {
  1422.       if (zoffset < -((GLint)teximage->Border)) {
  1423.          _mesa_error(ctx, GL_INVALID_VALUE,
  1424.                      "glCopyTexSubImage%dD(zoffset)", dimensions);
  1425.          return GL_TRUE;
  1426.       }
  1427.       if (zoffset > (GLint) (teximage->Depth + teximage->Border)) {
  1428.          _mesa_error(ctx, GL_INVALID_VALUE,
  1429.                      "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
  1430.          return GL_TRUE;
  1431.       }
  1432.    }
  1433.  
  1434.    if (teximage->IsCompressed) {
  1435.       if (target != GL_TEXTURE_2D) {
  1436.          _mesa_error(ctx, GL_INVALID_ENUM,
  1437.                      "glCopyTexSubImage%d(target)", dimensions);
  1438.          return GL_TRUE;
  1439.       }
  1440.       /* offset must be multiple of 4 */
  1441.       if ((xoffset & 3) || (yoffset & 3)) {
  1442.          _mesa_error(ctx, GL_INVALID_VALUE,
  1443.                      "glCopyTexSubImage%D(xoffset or yoffset)", dimensions);
  1444.          return GL_TRUE;
  1445.       }
  1446.       /* size must be multiple of 4 */
  1447.       if ((width & 3) != 0 && (GLuint) width != teximage->Width) {
  1448.          _mesa_error(ctx, GL_INVALID_VALUE,
  1449.                      "glCopyTexSubImage%D(width)", dimensions);
  1450.          return GL_TRUE;
  1451.       }         
  1452.       if ((height & 3) != 0 && (GLuint) height != teximage->Height) {
  1453.          _mesa_error(ctx, GL_INVALID_VALUE,
  1454.                      "glCopyTexSubImage%D(height)", dimensions);
  1455.          return GL_TRUE;
  1456.       }         
  1457.    }
  1458.  
  1459.    if (teximage->IntFormat == GL_YCBCR_MESA) {
  1460.       _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
  1461.       return GL_TRUE;
  1462.    }
  1463.  
  1464.    /* if we get here, the parameters are OK */
  1465.    return GL_FALSE;
  1466. }
  1467.  
  1468.  
  1469.  
  1470. void
  1471. _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
  1472.                    GLenum type, GLvoid *pixels )
  1473. {
  1474.    const struct gl_texture_unit *texUnit;
  1475.    const struct gl_texture_object *texObj;
  1476.    const struct gl_texture_image *texImage;
  1477.    GLint maxLevels = 0;
  1478.    GET_CURRENT_CONTEXT(ctx);
  1479.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  1480.  
  1481.    texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
  1482.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  1483.    if (!texObj || is_proxy_target(target)) {
  1484.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
  1485.       return;
  1486.    }
  1487.  
  1488.    maxLevels = _mesa_max_texture_levels(ctx, target);
  1489.    ASSERT(maxLevels > 0);  /* 0 indicates bad target, caught above */
  1490.  
  1491.    if (level < 0 || level >= maxLevels) {
  1492.       _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
  1493.       return;
  1494.    }
  1495.  
  1496.    if (_mesa_sizeof_packed_type(type) <= 0) {
  1497.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
  1498.       return;
  1499.    }
  1500.  
  1501.    if (_mesa_components_in_format(format) <= 0 ||
  1502.        format == GL_STENCIL_INDEX) {
  1503.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
  1504.       return;
  1505.    }
  1506.  
  1507.    if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
  1508.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
  1509.    }
  1510.  
  1511.    if (!ctx->Extensions.SGIX_depth_texture && format == GL_DEPTH_COMPONENT) {
  1512.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
  1513.    }
  1514.  
  1515.    if (!ctx->Extensions.MESA_ycbcr_texture && format == GL_YCBCR_MESA) {
  1516.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
  1517.    }
  1518.  
  1519.    /* XXX what if format/type doesn't match texture format/type? */
  1520.  
  1521.    if (!pixels)
  1522.       return;
  1523.  
  1524.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1525.    if (!texImage) {
  1526.       /* invalid mipmap level, not an error */
  1527.       return;
  1528.    }
  1529.  
  1530.    if (!texImage->Data) {
  1531.       /* no image data, not an error */
  1532.       return;
  1533.    }
  1534.  
  1535.    {
  1536.       const GLint width = texImage->Width;
  1537.       const GLint height = texImage->Height;
  1538.       const GLint depth = texImage->Depth;
  1539.       GLint img, row;
  1540.       for (img = 0; img < depth; img++) {
  1541.          for (row = 0; row < height; row++) {
  1542.             /* compute destination address in client memory */
  1543.             GLvoid *dest = _mesa_image_address( &ctx->Pack, pixels,
  1544.                                                 width, height, format, type,
  1545.                                                 img, row, 0);
  1546.             assert(dest);
  1547.  
  1548.             if (format == GL_COLOR_INDEX) {
  1549.                GLuint indexRow[MAX_WIDTH];
  1550.                GLint col;
  1551.                for (col = 0; col < width; col++) {
  1552.                   (*texImage->FetchTexel)(texImage, col, row, img,
  1553.                                           (GLvoid *) &indexRow[col]);
  1554.                }
  1555.                _mesa_pack_index_span(ctx, width, type, dest,
  1556.                                      indexRow, &ctx->Pack,
  1557.                                      0 /* no image transfer */);
  1558.             }
  1559.             else if (format == GL_DEPTH_COMPONENT) {
  1560.                GLfloat depthRow[MAX_WIDTH];
  1561.                GLint col;
  1562.                for (col = 0; col < width; col++) {
  1563.                   (*texImage->FetchTexel)(texImage, col, row, img,
  1564.                                           (GLvoid *) &depthRow[col]);
  1565.                }
  1566.                _mesa_pack_depth_span(ctx, width, dest, type,
  1567.                                      depthRow, &ctx->Pack);
  1568.             }
  1569.             else if (format == GL_YCBCR_MESA) {
  1570.                /* No pixel transfer */
  1571.                const GLint rowstride = texImage->RowStride;
  1572.                MEMCPY(dest,
  1573.                       (const GLushort *) texImage->Data + row * rowstride,
  1574.                       width * sizeof(GLushort));
  1575.                /* check for byte swapping */
  1576.                if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
  1577.                     && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
  1578.                    (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
  1579.                     && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
  1580.                   if (!ctx->Pack.SwapBytes)
  1581.                      _mesa_swap2((GLushort *) dest, width);
  1582.                }
  1583.                else if (ctx->Pack.SwapBytes) {
  1584.                   _mesa_swap2((GLushort *) dest, width);
  1585.                }
  1586.             }
  1587.             else {
  1588.                /* general case:  convert row to RGBA format */
  1589.                GLchan rgba[MAX_WIDTH][4];
  1590.                GLint col;
  1591.                for (col = 0; col < width; col++) {
  1592.                   (*texImage->FetchTexel)(texImage, col, row, img,
  1593.                                           (GLvoid *) rgba[col]);
  1594.                }
  1595.                _mesa_pack_rgba_span(ctx, width, (const GLchan (*)[4])rgba,
  1596.                                     format, type, dest, &ctx->Pack,
  1597.                                     0 /* no image transfer */);
  1598.             } /* format */
  1599.          } /* row */
  1600.       } /* img */
  1601.    }
  1602. }
  1603.  
  1604.  
  1605.  
  1606. /*
  1607.  * Called from the API.  Note that width includes the border.
  1608.  */
  1609. void
  1610. _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
  1611.                   GLsizei width, GLint border, GLenum format,
  1612.                   GLenum type, const GLvoid *pixels )
  1613. {
  1614.    GLsizei postConvWidth = width;
  1615.    GET_CURRENT_CONTEXT(ctx);
  1616.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  1617.  
  1618.    if (is_color_format(internalFormat)) {
  1619.       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
  1620.    }
  1621.  
  1622.    if (target == GL_TEXTURE_1D) {
  1623.       struct gl_texture_unit *texUnit;
  1624.       struct gl_texture_object *texObj;
  1625.       struct gl_texture_image *texImage;
  1626.  
  1627.       if (texture_error_check(ctx, target, level, internalFormat,
  1628.                               format, type, 1, postConvWidth, 1, 1, border)) {
  1629.          return;   /* error was recorded */
  1630.       }
  1631.  
  1632.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1633.       texObj = _mesa_select_tex_object(ctx, texUnit, target);
  1634.       texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1635.  
  1636.       if (!texImage) {
  1637.          texImage = _mesa_alloc_texture_image();
  1638.          texObj->Image[level] = texImage;
  1639.          if (!texImage) {
  1640.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
  1641.             return;
  1642.          }
  1643.       }
  1644.       else if (texImage->Data && !texImage->IsClientData) {
  1645.          /* free the old texture data */
  1646.          MESA_PBUFFER_FREE(texImage->Data);
  1647.       }
  1648.       texImage->Data = NULL;
  1649.       clear_teximage_fields(texImage); /* not really needed, but helpful */
  1650.       _mesa_init_teximage_fields(ctx, target, texImage,
  1651.                                  postConvWidth, 1, 1,
  1652.                                  border, internalFormat);
  1653.  
  1654.       if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  1655.          _mesa_update_state(ctx);
  1656.  
  1657.       ASSERT(ctx->Driver.TexImage1D);
  1658.  
  1659.       /* Give the texture to the driver!  <pixels> may be null! */
  1660.       (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
  1661.                                 width, border, format, type, pixels,
  1662.                                 &ctx->Unpack, texObj, texImage);
  1663.  
  1664.       ASSERT(texImage->TexFormat);
  1665.       if (!texImage->FetchTexel) {
  1666.          /* If driver didn't explicitly set this, use the default */
  1667.          texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
  1668.       }
  1669.       ASSERT(texImage->FetchTexel);
  1670.  
  1671.       /* state update */
  1672.       texObj->Complete = GL_FALSE;
  1673.       ctx->NewState |= _NEW_TEXTURE;
  1674.    }
  1675.    else if (target == GL_PROXY_TEXTURE_1D) {
  1676.       /* Proxy texture: check for errors and update proxy state */
  1677.       GLboolean error = texture_error_check(ctx, target, level, internalFormat,
  1678.                                  format, type, 1, postConvWidth, 1, 1, border);
  1679.       if (!error) {
  1680.          ASSERT(ctx->Driver.TestProxyTexImage);
  1681.          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
  1682.                                                   internalFormat, format, type,
  1683.                                                   postConvWidth, 1, 1, border);
  1684.       }
  1685.       if (error) {
  1686.          /* if error, clear all proxy texture image parameters */
  1687.          if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
  1688.             clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]);
  1689.          }
  1690.       }
  1691.       else {
  1692.          /* no error, set the tex image parameters */
  1693.          struct gl_texture_unit *texUnit;
  1694.          struct gl_texture_image *texImage;
  1695.          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1696.          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1697.          _mesa_init_teximage_fields(ctx, target, texImage,
  1698.                                     postConvWidth, 1, 1,
  1699.                                     border, internalFormat);
  1700.       }
  1701.    }
  1702.    else {
  1703.       _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
  1704.       return;
  1705.    }
  1706. }
  1707.  
  1708.  
  1709. void
  1710. _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
  1711.                   GLsizei width, GLsizei height, GLint border,
  1712.                   GLenum format, GLenum type,
  1713.                   const GLvoid *pixels )
  1714. {
  1715.    GLsizei postConvWidth = width, postConvHeight = height;
  1716.    GET_CURRENT_CONTEXT(ctx);
  1717.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  1718.  
  1719.    if (is_color_format(internalFormat)) {
  1720.       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
  1721.                      &postConvHeight);
  1722.    }
  1723.  
  1724.    if (target == GL_TEXTURE_2D ||
  1725.        (ctx->Extensions.ARB_texture_cube_map &&
  1726.         target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  1727.         target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) ||
  1728.        (ctx->Extensions.NV_texture_rectangle &&
  1729.         target == GL_TEXTURE_RECTANGLE_NV)) {
  1730.       /* non-proxy target */
  1731.       struct gl_texture_unit *texUnit;
  1732.       struct gl_texture_object *texObj;
  1733.       struct gl_texture_image *texImage;
  1734.  
  1735.       if (texture_error_check(ctx, target, level, internalFormat,
  1736.                               format, type, 2, postConvWidth, postConvHeight,
  1737.                               1, border)) {
  1738.          return;   /* error was recorded */
  1739.       }
  1740.  
  1741.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1742.       texObj = _mesa_select_tex_object(ctx, texUnit, target);
  1743.       texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1744.  
  1745.       if (!texImage) {
  1746.          texImage = _mesa_alloc_texture_image();
  1747.          _mesa_set_tex_image(texObj, target, level, texImage);
  1748.          if (!texImage) {
  1749.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
  1750.             return;
  1751.          }
  1752.       }
  1753.       else if (texImage->Data && !texImage->IsClientData) {
  1754.          /* free the old texture data */
  1755.          MESA_PBUFFER_FREE(texImage->Data);
  1756.       }
  1757.       texImage->Data = NULL;
  1758.       clear_teximage_fields(texImage); /* not really needed, but helpful */
  1759.       _mesa_init_teximage_fields(ctx, target, texImage,
  1760.                                  postConvWidth, postConvHeight, 1,
  1761.                                  border, internalFormat);
  1762.  
  1763.       if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  1764.          _mesa_update_state(ctx);
  1765.  
  1766.       ASSERT(ctx->Driver.TexImage2D);
  1767.  
  1768.       /* Give the texture to the driver!  <pixels> may be null! */
  1769.       (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
  1770.                                 width, height, border, format, type, pixels,
  1771.                                 &ctx->Unpack, texObj, texImage);
  1772.  
  1773.       ASSERT(texImage->TexFormat);
  1774.       if (!texImage->FetchTexel) {
  1775.          /* If driver didn't explicitly set this, use the default */
  1776.          texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
  1777.       }
  1778.       ASSERT(texImage->FetchTexel);
  1779.  
  1780.       /* state update */
  1781.       texObj->Complete = GL_FALSE;
  1782.       ctx->NewState |= _NEW_TEXTURE;
  1783.    }
  1784.    else if (target == GL_PROXY_TEXTURE_2D ||
  1785.             (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
  1786.              ctx->Extensions.ARB_texture_cube_map) ||
  1787.             (target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
  1788.              ctx->Extensions.NV_texture_rectangle)) {
  1789.       /* Proxy texture: check for errors and update proxy state */
  1790.       GLboolean error = texture_error_check(ctx, target, level, internalFormat,
  1791.                     format, type, 2, postConvWidth, postConvHeight, 1, border);
  1792.       if (!error) {
  1793.          ASSERT(ctx->Driver.TestProxyTexImage);
  1794.          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
  1795.                                     internalFormat, format, type,
  1796.                                     postConvWidth, postConvHeight, 1, border);
  1797.       }
  1798.       if (error) {
  1799.          /* if error, clear all proxy texture image parameters */
  1800.          const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ?
  1801.             ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
  1802.          if (level >= 0 && level < maxLevels) {
  1803.             clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
  1804.          }
  1805.       }
  1806.       else {
  1807.          /* no error, set the tex image parameters */
  1808.          struct gl_texture_unit *texUnit;
  1809.          struct gl_texture_image *texImage;
  1810.          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1811.          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1812.          _mesa_init_teximage_fields(ctx, target, texImage,
  1813.                                     postConvWidth, postConvHeight, 1,
  1814.                                     border, internalFormat);
  1815.       }
  1816.    }
  1817.    else {
  1818.       _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  1819.       return;
  1820.    }
  1821. }
  1822.  
  1823.  
  1824. /*
  1825.  * Called by the API or display list executor.
  1826.  * Note that width and height include the border.
  1827.  */
  1828. void
  1829. _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
  1830.                   GLsizei width, GLsizei height, GLsizei depth,
  1831.                   GLint border, GLenum format, GLenum type,
  1832.                   const GLvoid *pixels )
  1833. {
  1834.    GET_CURRENT_CONTEXT(ctx);
  1835.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  1836.  
  1837.    if (target == GL_TEXTURE_3D) {
  1838.       struct gl_texture_unit *texUnit;
  1839.       struct gl_texture_object *texObj;
  1840.       struct gl_texture_image *texImage;
  1841.  
  1842.       if (texture_error_check(ctx, target, level, (GLint) internalFormat,
  1843.                               format, type, 3, width, height, depth, border)) {
  1844.          return;   /* error was recorded */
  1845.       }
  1846.  
  1847.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1848.       texObj = _mesa_select_tex_object(ctx, texUnit, target);
  1849.       texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1850.  
  1851.       if (!texImage) {
  1852.          texImage = _mesa_alloc_texture_image();
  1853.          texObj->Image[level] = texImage;
  1854.          if (!texImage) {
  1855.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
  1856.             return;
  1857.          }
  1858.       }
  1859.       else if (texImage->Data && !texImage->IsClientData) {
  1860.          MESA_PBUFFER_FREE(texImage->Data);
  1861.       }
  1862.       texImage->Data = NULL;
  1863.       clear_teximage_fields(texImage); /* not really needed, but helpful */
  1864.       _mesa_init_teximage_fields(ctx, target, texImage,
  1865.                                  width, height, depth,
  1866.                                  border, internalFormat);
  1867.  
  1868.       if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  1869.          _mesa_update_state(ctx);
  1870.  
  1871.       ASSERT(ctx->Driver.TexImage3D);
  1872.  
  1873.       /* Give the texture to the driver!  <pixels> may be null! */
  1874.       (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
  1875.                                 width, height, depth, border, format, type,
  1876.                                 pixels, &ctx->Unpack, texObj, texImage);
  1877.  
  1878.       ASSERT(texImage->TexFormat);
  1879.       if (!texImage->FetchTexel) {
  1880.          /* If driver didn't explicitly set this, use the default */
  1881.          texImage->FetchTexel = texImage->TexFormat->FetchTexel3D;
  1882.       }
  1883.       ASSERT(texImage->FetchTexel);
  1884.  
  1885.       /* state update */
  1886.       texObj->Complete = GL_FALSE;
  1887.       ctx->NewState |= _NEW_TEXTURE;
  1888.    }
  1889.    else if (target == GL_PROXY_TEXTURE_3D) {
  1890.       /* Proxy texture: check for errors and update proxy state */
  1891.       GLboolean error = texture_error_check(ctx, target, level, internalFormat,
  1892.                                 format, type, 3, width, height, depth, border);
  1893.       if (!error) {
  1894.          ASSERT(ctx->Driver.TestProxyTexImage);
  1895.          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
  1896.                                                  internalFormat, format, type,
  1897.                                                  width, height, depth, border);
  1898.       }
  1899.       if (error) {
  1900.          /* if error, clear all proxy texture image parameters */
  1901.          if (level >= 0 && level < ctx->Const.Max3DTextureLevels) {
  1902.             clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
  1903.          }
  1904.       }
  1905.       else {
  1906.          /* no error, set the tex image parameters */
  1907.          struct gl_texture_unit *texUnit;
  1908.          struct gl_texture_image *texImage;
  1909.          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1910.          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1911.          _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
  1912.                                     border, internalFormat);
  1913.       }
  1914.    }
  1915.    else {
  1916.       _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
  1917.       return;
  1918.    }
  1919. }
  1920.  
  1921.  
  1922. void
  1923. _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
  1924.                      GLsizei width, GLsizei height, GLsizei depth,
  1925.                      GLint border, GLenum format, GLenum type,
  1926.                      const GLvoid *pixels )
  1927. {
  1928.    _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
  1929.                     depth, border, format, type, pixels);
  1930. }
  1931.  
  1932.  
  1933.  
  1934. void
  1935. _mesa_TexSubImage1D( GLenum target, GLint level,
  1936.                      GLint xoffset, GLsizei width,
  1937.                      GLenum format, GLenum type,
  1938.                      const GLvoid *pixels )
  1939. {
  1940.    GLsizei postConvWidth = width;
  1941.    struct gl_texture_unit *texUnit;
  1942.    struct gl_texture_object *texObj;
  1943.    struct gl_texture_image *texImage;
  1944.    GET_CURRENT_CONTEXT(ctx);
  1945.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  1946.  
  1947.    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  1948.       _mesa_update_state(ctx);
  1949.  
  1950.    /* XXX should test internal format */
  1951.    if (is_color_format(format)) {
  1952.       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
  1953.    }
  1954.  
  1955.    if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
  1956.                               postConvWidth, 1, 1, format, type)) {
  1957.       return;   /* error was detected */
  1958.    }
  1959.  
  1960.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1961.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  1962.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  1963.    assert(texImage);
  1964.  
  1965.    if (width == 0 || !pixels)
  1966.       return;  /* no-op, not an error */
  1967.  
  1968.    /* If we have a border, xoffset=-1 is legal.  Bias by border width */
  1969.    xoffset += texImage->Border;
  1970.  
  1971.    ASSERT(ctx->Driver.TexSubImage1D);
  1972.    (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
  1973.                                 format, type, pixels, &ctx->Unpack,
  1974.                                 texObj, texImage);
  1975.    ctx->NewState |= _NEW_TEXTURE;
  1976. }
  1977.  
  1978.  
  1979. void
  1980. _mesa_TexSubImage2D( GLenum target, GLint level,
  1981.                      GLint xoffset, GLint yoffset,
  1982.                      GLsizei width, GLsizei height,
  1983.                      GLenum format, GLenum type,
  1984.                      const GLvoid *pixels )
  1985. {
  1986.    GLsizei postConvWidth = width, postConvHeight = height;
  1987.    struct gl_texture_unit *texUnit;
  1988.    struct gl_texture_object *texObj;
  1989.    struct gl_texture_image *texImage;
  1990.    GET_CURRENT_CONTEXT(ctx);
  1991.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  1992.  
  1993.    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  1994.       _mesa_update_state(ctx);
  1995.  
  1996.    /* XXX should test internal format */
  1997.    if (is_color_format(format)) {
  1998.       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
  1999.                                          &postConvHeight);
  2000.    }
  2001.  
  2002.    if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
  2003.                              postConvWidth, postConvHeight, 1, format, type)) {
  2004.       return;   /* error was detected */
  2005.    }
  2006.  
  2007.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2008.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2009.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2010.    assert(texImage);
  2011.  
  2012.    if (width == 0 || height == 0 || !pixels)
  2013.       return;  /* no-op, not an error */
  2014.  
  2015.    /* If we have a border, xoffset=-1 is legal.  Bias by border width */
  2016.    xoffset += texImage->Border;
  2017.    yoffset += texImage->Border;
  2018.  
  2019.    ASSERT(ctx->Driver.TexSubImage2D);
  2020.    (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset,
  2021.                                 width, height, format, type, pixels,
  2022.                                 &ctx->Unpack, texObj, texImage);
  2023.    ctx->NewState |= _NEW_TEXTURE;
  2024. }
  2025.  
  2026.  
  2027.  
  2028. void
  2029. _mesa_TexSubImage3D( GLenum target, GLint level,
  2030.                      GLint xoffset, GLint yoffset, GLint zoffset,
  2031.                      GLsizei width, GLsizei height, GLsizei depth,
  2032.                      GLenum format, GLenum type,
  2033.                      const GLvoid *pixels )
  2034. {
  2035.    struct gl_texture_unit *texUnit;
  2036.    struct gl_texture_object *texObj;
  2037.    struct gl_texture_image *texImage;
  2038.    GET_CURRENT_CONTEXT(ctx);
  2039.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2040.  
  2041.    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  2042.       _mesa_update_state(ctx);
  2043.  
  2044.    if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
  2045.                               width, height, depth, format, type)) {
  2046.       return;   /* error was detected */
  2047.    }
  2048.  
  2049.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2050.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2051.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2052.    assert(texImage);
  2053.  
  2054.    if (width == 0 || height == 0 || height == 0 || !pixels)
  2055.       return;  /* no-op, not an error */
  2056.  
  2057.    /* If we have a border, xoffset=-1 is legal.  Bias by border width */
  2058.    xoffset += texImage->Border;
  2059.    yoffset += texImage->Border;
  2060.    zoffset += texImage->Border;
  2061.  
  2062.    ASSERT(ctx->Driver.TexSubImage3D);
  2063.    (*ctx->Driver.TexSubImage3D)(ctx, target, level,
  2064.                                 xoffset, yoffset, zoffset,
  2065.                                 width, height, depth,
  2066.                                 format, type, pixels,
  2067.                                 &ctx->Unpack, texObj, texImage );
  2068.    ctx->NewState |= _NEW_TEXTURE;
  2069. }
  2070.  
  2071.  
  2072.  
  2073. void
  2074. _mesa_CopyTexImage1D( GLenum target, GLint level,
  2075.                       GLenum internalFormat,
  2076.                       GLint x, GLint y,
  2077.                       GLsizei width, GLint border )
  2078. {
  2079.    struct gl_texture_unit *texUnit;
  2080.    struct gl_texture_object *texObj;
  2081.    struct gl_texture_image *texImage;
  2082.    GLsizei postConvWidth = width;
  2083.    GET_CURRENT_CONTEXT(ctx);
  2084.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2085.  
  2086.    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  2087.       _mesa_update_state(ctx);
  2088.  
  2089.    if (is_color_format(internalFormat)) {
  2090.       _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
  2091.    }
  2092.  
  2093.    if (copytexture_error_check(ctx, 1, target, level, internalFormat,
  2094.                                postConvWidth, 1, border))
  2095.       return;
  2096.  
  2097.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2098.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2099.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2100.    if (!texImage) {
  2101.       texImage = _mesa_alloc_texture_image();
  2102.       _mesa_set_tex_image(texObj, target, level, texImage);
  2103.       if (!texImage) {
  2104.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
  2105.          return;
  2106.       }
  2107.    }
  2108.    else if (texImage->Data && !texImage->IsClientData) {
  2109.       /* free the old texture data */
  2110.       MESA_PBUFFER_FREE(texImage->Data);
  2111.    }
  2112.    texImage->Data = NULL;
  2113.  
  2114.    clear_teximage_fields(texImage); /* not really needed, but helpful */
  2115.    _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
  2116.                               border, internalFormat);
  2117.  
  2118.  
  2119.    ASSERT(ctx->Driver.CopyTexImage1D);
  2120.    (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat,
  2121.                                  x, y, width, border);
  2122.  
  2123.    ASSERT(texImage->TexFormat);
  2124.    if (!texImage->FetchTexel) {
  2125.       /* If driver didn't explicitly set this, use the default */
  2126.       texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
  2127.    }
  2128.    ASSERT(texImage->FetchTexel);
  2129.  
  2130.    /* state update */
  2131.    texObj->Complete = GL_FALSE;
  2132.    ctx->NewState |= _NEW_TEXTURE;
  2133. }
  2134.  
  2135.  
  2136.  
  2137. void
  2138. _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
  2139.                       GLint x, GLint y, GLsizei width, GLsizei height,
  2140.                       GLint border )
  2141. {
  2142.    struct gl_texture_unit *texUnit;
  2143.    struct gl_texture_object *texObj;
  2144.    struct gl_texture_image *texImage;
  2145.    GLsizei postConvWidth = width, postConvHeight = height;
  2146.    GET_CURRENT_CONTEXT(ctx);
  2147.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2148.  
  2149.    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  2150.       _mesa_update_state(ctx);
  2151.  
  2152.    if (is_color_format(internalFormat)) {
  2153.       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
  2154.                                          &postConvHeight);
  2155.    }
  2156.  
  2157.    if (copytexture_error_check(ctx, 2, target, level, internalFormat,
  2158.                                postConvWidth, postConvHeight, border))
  2159.       return;
  2160.  
  2161.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2162.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2163.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2164.    if (!texImage) {
  2165.       texImage = _mesa_alloc_texture_image();
  2166.       _mesa_set_tex_image(texObj, target, level, texImage);
  2167.       if (!texImage) {
  2168.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
  2169.          return;
  2170.       }
  2171.    }
  2172.    else if (texImage->Data && !texImage->IsClientData) {
  2173.       /* free the old texture data */
  2174.       MESA_PBUFFER_FREE(texImage->Data);
  2175.    }
  2176.    texImage->Data = NULL;
  2177.  
  2178.    clear_teximage_fields(texImage); /* not really needed, but helpful */
  2179.    _mesa_init_teximage_fields(ctx, target, texImage,
  2180.                               postConvWidth, postConvHeight, 1,
  2181.                               border, internalFormat);
  2182.  
  2183.    ASSERT(ctx->Driver.CopyTexImage2D);
  2184.    (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat,
  2185.                                  x, y, width, height, border);
  2186.  
  2187.    ASSERT(texImage->TexFormat);
  2188.    if (!texImage->FetchTexel) {
  2189.       /* If driver didn't explicitly set this, use the default */
  2190.       texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
  2191.    }
  2192.    ASSERT(texImage->FetchTexel);
  2193.  
  2194.    /* state update */
  2195.    texObj->Complete = GL_FALSE;
  2196.    ctx->NewState |= _NEW_TEXTURE;
  2197. }
  2198.  
  2199.  
  2200.  
  2201. void
  2202. _mesa_CopyTexSubImage1D( GLenum target, GLint level,
  2203.                          GLint xoffset, GLint x, GLint y, GLsizei width )
  2204. {
  2205.    struct gl_texture_unit *texUnit;
  2206.    struct gl_texture_object *texObj;
  2207.    struct gl_texture_image *texImage;
  2208.    GLsizei postConvWidth = width;
  2209.    GET_CURRENT_CONTEXT(ctx);
  2210.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2211.  
  2212.    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  2213.       _mesa_update_state(ctx);
  2214.  
  2215.    /* XXX should test internal format */
  2216.    _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
  2217.  
  2218.    if (copytexsubimage_error_check(ctx, 1, target, level,
  2219.                                    xoffset, 0, 0, postConvWidth, 1))
  2220.       return;
  2221.  
  2222.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2223.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2224.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2225.  
  2226.    /* If we have a border, xoffset=-1 is legal.  Bias by border width */
  2227.    xoffset += texImage->Border;
  2228.  
  2229.    ASSERT(ctx->Driver.CopyTexSubImage1D);
  2230.    (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width);
  2231.    ctx->NewState |= _NEW_TEXTURE;
  2232. }
  2233.  
  2234.  
  2235.  
  2236. void
  2237. _mesa_CopyTexSubImage2D( GLenum target, GLint level,
  2238.                          GLint xoffset, GLint yoffset,
  2239.                          GLint x, GLint y, GLsizei width, GLsizei height )
  2240. {
  2241.    struct gl_texture_unit *texUnit;
  2242.    struct gl_texture_object *texObj;
  2243.    struct gl_texture_image *texImage;
  2244.    GLsizei postConvWidth = width, postConvHeight = height;
  2245.    GET_CURRENT_CONTEXT(ctx);
  2246.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2247.  
  2248.    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  2249.       _mesa_update_state(ctx);
  2250.  
  2251.    /* XXX should test internal format */
  2252.    _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
  2253.  
  2254.    if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
  2255.                                    postConvWidth, postConvHeight))
  2256.       return;
  2257.  
  2258.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2259.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2260.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2261.  
  2262.    /* If we have a border, xoffset=-1 is legal.  Bias by border width */
  2263.    xoffset += texImage->Border;
  2264.    yoffset += texImage->Border;
  2265.  
  2266.    ASSERT(ctx->Driver.CopyTexSubImage2D);
  2267.    (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level,
  2268.                                     xoffset, yoffset, x, y, width, height);
  2269.    ctx->NewState |= _NEW_TEXTURE;
  2270. }
  2271.  
  2272.  
  2273.  
  2274. void
  2275. _mesa_CopyTexSubImage3D( GLenum target, GLint level,
  2276.                          GLint xoffset, GLint yoffset, GLint zoffset,
  2277.                          GLint x, GLint y, GLsizei width, GLsizei height )
  2278. {
  2279.    struct gl_texture_unit *texUnit;
  2280.    struct gl_texture_object *texObj;
  2281.    struct gl_texture_image *texImage;
  2282.    GLsizei postConvWidth = width, postConvHeight = height;
  2283.    GET_CURRENT_CONTEXT(ctx);
  2284.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2285.  
  2286.    if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
  2287.       _mesa_update_state(ctx);
  2288.  
  2289.    /* XXX should test internal format */
  2290.    _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
  2291.  
  2292.    if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset,
  2293.                                    zoffset, postConvWidth, postConvHeight))
  2294.       return;
  2295.  
  2296.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2297.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2298.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2299.  
  2300.    /* If we have a border, xoffset=-1 is legal.  Bias by border width */
  2301.    xoffset += texImage->Border;
  2302.    yoffset += texImage->Border;
  2303.    zoffset += texImage->Border;
  2304.  
  2305.    ASSERT(ctx->Driver.CopyTexSubImage3D);
  2306.    (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level,
  2307.                                     xoffset, yoffset, zoffset,
  2308.                                     x, y, width, height);
  2309.    ctx->NewState |= _NEW_TEXTURE;
  2310. }
  2311.  
  2312.  
  2313.  
  2314.  
  2315. /**********************************************************************/
  2316. /******                   Compressed Textures                    ******/
  2317. /**********************************************************************/
  2318.  
  2319.  
  2320. /**
  2321.  * Error checking for glCompressedTexImage[123]D().
  2322.  * \return error code or GL_NO_ERROR.
  2323.  */
  2324. static GLenum
  2325. compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
  2326.                                GLenum target, GLint level,
  2327.                                GLenum internalFormat, GLsizei width,
  2328.                                GLsizei height, GLsizei depth, GLint border,
  2329.                                GLsizei imageSize)
  2330. {
  2331.    GLboolean isProxy = GL_FALSE;
  2332.    GLint expectedSize, maxLevels = 0, maxTextureSize;
  2333.  
  2334.    if (dimensions == 1) {
  2335.       /* 1D compressed textures not allowed */
  2336.       return GL_INVALID_ENUM;
  2337.    }
  2338.    else if (dimensions == 2) {
  2339.       if (target == GL_PROXY_TEXTURE_2D) {
  2340.          maxLevels = ctx->Const.MaxTextureLevels;
  2341.          isProxy = GL_TRUE;
  2342.       }
  2343.       else if (target == GL_TEXTURE_2D) {
  2344.          maxLevels = ctx->Const.MaxTextureLevels;
  2345.       }
  2346.       else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
  2347.          if (!ctx->Extensions.ARB_texture_cube_map)
  2348.             return GL_INVALID_ENUM; /*target*/
  2349.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  2350.          isProxy = GL_TRUE;
  2351.       }
  2352.       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  2353.                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  2354.          if (!ctx->Extensions.ARB_texture_cube_map)
  2355.             return GL_INVALID_ENUM; /*target*/
  2356.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  2357.       }
  2358.       else {
  2359.          return GL_INVALID_ENUM; /*target*/
  2360.       }
  2361.    }
  2362.    else if (dimensions == 3) {
  2363.       /* 3D compressed textures not allowed */
  2364.       return GL_INVALID_ENUM;
  2365.    }
  2366.  
  2367.    maxTextureSize = 1 << (maxLevels - 1);
  2368.  
  2369.    if (!is_compressed_format(internalFormat))
  2370.       return GL_INVALID_ENUM;
  2371.  
  2372.    if (border != 0)
  2373.       return GL_INVALID_VALUE;
  2374.  
  2375.    if (width < 1 || width > maxTextureSize || logbase2(width) < 0)
  2376.       return GL_INVALID_VALUE;
  2377.  
  2378.    if ((height < 1 || height > maxTextureSize || logbase2(height) < 0)
  2379.        && dimensions > 1)
  2380.       return GL_INVALID_VALUE;
  2381.  
  2382.    if ((depth < 1 || depth > maxTextureSize || logbase2(depth) < 0)
  2383.        && dimensions > 2)
  2384.       return GL_INVALID_VALUE;
  2385.  
  2386.    /* For cube map, width must equal height */
  2387.    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  2388.        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height)
  2389.       return GL_INVALID_VALUE;
  2390.  
  2391.    if (level < 0 || level >= maxLevels)
  2392.       return GL_INVALID_VALUE;
  2393.  
  2394.    expectedSize = _mesa_compressed_texture_size(ctx, width, height, depth,
  2395.                                                 internalFormat);
  2396.    if (expectedSize != imageSize)
  2397.       return GL_INVALID_VALUE;
  2398.  
  2399.    return GL_NO_ERROR;
  2400. }
  2401.  
  2402.  
  2403. /**
  2404.  * Error checking for glCompressedTexSubImage[123]D().
  2405.  * \return error code or GL_NO_ERROR.
  2406.  */
  2407. static GLenum
  2408. compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
  2409.                                   GLenum target, GLint level,
  2410.                                   GLint xoffset, GLint yoffset, GLint zoffset,
  2411.                                   GLsizei width, GLsizei height, GLsizei depth,
  2412.                                   GLenum format, GLsizei imageSize)
  2413. {
  2414.    GLboolean isProxy = GL_FALSE;
  2415.    GLint expectedSize, maxLevels = 0, maxTextureSize;
  2416.  
  2417.    if (dimensions == 1) {
  2418.       /* 1D compressed textures not allowed */
  2419.       return GL_INVALID_ENUM;
  2420.    }
  2421.    else if (dimensions == 2) {
  2422.       if (target == GL_PROXY_TEXTURE_2D) {
  2423.          maxLevels = ctx->Const.MaxTextureLevels;
  2424.          isProxy = GL_TRUE;
  2425.       }
  2426.       else if (target == GL_TEXTURE_2D) {
  2427.          maxLevels = ctx->Const.MaxTextureLevels;
  2428.       }
  2429.       else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
  2430.          if (!ctx->Extensions.ARB_texture_cube_map)
  2431.             return GL_INVALID_ENUM; /*target*/
  2432.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  2433.          isProxy = GL_TRUE;
  2434.       }
  2435.       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  2436.                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  2437.          if (!ctx->Extensions.ARB_texture_cube_map)
  2438.             return GL_INVALID_ENUM; /*target*/
  2439.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  2440.       }
  2441.       else {
  2442.          return GL_INVALID_ENUM; /*target*/
  2443.       }
  2444.    }
  2445.    else if (dimensions == 3) {
  2446.       /* 3D compressed textures not allowed */
  2447.       return GL_INVALID_ENUM;
  2448.    }
  2449.  
  2450.    maxTextureSize = 1 << (maxLevels - 1);
  2451.  
  2452.    if (!is_compressed_format(format))
  2453.       return GL_INVALID_ENUM;
  2454.  
  2455.    if (width < 1 || width > maxTextureSize || logbase2(width) < 0)
  2456.       return GL_INVALID_VALUE;
  2457.  
  2458.    if ((height < 1 || height > maxTextureSize || logbase2(height) < 0)
  2459.        && dimensions > 1)
  2460.       return GL_INVALID_VALUE;
  2461.  
  2462.    if (level < 0 || level >= maxLevels)
  2463.       return GL_INVALID_VALUE;
  2464.  
  2465.    if ((xoffset & 3) != 0 || (yoffset & 3) != 0)
  2466.       return GL_INVALID_VALUE;
  2467.  
  2468.    if ((width & 3) != 0 && width != 2 && width != 1)
  2469.       return GL_INVALID_VALUE;
  2470.  
  2471.    if ((height & 3) != 0 && height != 2 && height != 1)
  2472.       return GL_INVALID_VALUE;
  2473.  
  2474.    expectedSize = _mesa_compressed_texture_size(ctx, width, height, depth,
  2475.                                                 format);
  2476.    if (expectedSize != imageSize)
  2477.       return GL_INVALID_VALUE;
  2478.  
  2479.    return GL_NO_ERROR;
  2480. }
  2481.  
  2482.  
  2483.  
  2484. void
  2485. _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
  2486.                               GLenum internalFormat, GLsizei width,
  2487.                               GLint border, GLsizei imageSize,
  2488.                               const GLvoid *data)
  2489. {
  2490.    GET_CURRENT_CONTEXT(ctx);
  2491.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2492.  
  2493.    if (target == GL_TEXTURE_1D) {
  2494.       struct gl_texture_unit *texUnit;
  2495.       struct gl_texture_object *texObj;
  2496.       struct gl_texture_image *texImage;
  2497.       GLenum error = compressed_texture_error_check(ctx, 1, target, level,
  2498.                                internalFormat, width, 1, 1, border, imageSize);
  2499.       if (error) {
  2500.          _mesa_error(ctx, error, "glCompressedTexImage1D");
  2501.          return;
  2502.       }
  2503.  
  2504.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2505.       texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2506.       texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2507.  
  2508.       if (!texImage) {
  2509.          texImage = _mesa_alloc_texture_image();
  2510.          texObj->Image[level] = texImage;
  2511.          if (!texImage) {
  2512.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
  2513.             return;
  2514.          }
  2515.       }
  2516.       else if (texImage->Data && !texImage->IsClientData) {
  2517.          MESA_PBUFFER_FREE(texImage->Data);
  2518.       }
  2519.       texImage->Data = NULL;
  2520.  
  2521.       _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
  2522.                                  border, internalFormat);
  2523.  
  2524.       ASSERT(ctx->Driver.CompressedTexImage1D);
  2525.       (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
  2526.                                           internalFormat, width, border,
  2527.                                           imageSize, data,
  2528.                                           texObj, texImage);
  2529.  
  2530.       /* state update */
  2531.       texObj->Complete = GL_FALSE;
  2532.       ctx->NewState |= _NEW_TEXTURE;
  2533.    }
  2534.    else if (target == GL_PROXY_TEXTURE_1D) {
  2535.       /* Proxy texture: check for errors and update proxy state */
  2536.       GLenum error = compressed_texture_error_check(ctx, 1, target, level,
  2537.                                internalFormat, width, 1, 1, border, imageSize);
  2538.       if (!error) {
  2539.          ASSERT(ctx->Driver.TestProxyTexImage);
  2540.          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
  2541.                                              internalFormat, GL_NONE, GL_NONE,
  2542.                                              width, 1, 1, border);
  2543.       }
  2544.       if (error) {
  2545.          /* if error, clear all proxy texture image parameters */
  2546.          if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
  2547.             clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]);
  2548.          }
  2549.       }
  2550.       else {
  2551.          /* store the teximage parameters */
  2552.          struct gl_texture_unit *texUnit;
  2553.          struct gl_texture_image *texImage;
  2554.          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2555.          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2556.          _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
  2557.                                     border, internalFormat);
  2558.       }
  2559.    }
  2560.    else {
  2561.       _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)");
  2562.       return;
  2563.    }
  2564. }
  2565.  
  2566.  
  2567. void
  2568. _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
  2569.                               GLenum internalFormat, GLsizei width,
  2570.                               GLsizei height, GLint border, GLsizei imageSize,
  2571.                               const GLvoid *data)
  2572. {
  2573.    GET_CURRENT_CONTEXT(ctx);
  2574.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2575.  
  2576.    if (target == GL_TEXTURE_2D ||
  2577.        (ctx->Extensions.ARB_texture_cube_map &&
  2578.         target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  2579.         target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
  2580.       struct gl_texture_unit *texUnit;
  2581.       struct gl_texture_object *texObj;
  2582.       struct gl_texture_image *texImage;
  2583.       GLenum error = compressed_texture_error_check(ctx, 2, target, level,
  2584.                           internalFormat, width, height, 1, border, imageSize);
  2585.       if (error) {
  2586.          _mesa_error(ctx, error, "glCompressedTexImage2D");
  2587.          return;
  2588.       }
  2589.  
  2590.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2591.       texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2592.       texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2593.  
  2594.       if (!texImage) {
  2595.          texImage = _mesa_alloc_texture_image();
  2596.          texObj->Image[level] = texImage;
  2597.          if (!texImage) {
  2598.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
  2599.             return;
  2600.          }
  2601.       }
  2602.       else if (texImage->Data && !texImage->IsClientData) {
  2603.          MESA_PBUFFER_FREE(texImage->Data);
  2604.       }
  2605.       texImage->Data = NULL;
  2606.  
  2607.       _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
  2608.                                  border, internalFormat);
  2609.  
  2610.       ASSERT(ctx->Driver.CompressedTexImage2D);
  2611.       (*ctx->Driver.CompressedTexImage2D)(ctx, target, level,
  2612.                                           internalFormat, width, height,
  2613.                                           border, imageSize, data,
  2614.                                           texObj, texImage);
  2615.  
  2616.       /* state update */
  2617.       texObj->Complete = GL_FALSE;
  2618.       ctx->NewState |= _NEW_TEXTURE;
  2619.    }
  2620.    else if (target == GL_PROXY_TEXTURE_2D ||
  2621.             (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
  2622.              ctx->Extensions.ARB_texture_cube_map)) {
  2623.       /* Proxy texture: check for errors and update proxy state */
  2624.       GLenum error = compressed_texture_error_check(ctx, 2, target, level,
  2625.                           internalFormat, width, height, 1, border, imageSize);
  2626.       if (!error) {
  2627.          ASSERT(ctx->Driver.TestProxyTexImage);
  2628.          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
  2629.                                               internalFormat, GL_NONE, GL_NONE,
  2630.                                               width, height, 1, border);
  2631.       }
  2632.       if (error) {
  2633.          /* if error, clear all proxy texture image parameters */
  2634.          const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ?
  2635.             ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
  2636.          if (level >= 0 && level < maxLevels) {
  2637.             clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
  2638.          }
  2639.       }
  2640.       else {
  2641.          /* store the teximage parameters */
  2642.          struct gl_texture_unit *texUnit;
  2643.          struct gl_texture_image *texImage;
  2644.          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2645.          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2646.          _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
  2647.                                     border, internalFormat);
  2648.       }
  2649.    }
  2650.    else {
  2651.       _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)");
  2652.       return;
  2653.    }
  2654. }
  2655.  
  2656.  
  2657. void
  2658. _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
  2659.                               GLenum internalFormat, GLsizei width,
  2660.                               GLsizei height, GLsizei depth, GLint border,
  2661.                               GLsizei imageSize, const GLvoid *data)
  2662. {
  2663.    GET_CURRENT_CONTEXT(ctx);
  2664.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2665.  
  2666.    if (target == GL_TEXTURE_3D) {
  2667.       struct gl_texture_unit *texUnit;
  2668.       struct gl_texture_object *texObj;
  2669.       struct gl_texture_image *texImage;
  2670.       GLenum error = compressed_texture_error_check(ctx, 3, target, level,
  2671.                       internalFormat, width, height, depth, border, imageSize);
  2672.       if (error) {
  2673.          _mesa_error(ctx, error, "glCompressedTexImage3D");
  2674.          return;
  2675.       }
  2676.  
  2677.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2678.       texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2679.       texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2680.  
  2681.       if (!texImage) {
  2682.          texImage = _mesa_alloc_texture_image();
  2683.          texObj->Image[level] = texImage;
  2684.          if (!texImage) {
  2685.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
  2686.             return;
  2687.          }
  2688.       }
  2689.       else if (texImage->Data && !texImage->IsClientData) {
  2690.          MESA_PBUFFER_FREE(texImage->Data);
  2691.       }
  2692.       texImage->Data = NULL;
  2693.  
  2694.       _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
  2695.                                  border, internalFormat);
  2696.  
  2697.       ASSERT(ctx->Driver.CompressedTexImage3D);
  2698.       (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
  2699.                                           internalFormat,
  2700.                                           width, height, depth,
  2701.                                           border, imageSize, data,
  2702.                                           texObj, texImage);
  2703.  
  2704.       /* state update */
  2705.       texObj->Complete = GL_FALSE;
  2706.       ctx->NewState |= _NEW_TEXTURE;
  2707.    }
  2708.    else if (target == GL_PROXY_TEXTURE_3D) {
  2709.       /* Proxy texture: check for errors and update proxy state */
  2710.       GLenum error = compressed_texture_error_check(ctx, 3, target, level,
  2711.                       internalFormat, width, height, depth, border, imageSize);
  2712.       if (!error) {
  2713.          ASSERT(ctx->Driver.TestProxyTexImage);
  2714.          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
  2715.                                              internalFormat, GL_NONE, GL_NONE,
  2716.                                              width, height, depth, border);
  2717.       }
  2718.       if (error) {
  2719.          /* if error, clear all proxy texture image parameters */
  2720.          if (level >= 0 && level < ctx->Const.Max3DTextureLevels) {
  2721.             clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
  2722.          }
  2723.       }
  2724.       else {
  2725.          /* store the teximage parameters */
  2726.          struct gl_texture_unit *texUnit;
  2727.          struct gl_texture_image *texImage;
  2728.          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2729.          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2730.          _mesa_init_teximage_fields(ctx, target, texImage, width, height,
  2731.                                     depth, border, internalFormat);
  2732.       }
  2733.    }
  2734.    else {
  2735.       _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)");
  2736.       return;
  2737.    }
  2738. }
  2739.  
  2740.  
  2741. void
  2742. _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
  2743.                                  GLsizei width, GLenum format,
  2744.                                  GLsizei imageSize, const GLvoid *data)
  2745. {
  2746.    struct gl_texture_unit *texUnit;
  2747.    struct gl_texture_object *texObj;
  2748.    struct gl_texture_image *texImage;
  2749.    GLenum error;
  2750.    GET_CURRENT_CONTEXT(ctx);
  2751.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2752.  
  2753.    error = compressed_subtexture_error_check(ctx, 1, target, level,
  2754.                                 xoffset, 0, 0, width, 1, 1, format, imageSize);
  2755.    if (error) {
  2756.       _mesa_error(ctx, error, "glCompressedTexSubImage1D");
  2757.       return;
  2758.    }
  2759.  
  2760.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2761.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2762.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2763.    assert(texImage);
  2764.  
  2765.    if ((GLint) format != texImage->IntFormat) {
  2766.       _mesa_error(ctx, GL_INVALID_OPERATION,
  2767.                   "glCompressedTexSubImage1D(format)");
  2768.       return;
  2769.    }
  2770.  
  2771.    if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) {
  2772.       _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)");
  2773.       return;
  2774.    }
  2775.       
  2776.    if (width == 0 || !data)
  2777.       return;  /* no-op, not an error */
  2778.  
  2779.    if (ctx->Driver.CompressedTexSubImage1D) {
  2780.       (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
  2781.                                              xoffset, width,
  2782.                                              format, imageSize, data,
  2783.                                              texObj, texImage);
  2784.    }
  2785.    ctx->NewState |= _NEW_TEXTURE;
  2786. }
  2787.  
  2788.  
  2789. void
  2790. _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
  2791.                                  GLint yoffset, GLsizei width, GLsizei height,
  2792.                                  GLenum format, GLsizei imageSize,
  2793.                                  const GLvoid *data)
  2794. {
  2795.    struct gl_texture_unit *texUnit;
  2796.    struct gl_texture_object *texObj;
  2797.    struct gl_texture_image *texImage;
  2798.    GLenum error;
  2799.    GET_CURRENT_CONTEXT(ctx);
  2800.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2801.  
  2802.    error = compressed_subtexture_error_check(ctx, 2, target, level,
  2803.                      xoffset, yoffset, 0, width, height, 1, format, imageSize);
  2804.    if (error) {
  2805.       _mesa_error(ctx, error, "glCompressedTexSubImage2D");
  2806.       return;
  2807.    }
  2808.  
  2809.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2810.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2811.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2812.    assert(texImage);
  2813.  
  2814.    if ((GLint) format != texImage->IntFormat) {
  2815.       _mesa_error(ctx, GL_INVALID_OPERATION,
  2816.                   "glCompressedTexSubImage2D(format)");
  2817.       return;
  2818.    }
  2819.  
  2820.    if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
  2821.        ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) {
  2822.       _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)");
  2823.       return;
  2824.    }
  2825.       
  2826.    if (width == 0 || height == 0 || !data)
  2827.       return;  /* no-op, not an error */
  2828.  
  2829.    if (ctx->Driver.CompressedTexSubImage2D) {
  2830.       (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
  2831.                                              xoffset, yoffset, width, height,
  2832.                                              format, imageSize, data,
  2833.                                              texObj, texImage);
  2834.    }
  2835.    ctx->NewState |= _NEW_TEXTURE;
  2836. }
  2837.  
  2838.  
  2839. void
  2840. _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
  2841.                                  GLint yoffset, GLint zoffset, GLsizei width,
  2842.                                  GLsizei height, GLsizei depth, GLenum format,
  2843.                                  GLsizei imageSize, const GLvoid *data)
  2844. {
  2845.    struct gl_texture_unit *texUnit;
  2846.    struct gl_texture_object *texObj;
  2847.    struct gl_texture_image *texImage;
  2848.    GLenum error;
  2849.    GET_CURRENT_CONTEXT(ctx);
  2850.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2851.  
  2852.    error = compressed_subtexture_error_check(ctx, 3, target, level,
  2853.            xoffset, yoffset, zoffset, width, height, depth, format, imageSize);
  2854.    if (error) {
  2855.       _mesa_error(ctx, error, "glCompressedTexSubImage2D");
  2856.       return;
  2857.    }
  2858.  
  2859.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2860.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2861.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2862.    assert(texImage);
  2863.  
  2864.    if ((GLint) format != texImage->IntFormat) {
  2865.       _mesa_error(ctx, GL_INVALID_OPERATION,
  2866.                   "glCompressedTexSubImage3D(format)");
  2867.       return;
  2868.    }
  2869.  
  2870.    if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
  2871.        ((height == 1 || height == 2) && (GLuint) height != texImage->Height) ||
  2872.        ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) {
  2873.       _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)");
  2874.       return;
  2875.    }
  2876.       
  2877.    if (width == 0 || height == 0 || depth == 0 || !data)
  2878.       return;  /* no-op, not an error */
  2879.  
  2880.    if (ctx->Driver.CompressedTexSubImage3D) {
  2881.       (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
  2882.                                              xoffset, yoffset, zoffset,
  2883.                                              width, height, depth,
  2884.                                              format, imageSize, data,
  2885.                                              texObj, texImage);
  2886.    }
  2887.    ctx->NewState |= _NEW_TEXTURE;
  2888. }
  2889.  
  2890.  
  2891. void
  2892. _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
  2893. {
  2894.    const struct gl_texture_unit *texUnit;
  2895.    const struct gl_texture_object *texObj;
  2896.    struct gl_texture_image *texImage;
  2897.    GLint maxLevels;
  2898.    GET_CURRENT_CONTEXT(ctx);
  2899.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2900.  
  2901.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  2902.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  2903.    if (!texObj) {
  2904.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
  2905.       return;
  2906.    }
  2907.  
  2908.    maxLevels = _mesa_max_texture_levels(ctx, target);
  2909.    ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
  2910.  
  2911.    if (level < 0 || level >= maxLevels) {
  2912.       _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
  2913.       return;
  2914.    }
  2915.  
  2916.    if (is_proxy_target(target)) {
  2917.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
  2918.       return;
  2919.    }
  2920.  
  2921.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  2922.    if (!texImage) {
  2923.       /* probably invalid mipmap level */
  2924.       _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
  2925.       return;
  2926.    }
  2927.  
  2928.    if (!texImage->IsCompressed) {
  2929.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB");
  2930.       return;
  2931.    }
  2932.  
  2933.    if (!img)
  2934.       return;
  2935.  
  2936.    /* just memcpy, no pixelstore or pixel transfer */
  2937.    MEMCPY(img, texImage->Data, texImage->CompressedSize);
  2938. }
  2939.