Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * mesa 3-D graphics library
  3.  * Version:  7.6
  4.  *
  5.  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  6.  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the "Software"),
  10.  * to deal in the Software without restriction, including without limitation
  11.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12.  * and/or sell copies of the Software, and to permit persons to whom the
  13.  * Software is furnished to do so, subject to the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice shall be included
  16.  * in all copies or substantial portions of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  22.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  */
  25.  
  26.  
  27. /**
  28.  * \file teximage.c
  29.  * Texture image-related functions.
  30.  */
  31.  
  32.  
  33. #include "glheader.h"
  34. #include "bufferobj.h"
  35. #include "context.h"
  36. #include "enums.h"
  37. #include "fbobject.h"
  38. #include "framebuffer.h"
  39. #include "hash.h"
  40. #include "image.h"
  41. #include "imports.h"
  42. #include "macros.h"
  43. #include "state.h"
  44. #include "texcompress.h"
  45. #include "texfetch.h"
  46. #include "teximage.h"
  47. #include "texstate.h"
  48. #include "texpal.h"
  49. #include "mtypes.h"
  50.  
  51.  
  52. /**
  53.  * State changes which we care about for glCopyTex[Sub]Image() calls.
  54.  * In particular, we care about pixel transfer state and buffer state
  55.  * (such as glReadBuffer to make sure we read from the right renderbuffer).
  56.  */
  57. #define NEW_COPY_TEX_STATE (_MESA_NEW_TRANSFER_STATE | \
  58.                             _NEW_BUFFERS | \
  59.                             _NEW_PIXEL)
  60.  
  61.  
  62.  
  63. /**
  64.  * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE
  65.  * elsewhere.
  66.  */
  67. void *
  68. _mesa_alloc_texmemory(GLsizei bytes)
  69. {
  70.    return _mesa_align_malloc(bytes, 512);
  71. }
  72.  
  73.  
  74. /**
  75.  * Free texture memory allocated with _mesa_alloc_texmemory()
  76.  */
  77. void
  78. _mesa_free_texmemory(void *m)
  79. {
  80.    _mesa_align_free(m);
  81. }
  82.  
  83.  
  84. /*
  85.  * Compute floor(log_base_2(n)).
  86.  * If n < 0 return -1.
  87.  */
  88. static int
  89. logbase2( int n )
  90. {
  91.    GLint i = 1;
  92.    GLint log2 = 0;
  93.  
  94.    if (n < 0)
  95.       return -1;
  96.  
  97.    if (n == 0)
  98.       return 0;
  99.  
  100.    while ( n > i ) {
  101.       i *= 2;
  102.       log2++;
  103.    }
  104.    if (i != n) {
  105.       return log2 - 1;
  106.    }
  107.    else {
  108.       return log2;
  109.    }
  110. }
  111.  
  112.  
  113.  
  114. /**
  115.  * Return the simple base format for a given internal texture format.
  116.  * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
  117.  *
  118.  * \param ctx GL context.
  119.  * \param internalFormat the internal texture format token or 1, 2, 3, or 4.
  120.  *
  121.  * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
  122.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
  123.  *
  124.  * This is the format which is used during texture application (i.e. the
  125.  * texture format and env mode determine the arithmetic used.
  126.  *
  127.  * XXX this could be static
  128.  */
  129. GLint
  130. _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
  131. {
  132.    switch (internalFormat) {
  133.       case GL_ALPHA:
  134.       case GL_ALPHA4:
  135.       case GL_ALPHA8:
  136.       case GL_ALPHA12:
  137.       case GL_ALPHA16:
  138.          return GL_ALPHA;
  139.       case 1:
  140.       case GL_LUMINANCE:
  141.       case GL_LUMINANCE4:
  142.       case GL_LUMINANCE8:
  143.       case GL_LUMINANCE12:
  144.       case GL_LUMINANCE16:
  145.          return GL_LUMINANCE;
  146.       case 2:
  147.       case GL_LUMINANCE_ALPHA:
  148.       case GL_LUMINANCE4_ALPHA4:
  149.       case GL_LUMINANCE6_ALPHA2:
  150.       case GL_LUMINANCE8_ALPHA8:
  151.       case GL_LUMINANCE12_ALPHA4:
  152.       case GL_LUMINANCE12_ALPHA12:
  153.       case GL_LUMINANCE16_ALPHA16:
  154.          return GL_LUMINANCE_ALPHA;
  155.       case GL_INTENSITY:
  156.       case GL_INTENSITY4:
  157.       case GL_INTENSITY8:
  158.       case GL_INTENSITY12:
  159.       case GL_INTENSITY16:
  160.          return GL_INTENSITY;
  161.       case 3:
  162.       case GL_RGB:
  163.       case GL_R3_G3_B2:
  164.       case GL_RGB4:
  165.       case GL_RGB5:
  166.       case GL_RGB8:
  167.       case GL_RGB10:
  168.       case GL_RGB12:
  169.       case GL_RGB16:
  170.          return GL_RGB;
  171.       case 4:
  172.       case GL_RGBA:
  173.       case GL_RGBA2:
  174.       case GL_RGBA4:
  175.       case GL_RGB5_A1:
  176.       case GL_RGBA8:
  177.       case GL_RGB10_A2:
  178.       case GL_RGBA12:
  179.       case GL_RGBA16:
  180.          return GL_RGBA;
  181.       default:
  182.          ; /* fallthrough */
  183.    }
  184.  
  185.    if (ctx->Extensions.EXT_paletted_texture) {
  186.       switch (internalFormat) {
  187.          case GL_COLOR_INDEX:
  188.          case GL_COLOR_INDEX1_EXT:
  189.          case GL_COLOR_INDEX2_EXT:
  190.          case GL_COLOR_INDEX4_EXT:
  191.          case GL_COLOR_INDEX8_EXT:
  192.          case GL_COLOR_INDEX12_EXT:
  193.          case GL_COLOR_INDEX16_EXT:
  194.             return GL_COLOR_INDEX;
  195.          default:
  196.             ; /* fallthrough */
  197.       }
  198.    }
  199.  
  200.    if (ctx->Extensions.ARB_depth_texture) {
  201.       switch (internalFormat) {
  202.          case GL_DEPTH_COMPONENT:
  203.          case GL_DEPTH_COMPONENT16:
  204.          case GL_DEPTH_COMPONENT24:
  205.          case GL_DEPTH_COMPONENT32:
  206.             return GL_DEPTH_COMPONENT;
  207.          default:
  208.             ; /* fallthrough */
  209.       }
  210.    }
  211.  
  212.    switch (internalFormat) {
  213.    case GL_COMPRESSED_ALPHA:
  214.       return GL_ALPHA;
  215.    case GL_COMPRESSED_LUMINANCE:
  216.       return GL_LUMINANCE;
  217.    case GL_COMPRESSED_LUMINANCE_ALPHA:
  218.       return GL_LUMINANCE_ALPHA;
  219.    case GL_COMPRESSED_INTENSITY:
  220.       return GL_INTENSITY;
  221.    case GL_COMPRESSED_RGB:
  222.       return GL_RGB;
  223.    case GL_COMPRESSED_RGBA:
  224.       return GL_RGBA;
  225.    default:
  226.       ; /* fallthrough */
  227.    }
  228.          
  229.    if (ctx->Extensions.TDFX_texture_compression_FXT1) {
  230.       switch (internalFormat) {
  231.          case GL_COMPRESSED_RGB_FXT1_3DFX:
  232.             return GL_RGB;
  233.          case GL_COMPRESSED_RGBA_FXT1_3DFX:
  234.             return GL_RGBA;
  235.          default:
  236.             ; /* fallthrough */
  237.       }
  238.    }
  239.  
  240.    if (ctx->Extensions.EXT_texture_compression_s3tc) {
  241.       switch (internalFormat) {
  242.          case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  243.             return GL_RGB;
  244.          case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  245.          case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  246.          case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  247.             return GL_RGBA;
  248.          default:
  249.             ; /* fallthrough */
  250.       }
  251.    }
  252.  
  253.    if (ctx->Extensions.S3_s3tc) {
  254.       switch (internalFormat) {
  255.          case GL_RGB_S3TC:
  256.          case GL_RGB4_S3TC:
  257.             return GL_RGB;
  258.          case GL_RGBA_S3TC:
  259.          case GL_RGBA4_S3TC:
  260.             return GL_RGBA;
  261.          default:
  262.             ; /* fallthrough */
  263.       }
  264.    }
  265.  
  266.    if (ctx->Extensions.MESA_ycbcr_texture) {
  267.       if (internalFormat == GL_YCBCR_MESA)
  268.          return GL_YCBCR_MESA;
  269.    }
  270.  
  271.    if (ctx->Extensions.ARB_texture_float) {
  272.       switch (internalFormat) {
  273.          case GL_ALPHA16F_ARB:
  274.          case GL_ALPHA32F_ARB:
  275.             return GL_ALPHA;
  276.          case GL_RGBA16F_ARB:
  277.          case GL_RGBA32F_ARB:
  278.             return GL_RGBA;
  279.          case GL_RGB16F_ARB:
  280.          case GL_RGB32F_ARB:
  281.             return GL_RGB;
  282.          case GL_INTENSITY16F_ARB:
  283.          case GL_INTENSITY32F_ARB:
  284.             return GL_INTENSITY;
  285.          case GL_LUMINANCE16F_ARB:
  286.          case GL_LUMINANCE32F_ARB:
  287.             return GL_LUMINANCE;
  288.          case GL_LUMINANCE_ALPHA16F_ARB:
  289.          case GL_LUMINANCE_ALPHA32F_ARB:
  290.             return GL_LUMINANCE_ALPHA;
  291.          default:
  292.             ; /* fallthrough */
  293.       }
  294.    }
  295.  
  296.    if (ctx->Extensions.ATI_envmap_bumpmap) {
  297.       switch (internalFormat) {
  298.          case GL_DUDV_ATI:
  299.          case GL_DU8DV8_ATI:
  300.             return GL_DUDV_ATI;
  301.          default:
  302.             ; /* fallthrough */
  303.       }
  304.    }
  305.  
  306.    if (ctx->Extensions.MESA_texture_signed_rgba) {
  307.       switch (internalFormat) {
  308.          case GL_RGBA_SNORM:
  309.          case GL_RGBA8_SNORM:
  310.             return GL_RGBA;
  311.          default:
  312.             ; /* fallthrough */
  313.       }
  314.    }
  315.  
  316.    if (ctx->Extensions.EXT_packed_depth_stencil) {
  317.       switch (internalFormat) {
  318.          case GL_DEPTH_STENCIL_EXT:
  319.          case GL_DEPTH24_STENCIL8_EXT:
  320.             return GL_DEPTH_STENCIL_EXT;
  321.          default:
  322.             ; /* fallthrough */
  323.       }
  324.    }
  325.  
  326. #if FEATURE_EXT_texture_sRGB
  327.    if (ctx->Extensions.EXT_texture_sRGB) {
  328.       switch (internalFormat) {
  329.       case GL_SRGB_EXT:
  330.       case GL_SRGB8_EXT:
  331.       case GL_COMPRESSED_SRGB_EXT:
  332.       case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
  333.          return GL_RGB;
  334.       case GL_SRGB_ALPHA_EXT:
  335.       case GL_SRGB8_ALPHA8_EXT:
  336.       case GL_COMPRESSED_SRGB_ALPHA_EXT:
  337.       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
  338.       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
  339.       case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
  340.          return GL_RGBA;
  341.       case GL_SLUMINANCE_ALPHA_EXT:
  342.       case GL_SLUMINANCE8_ALPHA8_EXT:
  343.       case GL_COMPRESSED_SLUMINANCE_EXT:
  344.       case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
  345.          return GL_LUMINANCE_ALPHA;
  346.       case GL_SLUMINANCE_EXT:
  347.       case GL_SLUMINANCE8_EXT:
  348.          return GL_LUMINANCE;
  349.       default:
  350.          ; /* fallthrough */
  351.       }
  352.    }
  353. #endif /* FEATURE_EXT_texture_sRGB */
  354.  
  355.    if (ctx->Extensions.EXT_texture_integer) {
  356.       switch (internalFormat) {
  357.       case GL_RGBA8UI_EXT:
  358.       case GL_RGBA16UI_EXT:
  359.       case GL_RGBA32UI_EXT:
  360.       case GL_RGBA8I_EXT:
  361.       case GL_RGBA16I_EXT:
  362.       case GL_RGBA32I_EXT:
  363.          return GL_RGBA;
  364.       case GL_RGB8UI_EXT:
  365.       case GL_RGB16UI_EXT:
  366.       case GL_RGB32UI_EXT:
  367.       case GL_RGB8I_EXT:
  368.       case GL_RGB16I_EXT:
  369.       case GL_RGB32I_EXT:
  370.          return GL_RGB;
  371.       case GL_ALPHA8UI_EXT:
  372.       case GL_ALPHA16UI_EXT:
  373.       case GL_ALPHA32UI_EXT:
  374.       case GL_ALPHA8I_EXT:
  375.       case GL_ALPHA16I_EXT:
  376.       case GL_ALPHA32I_EXT:
  377.          return GL_ALPHA;
  378.       case GL_INTENSITY8UI_EXT:
  379.       case GL_INTENSITY16UI_EXT:
  380.       case GL_INTENSITY32UI_EXT:
  381.       case GL_INTENSITY8I_EXT:
  382.       case GL_INTENSITY16I_EXT:
  383.       case GL_INTENSITY32I_EXT:
  384.          return GL_INTENSITY;
  385.       case GL_LUMINANCE8UI_EXT:
  386.       case GL_LUMINANCE16UI_EXT:
  387.       case GL_LUMINANCE32UI_EXT:
  388.       case GL_LUMINANCE8I_EXT:
  389.       case GL_LUMINANCE16I_EXT:
  390.       case GL_LUMINANCE32I_EXT:
  391.          return GL_LUMINANCE;
  392.       case GL_LUMINANCE_ALPHA8UI_EXT:
  393.       case GL_LUMINANCE_ALPHA16UI_EXT:
  394.       case GL_LUMINANCE_ALPHA32UI_EXT:
  395.       case GL_LUMINANCE_ALPHA8I_EXT:
  396.       case GL_LUMINANCE_ALPHA16I_EXT:
  397.       case GL_LUMINANCE_ALPHA32I_EXT:
  398.          return GL_LUMINANCE_ALPHA;
  399.       default:
  400.          ; /* fallthrough */
  401.       }
  402.    }
  403.  
  404.    if (ctx->Extensions.ARB_texture_rg) {
  405.       switch (internalFormat) {
  406.       case GL_R16F:
  407.          /* R16F depends on both ARB_half_float_pixel and ARB_texture_float.
  408.           */
  409.          if (!ctx->Extensions.ARB_half_float_pixel)
  410.             break;
  411.          /* FALLTHROUGH */
  412.       case GL_R32F:
  413.          if (!ctx->Extensions.ARB_texture_float)
  414.             break;
  415.          return GL_RED;
  416.       case GL_R8I:
  417.       case GL_R8UI:
  418.       case GL_R16I:
  419.       case GL_R16UI:
  420.       case GL_R32I:
  421.       case GL_R32UI:
  422.          if (!ctx->Extensions.EXT_texture_integer)
  423.             break;
  424.          /* FALLTHROUGH */
  425.       case GL_R8:
  426.       case GL_R16:
  427.       case GL_RED:
  428.       case GL_COMPRESSED_RED:
  429.          return GL_RED;
  430.  
  431.       case GL_RG16F:
  432.          /* RG16F depends on both ARB_half_float_pixel and ARB_texture_float.
  433.           */
  434.          if (!ctx->Extensions.ARB_half_float_pixel)
  435.             break;
  436.          /* FALLTHROUGH */
  437.       case GL_RG32F:
  438.          if (!ctx->Extensions.ARB_texture_float)
  439.             break;
  440.          return GL_RG;
  441.       case GL_RG8I:
  442.       case GL_RG8UI:
  443.       case GL_RG16I:
  444.       case GL_RG16UI:
  445.       case GL_RG32I:
  446.       case GL_RG32UI:
  447.          if (!ctx->Extensions.EXT_texture_integer)
  448.             break;
  449.          /* FALLTHROUGH */
  450.       case GL_RG:
  451.       case GL_RG8:
  452.       case GL_RG16:
  453.       case GL_COMPRESSED_RG:
  454.          return GL_RG;
  455.       default:
  456.          ; /* fallthrough */
  457.       }
  458.    }
  459.  
  460.    if (ctx->Extensions.EXT_texture_shared_exponent) {
  461.       switch (internalFormat) {
  462.       case GL_RGB9_E5_EXT:
  463.          return GL_RGB;
  464.       default:
  465.          ; /* fallthrough */
  466.       }
  467.    }
  468.  
  469.    if (ctx->Extensions.EXT_packed_float) {
  470.       switch (internalFormat) {
  471.       case GL_R11F_G11F_B10F_EXT:
  472.          return GL_RGB;
  473.       default:
  474.          ; /* fallthrough */
  475.       }
  476.    }
  477.  
  478.    if (ctx->Extensions.ARB_depth_buffer_float) {
  479.       switch (internalFormat) {
  480.       case GL_DEPTH_COMPONENT32F:
  481.          return GL_DEPTH_COMPONENT;
  482.       case GL_DEPTH32F_STENCIL8:
  483.          return GL_DEPTH_STENCIL;
  484.       default:
  485.          ; /* fallthrough */
  486.       }
  487.    }
  488.  
  489.    if (ctx->Extensions.ARB_texture_compression_rgtc) {
  490.       switch (internalFormat) {
  491.       case GL_COMPRESSED_RED_RGTC1:
  492.       case GL_COMPRESSED_SIGNED_RED_RGTC1:
  493.          return GL_RED;
  494.       case GL_COMPRESSED_RG_RGTC2:
  495.       case GL_COMPRESSED_SIGNED_RG_RGTC2:
  496.          return GL_RG;
  497.       default:
  498.          ; /* fallthrough */
  499.       }
  500.    }
  501.  
  502.    return -1; /* error */
  503. }
  504.  
  505.  
  506. /**
  507.  * For cube map faces, return a face index in [0,5].
  508.  * For other targets return 0;
  509.  */
  510. GLuint
  511. _mesa_tex_target_to_face(GLenum target)
  512. {
  513.    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  514.        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
  515.       return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  516.    else
  517.       return 0;
  518. }
  519.  
  520.  
  521.  
  522. /**
  523.  * Store a gl_texture_image pointer in a gl_texture_object structure
  524.  * according to the target and level parameters.
  525.  *
  526.  * \param tObj texture object.
  527.  * \param target texture target.
  528.  * \param level image level.
  529.  * \param texImage texture image.
  530.  *
  531.  * This was basically prompted by the introduction of cube maps.
  532.  */
  533. void
  534. _mesa_set_tex_image(struct gl_texture_object *tObj,
  535.                     GLenum target, GLint level,
  536.                     struct gl_texture_image *texImage)
  537. {
  538.    const GLuint face = _mesa_tex_target_to_face(target);
  539.  
  540.    ASSERT(tObj);
  541.    ASSERT(texImage);
  542.    ASSERT(target != GL_TEXTURE_RECTANGLE_NV || level == 0);
  543.  
  544.    tObj->Image[face][level] = texImage;
  545.  
  546.    /* Set the 'back' pointer */
  547.    texImage->TexObject = tObj;
  548. }
  549.  
  550.  
  551. /**
  552.  * Allocate a texture image structure.
  553.  *
  554.  * Called via ctx->Driver.NewTextureImage() unless overriden by a device
  555.  * driver.
  556.  *
  557.  * \return a pointer to gl_texture_image struct with all fields initialized to
  558.  * zero.
  559.  */
  560. struct gl_texture_image *
  561. _mesa_new_texture_image( struct gl_context *ctx )
  562. {
  563.    (void) ctx;
  564.    return CALLOC_STRUCT(gl_texture_image);
  565. }
  566.  
  567.  
  568. /**
  569.  * Free texture image data.
  570.  * This function is a fallback called via ctx->Driver.FreeTexImageData().
  571.  *
  572.  * \param texImage texture image.
  573.  *
  574.  * Free the texture image data if it's not marked as client data.
  575.  */
  576. void
  577. _mesa_free_texture_image_data(struct gl_context *ctx,
  578.                               struct gl_texture_image *texImage)
  579. {
  580.    (void) ctx;
  581.  
  582.    if (texImage->Data && !texImage->IsClientData) {
  583.       /* free the old texture data */
  584.       _mesa_free_texmemory(texImage->Data);
  585.    }
  586.  
  587.    texImage->Data = NULL;
  588. }
  589.  
  590.  
  591. /**
  592.  * Free texture image.
  593.  *
  594.  * \param texImage texture image.
  595.  *
  596.  * Free the texture image structure and the associated image data.
  597.  */
  598. void
  599. _mesa_delete_texture_image(struct gl_context *ctx,
  600.                            struct gl_texture_image *texImage)
  601. {
  602.    /* Free texImage->Data and/or any other driver-specific texture
  603.     * image storage.
  604.     */
  605.    ASSERT(ctx->Driver.FreeTexImageData);
  606.    ctx->Driver.FreeTexImageData( ctx, texImage );
  607.  
  608.    ASSERT(texImage->Data == NULL);
  609.    if (texImage->ImageOffsets)
  610.       free(texImage->ImageOffsets);
  611.    free(texImage);
  612. }
  613.  
  614.  
  615. /**
  616.  * Test if a target is a proxy target.
  617.  *
  618.  * \param target texture target.
  619.  *
  620.  * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
  621.  */
  622. GLboolean
  623. _mesa_is_proxy_texture(GLenum target)
  624. {
  625.    /* NUM_TEXTURE_TARGETS should match number of terms below */
  626.    assert(NUM_TEXTURE_TARGETS == 7);
  627.  
  628.    return (target == GL_PROXY_TEXTURE_1D ||
  629.            target == GL_PROXY_TEXTURE_2D ||
  630.            target == GL_PROXY_TEXTURE_3D ||
  631.            target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
  632.            target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
  633.            target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
  634.            target == GL_PROXY_TEXTURE_2D_ARRAY_EXT);
  635. }
  636.  
  637.  
  638. /**
  639.  * Return the proxy target which corresponds to the given texture target
  640.  */
  641. static GLenum
  642. get_proxy_target(GLenum target)
  643. {
  644.    switch (target) {
  645.    case GL_TEXTURE_1D:
  646.    case GL_PROXY_TEXTURE_1D:
  647.       return GL_PROXY_TEXTURE_1D;
  648.    case GL_TEXTURE_2D:
  649.    case GL_PROXY_TEXTURE_2D:
  650.       return GL_PROXY_TEXTURE_2D;
  651.    case GL_TEXTURE_3D:
  652.    case GL_PROXY_TEXTURE_3D:
  653.       return GL_PROXY_TEXTURE_3D;
  654.    case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
  655.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
  656.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
  657.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
  658.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
  659.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
  660.    case GL_TEXTURE_CUBE_MAP_ARB:
  661.    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
  662.       return GL_PROXY_TEXTURE_CUBE_MAP_ARB;
  663.    case GL_TEXTURE_RECTANGLE_NV:
  664.    case GL_PROXY_TEXTURE_RECTANGLE_NV:
  665.       return GL_PROXY_TEXTURE_RECTANGLE_NV;
  666.    case GL_TEXTURE_1D_ARRAY_EXT:
  667.    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
  668.       return GL_PROXY_TEXTURE_1D_ARRAY_EXT;
  669.    case GL_TEXTURE_2D_ARRAY_EXT:
  670.    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
  671.       return GL_PROXY_TEXTURE_2D_ARRAY_EXT;
  672.    default:
  673.       _mesa_problem(NULL, "unexpected target in get_proxy_target()");
  674.       return 0;
  675.    }
  676. }
  677.  
  678.  
  679. /**
  680.  * Get the texture object that corresponds to the target of the given
  681.  * texture unit.
  682.  *
  683.  * \param ctx GL context.
  684.  * \param texUnit texture unit.
  685.  * \param target texture target.
  686.  *
  687.  * \return pointer to the texture object on success, or NULL on failure.
  688.  *
  689.  * \sa gl_texture_unit.
  690.  */
  691. struct gl_texture_object *
  692. _mesa_select_tex_object(struct gl_context *ctx,
  693.                         const struct gl_texture_unit *texUnit,
  694.                         GLenum target)
  695. {
  696.    switch (target) {
  697.       case GL_TEXTURE_1D:
  698.          return texUnit->CurrentTex[TEXTURE_1D_INDEX];
  699.       case GL_PROXY_TEXTURE_1D:
  700.          return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
  701.       case GL_TEXTURE_2D:
  702.          return texUnit->CurrentTex[TEXTURE_2D_INDEX];
  703.       case GL_PROXY_TEXTURE_2D:
  704.          return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
  705.       case GL_TEXTURE_3D:
  706.          return texUnit->CurrentTex[TEXTURE_3D_INDEX];
  707.       case GL_PROXY_TEXTURE_3D:
  708.          return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
  709.       case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
  710.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
  711.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
  712.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
  713.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
  714.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
  715.       case GL_TEXTURE_CUBE_MAP_ARB:
  716.          return ctx->Extensions.ARB_texture_cube_map
  717.                 ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL;
  718.       case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
  719.          return ctx->Extensions.ARB_texture_cube_map
  720.                 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
  721.       case GL_TEXTURE_RECTANGLE_NV:
  722.          return ctx->Extensions.NV_texture_rectangle
  723.                 ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL;
  724.       case GL_PROXY_TEXTURE_RECTANGLE_NV:
  725.          return ctx->Extensions.NV_texture_rectangle
  726.                 ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
  727.       case GL_TEXTURE_1D_ARRAY_EXT:
  728.          return ctx->Extensions.MESA_texture_array
  729.                 ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
  730.       case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
  731.          return ctx->Extensions.MESA_texture_array
  732.                 ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
  733.       case GL_TEXTURE_2D_ARRAY_EXT:
  734.          return ctx->Extensions.MESA_texture_array
  735.                 ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
  736.       case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
  737.          return ctx->Extensions.MESA_texture_array
  738.                 ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
  739.       default:
  740.          _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
  741.          return NULL;
  742.    }
  743. }
  744.  
  745.  
  746. /**
  747.  * Return pointer to texture object for given target on current texture unit.
  748.  */
  749. struct gl_texture_object *
  750. _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target)
  751. {
  752.    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
  753.    return _mesa_select_tex_object(ctx, texUnit, target);
  754. }
  755.  
  756.  
  757. /**
  758.  * Get a texture image pointer from a texture object, given a texture
  759.  * target and mipmap level.  The target and level parameters should
  760.  * have already been error-checked.
  761.  *
  762.  * \param ctx GL context.
  763.  * \param texObj texture unit.
  764.  * \param target texture target.
  765.  * \param level image level.
  766.  *
  767.  * \return pointer to the texture image structure, or NULL on failure.
  768.  */
  769. struct gl_texture_image *
  770. _mesa_select_tex_image(struct gl_context *ctx,
  771.                        const struct gl_texture_object *texObj,
  772.                        GLenum target, GLint level)
  773. {
  774.    const GLuint face = _mesa_tex_target_to_face(target);
  775.  
  776.    ASSERT(texObj);
  777.    ASSERT(level >= 0);
  778.    ASSERT(level < MAX_TEXTURE_LEVELS);
  779.  
  780.    return texObj->Image[face][level];
  781. }
  782.  
  783.  
  784. /**
  785.  * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
  786.  * it and install it.  Only return NULL if passed a bad parameter or run
  787.  * out of memory.
  788.  */
  789. struct gl_texture_image *
  790. _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
  791.                     GLenum target, GLint level)
  792. {
  793.    struct gl_texture_image *texImage;
  794.  
  795.    if (!texObj)
  796.       return NULL;
  797.    
  798.    texImage = _mesa_select_tex_image(ctx, texObj, target, level);
  799.    if (!texImage) {
  800.       texImage = ctx->Driver.NewTextureImage(ctx);
  801.       if (!texImage) {
  802.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
  803.          return NULL;
  804.       }
  805.  
  806.       _mesa_set_tex_image(texObj, target, level, texImage);
  807.    }
  808.  
  809.    return texImage;
  810. }
  811.  
  812.  
  813. /**
  814.  * Return pointer to the specified proxy texture image.
  815.  * Note that proxy textures are per-context, not per-texture unit.
  816.  * \return pointer to texture image or NULL if invalid target, invalid
  817.  *         level, or out of memory.
  818.  */
  819. struct gl_texture_image *
  820. _mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
  821. {
  822.    struct gl_texture_image *texImage;
  823.    GLuint texIndex;
  824.  
  825.    if (level < 0 )
  826.       return NULL;
  827.  
  828.    switch (target) {
  829.    case GL_PROXY_TEXTURE_1D:
  830.       if (level >= ctx->Const.MaxTextureLevels)
  831.          return NULL;
  832.       texIndex = TEXTURE_1D_INDEX;
  833.       break;
  834.    case GL_PROXY_TEXTURE_2D:
  835.       if (level >= ctx->Const.MaxTextureLevels)
  836.          return NULL;
  837.       texIndex = TEXTURE_2D_INDEX;
  838.       break;
  839.    case GL_PROXY_TEXTURE_3D:
  840.       if (level >= ctx->Const.Max3DTextureLevels)
  841.          return NULL;
  842.       texIndex = TEXTURE_3D_INDEX;
  843.       break;
  844.    case GL_PROXY_TEXTURE_CUBE_MAP:
  845.       if (level >= ctx->Const.MaxCubeTextureLevels)
  846.          return NULL;
  847.       texIndex = TEXTURE_CUBE_INDEX;
  848.       break;
  849.    case GL_PROXY_TEXTURE_RECTANGLE_NV:
  850.       if (level > 0)
  851.          return NULL;
  852.       texIndex = TEXTURE_RECT_INDEX;
  853.       break;
  854.    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
  855.       if (level >= ctx->Const.MaxTextureLevels)
  856.          return NULL;
  857.       texIndex = TEXTURE_1D_ARRAY_INDEX;
  858.       break;
  859.    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
  860.       if (level >= ctx->Const.MaxTextureLevels)
  861.          return NULL;
  862.       texIndex = TEXTURE_2D_ARRAY_INDEX;
  863.       break;
  864.    default:
  865.       return NULL;
  866.    }
  867.  
  868.    texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level];
  869.    if (!texImage) {
  870.       texImage = ctx->Driver.NewTextureImage(ctx);
  871.       if (!texImage) {
  872.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
  873.          return NULL;
  874.       }
  875.       ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage;
  876.       /* Set the 'back' pointer */
  877.       texImage->TexObject = ctx->Texture.ProxyTex[texIndex];
  878.    }
  879.    return texImage;
  880. }
  881.  
  882.  
  883. /**
  884.  * Get the maximum number of allowed mipmap levels.
  885.  *
  886.  * \param ctx GL context.
  887.  * \param target texture target.
  888.  *
  889.  * \return the maximum number of allowed mipmap levels for the given
  890.  * texture target, or zero if passed a bad target.
  891.  *
  892.  * \sa gl_constants.
  893.  */
  894. GLint
  895. _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
  896. {
  897.    switch (target) {
  898.    case GL_TEXTURE_1D:
  899.    case GL_PROXY_TEXTURE_1D:
  900.    case GL_TEXTURE_2D:
  901.    case GL_PROXY_TEXTURE_2D:
  902.       return ctx->Const.MaxTextureLevels;
  903.    case GL_TEXTURE_3D:
  904.    case GL_PROXY_TEXTURE_3D:
  905.       return ctx->Const.Max3DTextureLevels;
  906.    case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
  907.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
  908.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
  909.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
  910.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
  911.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
  912.    case GL_TEXTURE_CUBE_MAP_ARB:
  913.    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
  914.       return ctx->Extensions.ARB_texture_cube_map
  915.          ? ctx->Const.MaxCubeTextureLevels : 0;
  916.    case GL_TEXTURE_RECTANGLE_NV:
  917.    case GL_PROXY_TEXTURE_RECTANGLE_NV:
  918.       return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
  919.    case GL_TEXTURE_1D_ARRAY_EXT:
  920.    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
  921.    case GL_TEXTURE_2D_ARRAY_EXT:
  922.    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
  923.       return ctx->Extensions.MESA_texture_array
  924.          ? ctx->Const.MaxTextureLevels : 0;
  925.    default:
  926.       return 0; /* bad target */
  927.    }
  928. }
  929.  
  930.  
  931. /**
  932.  * Return number of dimensions per mipmap level for the given texture target.
  933.  */
  934. static GLint
  935. get_texture_dimensions(GLenum target)
  936. {
  937.    switch (target) {
  938.    case GL_TEXTURE_1D:
  939.    case GL_PROXY_TEXTURE_1D:
  940.       return 1;
  941.    case GL_TEXTURE_2D:
  942.    case GL_TEXTURE_RECTANGLE:
  943.    case GL_TEXTURE_CUBE_MAP:
  944.    case GL_PROXY_TEXTURE_2D:
  945.    case GL_PROXY_TEXTURE_RECTANGLE:
  946.    case GL_PROXY_TEXTURE_CUBE_MAP:
  947.    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  948.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  949.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  950.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  951.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  952.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  953.    case GL_TEXTURE_1D_ARRAY:
  954.    case GL_PROXY_TEXTURE_1D_ARRAY:
  955.       return 2;
  956.    case GL_TEXTURE_3D:
  957.    case GL_PROXY_TEXTURE_3D:
  958.    case GL_TEXTURE_2D_ARRAY:
  959.    case GL_PROXY_TEXTURE_2D_ARRAY:
  960.       return 3;
  961.    default:
  962.       _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
  963.                     target);
  964.       return 2;
  965.    }
  966. }
  967.  
  968.  
  969.  
  970.  
  971. #if 000 /* not used anymore */
  972. /*
  973.  * glTexImage[123]D can accept a NULL image pointer.  In this case we
  974.  * create a texture image with unspecified image contents per the OpenGL
  975.  * spec.
  976.  */
  977. static GLubyte *
  978. make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
  979. {
  980.    const GLint components = _mesa_components_in_format(format);
  981.    const GLint numPixels = width * height * depth;
  982.    GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
  983.  
  984. #ifdef DEBUG
  985.    /*
  986.     * Let's see if anyone finds this.  If glTexImage2D() is called with
  987.     * a NULL image pointer then load the texture image with something
  988.     * interesting instead of leaving it indeterminate.
  989.     */
  990.    if (data) {
  991.       static const char message[8][32] = {
  992.          "   X   X  XXXXX   XXX     X    ",
  993.          "   XX XX  X      X   X   X X   ",
  994.          "   X X X  X      X      X   X  ",
  995.          "   X   X  XXXX    XXX   XXXXX  ",
  996.          "   X   X  X          X  X   X  ",
  997.          "   X   X  X      X   X  X   X  ",
  998.          "   X   X  XXXXX   XXX   X   X  ",
  999.          "                               "
  1000.       };
  1001.  
  1002.       GLubyte *imgPtr = data;
  1003.       GLint h, i, j, k;
  1004.       for (h = 0; h < depth; h++) {
  1005.          for (i = 0; i < height; i++) {
  1006.             GLint srcRow = 7 - (i % 8);
  1007.             for (j = 0; j < width; j++) {
  1008.                GLint srcCol = j % 32;
  1009.                GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
  1010.                for (k = 0; k < components; k++) {
  1011.                   *imgPtr++ = texel;
  1012.                }
  1013.             }
  1014.          }
  1015.       }
  1016.    }
  1017. #endif
  1018.  
  1019.    return data;
  1020. }
  1021. #endif
  1022.  
  1023.  
  1024.  
  1025. /**
  1026.  * Reset the fields of a gl_texture_image struct to zero.
  1027.  *
  1028.  * \param img texture image structure.
  1029.  *
  1030.  * This is called when a proxy texture test fails, we set all the
  1031.  * image members (except DriverData) to zero.
  1032.  * It's also used in glTexImage[123]D as a safeguard to be sure all
  1033.  * required fields get initialized properly by the Driver.TexImage[123]D
  1034.  * functions.
  1035.  */
  1036. static void
  1037. clear_teximage_fields(struct gl_texture_image *img)
  1038. {
  1039.    ASSERT(img);
  1040.    img->_BaseFormat = 0;
  1041.    img->InternalFormat = 0;
  1042.    img->Border = 0;
  1043.    img->Width = 0;
  1044.    img->Height = 0;
  1045.    img->Depth = 0;
  1046.    img->RowStride = 0;
  1047.    if (img->ImageOffsets) {
  1048.       free(img->ImageOffsets);
  1049.       img->ImageOffsets = NULL;
  1050.    }
  1051.    img->Width2 = 0;
  1052.    img->Height2 = 0;
  1053.    img->Depth2 = 0;
  1054.    img->WidthLog2 = 0;
  1055.    img->HeightLog2 = 0;
  1056.    img->DepthLog2 = 0;
  1057.    img->Data = NULL;
  1058.    img->TexFormat = MESA_FORMAT_NONE;
  1059.    img->FetchTexelc = NULL;
  1060.    img->FetchTexelf = NULL;
  1061. }
  1062.  
  1063.  
  1064. /**
  1065.  * Initialize basic fields of the gl_texture_image struct.
  1066.  *
  1067.  * \param ctx GL context.
  1068.  * \param target texture target (GL_TEXTURE_1D, GL_TEXTURE_RECTANGLE, etc).
  1069.  * \param img texture image structure to be initialized.
  1070.  * \param width image width.
  1071.  * \param height image height.
  1072.  * \param depth image depth.
  1073.  * \param border image border.
  1074.  * \param internalFormat internal format.
  1075.  * \param format  the actual hardware format (one of MESA_FORMAT_*)
  1076.  *
  1077.  * Fills in the fields of \p img with the given information.
  1078.  * Note: width, height and depth include the border.
  1079.  */
  1080. void
  1081. _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
  1082.                            struct gl_texture_image *img,
  1083.                            GLsizei width, GLsizei height, GLsizei depth,
  1084.                            GLint border, GLenum internalFormat,
  1085.                            gl_format format)
  1086. {
  1087.    GLint i, dims;
  1088.  
  1089.    ASSERT(img);
  1090.    ASSERT(width >= 0);
  1091.    ASSERT(height >= 0);
  1092.    ASSERT(depth >= 0);
  1093.  
  1094.    img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
  1095.    ASSERT(img->_BaseFormat > 0);
  1096.    img->InternalFormat = internalFormat;
  1097.    img->Border = border;
  1098.    img->Width = width;
  1099.    img->Height = height;
  1100.    img->Depth = depth;
  1101.  
  1102.    img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
  1103.    img->WidthLog2 = logbase2(img->Width2);
  1104.  
  1105.    if (height == 1) { /* 1-D texture */
  1106.       img->Height2 = 1;
  1107.       img->HeightLog2 = 0;
  1108.    }
  1109.    else {
  1110.       img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
  1111.       img->HeightLog2 = logbase2(img->Height2);
  1112.    }
  1113.  
  1114.    if (depth == 1) {  /* 2-D texture */
  1115.       img->Depth2 = 1;
  1116.       img->DepthLog2 = 0;
  1117.    }
  1118.    else {
  1119.       img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
  1120.       img->DepthLog2 = logbase2(img->Depth2);
  1121.    }
  1122.  
  1123.    img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
  1124.  
  1125.    if ((width == 1 || _mesa_is_pow_two(img->Width2)) &&
  1126.        (height == 1 || _mesa_is_pow_two(img->Height2)) &&
  1127.        (depth == 1 || _mesa_is_pow_two(img->Depth2)))
  1128.       img->_IsPowerOfTwo = GL_TRUE;
  1129.    else
  1130.       img->_IsPowerOfTwo = GL_FALSE;
  1131.  
  1132.    /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */
  1133.    img->RowStride = width;
  1134.    /* Allocate the ImageOffsets array and initialize to typical values.
  1135.     * We allocate the array for 1D/2D textures too in order to avoid special-
  1136.     * case code in the texstore routines.
  1137.     */
  1138.    if (img->ImageOffsets)
  1139.       free(img->ImageOffsets);
  1140.    img->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint));
  1141.    for (i = 0; i < depth; i++) {
  1142.       img->ImageOffsets[i] = i * width * height;
  1143.    }
  1144.  
  1145.    /* Compute Width/Height/DepthScale for mipmap lod computation */
  1146.    if (target == GL_TEXTURE_RECTANGLE_NV) {
  1147.       /* scale = 1.0 since texture coords directly map to texels */
  1148.       img->WidthScale = 1.0;
  1149.       img->HeightScale = 1.0;
  1150.       img->DepthScale = 1.0;
  1151.    }
  1152.    else {
  1153.       img->WidthScale = (GLfloat) img->Width;
  1154.       img->HeightScale = (GLfloat) img->Height;
  1155.       img->DepthScale = (GLfloat) img->Depth;
  1156.    }
  1157.  
  1158.    img->TexFormat = format;
  1159.  
  1160.    dims = get_texture_dimensions(target);
  1161.  
  1162.    _mesa_set_fetch_functions(img, dims);
  1163. }
  1164.  
  1165.  
  1166. /**
  1167.  * Free and clear fields of the gl_texture_image struct.
  1168.  *
  1169.  * \param ctx GL context.
  1170.  * \param texImage texture image structure to be cleared.
  1171.  *
  1172.  * After the call, \p texImage will have no data associated with it.  Its
  1173.  * fields are cleared so that its parent object will test incomplete.
  1174.  */
  1175. void
  1176. _mesa_clear_texture_image(struct gl_context *ctx,
  1177.                           struct gl_texture_image *texImage)
  1178. {
  1179.    ctx->Driver.FreeTexImageData(ctx, texImage);
  1180.    clear_teximage_fields(texImage);
  1181. }
  1182.  
  1183.  
  1184. /**
  1185.  * This is the fallback for Driver.TestProxyTexImage().  Test the texture
  1186.  * level, width, height and depth against the ctx->Const limits for textures.
  1187.  *
  1188.  * A hardware driver might override this function if, for example, the
  1189.  * max 3D texture size is 512x512x64 (i.e. not a cube).
  1190.  *
  1191.  * Note that width, height, depth == 0 is not an error.  However, a
  1192.  * texture with zero width/height/depth will be considered "incomplete"
  1193.  * and texturing will effectively be disabled.
  1194.  *
  1195.  * \param target  one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
  1196.  *                GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
  1197.  *                GL_PROXY_TEXTURE_CUBE_MAP_ARB.
  1198.  * \param level  as passed to glTexImage
  1199.  * \param internalFormat  as passed to glTexImage
  1200.  * \param format  as passed to glTexImage
  1201.  * \param type  as passed to glTexImage
  1202.  * \param width  as passed to glTexImage
  1203.  * \param height  as passed to glTexImage
  1204.  * \param depth  as passed to glTexImage
  1205.  * \param border  as passed to glTexImage
  1206.  * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
  1207.  */
  1208. GLboolean
  1209. _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
  1210.                           GLint internalFormat, GLenum format, GLenum type,
  1211.                           GLint width, GLint height, GLint depth, GLint border)
  1212. {
  1213.    GLint maxSize;
  1214.  
  1215.    (void) internalFormat;
  1216.    (void) format;
  1217.    (void) type;
  1218.  
  1219.    switch (target) {
  1220.    case GL_PROXY_TEXTURE_1D:
  1221.       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
  1222.       if (width < 2 * border || width > 2 + maxSize)
  1223.          return GL_FALSE;
  1224.       if (level >= ctx->Const.MaxTextureLevels)
  1225.          return GL_FALSE;
  1226.       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
  1227.          if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
  1228.             return GL_FALSE;
  1229.       }
  1230.       return GL_TRUE;
  1231.  
  1232.    case GL_PROXY_TEXTURE_2D:
  1233.       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
  1234.       if (width < 2 * border || width > 2 + maxSize)
  1235.          return GL_FALSE;
  1236.       if (height < 2 * border || height > 2 + maxSize)
  1237.          return GL_FALSE;
  1238.       if (level >= ctx->Const.MaxTextureLevels)
  1239.          return GL_FALSE;
  1240.       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
  1241.          if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
  1242.             return GL_FALSE;
  1243.          if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
  1244.             return GL_FALSE;
  1245.       }
  1246.       return GL_TRUE;
  1247.  
  1248.    case GL_PROXY_TEXTURE_3D:
  1249.       maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
  1250.       if (width < 2 * border || width > 2 + maxSize)
  1251.          return GL_FALSE;
  1252.       if (height < 2 * border || height > 2 + maxSize)
  1253.          return GL_FALSE;
  1254.       if (depth < 2 * border || depth > 2 + maxSize)
  1255.          return GL_FALSE;
  1256.       if (level >= ctx->Const.Max3DTextureLevels)
  1257.          return GL_FALSE;
  1258.       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
  1259.          if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
  1260.             return GL_FALSE;
  1261.          if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
  1262.             return GL_FALSE;
  1263.          if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border))
  1264.             return GL_FALSE;
  1265.       }
  1266.       return GL_TRUE;
  1267.  
  1268.    case GL_PROXY_TEXTURE_RECTANGLE_NV:
  1269.       maxSize = ctx->Const.MaxTextureRectSize;
  1270.       if (width < 0 || width > maxSize)
  1271.          return GL_FALSE;
  1272.       if (height < 0 || height > maxSize)
  1273.          return GL_FALSE;
  1274.       if (level != 0)
  1275.          return GL_FALSE;
  1276.       return GL_TRUE;
  1277.  
  1278.    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
  1279.       maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
  1280.       if (width < 2 * border || width > 2 + maxSize)
  1281.          return GL_FALSE;
  1282.       if (height < 2 * border || height > 2 + maxSize)
  1283.          return GL_FALSE;
  1284.       if (level >= ctx->Const.MaxCubeTextureLevels)
  1285.          return GL_FALSE;
  1286.       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
  1287.          if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
  1288.             return GL_FALSE;
  1289.          if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
  1290.             return GL_FALSE;
  1291.       }
  1292.       return GL_TRUE;
  1293.  
  1294.    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
  1295.       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
  1296.       if (width < 2 * border || width > 2 + maxSize)
  1297.          return GL_FALSE;
  1298.       if (height < 1 || height > ctx->Const.MaxArrayTextureLayers)
  1299.          return GL_FALSE;
  1300.       if (level >= ctx->Const.MaxTextureLevels)
  1301.          return GL_FALSE;
  1302.       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
  1303.          if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
  1304.             return GL_FALSE;
  1305.       }
  1306.       return GL_TRUE;
  1307.  
  1308.    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
  1309.       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
  1310.       if (width < 2 * border || width > 2 + maxSize)
  1311.          return GL_FALSE;
  1312.       if (height < 2 * border || height > 2 + maxSize)
  1313.          return GL_FALSE;
  1314.       if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers)
  1315.          return GL_FALSE;
  1316.       if (level >= ctx->Const.MaxTextureLevels)
  1317.          return GL_FALSE;
  1318.       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
  1319.          if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
  1320.             return GL_FALSE;
  1321.          if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
  1322.             return GL_FALSE;
  1323.       }
  1324.       return GL_TRUE;
  1325.  
  1326.    default:
  1327.       _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
  1328.       return GL_FALSE;
  1329.    }
  1330. }
  1331.  
  1332.  
  1333. /**
  1334.  * Check if the memory used by the texture would exceed the driver's limit.
  1335.  * This lets us support a max 3D texture size of 8K (for example) but
  1336.  * prevents allocating a full 8K x 8K x 8K texture.
  1337.  * XXX this could be rolled into the proxy texture size test (above) but
  1338.  * we don't have the actual texture internal format at that point.
  1339.  */
  1340. static GLboolean
  1341. legal_texture_size(struct gl_context *ctx, gl_format format,
  1342.                    GLint width, GLint height, GLint depth)
  1343. {
  1344.    uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
  1345.    uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
  1346.    return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
  1347. }
  1348.  
  1349.  
  1350.  
  1351. /**
  1352.  * Helper function to determine whether a target and specific compression
  1353.  * format are supported.
  1354.  */
  1355. static GLboolean
  1356. target_can_be_compressed(const struct gl_context *ctx, GLenum target,
  1357.                          GLenum intFormat)
  1358. {
  1359.    (void) intFormat;  /* not used yet */
  1360.  
  1361.    switch (target) {
  1362.    case GL_TEXTURE_2D:
  1363.    case GL_PROXY_TEXTURE_2D:
  1364.       return GL_TRUE; /* true for any compressed format so far */
  1365.    case GL_PROXY_TEXTURE_CUBE_MAP:
  1366.    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  1367.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  1368.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  1369.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  1370.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  1371.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  1372.       return ctx->Extensions.ARB_texture_cube_map;
  1373.    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
  1374.    case GL_TEXTURE_2D_ARRAY_EXT:
  1375.       return ctx->Extensions.MESA_texture_array;
  1376.    default:
  1377.       return GL_FALSE;
  1378.    }      
  1379. }
  1380.  
  1381.  
  1382. /**
  1383.  * Check if the given texture target value is legal for a
  1384.  * glTexImage1/2/3D call.
  1385.  */
  1386. static GLboolean
  1387. legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
  1388. {
  1389.    switch (dims) {
  1390.    case 1:
  1391.       switch (target) {
  1392.       case GL_TEXTURE_1D:
  1393.       case GL_PROXY_TEXTURE_1D:
  1394.          return GL_TRUE;
  1395.       default:
  1396.          return GL_FALSE;
  1397.       }
  1398.    case 2:
  1399.       switch (target) {
  1400.       case GL_TEXTURE_2D:
  1401.       case GL_PROXY_TEXTURE_2D:
  1402.          return GL_TRUE;
  1403.       case GL_PROXY_TEXTURE_CUBE_MAP:
  1404.       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  1405.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  1406.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  1407.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  1408.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  1409.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  1410.          return ctx->Extensions.ARB_texture_cube_map;
  1411.       case GL_TEXTURE_RECTANGLE_NV:
  1412.       case GL_PROXY_TEXTURE_RECTANGLE_NV:
  1413.          return ctx->Extensions.NV_texture_rectangle;
  1414.       case GL_TEXTURE_1D_ARRAY_EXT:
  1415.       case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
  1416.          return ctx->Extensions.MESA_texture_array;
  1417.       default:
  1418.          return GL_FALSE;
  1419.       }
  1420.    case 3:
  1421.       switch (target) {
  1422.       case GL_TEXTURE_3D:
  1423.       case GL_PROXY_TEXTURE_3D:
  1424.          return GL_TRUE;
  1425.       case GL_TEXTURE_2D_ARRAY_EXT:
  1426.       case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
  1427.          return ctx->Extensions.MESA_texture_array;
  1428.       default:
  1429.          return GL_FALSE;
  1430.       }
  1431.    default:
  1432.       _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
  1433.       return GL_FALSE;
  1434.    }
  1435. }
  1436.  
  1437.  
  1438. /**
  1439.  * Check if the given texture target value is legal for a
  1440.  * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
  1441.  * The difference compared to legal_teximage_target() above is that
  1442.  * proxy targets are not supported.
  1443.  */
  1444. static GLboolean
  1445. legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
  1446. {
  1447.    switch (dims) {
  1448.    case 1:
  1449.       return target == GL_TEXTURE_1D;
  1450.    case 2:
  1451.       switch (target) {
  1452.       case GL_TEXTURE_2D:
  1453.          return GL_TRUE;
  1454.       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  1455.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  1456.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  1457.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  1458.       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  1459.       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  1460.          return ctx->Extensions.ARB_texture_cube_map;
  1461.       case GL_TEXTURE_RECTANGLE_NV:
  1462.          return ctx->Extensions.NV_texture_rectangle;
  1463.       case GL_TEXTURE_1D_ARRAY_EXT:
  1464.          return ctx->Extensions.MESA_texture_array;
  1465.       default:
  1466.          return GL_FALSE;
  1467.       }
  1468.    case 3:
  1469.       switch (target) {
  1470.       case GL_TEXTURE_3D:
  1471.          return GL_TRUE;
  1472.       case GL_TEXTURE_2D_ARRAY_EXT:
  1473.          return ctx->Extensions.MESA_texture_array;
  1474.       default:
  1475.          return GL_FALSE;
  1476.       }
  1477.    default:
  1478.       _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
  1479.                     dims);
  1480.       return GL_FALSE;
  1481.    }
  1482. }
  1483.  
  1484.  
  1485. /**
  1486.  * Test the glTexImage[123]D() parameters for errors.
  1487.  *
  1488.  * \param ctx GL context.
  1489.  * \param dimensions texture image dimensions (must be 1, 2 or 3).
  1490.  * \param target texture target given by the user.
  1491.  * \param level image level given by the user.
  1492.  * \param internalFormat internal format given by the user.
  1493.  * \param format pixel data format given by the user.
  1494.  * \param type pixel data type given by the user.
  1495.  * \param width image width given by the user.
  1496.  * \param height image height given by the user.
  1497.  * \param depth image depth given by the user.
  1498.  * \param border image border given by the user.
  1499.  *
  1500.  * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
  1501.  *
  1502.  * Verifies each of the parameters against the constants specified in
  1503.  * __struct gl_contextRec::Const and the supported extensions, and according
  1504.  * to the OpenGL specification.
  1505.  */
  1506. static GLboolean
  1507. texture_error_check( struct gl_context *ctx,
  1508.                      GLuint dimensions, GLenum target,
  1509.                      GLint level, GLint internalFormat,
  1510.                      GLenum format, GLenum type,
  1511.                      GLint width, GLint height,
  1512.                      GLint depth, GLint border )
  1513. {
  1514.    const GLenum proxyTarget = get_proxy_target(target);
  1515.    const GLboolean isProxy = target == proxyTarget;
  1516.    GLboolean sizeOK = GL_TRUE;
  1517.    GLboolean colorFormat, indexFormat;
  1518.  
  1519.    /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
  1520.    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
  1521.       if (!isProxy) {
  1522.          _mesa_error(ctx, GL_INVALID_VALUE,
  1523.                      "glTexImage%dD(level=%d)", dimensions, level);
  1524.       }
  1525.       return GL_TRUE;
  1526.    }
  1527.  
  1528.    /* Check border */
  1529.    if (border < 0 || border > 1 ||
  1530.        ((target == GL_TEXTURE_RECTANGLE_NV ||
  1531.          target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
  1532.       if (!isProxy) {
  1533.          _mesa_error(ctx, GL_INVALID_VALUE,
  1534.                      "glTexImage%dD(border=%d)", dimensions, border);
  1535.       }
  1536.       return GL_TRUE;
  1537.    }
  1538.  
  1539.    if (width < 0 || height < 0 || depth < 0) {
  1540.       if (!isProxy) {
  1541.          _mesa_error(ctx, GL_INVALID_VALUE,
  1542.                      "glTexImage%dD(width, height or depth < 0)", dimensions);
  1543.       }
  1544.       return GL_TRUE;
  1545.    }
  1546.  
  1547.    /* Do this simple check before calling the TestProxyTexImage() function */
  1548.    if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
  1549.       sizeOK = (width == height);
  1550.    }
  1551.  
  1552.    /*
  1553.     * Use the proxy texture driver hook to see if the size/level/etc are
  1554.     * legal.
  1555.     */
  1556.    sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
  1557.                                                     internalFormat, format,
  1558.                                                     type, width, height,
  1559.                                                     depth, border);
  1560.    if (!sizeOK) {
  1561.       if (!isProxy) {
  1562.          _mesa_error(ctx, GL_INVALID_VALUE,
  1563.                      "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
  1564.                      dimensions, level, width, height, depth);
  1565.       }
  1566.       return GL_TRUE;
  1567.    }
  1568.  
  1569.    /* Check internalFormat */
  1570.    if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
  1571.       if (!isProxy) {
  1572.          _mesa_error(ctx, GL_INVALID_VALUE,
  1573.                      "glTexImage%dD(internalFormat=%s)",
  1574.                      dimensions, _mesa_lookup_enum_by_nr(internalFormat));
  1575.       }
  1576.       return GL_TRUE;
  1577.    }
  1578.  
  1579.    /* Check incoming image format and type */
  1580.    if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
  1581.       /* Normally, GL_INVALID_OPERATION is generated by a format/type
  1582.        * mismatch (see the 1.2 spec page 94, sec 3.6.4.).  But with the
  1583.        * GL_EXT_texture_integer extension, some combinations should generate
  1584.        * GL_INVALID_ENUM instead (grr!).
  1585.        */
  1586.       if (!isProxy) {
  1587.          GLenum error = _mesa_is_integer_format(format)
  1588.             ? GL_INVALID_ENUM : GL_INVALID_OPERATION;
  1589.          _mesa_error(ctx, error,
  1590.                      "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
  1591.                      dimensions, format, type);
  1592.       }
  1593.       return GL_TRUE;
  1594.    }
  1595.  
  1596.    /* make sure internal format and format basically agree */
  1597.    colorFormat = _mesa_is_color_format(format);
  1598.    indexFormat = _mesa_is_index_format(format);
  1599.    if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
  1600.        (_mesa_is_index_format(internalFormat) && !indexFormat) ||
  1601.        (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
  1602.        (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
  1603.        (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
  1604.        (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
  1605.       if (!isProxy)
  1606.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1607.                      "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
  1608.                      dimensions, internalFormat, format);
  1609.       return GL_TRUE;
  1610.    }
  1611.  
  1612.    /* additional checks for ycbcr textures */
  1613.    if (internalFormat == GL_YCBCR_MESA) {
  1614.       ASSERT(ctx->Extensions.MESA_ycbcr_texture);
  1615.       if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
  1616.           type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
  1617.          char message[100];
  1618.          _mesa_snprintf(message, sizeof(message),
  1619.                         "glTexImage%dD(format/type YCBCR mismatch", dimensions);
  1620.          _mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
  1621.          return GL_TRUE; /* error */
  1622.       }
  1623.       if (target != GL_TEXTURE_2D &&
  1624.           target != GL_PROXY_TEXTURE_2D &&
  1625.           target != GL_TEXTURE_RECTANGLE_NV &&
  1626.           target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
  1627.          if (!isProxy)
  1628.             _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
  1629.          return GL_TRUE;
  1630.       }
  1631.       if (border != 0) {
  1632.          if (!isProxy) {
  1633.             char message[100];
  1634.             _mesa_snprintf(message, sizeof(message),
  1635.                            "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
  1636.                            dimensions, border);
  1637.             _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
  1638.          }
  1639.          return GL_TRUE;
  1640.       }
  1641.    }
  1642.  
  1643.    /* additional checks for depth textures */
  1644.    if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
  1645.       /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */
  1646.       if (target != GL_TEXTURE_1D &&
  1647.           target != GL_PROXY_TEXTURE_1D &&
  1648.           target != GL_TEXTURE_2D &&
  1649.           target != GL_PROXY_TEXTURE_2D &&
  1650.           target != GL_TEXTURE_RECTANGLE_ARB &&
  1651.           target != GL_PROXY_TEXTURE_RECTANGLE_ARB) {
  1652.          if (!isProxy)
  1653.             _mesa_error(ctx, GL_INVALID_ENUM,
  1654.                         "glTexImage(target/internalFormat)");
  1655.          return GL_TRUE;
  1656.       }
  1657.    }
  1658.  
  1659.    /* additional checks for compressed textures */
  1660.    if (_mesa_is_compressed_format(ctx, internalFormat)) {
  1661.       if (!target_can_be_compressed(ctx, target, internalFormat)) {
  1662.          if (!isProxy)
  1663.             _mesa_error(ctx, GL_INVALID_ENUM,
  1664.                         "glTexImage%dD(target)", dimensions);
  1665.          return GL_TRUE;
  1666.       }
  1667.       if (border != 0) {
  1668.          if (!isProxy) {
  1669.             _mesa_error(ctx, GL_INVALID_OPERATION,
  1670.                         "glTexImage%dD(border!=0)", dimensions);
  1671.          }
  1672.          return GL_TRUE;
  1673.       }
  1674.    }
  1675.  
  1676.    /* additional checks for integer textures */
  1677.    if (ctx->Extensions.EXT_texture_integer &&
  1678.        (_mesa_is_integer_format(format) !=
  1679.         _mesa_is_integer_format(internalFormat))) {
  1680.       if (!isProxy) {
  1681.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1682.                      "glTexImage%dD(integer/non-integer format mismatch)",
  1683.                      dimensions);
  1684.       }
  1685.       return GL_TRUE;
  1686.    }
  1687.  
  1688.    /* if we get here, the parameters are OK */
  1689.    return GL_FALSE;
  1690. }
  1691.  
  1692.  
  1693. /**
  1694.  * Test glTexSubImage[123]D() parameters for errors.
  1695.  *
  1696.  * \param ctx GL context.
  1697.  * \param dimensions texture image dimensions (must be 1, 2 or 3).
  1698.  * \param target texture target given by the user.
  1699.  * \param level image level given by the user.
  1700.  * \param xoffset sub-image x offset given by the user.
  1701.  * \param yoffset sub-image y offset given by the user.
  1702.  * \param zoffset sub-image z offset given by the user.
  1703.  * \param format pixel data format given by the user.
  1704.  * \param type pixel data type given by the user.
  1705.  * \param width image width given by the user.
  1706.  * \param height image height given by the user.
  1707.  * \param depth image depth given by the user.
  1708.  *
  1709.  * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
  1710.  *
  1711.  * Verifies each of the parameters against the constants specified in
  1712.  * __struct gl_contextRec::Const and the supported extensions, and according
  1713.  * to the OpenGL specification.
  1714.  */
  1715. static GLboolean
  1716. subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
  1717.                         GLenum target, GLint level,
  1718.                         GLint xoffset, GLint yoffset, GLint zoffset,
  1719.                         GLint width, GLint height, GLint depth,
  1720.                         GLenum format, GLenum type )
  1721. {
  1722.    /* Basic level check */
  1723.    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
  1724.       _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
  1725.       return GL_TRUE;
  1726.    }
  1727.  
  1728.    /* Check for negative sizes */
  1729.    if (width < 0) {
  1730.       _mesa_error(ctx, GL_INVALID_VALUE,
  1731.                   "glTexSubImage%dD(width=%d)", dimensions, width);
  1732.       return GL_TRUE;
  1733.    }
  1734.    if (height < 0 && dimensions > 1) {
  1735.       _mesa_error(ctx, GL_INVALID_VALUE,
  1736.                   "glTexSubImage%dD(height=%d)", dimensions, height);
  1737.       return GL_TRUE;
  1738.    }
  1739.    if (depth < 0 && dimensions > 2) {
  1740.       _mesa_error(ctx, GL_INVALID_VALUE,
  1741.                   "glTexSubImage%dD(depth=%d)", dimensions, depth);
  1742.       return GL_TRUE;
  1743.    }
  1744.  
  1745.    if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
  1746.       /* As with the glTexImage2D check above, the error code here
  1747.        * depends on texture integer.
  1748.        */
  1749.       GLenum error = _mesa_is_integer_format(format)
  1750.          ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
  1751.       _mesa_error(ctx, error,
  1752.                   "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)",
  1753.                   dimensions, format, type);
  1754.       return GL_TRUE;
  1755.    }
  1756.  
  1757.    return GL_FALSE;
  1758. }
  1759.  
  1760.  
  1761. /**
  1762.  * Do second part of glTexSubImage which depends on the destination texture.
  1763.  * \return GL_TRUE if error recorded, GL_FALSE otherwise
  1764.  */
  1765. static GLboolean
  1766. subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
  1767.                          GLenum target, GLint level,
  1768.                          GLint xoffset, GLint yoffset, GLint zoffset,
  1769.                          GLint width, GLint height, GLint depth,
  1770.                          GLenum format, GLenum type,
  1771.                          const struct gl_texture_image *destTex )
  1772. {
  1773.    if (!destTex) {
  1774.       /* undefined image level */
  1775.       _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
  1776.       return GL_TRUE;
  1777.    }
  1778.  
  1779.    if (xoffset < -((GLint)destTex->Border)) {
  1780.       _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
  1781.                   dimensions);
  1782.       return GL_TRUE;
  1783.    }
  1784.    if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
  1785.       _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
  1786.                   dimensions);
  1787.       return GL_TRUE;
  1788.    }
  1789.    if (dimensions > 1) {
  1790.       if (yoffset < -((GLint)destTex->Border)) {
  1791.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
  1792.                      dimensions);
  1793.          return GL_TRUE;
  1794.       }
  1795.       if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
  1796.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
  1797.                      dimensions);
  1798.          return GL_TRUE;
  1799.       }
  1800.    }
  1801.    if (dimensions > 2) {
  1802.       if (zoffset < -((GLint)destTex->Border)) {
  1803.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
  1804.          return GL_TRUE;
  1805.       }
  1806.       if (zoffset + depth  > (GLint) (destTex->Depth + destTex->Border)) {
  1807.          _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
  1808.          return GL_TRUE;
  1809.       }
  1810.    }
  1811.  
  1812.    if (_mesa_is_format_compressed(destTex->TexFormat)) {
  1813.       GLuint bw, bh;
  1814.  
  1815.       /* do tests which depend on compression block size */
  1816.       _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh);
  1817.  
  1818.       /* offset must be multiple of block size */
  1819.       if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
  1820.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1821.                      "glTexSubImage%dD(xoffset = %d, yoffset = %d)",
  1822.                      dimensions, xoffset, yoffset);
  1823.          return GL_TRUE;
  1824.       }
  1825.       /* size must be multiple of bw by bh or equal to whole texture size */
  1826.       if ((width % bw != 0) && (GLuint) width != destTex->Width) {
  1827.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1828.                      "glTexSubImage%dD(width = %d)", dimensions, width);
  1829.          return GL_TRUE;
  1830.       }        
  1831.       if ((height % bh != 0) && (GLuint) height != destTex->Height) {
  1832.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1833.                      "glTexSubImage%dD(height = %d)", dimensions, height);
  1834.          return GL_TRUE;
  1835.       }        
  1836.    }
  1837.  
  1838.    return GL_FALSE;
  1839. }
  1840.  
  1841.  
  1842. /**
  1843.  * Test glCopyTexImage[12]D() parameters for errors.
  1844.  *
  1845.  * \param ctx GL context.
  1846.  * \param dimensions texture image dimensions (must be 1, 2 or 3).
  1847.  * \param target texture target given by the user.
  1848.  * \param level image level given by the user.
  1849.  * \param internalFormat internal format given by the user.
  1850.  * \param width image width given by the user.
  1851.  * \param height image height given by the user.
  1852.  * \param border texture border.
  1853.  *
  1854.  * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
  1855.  *
  1856.  * Verifies each of the parameters against the constants specified in
  1857.  * __struct gl_contextRec::Const and the supported extensions, and according
  1858.  * to the OpenGL specification.
  1859.  */
  1860. static GLboolean
  1861. copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
  1862.                          GLenum target, GLint level, GLint internalFormat,
  1863.                          GLint width, GLint height, GLint border )
  1864. {
  1865.    const GLenum proxyTarget = get_proxy_target(target);
  1866.    const GLenum type = GL_FLOAT;
  1867.    GLboolean sizeOK;
  1868.    GLint format;
  1869.  
  1870.    /* check target */
  1871.    if (!legal_texsubimage_target(ctx, dimensions, target)) {
  1872.       _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
  1873.                   dimensions, _mesa_lookup_enum_by_nr(target));
  1874.       return GL_TRUE;
  1875.    }      
  1876.  
  1877.    /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
  1878.    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
  1879.       _mesa_error(ctx, GL_INVALID_VALUE,
  1880.                   "glCopyTexImage%dD(level=%d)", dimensions, level);
  1881.       return GL_TRUE;
  1882.    }
  1883.  
  1884.    /* Check that the source buffer is complete */
  1885.    if (ctx->ReadBuffer->Name) {
  1886.       _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
  1887.       if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  1888.          _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
  1889.                      "glCopyTexImage%dD(invalid readbuffer)", dimensions);
  1890.          return GL_TRUE;
  1891.       }
  1892.    }
  1893.  
  1894.    /* Check border */
  1895.    if (border < 0 || border > 1 ||
  1896.        ((target == GL_TEXTURE_RECTANGLE_NV ||
  1897.          target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
  1898.       return GL_TRUE;
  1899.    }
  1900.  
  1901.    format = _mesa_base_tex_format(ctx, internalFormat);
  1902.    if (format < 0) {
  1903.       _mesa_error(ctx, GL_INVALID_VALUE,
  1904.                   "glCopyTexImage%dD(internalFormat)", dimensions);
  1905.       return GL_TRUE;
  1906.    }
  1907.  
  1908.    if (!_mesa_source_buffer_exists(ctx, format)) {
  1909.       _mesa_error(ctx, GL_INVALID_OPERATION,
  1910.                   "glCopyTexImage%dD(missing readbuffer)", dimensions);
  1911.       return GL_TRUE;
  1912.    }
  1913.  
  1914.    /* Do size, level checking */
  1915.    sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
  1916.       ? (width == height) : 1;
  1917.  
  1918.    sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
  1919.                                                     internalFormat, format,
  1920.                                                     type, width, height,
  1921.                                                     1, border);
  1922.  
  1923.    if (!sizeOK) {
  1924.       if (dimensions == 1) {
  1925.          _mesa_error(ctx, GL_INVALID_VALUE,
  1926.                      "glCopyTexImage1D(width=%d)", width);
  1927.       }
  1928.       else {
  1929.          ASSERT(dimensions == 2);
  1930.          _mesa_error(ctx, GL_INVALID_VALUE,
  1931.                      "glCopyTexImage2D(width=%d, height=%d)", width, height);
  1932.       }
  1933.       return GL_TRUE;
  1934.    }
  1935.  
  1936.    if (_mesa_is_compressed_format(ctx, internalFormat)) {
  1937.       if (!target_can_be_compressed(ctx, target, internalFormat)) {
  1938.          _mesa_error(ctx, GL_INVALID_ENUM,
  1939.                      "glCopyTexImage%dD(target)", dimensions);
  1940.          return GL_TRUE;
  1941.       }
  1942.       if (border != 0) {
  1943.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1944.                      "glCopyTexImage%dD(border!=0)", dimensions);
  1945.          return GL_TRUE;
  1946.       }
  1947.    }
  1948.    else if (_mesa_is_depth_format(internalFormat)) {
  1949.       /* make sure we have depth/stencil buffers */
  1950.       if (!ctx->ReadBuffer->_DepthBuffer) {
  1951.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1952.                      "glCopyTexImage%dD(no depth)", dimensions);
  1953.          return GL_TRUE;
  1954.       }
  1955.    }
  1956.    else if (_mesa_is_depthstencil_format(internalFormat)) {
  1957.       /* make sure we have depth/stencil buffers */
  1958.       if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
  1959.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1960.                      "glCopyTexImage%dD(no depth/stencil buffer)", dimensions);
  1961.          return GL_TRUE;
  1962.       }
  1963.    }
  1964.  
  1965.    /* if we get here, the parameters are OK */
  1966.    return GL_FALSE;
  1967. }
  1968.  
  1969.  
  1970. /**
  1971.  * Test glCopyTexSubImage[12]D() parameters for errors.
  1972.  * Note that this is the first part of error checking.
  1973.  * See also copytexsubimage_error_check2() below for the second part.
  1974.  *
  1975.  * \param ctx GL context.
  1976.  * \param dimensions texture image dimensions (must be 1, 2 or 3).
  1977.  * \param target texture target given by the user.
  1978.  * \param level image level given by the user.
  1979.  *
  1980.  * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
  1981.  */
  1982. static GLboolean
  1983. copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
  1984.                               GLenum target, GLint level)
  1985. {
  1986.    /* Check that the source buffer is complete */
  1987.    if (ctx->ReadBuffer->Name) {
  1988.       _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
  1989.       if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  1990.          _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
  1991.                      "glCopyTexImage%dD(invalid readbuffer)", dimensions);
  1992.          return GL_TRUE;
  1993.       }
  1994.    }
  1995.  
  1996.    /* check target (proxies not allowed) */
  1997.    if (!legal_texsubimage_target(ctx, dimensions, target)) {
  1998.       _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
  1999.                   dimensions, _mesa_lookup_enum_by_nr(target));
  2000.       return GL_TRUE;
  2001.    }
  2002.  
  2003.    /* Check level */
  2004.    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
  2005.       _mesa_error(ctx, GL_INVALID_VALUE,
  2006.                   "glCopyTexSubImage%dD(level=%d)", dimensions, level);
  2007.       return GL_TRUE;
  2008.    }
  2009.  
  2010.    return GL_FALSE;
  2011. }
  2012.  
  2013.  
  2014. /**
  2015.  * Second part of error checking for glCopyTexSubImage[12]D().
  2016.  * \param xoffset sub-image x offset given by the user.
  2017.  * \param yoffset sub-image y offset given by the user.
  2018.  * \param zoffset sub-image z offset given by the user.
  2019.  * \param width image width given by the user.
  2020.  * \param height image height given by the user.
  2021.  */
  2022. static GLboolean
  2023. copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
  2024.                               GLenum target, GLint level,
  2025.                               GLint xoffset, GLint yoffset, GLint zoffset,
  2026.                               GLsizei width, GLsizei height,
  2027.                               const struct gl_texture_image *teximage )
  2028. {
  2029.    /* check that dest tex image exists */
  2030.    if (!teximage) {
  2031.       _mesa_error(ctx, GL_INVALID_OPERATION,
  2032.                   "glCopyTexSubImage%dD(undefined texture level: %d)",
  2033.                   dimensions, level);
  2034.       return GL_TRUE;
  2035.    }
  2036.  
  2037.    /* Check size */
  2038.    if (width < 0) {
  2039.       _mesa_error(ctx, GL_INVALID_VALUE,
  2040.                   "glCopyTexSubImage%dD(width=%d)", dimensions, width);
  2041.       return GL_TRUE;
  2042.    }
  2043.    if (dimensions > 1 && height < 0) {
  2044.       _mesa_error(ctx, GL_INVALID_VALUE,
  2045.                   "glCopyTexSubImage%dD(height=%d)", dimensions, height);
  2046.       return GL_TRUE;
  2047.    }
  2048.  
  2049.    /* check x/y offsets */
  2050.    if (xoffset < -((GLint)teximage->Border)) {
  2051.       _mesa_error(ctx, GL_INVALID_VALUE,
  2052.                   "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
  2053.       return GL_TRUE;
  2054.    }
  2055.    if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
  2056.       _mesa_error(ctx, GL_INVALID_VALUE,
  2057.                   "glCopyTexSubImage%dD(xoffset+width)", dimensions);
  2058.       return GL_TRUE;
  2059.    }
  2060.    if (dimensions > 1) {
  2061.       if (yoffset < -((GLint)teximage->Border)) {
  2062.          _mesa_error(ctx, GL_INVALID_VALUE,
  2063.                      "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
  2064.          return GL_TRUE;
  2065.       }
  2066.       /* NOTE: we're adding the border here, not subtracting! */
  2067.       if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) {
  2068.          _mesa_error(ctx, GL_INVALID_VALUE,
  2069.                      "glCopyTexSubImage%dD(yoffset+height)", dimensions);
  2070.          return GL_TRUE;
  2071.       }
  2072.    }
  2073.  
  2074.    /* check z offset */
  2075.    if (dimensions > 2) {
  2076.       if (zoffset < -((GLint)teximage->Border)) {
  2077.          _mesa_error(ctx, GL_INVALID_VALUE,
  2078.                      "glCopyTexSubImage%dD(zoffset)", dimensions);
  2079.          return GL_TRUE;
  2080.       }
  2081.       if (zoffset > (GLint) (teximage->Depth + teximage->Border)) {
  2082.          _mesa_error(ctx, GL_INVALID_VALUE,
  2083.                      "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
  2084.          return GL_TRUE;
  2085.       }
  2086.    }
  2087.  
  2088.    if (_mesa_is_format_compressed(teximage->TexFormat)) {
  2089.       /* offset must be multiple of 4 */
  2090.       if ((xoffset & 3) || (yoffset & 3)) {
  2091.          _mesa_error(ctx, GL_INVALID_VALUE,
  2092.                      "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions);
  2093.          return GL_TRUE;
  2094.       }
  2095.       /* size must be multiple of 4 */
  2096.       if ((width & 3) != 0 && (GLuint) width != teximage->Width) {
  2097.          _mesa_error(ctx, GL_INVALID_VALUE,
  2098.                      "glCopyTexSubImage%dD(width)", dimensions);
  2099.          return GL_TRUE;
  2100.       }        
  2101.       if ((height & 3) != 0 && (GLuint) height != teximage->Height) {
  2102.          _mesa_error(ctx, GL_INVALID_VALUE,
  2103.                      "glCopyTexSubImage%dD(height)", dimensions);
  2104.          return GL_TRUE;
  2105.       }        
  2106.    }
  2107.  
  2108.    if (teximage->InternalFormat == GL_YCBCR_MESA) {
  2109.       _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
  2110.       return GL_TRUE;
  2111.    }
  2112.  
  2113.    if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
  2114.       _mesa_error(ctx, GL_INVALID_OPERATION,
  2115.                   "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)",
  2116.                   dimensions, teximage->_BaseFormat);
  2117.       return GL_TRUE;
  2118.    }
  2119.  
  2120.    if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) {
  2121.       if (!ctx->ReadBuffer->_DepthBuffer) {
  2122.          _mesa_error(ctx, GL_INVALID_OPERATION,
  2123.                      "glCopyTexSubImage%dD(no depth buffer)",
  2124.                      dimensions);
  2125.          return GL_TRUE;
  2126.       }
  2127.    }
  2128.    else if (teximage->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
  2129.       if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
  2130.          _mesa_error(ctx, GL_INVALID_OPERATION,
  2131.                      "glCopyTexSubImage%dD(no depth/stencil buffer)",
  2132.                      dimensions);
  2133.          return GL_TRUE;
  2134.       }
  2135.    }
  2136.  
  2137.    /* If copying into an integer texture, the source buffer must also be
  2138.     * integer-valued.
  2139.     */
  2140.    if (_mesa_is_format_integer_color(teximage->TexFormat)) {
  2141.       struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
  2142.       if (!_mesa_is_format_integer_color(rb->Format)) {
  2143.          _mesa_error(ctx, GL_INVALID_OPERATION,
  2144.                   "glCopyTexSubImage%dD(source buffer is not integer format)",
  2145.                   dimensions);
  2146.          return GL_TRUE;
  2147.       }
  2148.    }
  2149.  
  2150.    /* if we get here, the parameters are OK */
  2151.    return GL_FALSE;
  2152. }
  2153.  
  2154.  
  2155. /** Callback info for walking over FBO hash table */
  2156. struct cb_info
  2157. {
  2158.    struct gl_context *ctx;
  2159.    struct gl_texture_object *texObj;
  2160.    GLuint level, face;
  2161. };
  2162.  
  2163.  
  2164. /**
  2165.  * Check render to texture callback.  Called from _mesa_HashWalk().
  2166.  */
  2167. static void
  2168. check_rtt_cb(GLuint key, void *data, void *userData)
  2169. {
  2170.    struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
  2171.    const struct cb_info *info = (struct cb_info *) userData;
  2172.    struct gl_context *ctx = info->ctx;
  2173.    const struct gl_texture_object *texObj = info->texObj;
  2174.    const GLuint level = info->level, face = info->face;
  2175.  
  2176.    /* If this is a user-created FBO */
  2177.    if (fb->Name) {
  2178.       GLuint i;
  2179.       /* check if any of the FBO's attachments point to 'texObj' */
  2180.       for (i = 0; i < BUFFER_COUNT; i++) {
  2181.          struct gl_renderbuffer_attachment *att = fb->Attachment + i;
  2182.          if (att->Type == GL_TEXTURE &&
  2183.              att->Texture == texObj &&
  2184.              att->TextureLevel == level &&
  2185.              att->CubeMapFace == face) {
  2186.             ASSERT(att->Texture->Image[att->CubeMapFace][att->TextureLevel]);
  2187.             /* Tell driver about the new renderbuffer texture */
  2188.             ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
  2189.             /* Mark fb status as indeterminate to force re-validation */
  2190.             fb->_Status = 0;
  2191.          }
  2192.       }
  2193.    }
  2194. }
  2195.  
  2196.  
  2197. /**
  2198.  * When a texture image is specified we have to check if it's bound to
  2199.  * any framebuffer objects (render to texture) in order to detect changes
  2200.  * in size or format since that effects FBO completeness.
  2201.  * Any FBOs rendering into the texture must be re-validated.
  2202.  */
  2203. static void
  2204. update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj,
  2205.                    GLuint face, GLuint level)
  2206. {
  2207.    /* Only check this texture if it's been marked as RenderToTexture */
  2208.    if (texObj->_RenderToTexture) {
  2209.       struct cb_info info;
  2210.       info.ctx = ctx;
  2211.       info.texObj = texObj;
  2212.       info.level = level;
  2213.       info.face = face;
  2214.       _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info);
  2215.    }
  2216. }
  2217.  
  2218.  
  2219. /**
  2220.  * If the texture object's GenerateMipmap flag is set and we've
  2221.  * changed the texture base level image, regenerate the rest of the
  2222.  * mipmap levels now.
  2223.  */
  2224. static INLINE void
  2225. check_gen_mipmap(struct gl_context *ctx, GLenum target,
  2226.                  struct gl_texture_object *texObj, GLint level)
  2227. {
  2228.    ASSERT(target != GL_TEXTURE_CUBE_MAP);
  2229.    if (texObj->GenerateMipmap &&
  2230.        level == texObj->BaseLevel &&
  2231.        level < texObj->MaxLevel) {
  2232.       ASSERT(ctx->Driver.GenerateMipmap);
  2233.       ctx->Driver.GenerateMipmap(ctx, target, texObj);
  2234.    }
  2235. }
  2236.  
  2237.  
  2238. /** Debug helper: override the user-requested internal format */
  2239. static GLenum
  2240. override_internal_format(GLenum internalFormat, GLint width, GLint height)
  2241. {
  2242. #if 0
  2243.    if (internalFormat == GL_RGBA16F_ARB ||
  2244.        internalFormat == GL_RGBA32F_ARB) {
  2245.       printf("Convert rgba float tex to int %d x %d\n", width, height);
  2246.       return GL_RGBA;
  2247.    }
  2248.    else if (internalFormat == GL_RGB16F_ARB ||
  2249.             internalFormat == GL_RGB32F_ARB) {
  2250.       printf("Convert rgb float tex to int %d x %d\n", width, height);
  2251.       return GL_RGB;
  2252.    }
  2253.    else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB ||
  2254.             internalFormat == GL_LUMINANCE_ALPHA32F_ARB) {
  2255.       printf("Convert luminance float tex to int %d x %d\n", width, height);
  2256.       return GL_LUMINANCE_ALPHA;
  2257.    }
  2258.    else if (internalFormat == GL_LUMINANCE16F_ARB ||
  2259.             internalFormat == GL_LUMINANCE32F_ARB) {
  2260.       printf("Convert luminance float tex to int %d x %d\n", width, height);
  2261.       return GL_LUMINANCE;
  2262.    }
  2263.    else if (internalFormat == GL_ALPHA16F_ARB ||
  2264.             internalFormat == GL_ALPHA32F_ARB) {
  2265.       printf("Convert luminance float tex to int %d x %d\n", width, height);
  2266.       return GL_ALPHA;
  2267.    }
  2268.    /*
  2269.    else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
  2270.       internalFormat = GL_RGBA;
  2271.    }
  2272.    */
  2273.    else {
  2274.       return internalFormat;
  2275.    }
  2276. #else
  2277.    return internalFormat;
  2278. #endif
  2279. }
  2280.  
  2281.  
  2282. /**
  2283.  * Choose the actual hardware format for a texture image.
  2284.  * Try to use the same format as the previous image level when possible.
  2285.  * Otherwise, ask the driver for the best format.
  2286.  * It's important to try to choose a consistant format for all levels
  2287.  * for efficient texture memory layout/allocation.  In particular, this
  2288.  * comes up during automatic mipmap generation.
  2289.  */
  2290. gl_format
  2291. _mesa_choose_texture_format(struct gl_context *ctx,
  2292.                             struct gl_texture_object *texObj,
  2293.                             GLenum target, GLint level,
  2294.                             GLenum internalFormat, GLenum format, GLenum type)
  2295. {
  2296.    gl_format f;
  2297.  
  2298.    /* see if we've already chosen a format for the previous level */
  2299.    if (level > 0) {
  2300.       struct gl_texture_image *prevImage =
  2301.          _mesa_select_tex_image(ctx, texObj, target, level - 1);
  2302.       /* See if the prev level is defined and has an internal format which
  2303.        * matches the new internal format.
  2304.        */
  2305.       if (prevImage &&
  2306.           prevImage->Width > 0 &&
  2307.           prevImage->InternalFormat == internalFormat) {
  2308.          /* use the same format */
  2309.          ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE);
  2310.          return prevImage->TexFormat;
  2311.       }
  2312.    }
  2313.  
  2314.    /* choose format from scratch */
  2315.    f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
  2316.    ASSERT(f != MESA_FORMAT_NONE);
  2317.    return f;
  2318. }
  2319.  
  2320.  
  2321. /**
  2322.  * Common code to implement all the glTexImage1D/2D/3D functions.
  2323.  */
  2324. static void
  2325. teximage(struct gl_context *ctx, GLuint dims,
  2326.          GLenum target, GLint level, GLint internalFormat,
  2327.          GLsizei width, GLsizei height, GLsizei depth,
  2328.          GLint border, GLenum format, GLenum type,
  2329.          const GLvoid *pixels)
  2330. {
  2331.    GLboolean error;
  2332.  
  2333.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2334.  
  2335.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  2336.       _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
  2337.                   dims,
  2338.                   _mesa_lookup_enum_by_nr(target), level,
  2339.                   _mesa_lookup_enum_by_nr(internalFormat),
  2340.                   width, height, depth, border,
  2341.                   _mesa_lookup_enum_by_nr(format),
  2342.                   _mesa_lookup_enum_by_nr(type), pixels);
  2343.  
  2344.    internalFormat = override_internal_format(internalFormat, width, height);
  2345.  
  2346.    /* target error checking */
  2347.    if (!legal_teximage_target(ctx, dims, target)) {
  2348.       _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
  2349.                   dims, _mesa_lookup_enum_by_nr(target));
  2350.       return;
  2351.    }
  2352.  
  2353.    /* general error checking */
  2354.    error = texture_error_check(ctx, dims, target, level, internalFormat,
  2355.                                format, type, width, height, depth, border);
  2356.  
  2357.    if (_mesa_is_proxy_texture(target)) {
  2358.       /* Proxy texture: just clear or set state depending on error checking */
  2359.       struct gl_texture_image *texImage =
  2360.          _mesa_get_proxy_tex_image(ctx, target, level);
  2361.  
  2362.       if (error) {
  2363.          /* when error, clear all proxy texture image parameters */
  2364.          if (texImage)
  2365.             clear_teximage_fields(texImage);
  2366.       }
  2367.       else {
  2368.          /* no error, set the tex image parameters */
  2369.          struct gl_texture_object *texObj =
  2370.             _mesa_get_current_tex_object(ctx, target);
  2371.          gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
  2372.                                                            target, level,
  2373.                                                            internalFormat,
  2374.                                                            format, type);
  2375.  
  2376.          if (legal_texture_size(ctx, texFormat, width, height, depth)) {
  2377.             _mesa_init_teximage_fields(ctx, target, texImage, width, height,
  2378.                                        depth, border, internalFormat,
  2379.                                        texFormat);
  2380.          }
  2381.          else if (texImage) {
  2382.             clear_teximage_fields(texImage);
  2383.          }
  2384.       }
  2385.    }
  2386.    else {
  2387.       /* non-proxy target */
  2388.       const GLuint face = _mesa_tex_target_to_face(target);
  2389.       struct gl_texture_object *texObj;
  2390.       struct gl_texture_image *texImage;
  2391.  
  2392.       if (error) {
  2393.          return;   /* error was recorded */
  2394.       }
  2395.  
  2396.       if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
  2397.          _mesa_update_state(ctx);
  2398.  
  2399.       texObj = _mesa_get_current_tex_object(ctx, target);
  2400.  
  2401.       _mesa_lock_texture(ctx, texObj);
  2402.       {
  2403.          texImage = _mesa_get_tex_image(ctx, texObj, target, level);
  2404.  
  2405.          if (!texImage) {
  2406.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
  2407.          }
  2408.          else {
  2409.             gl_format texFormat;
  2410.  
  2411.             if (texImage->Data) {
  2412.                ctx->Driver.FreeTexImageData( ctx, texImage );
  2413.             }
  2414.  
  2415.             ASSERT(texImage->Data == NULL);
  2416.             texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
  2417.                                                     internalFormat, format,
  2418.                                                     type);
  2419.  
  2420.             if (legal_texture_size(ctx, texFormat, width, height, depth)) {
  2421.                _mesa_init_teximage_fields(ctx, target, texImage,
  2422.                                           width, height, depth,
  2423.                                           border, internalFormat, texFormat);
  2424.  
  2425.                /* Give the texture to the driver.  <pixels> may be null. */
  2426.                ASSERT(ctx->Driver.TexImage3D);
  2427.                switch (dims) {
  2428.                case 1:
  2429.                   ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
  2430.                                          width, border, format,
  2431.                                          type, pixels, &ctx->Unpack, texObj,
  2432.                                          texImage);
  2433.                   break;
  2434.                case 2:
  2435.                   ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
  2436.                                          width, height, border, format,
  2437.                                          type, pixels, &ctx->Unpack, texObj,
  2438.                                          texImage);
  2439.                   break;
  2440.                case 3:
  2441.                   ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
  2442.                                          width, height, depth, border, format,
  2443.                                          type, pixels, &ctx->Unpack, texObj,
  2444.                                          texImage);
  2445.                   break;
  2446.                default:
  2447.                   _mesa_problem(ctx, "invalid dims=%u in teximage()", dims);
  2448.                }
  2449.  
  2450.                check_gen_mipmap(ctx, target, texObj, level);
  2451.  
  2452.                update_fbo_texture(ctx, texObj, face, level);
  2453.  
  2454.                /* state update */
  2455.                texObj->_Complete = GL_FALSE;
  2456.                ctx->NewState |= _NEW_TEXTURE;
  2457.             }
  2458.             else {
  2459.                _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
  2460.             }
  2461.          }
  2462.       }
  2463.       _mesa_unlock_texture(ctx, texObj);
  2464.    }
  2465. }
  2466.  
  2467.  
  2468. /*
  2469.  * Called from the API.  Note that width includes the border.
  2470.  */
  2471. void GLAPIENTRY
  2472. _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
  2473.                   GLsizei width, GLint border, GLenum format,
  2474.                   GLenum type, const GLvoid *pixels )
  2475. {
  2476.    GET_CURRENT_CONTEXT(ctx);
  2477.    teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
  2478.             border, format, type, pixels);
  2479. }
  2480.  
  2481.  
  2482. void GLAPIENTRY
  2483. _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
  2484.                   GLsizei width, GLsizei height, GLint border,
  2485.                   GLenum format, GLenum type,
  2486.                   const GLvoid *pixels )
  2487. {
  2488.    GET_CURRENT_CONTEXT(ctx);
  2489.    teximage(ctx, 2, target, level, internalFormat, width, height, 1,
  2490.             border, format, type, pixels);
  2491. }
  2492.  
  2493.  
  2494. /*
  2495.  * Called by the API or display list executor.
  2496.  * Note that width and height include the border.
  2497.  */
  2498. void GLAPIENTRY
  2499. _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
  2500.                   GLsizei width, GLsizei height, GLsizei depth,
  2501.                   GLint border, GLenum format, GLenum type,
  2502.                   const GLvoid *pixels )
  2503. {
  2504.    GET_CURRENT_CONTEXT(ctx);
  2505.    teximage(ctx, 3, target, level, internalFormat, width, height, depth,
  2506.             border, format, type, pixels);
  2507. }
  2508.  
  2509.  
  2510. void GLAPIENTRY
  2511. _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
  2512.                      GLsizei width, GLsizei height, GLsizei depth,
  2513.                      GLint border, GLenum format, GLenum type,
  2514.                      const GLvoid *pixels )
  2515. {
  2516.    _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
  2517.                     depth, border, format, type, pixels);
  2518. }
  2519.  
  2520.  
  2521. #if FEATURE_OES_EGL_image
  2522. void GLAPIENTRY
  2523. _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
  2524. {
  2525.    struct gl_texture_object *texObj;
  2526.    struct gl_texture_image *texImage;
  2527.    GET_CURRENT_CONTEXT(ctx);
  2528.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2529.  
  2530.    if (!ctx->Extensions.OES_EGL_image) {
  2531.       _mesa_error(ctx, GL_INVALID_OPERATION,
  2532.                   "glEGLImageTargetTexture2DOES(unsupported)");
  2533.       return;
  2534.    }
  2535.  
  2536.    if (target != GL_TEXTURE_2D) {
  2537.       _mesa_error(ctx, GL_INVALID_ENUM,
  2538.                   "glEGLImageTargetTexture2D(target=%d)", target);
  2539.       return;
  2540.    }
  2541.  
  2542.    if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
  2543.       _mesa_update_state(ctx);
  2544.  
  2545.    texObj = _mesa_get_current_tex_object(ctx, target);
  2546.    _mesa_lock_texture(ctx, texObj);
  2547.  
  2548.    texImage = _mesa_get_tex_image(ctx, texObj, target, 0);
  2549.    if (!texImage) {
  2550.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D");
  2551.    } else {
  2552.       if (texImage->Data)
  2553.          ctx->Driver.FreeTexImageData( ctx, texImage );
  2554.  
  2555.       ASSERT(texImage->Data == NULL);
  2556.       ctx->Driver.EGLImageTargetTexture2D(ctx, target,
  2557.                                           texObj, texImage, image);
  2558.  
  2559.       /* state update */
  2560.       texObj->_Complete = GL_FALSE;
  2561.       ctx->NewState |= _NEW_TEXTURE;
  2562.    }
  2563.    _mesa_unlock_texture(ctx, texObj);
  2564.  
  2565. }
  2566. #endif
  2567.  
  2568.  
  2569.  
  2570. /**
  2571.  * Implement all the glTexSubImage1/2/3D() functions.
  2572.  */
  2573. static void
  2574. texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
  2575.             GLint xoffset, GLint yoffset, GLint zoffset,
  2576.             GLsizei width, GLsizei height, GLsizei depth,
  2577.             GLenum format, GLenum type, const GLvoid *pixels )
  2578. {
  2579.    struct gl_texture_object *texObj;
  2580.    struct gl_texture_image *texImage;
  2581.  
  2582.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2583.  
  2584.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  2585.       _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
  2586.                   dims,
  2587.                   _mesa_lookup_enum_by_nr(target), level,
  2588.                   xoffset, yoffset, zoffset, width, height, depth,
  2589.                   _mesa_lookup_enum_by_nr(format),
  2590.                   _mesa_lookup_enum_by_nr(type), pixels);
  2591.  
  2592.    /* check target (proxies not allowed) */
  2593.    if (!legal_texsubimage_target(ctx, dims, target)) {
  2594.       _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
  2595.                   dims, _mesa_lookup_enum_by_nr(target));
  2596.       return;
  2597.    }      
  2598.  
  2599.    if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
  2600.       _mesa_update_state(ctx);
  2601.  
  2602.    if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset,
  2603.                               width, height, depth, format, type)) {
  2604.       return;   /* error was detected */
  2605.    }
  2606.  
  2607.    texObj = _mesa_get_current_tex_object(ctx, target);
  2608.  
  2609.    _mesa_lock_texture(ctx, texObj);
  2610.    {
  2611.       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
  2612.  
  2613.       if (subtexture_error_check2(ctx, dims, target, level,
  2614.                                   xoffset, yoffset, zoffset,
  2615.                                   width, height, depth,
  2616.                                   format, type, texImage)) {
  2617.          /* error was recorded */
  2618.       }
  2619.       else if (width > 0 && height > 0 && height > 0) {
  2620.          /* If we have a border, offset=-1 is legal.  Bias by border width. */
  2621.          switch (dims) {
  2622.          case 3:
  2623.             zoffset += texImage->Border;
  2624.             /* fall-through */
  2625.          case 2:
  2626.             yoffset += texImage->Border;
  2627.             /* fall-through */
  2628.          case 1:
  2629.             xoffset += texImage->Border;
  2630.          }
  2631.  
  2632.          switch (dims) {
  2633.          case 1:
  2634.             ctx->Driver.TexSubImage1D(ctx, target, level,
  2635.                                       xoffset, width,
  2636.                                       format, type, pixels,
  2637.                                       &ctx->Unpack, texObj, texImage );
  2638.             break;
  2639.          case 2:
  2640.             ctx->Driver.TexSubImage2D(ctx, target, level,
  2641.                                       xoffset, yoffset, width, height,
  2642.                                       format, type, pixels,
  2643.                                       &ctx->Unpack, texObj, texImage );
  2644.             break;
  2645.          case 3:
  2646.             ctx->Driver.TexSubImage3D(ctx, target, level,
  2647.                                       xoffset, yoffset, zoffset,
  2648.                                       width, height, depth,
  2649.                                       format, type, pixels,
  2650.                                       &ctx->Unpack, texObj, texImage );
  2651.             break;
  2652.          default:
  2653.             _mesa_problem(ctx, "unexpected dims in subteximage()");
  2654.          }
  2655.  
  2656.          check_gen_mipmap(ctx, target, texObj, level);
  2657.  
  2658.          ctx->NewState |= _NEW_TEXTURE;
  2659.       }
  2660.    }
  2661.    _mesa_unlock_texture(ctx, texObj);
  2662. }
  2663.  
  2664.  
  2665. void GLAPIENTRY
  2666. _mesa_TexSubImage1D( GLenum target, GLint level,
  2667.                      GLint xoffset, GLsizei width,
  2668.                      GLenum format, GLenum type,
  2669.                      const GLvoid *pixels )
  2670. {
  2671.    GET_CURRENT_CONTEXT(ctx);
  2672.    texsubimage(ctx, 1, target, level,
  2673.                xoffset, 0, 0,
  2674.                width, 1, 1,
  2675.                format, type, pixels);
  2676. }
  2677.  
  2678.  
  2679. void GLAPIENTRY
  2680. _mesa_TexSubImage2D( GLenum target, GLint level,
  2681.                      GLint xoffset, GLint yoffset,
  2682.                      GLsizei width, GLsizei height,
  2683.                      GLenum format, GLenum type,
  2684.                      const GLvoid *pixels )
  2685. {
  2686.    GET_CURRENT_CONTEXT(ctx);
  2687.    texsubimage(ctx, 2, target, level,
  2688.                xoffset, yoffset, 0,
  2689.                width, height, 1,
  2690.                format, type, pixels);
  2691. }
  2692.  
  2693.  
  2694.  
  2695. void GLAPIENTRY
  2696. _mesa_TexSubImage3D( GLenum target, GLint level,
  2697.                      GLint xoffset, GLint yoffset, GLint zoffset,
  2698.                      GLsizei width, GLsizei height, GLsizei depth,
  2699.                      GLenum format, GLenum type,
  2700.                      const GLvoid *pixels )
  2701. {
  2702.    GET_CURRENT_CONTEXT(ctx);
  2703.    texsubimage(ctx, 3, target, level,
  2704.                xoffset, yoffset, zoffset,
  2705.                width, height, depth,
  2706.                format, type, pixels);
  2707. }
  2708.  
  2709.  
  2710.  
  2711. /**
  2712.  * Implement the glCopyTexImage1/2D() functions.
  2713.  */
  2714. static void
  2715. copyteximage(struct gl_context *ctx, GLuint dims,
  2716.              GLenum target, GLint level, GLenum internalFormat,
  2717.              GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
  2718. {
  2719.    struct gl_texture_object *texObj;
  2720.    struct gl_texture_image *texImage;
  2721.    const GLuint face = _mesa_tex_target_to_face(target);
  2722.  
  2723.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2724.  
  2725.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  2726.       _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
  2727.                   dims,
  2728.                   _mesa_lookup_enum_by_nr(target), level,
  2729.                   _mesa_lookup_enum_by_nr(internalFormat),
  2730.                   x, y, width, height, border);
  2731.  
  2732.    if (ctx->NewState & NEW_COPY_TEX_STATE)
  2733.       _mesa_update_state(ctx);
  2734.  
  2735.    if (copytexture_error_check(ctx, dims, target, level, internalFormat,
  2736.                                width, height, border))
  2737.       return;
  2738.  
  2739.    texObj = _mesa_get_current_tex_object(ctx, target);
  2740.  
  2741.    _mesa_lock_texture(ctx, texObj);
  2742.    {
  2743.       texImage = _mesa_get_tex_image(ctx, texObj, target, level);
  2744.  
  2745.       if (!texImage) {
  2746.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
  2747.       }
  2748.       else {
  2749.          gl_format texFormat;
  2750.  
  2751.          if (texImage->Data) {
  2752.             ctx->Driver.FreeTexImageData( ctx, texImage );
  2753.          }
  2754.  
  2755.          ASSERT(texImage->Data == NULL);
  2756.  
  2757.          texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
  2758.                                                  internalFormat, GL_NONE,
  2759.                                                  GL_NONE);
  2760.  
  2761.          if (legal_texture_size(ctx, texFormat, width, height, 1)) {
  2762.             _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
  2763.                                        border, internalFormat, texFormat);
  2764.  
  2765.             ASSERT(ctx->Driver.CopyTexImage2D);
  2766.             if (dims == 1)
  2767.                ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
  2768.                                           x, y, width, border);
  2769.             else
  2770.                ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
  2771.                                           x, y, width, height, border);
  2772.  
  2773.             check_gen_mipmap(ctx, target, texObj, level);
  2774.  
  2775.             update_fbo_texture(ctx, texObj, face, level);
  2776.  
  2777.             /* state update */
  2778.             texObj->_Complete = GL_FALSE;
  2779.             ctx->NewState |= _NEW_TEXTURE;
  2780.          }
  2781.          else {
  2782.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
  2783.          }
  2784.       }
  2785.    }
  2786.    _mesa_unlock_texture(ctx, texObj);
  2787. }
  2788.  
  2789.  
  2790.  
  2791. void GLAPIENTRY
  2792. _mesa_CopyTexImage1D( GLenum target, GLint level,
  2793.                       GLenum internalFormat,
  2794.                       GLint x, GLint y,
  2795.                       GLsizei width, GLint border )
  2796. {
  2797.    GET_CURRENT_CONTEXT(ctx);
  2798.    copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
  2799. }
  2800.  
  2801.  
  2802.  
  2803. void GLAPIENTRY
  2804. _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
  2805.                       GLint x, GLint y, GLsizei width, GLsizei height,
  2806.                       GLint border )
  2807. {
  2808.    GET_CURRENT_CONTEXT(ctx);
  2809.    copyteximage(ctx, 2, target, level, internalFormat,
  2810.                 x, y, width, height, border);
  2811. }
  2812.  
  2813.  
  2814.  
  2815. /**
  2816.  * Implementation for glCopyTexSubImage1/2/3D() functions.
  2817.  */
  2818. static void
  2819. copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
  2820.                 GLint xoffset, GLint yoffset, GLint zoffset,
  2821.                 GLint x, GLint y, GLsizei width, GLsizei height)
  2822. {
  2823.    struct gl_texture_object *texObj;
  2824.    struct gl_texture_image *texImage;
  2825.  
  2826.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  2827.  
  2828.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  2829.       _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n",
  2830.                   dims,
  2831.                   _mesa_lookup_enum_by_nr(target),
  2832.                   level, xoffset, yoffset, zoffset, x, y, width, height);
  2833.  
  2834.    if (ctx->NewState & NEW_COPY_TEX_STATE)
  2835.       _mesa_update_state(ctx);
  2836.  
  2837.    if (copytexsubimage_error_check1(ctx, dims, target, level))
  2838.       return;
  2839.  
  2840.    texObj = _mesa_get_current_tex_object(ctx, target);
  2841.  
  2842.    _mesa_lock_texture(ctx, texObj);
  2843.    {
  2844.       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
  2845.  
  2846.       if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset,
  2847.                                        zoffset, width, height, texImage)) {
  2848.          /* error was recored */
  2849.       }
  2850.       else {
  2851.          /* If we have a border, offset=-1 is legal.  Bias by border width. */
  2852.          switch (dims) {
  2853.          case 3:
  2854.             zoffset += texImage->Border;
  2855.             /* fall-through */
  2856.          case 2:
  2857.             yoffset += texImage->Border;
  2858.             /* fall-through */
  2859.          case 1:
  2860.             xoffset += texImage->Border;
  2861.          }
  2862.  
  2863.          if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
  2864.                                         &width, &height)) {
  2865.             switch (dims) {
  2866.             case 1:
  2867.                ctx->Driver.CopyTexSubImage1D(ctx, target, level,
  2868.                                              xoffset, x, y, width);
  2869.                break;
  2870.             case 2:
  2871.                ctx->Driver.CopyTexSubImage2D(ctx, target, level,
  2872.                                              xoffset, yoffset,
  2873.                                              x, y, width, height);
  2874.                break;
  2875.             case 3:
  2876.                ctx->Driver.CopyTexSubImage3D(ctx, target, level,
  2877.                                              xoffset, yoffset, zoffset,
  2878.                                              x, y, width, height);
  2879.                break;
  2880.             default:
  2881.                _mesa_problem(ctx, "bad dims in copytexsubimage()");
  2882.             }
  2883.  
  2884.             check_gen_mipmap(ctx, target, texObj, level);
  2885.  
  2886.             ctx->NewState |= _NEW_TEXTURE;
  2887.          }
  2888.       }
  2889.    }
  2890.    _mesa_unlock_texture(ctx, texObj);
  2891. }
  2892.  
  2893.  
  2894. void GLAPIENTRY
  2895. _mesa_CopyTexSubImage1D( GLenum target, GLint level,
  2896.                          GLint xoffset, GLint x, GLint y, GLsizei width )
  2897. {
  2898.    GET_CURRENT_CONTEXT(ctx);
  2899.    copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1);
  2900. }
  2901.  
  2902.  
  2903.  
  2904. void GLAPIENTRY
  2905. _mesa_CopyTexSubImage2D( GLenum target, GLint level,
  2906.                          GLint xoffset, GLint yoffset,
  2907.                          GLint x, GLint y, GLsizei width, GLsizei height )
  2908. {
  2909.    GET_CURRENT_CONTEXT(ctx);
  2910.    copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y,
  2911.                    width, height);
  2912. }
  2913.  
  2914.  
  2915.  
  2916. void GLAPIENTRY
  2917. _mesa_CopyTexSubImage3D( GLenum target, GLint level,
  2918.                          GLint xoffset, GLint yoffset, GLint zoffset,
  2919.                          GLint x, GLint y, GLsizei width, GLsizei height )
  2920. {
  2921.    GET_CURRENT_CONTEXT(ctx);
  2922.    copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
  2923.                    x, y, width, height);
  2924. }
  2925.  
  2926.  
  2927.  
  2928.  
  2929. /**********************************************************************/
  2930. /******                   Compressed Textures                    ******/
  2931. /**********************************************************************/
  2932.  
  2933.  
  2934. /**
  2935.  * Return expected size of a compressed texture.
  2936.  */
  2937. static GLuint
  2938. compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
  2939.                     GLenum glformat)
  2940. {
  2941.    gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
  2942.    return _mesa_format_image_size(mesaFormat, width, height, depth);
  2943. }
  2944.  
  2945.  
  2946. /*
  2947.  * Return compressed texture block size, in pixels.
  2948.  */
  2949. static void
  2950. get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
  2951. {
  2952.    gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
  2953.    _mesa_get_format_block_size(mesaFormat, bw, bh);
  2954. }
  2955.  
  2956.  
  2957. /**
  2958.  * Error checking for glCompressedTexImage[123]D().
  2959.  * \return error code or GL_NO_ERROR.
  2960.  */
  2961. static GLenum
  2962. compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
  2963.                                GLenum target, GLint level,
  2964.                                GLenum internalFormat, GLsizei width,
  2965.                                GLsizei height, GLsizei depth, GLint border,
  2966.                                GLsizei imageSize)
  2967. {
  2968.    const GLenum proxyTarget = get_proxy_target(target);
  2969.    const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
  2970.    GLint expectedSize;
  2971.  
  2972.    /* check level */
  2973.    if (level < 0 || level >= maxLevels)
  2974.       return GL_INVALID_VALUE;
  2975.  
  2976.    if (!target_can_be_compressed(ctx, target, internalFormat)) {
  2977.       return GL_INVALID_ENUM;
  2978.    }
  2979.  
  2980.    /* This will detect any invalid internalFormat value */
  2981.    if (!_mesa_is_compressed_format(ctx, internalFormat))
  2982.       return GL_INVALID_ENUM;
  2983.  
  2984.    /* This should really never fail */
  2985.    if (_mesa_base_tex_format(ctx, internalFormat) < 0)
  2986.       return GL_INVALID_ENUM;
  2987.  
  2988.    /* No compressed formats support borders at this time */
  2989.    if (border != 0)
  2990.       return GL_INVALID_VALUE;
  2991.  
  2992.    /* For cube map, width must equal height */
  2993.    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  2994.        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height)
  2995.       return GL_INVALID_VALUE;
  2996.  
  2997.    /* check image size against compression block size */
  2998.    {
  2999.       gl_format texFormat =
  3000.          ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
  3001.                                          GL_NONE, GL_NONE);
  3002.       GLuint bw, bh;
  3003.  
  3004.       _mesa_get_format_block_size(texFormat, &bw, &bh);
  3005.       if ((width > bw && width % bw > 0) ||
  3006.           (height > bh && height % bh > 0)) {
  3007.          /*
  3008.           * Per GL_ARB_texture_compression:  GL_INVALID_OPERATION is
  3009.           * generated [...] if any parameter combinations are not
  3010.           * supported by the specific compressed internal format.
  3011.           */
  3012.          return GL_INVALID_OPERATION;
  3013.       }
  3014.    }
  3015.  
  3016.    /* check image sizes */
  3017.    if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
  3018.                                       internalFormat, GL_NONE, GL_NONE,
  3019.                                       width, height, depth, border)) {
  3020.       /* See error comment above */
  3021.       return GL_INVALID_OPERATION;
  3022.    }
  3023.  
  3024.    /* check image size in bytes */
  3025.    expectedSize = compressed_tex_size(width, height, depth, internalFormat);
  3026.    if (expectedSize != imageSize) {
  3027.       /* Per GL_ARB_texture_compression:  GL_INVALID_VALUE is generated [...]
  3028.        * if <imageSize> is not consistent with the format, dimensions, and
  3029.        * contents of the specified image.
  3030.        */
  3031.       return GL_INVALID_VALUE;
  3032.    }
  3033.  
  3034.    return GL_NO_ERROR;
  3035. }
  3036.  
  3037.  
  3038. /**
  3039.  * Error checking for glCompressedTexSubImage[123]D().
  3040.  * \warning  There are some bad assumptions here about the size of compressed
  3041.  *           texture tiles (multiple of 4) used to test the validity of the
  3042.  *           offset and size parameters.
  3043.  * \return error code or GL_NO_ERROR.
  3044.  */
  3045. static GLenum
  3046. compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
  3047.                                   GLenum target, GLint level,
  3048.                                   GLint xoffset, GLint yoffset, GLint zoffset,
  3049.                                   GLsizei width, GLsizei height, GLsizei depth,
  3050.                                   GLenum format, GLsizei imageSize)
  3051. {
  3052.    GLint expectedSize, maxLevels = 0, maxTextureSize;
  3053.    GLuint bw, bh;
  3054.    (void) zoffset;
  3055.  
  3056.    if (dimensions == 1) {
  3057.       /* 1D compressed textures not allowed */
  3058.       return GL_INVALID_ENUM;
  3059.    }
  3060.    else if (dimensions == 2) {
  3061.       if (target == GL_PROXY_TEXTURE_2D) {
  3062.          maxLevels = ctx->Const.MaxTextureLevels;
  3063.       }
  3064.       else if (target == GL_TEXTURE_2D) {
  3065.          maxLevels = ctx->Const.MaxTextureLevels;
  3066.       }
  3067.       else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
  3068.          if (!ctx->Extensions.ARB_texture_cube_map)
  3069.             return GL_INVALID_ENUM; /*target*/
  3070.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  3071.       }
  3072.       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
  3073.                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
  3074.          if (!ctx->Extensions.ARB_texture_cube_map)
  3075.             return GL_INVALID_ENUM; /*target*/
  3076.          maxLevels = ctx->Const.MaxCubeTextureLevels;
  3077.       }
  3078.       else {
  3079.          return GL_INVALID_ENUM; /*target*/
  3080.       }
  3081.    }
  3082.    else if (dimensions == 3) {
  3083.       /* 3D compressed textures not allowed */
  3084.       return GL_INVALID_ENUM;
  3085.    }
  3086.  
  3087.    maxTextureSize = 1 << (maxLevels - 1);
  3088.  
  3089.    /* this will catch any invalid compressed format token */
  3090.    if (!_mesa_is_compressed_format(ctx, format))
  3091.       return GL_INVALID_ENUM;
  3092.  
  3093.    if (width < 1 || width > maxTextureSize)
  3094.       return GL_INVALID_VALUE;
  3095.  
  3096.    if ((height < 1 || height > maxTextureSize)
  3097.        && dimensions > 1)
  3098.       return GL_INVALID_VALUE;
  3099.  
  3100.    if (level < 0 || level >= maxLevels)
  3101.       return GL_INVALID_VALUE;
  3102.  
  3103.    /*
  3104.     * do checks which depend on compression block size
  3105.     */
  3106.    get_compressed_block_size(format, &bw, &bh);
  3107.  
  3108.    if ((xoffset % bw != 0) || (yoffset % bh != 0))
  3109.       return GL_INVALID_VALUE;
  3110.  
  3111.    if ((width % bw != 0) && width != 2 && width != 1)
  3112.       return GL_INVALID_VALUE;
  3113.  
  3114.    if ((height % bh != 0) && height != 2 && height != 1)
  3115.       return GL_INVALID_VALUE;
  3116.  
  3117.    expectedSize = compressed_tex_size(width, height, depth, format);
  3118.    if (expectedSize != imageSize)
  3119.       return GL_INVALID_VALUE;
  3120.  
  3121.    return GL_NO_ERROR;
  3122. }
  3123.  
  3124.  
  3125. /**
  3126.  * Do second part of glCompressedTexSubImage error checking.
  3127.  * \return GL_TRUE if error found, GL_FALSE otherwise.
  3128.  */
  3129. static GLboolean
  3130. compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
  3131.                                    GLsizei width, GLsizei height,
  3132.                                    GLsizei depth, GLenum format,
  3133.                                    struct gl_texture_image *texImage)
  3134. {
  3135.  
  3136.    if ((GLint) format != texImage->InternalFormat) {
  3137.       _mesa_error(ctx, GL_INVALID_OPERATION,
  3138.                   "glCompressedTexSubImage%uD(format=0x%x)", dims, format);
  3139.       return GL_TRUE;
  3140.    }
  3141.  
  3142.    if (((width == 1 || width == 2) &&
  3143.         width != (GLsizei) texImage->Width) ||
  3144.        (width > (GLsizei) texImage->Width)) {
  3145.       _mesa_error(ctx, GL_INVALID_VALUE,
  3146.                   "glCompressedTexSubImage%uD(width=%d)", dims, width);
  3147.       return GL_TRUE;
  3148.    }
  3149.  
  3150.    if (dims >= 2) {
  3151.       if (((height == 1 || height == 2) &&
  3152.            height != (GLsizei) texImage->Height) ||
  3153.           (height > (GLsizei) texImage->Height)) {
  3154.          _mesa_error(ctx, GL_INVALID_VALUE,
  3155.                      "glCompressedTexSubImage%uD(height=%d)", dims, height);
  3156.          return GL_TRUE;
  3157.       }
  3158.    }
  3159.  
  3160.    if (dims >= 3) {
  3161.       if (((depth == 1 || depth == 2) &&
  3162.            depth != (GLsizei) texImage->Depth) ||
  3163.           (depth > (GLsizei) texImage->Depth)) {
  3164.          _mesa_error(ctx, GL_INVALID_VALUE,
  3165.                      "glCompressedTexSubImage%uD(depth=%d)", dims, depth);
  3166.          return GL_TRUE;
  3167.       }
  3168.    }
  3169.  
  3170.    return GL_FALSE;
  3171. }
  3172.  
  3173.  
  3174. /**
  3175.  * Implementation of the glCompressedTexImage1/2/3D() functions.
  3176.  */
  3177. static void
  3178. compressedteximage(struct gl_context *ctx, GLuint dims,
  3179.                    GLenum target, GLint level,
  3180.                    GLenum internalFormat, GLsizei width,
  3181.                    GLsizei height, GLsizei depth, GLint border,
  3182.                    GLsizei imageSize, const GLvoid *data)
  3183. {
  3184.    GLenum error;
  3185.  
  3186.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  3187.  
  3188.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  3189.       _mesa_debug(ctx,
  3190.                   "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n",
  3191.                   dims,
  3192.                   _mesa_lookup_enum_by_nr(target), level,
  3193.                   _mesa_lookup_enum_by_nr(internalFormat),
  3194.                   width, height, depth, border, imageSize, data);
  3195.  
  3196.    /* check target */
  3197.    if (!legal_teximage_target(ctx, dims, target)) {
  3198.       _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)",
  3199.                   dims, _mesa_lookup_enum_by_nr(target));
  3200.       return;
  3201.    }
  3202.  
  3203.    error = compressed_texture_error_check(ctx, dims, target, level,
  3204.                                           internalFormat, width, height, depth,
  3205.                                           border, imageSize);
  3206.  
  3207. #if FEATURE_ES
  3208.    /* XXX this is kind of a hack */
  3209.    if (error) {
  3210.       _mesa_error(ctx, error, "glTexImage2D");
  3211.       return;
  3212.    }
  3213.  
  3214.    if (dims == 2) {
  3215.       switch (internalFormat) {
  3216.       case GL_PALETTE4_RGB8_OES:
  3217.       case GL_PALETTE4_RGBA8_OES:
  3218.       case GL_PALETTE4_R5_G6_B5_OES:
  3219.       case GL_PALETTE4_RGBA4_OES:
  3220.       case GL_PALETTE4_RGB5_A1_OES:
  3221.       case GL_PALETTE8_RGB8_OES:
  3222.       case GL_PALETTE8_RGBA8_OES:
  3223.       case GL_PALETTE8_R5_G6_B5_OES:
  3224.       case GL_PALETTE8_RGBA4_OES:
  3225.       case GL_PALETTE8_RGB5_A1_OES:
  3226.          _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
  3227.                                           width, height, imageSize, data);
  3228.          return;
  3229.       }
  3230.    }
  3231. #endif
  3232.  
  3233.    if (_mesa_is_proxy_texture(target)) {
  3234.       /* Proxy texture: just check for errors and update proxy state */
  3235.       struct gl_texture_image *texImage;
  3236.  
  3237.       if (!error) {
  3238.          struct gl_texture_object *texObj =
  3239.             _mesa_get_current_tex_object(ctx, target);
  3240.          gl_format texFormat =
  3241.             _mesa_choose_texture_format(ctx, texObj, target, level,
  3242.                                         internalFormat, GL_NONE, GL_NONE);
  3243.          if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
  3244.             error = GL_OUT_OF_MEMORY;
  3245.          }
  3246.       }
  3247.  
  3248.       texImage = _mesa_get_proxy_tex_image(ctx, target, level);
  3249.       if (texImage) {
  3250.          if (error) {
  3251.             /* if error, clear all proxy texture image parameters */
  3252.             clear_teximage_fields(texImage);
  3253.          }
  3254.          else {
  3255.             /* no error: store the teximage parameters */
  3256.             _mesa_init_teximage_fields(ctx, target, texImage, width, height,
  3257.                                        depth, border, internalFormat,
  3258.                                        MESA_FORMAT_NONE);
  3259.          }
  3260.       }
  3261.    }
  3262.    else {
  3263.       /* non-proxy target */
  3264.       struct gl_texture_object *texObj;
  3265.       struct gl_texture_image *texImage;
  3266.  
  3267.       if (error) {
  3268.          _mesa_error(ctx, error, "glCompressedTexImage%uD", dims);
  3269.          return;
  3270.       }
  3271.  
  3272.       texObj = _mesa_get_current_tex_object(ctx, target);
  3273.  
  3274.       _mesa_lock_texture(ctx, texObj);
  3275.       {
  3276.          texImage = _mesa_get_tex_image(ctx, texObj, target, level);
  3277.          if (!texImage) {
  3278.             _mesa_error(ctx, GL_OUT_OF_MEMORY,
  3279.                         "glCompressedTexImage%uD", dims);
  3280.          }
  3281.          else {
  3282.             gl_format texFormat;
  3283.  
  3284.             if (texImage->Data) {
  3285.                ctx->Driver.FreeTexImageData( ctx, texImage );
  3286.             }
  3287.             ASSERT(texImage->Data == NULL);
  3288.  
  3289.             texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
  3290.                                                     internalFormat, GL_NONE,
  3291.                                                     GL_NONE);
  3292.  
  3293.             if (legal_texture_size(ctx, texFormat, width, height, depth)) {
  3294.                _mesa_init_teximage_fields(ctx, target, texImage,
  3295.                                           width, height, depth,
  3296.                                           border, internalFormat, texFormat);
  3297.  
  3298.                switch (dims) {
  3299.                case 1:
  3300.                   ASSERT(ctx->Driver.CompressedTexImage1D);
  3301.                   ctx->Driver.CompressedTexImage1D(ctx, target, level,
  3302.                                                    internalFormat,
  3303.                                                    width,
  3304.                                                    border, imageSize, data,
  3305.                                                    texObj, texImage);
  3306.                   break;
  3307.                case 2:
  3308.                   ASSERT(ctx->Driver.CompressedTexImage2D);
  3309.                   ctx->Driver.CompressedTexImage2D(ctx, target, level,
  3310.                                                    internalFormat,
  3311.                                                    width, height,
  3312.                                                    border, imageSize, data,
  3313.                                                    texObj, texImage);
  3314.                   break;
  3315.                case 3:
  3316.                   ASSERT(ctx->Driver.CompressedTexImage3D);
  3317.                   ctx->Driver.CompressedTexImage3D(ctx, target, level,
  3318.                                                    internalFormat,
  3319.                                                    width, height, depth,
  3320.                                                    border, imageSize, data,
  3321.                                                    texObj, texImage);
  3322.                   break;
  3323.                default:
  3324.                   _mesa_problem(ctx, "bad dims in compressedteximage");
  3325.                }
  3326.  
  3327.                check_gen_mipmap(ctx, target, texObj, level);
  3328.  
  3329.                /* state update */
  3330.                texObj->_Complete = GL_FALSE;
  3331.                ctx->NewState |= _NEW_TEXTURE;
  3332.             }
  3333.             else {
  3334.                _mesa_error(ctx, GL_OUT_OF_MEMORY,
  3335.                            "glCompressedTexImage%uD", dims);
  3336.             }
  3337.          }
  3338.       }
  3339.       _mesa_unlock_texture(ctx, texObj);
  3340.    }
  3341. }
  3342.  
  3343.  
  3344. void GLAPIENTRY
  3345. _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
  3346.                               GLenum internalFormat, GLsizei width,
  3347.                               GLint border, GLsizei imageSize,
  3348.                               const GLvoid *data)
  3349. {
  3350.    GET_CURRENT_CONTEXT(ctx);
  3351.    compressedteximage(ctx, 1, target, level, internalFormat,
  3352.                       width, 1, 1, border, imageSize, data);
  3353. }
  3354.  
  3355.  
  3356. void GLAPIENTRY
  3357. _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
  3358.                               GLenum internalFormat, GLsizei width,
  3359.                               GLsizei height, GLint border, GLsizei imageSize,
  3360.                               const GLvoid *data)
  3361. {
  3362.    GET_CURRENT_CONTEXT(ctx);
  3363.    compressedteximage(ctx, 2, target, level, internalFormat,
  3364.                       width, height, 1, border, imageSize, data);
  3365. }
  3366.  
  3367.  
  3368. void GLAPIENTRY
  3369. _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
  3370.                               GLenum internalFormat, GLsizei width,
  3371.                               GLsizei height, GLsizei depth, GLint border,
  3372.                               GLsizei imageSize, const GLvoid *data)
  3373. {
  3374.    GET_CURRENT_CONTEXT(ctx);
  3375.    compressedteximage(ctx, 3, target, level, internalFormat,
  3376.                       width, height, depth, border, imageSize, data);
  3377. }
  3378.  
  3379.  
  3380. /**
  3381.  * Common helper for glCompressedTexSubImage1/2/3D().
  3382.  */
  3383. static void
  3384. compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
  3385.                          GLint xoffset, GLint yoffset, GLint zoffset,
  3386.                          GLsizei width, GLsizei height, GLsizei depth,
  3387.                          GLenum format, GLsizei imageSize, const GLvoid *data)
  3388. {
  3389.    struct gl_texture_object *texObj;
  3390.    struct gl_texture_image *texImage;
  3391.    GLenum error;
  3392.    GET_CURRENT_CONTEXT(ctx);
  3393.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  3394.  
  3395.    error = compressed_subtexture_error_check(ctx, dims, target, level,
  3396.                                              xoffset, 0, 0, /* pos */
  3397.                                              width, height, depth,   /* size */
  3398.                                              format, imageSize);
  3399.    if (error) {
  3400.       _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims);
  3401.       return;
  3402.    }
  3403.  
  3404.    texObj = _mesa_get_current_tex_object(ctx, target);
  3405.  
  3406.    _mesa_lock_texture(ctx, texObj);
  3407.    {
  3408.       texImage = _mesa_select_tex_image(ctx, texObj, target, level);
  3409.       assert(texImage);
  3410.  
  3411.       if (compressed_subtexture_error_check2(ctx, dims, width, height, depth,
  3412.                                              format, texImage)) {
  3413.          /* error was recorded */
  3414.       }
  3415.       else if (width > 0 && height > 0 && depth > 0) {
  3416.          switch (dims) {
  3417.          case 1:
  3418.             if (ctx->Driver.CompressedTexSubImage1D) {
  3419.                ctx->Driver.CompressedTexSubImage1D(ctx, target, level,
  3420.                                                    xoffset, width,
  3421.                                                    format, imageSize, data,
  3422.                                                    texObj, texImage);
  3423.             }
  3424.             break;
  3425.          case 2:
  3426.             if (ctx->Driver.CompressedTexSubImage2D) {
  3427.                ctx->Driver.CompressedTexSubImage2D(ctx, target, level,
  3428.                                                    xoffset, yoffset,
  3429.                                                    width, height,
  3430.                                                    format, imageSize, data,
  3431.                                                    texObj, texImage);
  3432.             }
  3433.             break;
  3434.          case 3:
  3435.             if (ctx->Driver.CompressedTexSubImage3D) {
  3436.                ctx->Driver.CompressedTexSubImage3D(ctx, target, level,
  3437.                                                    xoffset, yoffset, zoffset,
  3438.                                                    width, height, depth,
  3439.                                                    format, imageSize, data,
  3440.                                                    texObj, texImage);
  3441.             }
  3442.             break;
  3443.          default:
  3444.             ;
  3445.          }
  3446.  
  3447.          check_gen_mipmap(ctx, target, texObj, level);
  3448.  
  3449.          ctx->NewState |= _NEW_TEXTURE;
  3450.       }
  3451.    }
  3452.    _mesa_unlock_texture(ctx, texObj);
  3453. }
  3454.  
  3455.  
  3456. void GLAPIENTRY
  3457. _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
  3458.                                  GLsizei width, GLenum format,
  3459.                                  GLsizei imageSize, const GLvoid *data)
  3460. {
  3461.    compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1,
  3462.                             format, imageSize, data);
  3463. }
  3464.  
  3465.  
  3466. void GLAPIENTRY
  3467. _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
  3468.                                  GLint yoffset, GLsizei width, GLsizei height,
  3469.                                  GLenum format, GLsizei imageSize,
  3470.                                  const GLvoid *data)
  3471. {
  3472.    compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0,
  3473.                             width, height, 1, format, imageSize, data);
  3474. }
  3475.  
  3476.  
  3477. void GLAPIENTRY
  3478. _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
  3479.                                  GLint yoffset, GLint zoffset, GLsizei width,
  3480.                                  GLsizei height, GLsizei depth, GLenum format,
  3481.                                  GLsizei imageSize, const GLvoid *data)
  3482. {
  3483.    compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset,
  3484.                             width, height, depth, format, imageSize, data);
  3485. }
  3486.