xref: /aosp_15_r20/external/mesa3d/src/mesa/main/teximage.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker  *
7*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
9*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
10*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
12*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included
15*61046927SAndroid Build Coastguard Worker  * in all copies or substantial portions of the Software.
16*61046927SAndroid Build Coastguard Worker  *
17*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21*61046927SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22*61046927SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23*61046927SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
24*61046927SAndroid Build Coastguard Worker  */
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker /**
28*61046927SAndroid Build Coastguard Worker  * \file teximage.c
29*61046927SAndroid Build Coastguard Worker  * Texture image-related functions.
30*61046927SAndroid Build Coastguard Worker  */
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
33*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
34*61046927SAndroid Build Coastguard Worker #include "bufferobj.h"
35*61046927SAndroid Build Coastguard Worker #include "context.h"
36*61046927SAndroid Build Coastguard Worker #include "enums.h"
37*61046927SAndroid Build Coastguard Worker #include "fbobject.h"
38*61046927SAndroid Build Coastguard Worker #include "framebuffer.h"
39*61046927SAndroid Build Coastguard Worker #include "hash.h"
40*61046927SAndroid Build Coastguard Worker #include "image.h"
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker #include "macros.h"
43*61046927SAndroid Build Coastguard Worker #include "mipmap.h"
44*61046927SAndroid Build Coastguard Worker #include "multisample.h"
45*61046927SAndroid Build Coastguard Worker #include "pixel.h"
46*61046927SAndroid Build Coastguard Worker #include "pixelstore.h"
47*61046927SAndroid Build Coastguard Worker #include "state.h"
48*61046927SAndroid Build Coastguard Worker #include "texcompress.h"
49*61046927SAndroid Build Coastguard Worker #include "texcompress_cpal.h"
50*61046927SAndroid Build Coastguard Worker #include "teximage.h"
51*61046927SAndroid Build Coastguard Worker #include "texobj.h"
52*61046927SAndroid Build Coastguard Worker #include "texstate.h"
53*61046927SAndroid Build Coastguard Worker #include "texstorage.h"
54*61046927SAndroid Build Coastguard Worker #include "textureview.h"
55*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
56*61046927SAndroid Build Coastguard Worker #include "glformats.h"
57*61046927SAndroid Build Coastguard Worker #include "texstore.h"
58*61046927SAndroid Build Coastguard Worker #include "pbo.h"
59*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker #include "program/prog_instruction.h"
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_texture.h"
66*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_context.h"
67*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_format.h"
68*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_gen_mipmap.h"
69*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_eglimage.h"
70*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_sampler_view.h"
71*61046927SAndroid Build Coastguard Worker 
72*61046927SAndroid Build Coastguard Worker /**
73*61046927SAndroid Build Coastguard Worker  * Returns a corresponding internal floating point format for a given base
74*61046927SAndroid Build Coastguard Worker  * format as specifed by OES_texture_float. In case of GL_FLOAT, the internal
75*61046927SAndroid Build Coastguard Worker  * format needs to be a 32 bit component and in case of GL_HALF_FLOAT_OES it
76*61046927SAndroid Build Coastguard Worker  * needs to be a 16 bit component.
77*61046927SAndroid Build Coastguard Worker  *
78*61046927SAndroid Build Coastguard Worker  * For example, given base format GL_RGBA, type GL_FLOAT return GL_RGBA32F_ARB.
79*61046927SAndroid Build Coastguard Worker  */
80*61046927SAndroid Build Coastguard Worker static GLenum
adjust_for_oes_float_texture(const struct gl_context * ctx,GLenum format,GLenum type)81*61046927SAndroid Build Coastguard Worker adjust_for_oes_float_texture(const struct gl_context *ctx,
82*61046927SAndroid Build Coastguard Worker                              GLenum format, GLenum type)
83*61046927SAndroid Build Coastguard Worker {
84*61046927SAndroid Build Coastguard Worker    switch (type) {
85*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
86*61046927SAndroid Build Coastguard Worker       if (ctx->Extensions.OES_texture_float) {
87*61046927SAndroid Build Coastguard Worker          switch (format) {
88*61046927SAndroid Build Coastguard Worker          case GL_RGBA:
89*61046927SAndroid Build Coastguard Worker             return GL_RGBA32F;
90*61046927SAndroid Build Coastguard Worker          case GL_RGB:
91*61046927SAndroid Build Coastguard Worker             return GL_RGB32F;
92*61046927SAndroid Build Coastguard Worker          case GL_ALPHA:
93*61046927SAndroid Build Coastguard Worker             return GL_ALPHA32F_ARB;
94*61046927SAndroid Build Coastguard Worker          case GL_LUMINANCE:
95*61046927SAndroid Build Coastguard Worker             return GL_LUMINANCE32F_ARB;
96*61046927SAndroid Build Coastguard Worker          case GL_LUMINANCE_ALPHA:
97*61046927SAndroid Build Coastguard Worker             return GL_LUMINANCE_ALPHA32F_ARB;
98*61046927SAndroid Build Coastguard Worker          default:
99*61046927SAndroid Build Coastguard Worker             break;
100*61046927SAndroid Build Coastguard Worker          }
101*61046927SAndroid Build Coastguard Worker       }
102*61046927SAndroid Build Coastguard Worker       break;
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker    case GL_HALF_FLOAT_OES:
105*61046927SAndroid Build Coastguard Worker       if (ctx->Extensions.OES_texture_half_float) {
106*61046927SAndroid Build Coastguard Worker          switch (format) {
107*61046927SAndroid Build Coastguard Worker          case GL_RGBA:
108*61046927SAndroid Build Coastguard Worker             return GL_RGBA16F;
109*61046927SAndroid Build Coastguard Worker          case GL_RGB:
110*61046927SAndroid Build Coastguard Worker             return GL_RGB16F;
111*61046927SAndroid Build Coastguard Worker          case GL_ALPHA:
112*61046927SAndroid Build Coastguard Worker             return GL_ALPHA16F_ARB;
113*61046927SAndroid Build Coastguard Worker          case GL_LUMINANCE:
114*61046927SAndroid Build Coastguard Worker             return GL_LUMINANCE16F_ARB;
115*61046927SAndroid Build Coastguard Worker          case GL_LUMINANCE_ALPHA:
116*61046927SAndroid Build Coastguard Worker             return GL_LUMINANCE_ALPHA16F_ARB;
117*61046927SAndroid Build Coastguard Worker          default:
118*61046927SAndroid Build Coastguard Worker             break;
119*61046927SAndroid Build Coastguard Worker          }
120*61046927SAndroid Build Coastguard Worker       }
121*61046927SAndroid Build Coastguard Worker       break;
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker    default:
124*61046927SAndroid Build Coastguard Worker       break;
125*61046927SAndroid Build Coastguard Worker    }
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker    return format;
128*61046927SAndroid Build Coastguard Worker }
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker /**
131*61046927SAndroid Build Coastguard Worker  * Returns a corresponding base format for a given internal floating point
132*61046927SAndroid Build Coastguard Worker  * format as specifed by OES_texture_float.
133*61046927SAndroid Build Coastguard Worker  */
134*61046927SAndroid Build Coastguard Worker static GLenum
oes_float_internal_format(const struct gl_context * ctx,GLenum format,GLenum type)135*61046927SAndroid Build Coastguard Worker oes_float_internal_format(const struct gl_context *ctx,
136*61046927SAndroid Build Coastguard Worker                           GLenum format, GLenum type)
137*61046927SAndroid Build Coastguard Worker {
138*61046927SAndroid Build Coastguard Worker    switch (type) {
139*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
140*61046927SAndroid Build Coastguard Worker       if (ctx->Extensions.OES_texture_float) {
141*61046927SAndroid Build Coastguard Worker          switch (format) {
142*61046927SAndroid Build Coastguard Worker          case GL_RGBA32F:
143*61046927SAndroid Build Coastguard Worker             return GL_RGBA;
144*61046927SAndroid Build Coastguard Worker          case GL_RGB32F:
145*61046927SAndroid Build Coastguard Worker             return GL_RGB;
146*61046927SAndroid Build Coastguard Worker          case GL_ALPHA32F_ARB:
147*61046927SAndroid Build Coastguard Worker             return GL_ALPHA;
148*61046927SAndroid Build Coastguard Worker          case GL_LUMINANCE32F_ARB:
149*61046927SAndroid Build Coastguard Worker             return GL_LUMINANCE;
150*61046927SAndroid Build Coastguard Worker          case GL_LUMINANCE_ALPHA32F_ARB:
151*61046927SAndroid Build Coastguard Worker             return GL_LUMINANCE_ALPHA;
152*61046927SAndroid Build Coastguard Worker          default:
153*61046927SAndroid Build Coastguard Worker             break;
154*61046927SAndroid Build Coastguard Worker          }
155*61046927SAndroid Build Coastguard Worker       }
156*61046927SAndroid Build Coastguard Worker       break;
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker    case GL_HALF_FLOAT_OES:
159*61046927SAndroid Build Coastguard Worker       if (ctx->Extensions.OES_texture_half_float) {
160*61046927SAndroid Build Coastguard Worker          switch (format) {
161*61046927SAndroid Build Coastguard Worker          case GL_RGBA16F:
162*61046927SAndroid Build Coastguard Worker             return GL_RGBA;
163*61046927SAndroid Build Coastguard Worker          case GL_RGB16F:
164*61046927SAndroid Build Coastguard Worker             return GL_RGB;
165*61046927SAndroid Build Coastguard Worker          case GL_ALPHA16F_ARB:
166*61046927SAndroid Build Coastguard Worker             return GL_ALPHA;
167*61046927SAndroid Build Coastguard Worker          case GL_LUMINANCE16F_ARB:
168*61046927SAndroid Build Coastguard Worker             return GL_LUMINANCE;
169*61046927SAndroid Build Coastguard Worker          case GL_LUMINANCE_ALPHA16F_ARB:
170*61046927SAndroid Build Coastguard Worker             return GL_LUMINANCE_ALPHA;
171*61046927SAndroid Build Coastguard Worker          default:
172*61046927SAndroid Build Coastguard Worker             break;
173*61046927SAndroid Build Coastguard Worker          }
174*61046927SAndroid Build Coastguard Worker       }
175*61046927SAndroid Build Coastguard Worker       break;
176*61046927SAndroid Build Coastguard Worker    }
177*61046927SAndroid Build Coastguard Worker    return format;
178*61046927SAndroid Build Coastguard Worker }
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker /**
182*61046927SAndroid Build Coastguard Worker  * Install gl_texture_image in a gl_texture_object according to the target
183*61046927SAndroid Build Coastguard Worker  * and level parameters.
184*61046927SAndroid Build Coastguard Worker  *
185*61046927SAndroid Build Coastguard Worker  * \param tObj texture object.
186*61046927SAndroid Build Coastguard Worker  * \param target texture target.
187*61046927SAndroid Build Coastguard Worker  * \param level image level.
188*61046927SAndroid Build Coastguard Worker  * \param texImage texture image.
189*61046927SAndroid Build Coastguard Worker  */
190*61046927SAndroid Build Coastguard Worker static void
set_tex_image(struct gl_texture_object * tObj,GLenum target,GLint level,struct gl_texture_image * texImage)191*61046927SAndroid Build Coastguard Worker set_tex_image(struct gl_texture_object *tObj,
192*61046927SAndroid Build Coastguard Worker               GLenum target, GLint level,
193*61046927SAndroid Build Coastguard Worker               struct gl_texture_image *texImage)
194*61046927SAndroid Build Coastguard Worker {
195*61046927SAndroid Build Coastguard Worker    const GLuint face = _mesa_tex_target_to_face(target);
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker    assert(tObj);
198*61046927SAndroid Build Coastguard Worker    assert(texImage);
199*61046927SAndroid Build Coastguard Worker    if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES)
200*61046927SAndroid Build Coastguard Worker       assert(level == 0);
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker    tObj->Image[face][level] = texImage;
203*61046927SAndroid Build Coastguard Worker 
204*61046927SAndroid Build Coastguard Worker    /* Set the 'back' pointer */
205*61046927SAndroid Build Coastguard Worker    texImage->TexObject = tObj;
206*61046927SAndroid Build Coastguard Worker    texImage->Level = level;
207*61046927SAndroid Build Coastguard Worker    texImage->Face = face;
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker /**
212*61046927SAndroid Build Coastguard Worker  * Free a gl_texture_image and associated data.
213*61046927SAndroid Build Coastguard Worker  * This function is a fallback.
214*61046927SAndroid Build Coastguard Worker  *
215*61046927SAndroid Build Coastguard Worker  * \param texImage texture image.
216*61046927SAndroid Build Coastguard Worker  *
217*61046927SAndroid Build Coastguard Worker  * Free the texture image structure and the associated image data.
218*61046927SAndroid Build Coastguard Worker  */
219*61046927SAndroid Build Coastguard Worker void
_mesa_delete_texture_image(struct gl_context * ctx,struct gl_texture_image * texImage)220*61046927SAndroid Build Coastguard Worker _mesa_delete_texture_image(struct gl_context *ctx,
221*61046927SAndroid Build Coastguard Worker                            struct gl_texture_image *texImage)
222*61046927SAndroid Build Coastguard Worker {
223*61046927SAndroid Build Coastguard Worker    /* Free texImage->Data and/or any other driver-specific texture
224*61046927SAndroid Build Coastguard Worker     * image storage.
225*61046927SAndroid Build Coastguard Worker     */
226*61046927SAndroid Build Coastguard Worker    st_FreeTextureImageBuffer( ctx, texImage );
227*61046927SAndroid Build Coastguard Worker    FREE(texImage);
228*61046927SAndroid Build Coastguard Worker }
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker 
231*61046927SAndroid Build Coastguard Worker /**
232*61046927SAndroid Build Coastguard Worker  * Test if a target is a proxy target.
233*61046927SAndroid Build Coastguard Worker  *
234*61046927SAndroid Build Coastguard Worker  * \param target texture target.
235*61046927SAndroid Build Coastguard Worker  *
236*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
237*61046927SAndroid Build Coastguard Worker  */
238*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_is_proxy_texture(GLenum target)239*61046927SAndroid Build Coastguard Worker _mesa_is_proxy_texture(GLenum target)
240*61046927SAndroid Build Coastguard Worker {
241*61046927SAndroid Build Coastguard Worker    unsigned i;
242*61046927SAndroid Build Coastguard Worker    static const GLenum targets[] = {
243*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_1D,
244*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_2D,
245*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_3D,
246*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_CUBE_MAP,
247*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_RECTANGLE,
248*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_1D_ARRAY,
249*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_2D_ARRAY,
250*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_CUBE_MAP_ARRAY,
251*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_2D_MULTISAMPLE,
252*61046927SAndroid Build Coastguard Worker       GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY
253*61046927SAndroid Build Coastguard Worker    };
254*61046927SAndroid Build Coastguard Worker    /*
255*61046927SAndroid Build Coastguard Worker     * NUM_TEXTURE_TARGETS should match number of terms above, except there's no
256*61046927SAndroid Build Coastguard Worker     * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
257*61046927SAndroid Build Coastguard Worker     */
258*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(NUM_TEXTURE_TARGETS == ARRAY_SIZE(targets) + 2);
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker    for (i = 0; i < ARRAY_SIZE(targets); ++i)
261*61046927SAndroid Build Coastguard Worker       if (target == targets[i])
262*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
263*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker /**
268*61046927SAndroid Build Coastguard Worker  * Test if a target is an array target.
269*61046927SAndroid Build Coastguard Worker  *
270*61046927SAndroid Build Coastguard Worker  * \param target texture target.
271*61046927SAndroid Build Coastguard Worker  *
272*61046927SAndroid Build Coastguard Worker  * \return true if the target is an array target, false otherwise.
273*61046927SAndroid Build Coastguard Worker  */
274*61046927SAndroid Build Coastguard Worker bool
_mesa_is_array_texture(GLenum target)275*61046927SAndroid Build Coastguard Worker _mesa_is_array_texture(GLenum target)
276*61046927SAndroid Build Coastguard Worker {
277*61046927SAndroid Build Coastguard Worker    switch (target) {
278*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY:
279*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY:
280*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
281*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
282*61046927SAndroid Build Coastguard Worker       return true;
283*61046927SAndroid Build Coastguard Worker    default:
284*61046927SAndroid Build Coastguard Worker       return false;
285*61046927SAndroid Build Coastguard Worker    };
286*61046927SAndroid Build Coastguard Worker }
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker /**
289*61046927SAndroid Build Coastguard Worker  * Test if a target is a cube map.
290*61046927SAndroid Build Coastguard Worker  *
291*61046927SAndroid Build Coastguard Worker  * \param target texture target.
292*61046927SAndroid Build Coastguard Worker  *
293*61046927SAndroid Build Coastguard Worker  * \return true if the target is a cube map, false otherwise.
294*61046927SAndroid Build Coastguard Worker  */
295*61046927SAndroid Build Coastguard Worker bool
_mesa_is_cube_map_texture(GLenum target)296*61046927SAndroid Build Coastguard Worker _mesa_is_cube_map_texture(GLenum target)
297*61046927SAndroid Build Coastguard Worker {
298*61046927SAndroid Build Coastguard Worker    switch(target) {
299*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
300*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
301*61046927SAndroid Build Coastguard Worker       return true;
302*61046927SAndroid Build Coastguard Worker    default:
303*61046927SAndroid Build Coastguard Worker       return false;
304*61046927SAndroid Build Coastguard Worker    }
305*61046927SAndroid Build Coastguard Worker }
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker /**
308*61046927SAndroid Build Coastguard Worker  * Return the proxy target which corresponds to the given texture target
309*61046927SAndroid Build Coastguard Worker  */
310*61046927SAndroid Build Coastguard Worker static GLenum
proxy_target(GLenum target)311*61046927SAndroid Build Coastguard Worker proxy_target(GLenum target)
312*61046927SAndroid Build Coastguard Worker {
313*61046927SAndroid Build Coastguard Worker    switch (target) {
314*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
315*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D:
316*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_1D;
317*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
318*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
319*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_2D;
320*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
321*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_3D:
322*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_3D;
323*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
324*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
325*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
326*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
327*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
328*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
329*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
330*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
331*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_CUBE_MAP;
332*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_RECTANGLE_NV:
333*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_RECTANGLE_NV:
334*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_RECTANGLE_NV;
335*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY_EXT:
336*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
337*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_1D_ARRAY_EXT;
338*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY_EXT:
339*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
340*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_2D_ARRAY_EXT;
341*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
342*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
343*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY;
344*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
345*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
346*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_2D_MULTISAMPLE;
347*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
348*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
349*61046927SAndroid Build Coastguard Worker       return GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY;
350*61046927SAndroid Build Coastguard Worker    default:
351*61046927SAndroid Build Coastguard Worker       _mesa_problem(NULL, "unexpected target in proxy_target()");
352*61046927SAndroid Build Coastguard Worker       return 0;
353*61046927SAndroid Build Coastguard Worker    }
354*61046927SAndroid Build Coastguard Worker }
355*61046927SAndroid Build Coastguard Worker 
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker 
358*61046927SAndroid Build Coastguard Worker 
359*61046927SAndroid Build Coastguard Worker /**
360*61046927SAndroid Build Coastguard Worker  * Get a texture image pointer from a texture object, given a texture
361*61046927SAndroid Build Coastguard Worker  * target and mipmap level.  The target and level parameters should
362*61046927SAndroid Build Coastguard Worker  * have already been error-checked.
363*61046927SAndroid Build Coastguard Worker  *
364*61046927SAndroid Build Coastguard Worker  * \param texObj texture unit.
365*61046927SAndroid Build Coastguard Worker  * \param target texture target.
366*61046927SAndroid Build Coastguard Worker  * \param level image level.
367*61046927SAndroid Build Coastguard Worker  *
368*61046927SAndroid Build Coastguard Worker  * \return pointer to the texture image structure, or NULL on failure.
369*61046927SAndroid Build Coastguard Worker  */
370*61046927SAndroid Build Coastguard Worker struct gl_texture_image *
_mesa_select_tex_image(const struct gl_texture_object * texObj,GLenum target,GLint level)371*61046927SAndroid Build Coastguard Worker _mesa_select_tex_image(const struct gl_texture_object *texObj,
372*61046927SAndroid Build Coastguard Worker 		                 GLenum target, GLint level)
373*61046927SAndroid Build Coastguard Worker {
374*61046927SAndroid Build Coastguard Worker    const GLuint face = _mesa_tex_target_to_face(target);
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker    assert(texObj);
377*61046927SAndroid Build Coastguard Worker    assert(level >= 0);
378*61046927SAndroid Build Coastguard Worker    assert(level < MAX_TEXTURE_LEVELS);
379*61046927SAndroid Build Coastguard Worker 
380*61046927SAndroid Build Coastguard Worker    return texObj->Image[face][level];
381*61046927SAndroid Build Coastguard Worker }
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker 
384*61046927SAndroid Build Coastguard Worker /**
385*61046927SAndroid Build Coastguard Worker  * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
386*61046927SAndroid Build Coastguard Worker  * it and install it.  Only return NULL if passed a bad parameter or run
387*61046927SAndroid Build Coastguard Worker  * out of memory.
388*61046927SAndroid Build Coastguard Worker  */
389*61046927SAndroid Build Coastguard Worker struct gl_texture_image *
_mesa_get_tex_image(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum target,GLint level)390*61046927SAndroid Build Coastguard Worker _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
391*61046927SAndroid Build Coastguard Worker                     GLenum target, GLint level)
392*61046927SAndroid Build Coastguard Worker {
393*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
394*61046927SAndroid Build Coastguard Worker 
395*61046927SAndroid Build Coastguard Worker    if (!texObj)
396*61046927SAndroid Build Coastguard Worker       return NULL;
397*61046927SAndroid Build Coastguard Worker 
398*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
399*61046927SAndroid Build Coastguard Worker    if (!texImage) {
400*61046927SAndroid Build Coastguard Worker       texImage = CALLOC_STRUCT(gl_texture_image);
401*61046927SAndroid Build Coastguard Worker       if (!texImage) {
402*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
403*61046927SAndroid Build Coastguard Worker          return NULL;
404*61046927SAndroid Build Coastguard Worker       }
405*61046927SAndroid Build Coastguard Worker 
406*61046927SAndroid Build Coastguard Worker       set_tex_image(texObj, target, level, texImage);
407*61046927SAndroid Build Coastguard Worker    }
408*61046927SAndroid Build Coastguard Worker 
409*61046927SAndroid Build Coastguard Worker    return texImage;
410*61046927SAndroid Build Coastguard Worker }
411*61046927SAndroid Build Coastguard Worker 
412*61046927SAndroid Build Coastguard Worker 
413*61046927SAndroid Build Coastguard Worker /**
414*61046927SAndroid Build Coastguard Worker  * Return pointer to the specified proxy texture image.
415*61046927SAndroid Build Coastguard Worker  * Note that proxy textures are per-context, not per-texture unit.
416*61046927SAndroid Build Coastguard Worker  * \return pointer to texture image or NULL if invalid target, invalid
417*61046927SAndroid Build Coastguard Worker  *         level, or out of memory.
418*61046927SAndroid Build Coastguard Worker  */
419*61046927SAndroid Build Coastguard Worker static struct gl_texture_image *
get_proxy_tex_image(struct gl_context * ctx,GLenum target,GLint level)420*61046927SAndroid Build Coastguard Worker get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
421*61046927SAndroid Build Coastguard Worker {
422*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
423*61046927SAndroid Build Coastguard Worker    GLuint texIndex;
424*61046927SAndroid Build Coastguard Worker 
425*61046927SAndroid Build Coastguard Worker    if (level < 0)
426*61046927SAndroid Build Coastguard Worker       return NULL;
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker    switch (target) {
429*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D:
430*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_1D_INDEX;
431*61046927SAndroid Build Coastguard Worker       break;
432*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
433*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_2D_INDEX;
434*61046927SAndroid Build Coastguard Worker       break;
435*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_3D:
436*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_3D_INDEX;
437*61046927SAndroid Build Coastguard Worker       break;
438*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
439*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_CUBE_INDEX;
440*61046927SAndroid Build Coastguard Worker       break;
441*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_RECTANGLE_NV:
442*61046927SAndroid Build Coastguard Worker       if (level > 0)
443*61046927SAndroid Build Coastguard Worker          return NULL;
444*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_RECT_INDEX;
445*61046927SAndroid Build Coastguard Worker       break;
446*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
447*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_1D_ARRAY_INDEX;
448*61046927SAndroid Build Coastguard Worker       break;
449*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
450*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_2D_ARRAY_INDEX;
451*61046927SAndroid Build Coastguard Worker       break;
452*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
453*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_CUBE_ARRAY_INDEX;
454*61046927SAndroid Build Coastguard Worker       break;
455*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
456*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_2D_MULTISAMPLE_INDEX;
457*61046927SAndroid Build Coastguard Worker       break;
458*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
459*61046927SAndroid Build Coastguard Worker       texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX;
460*61046927SAndroid Build Coastguard Worker       break;
461*61046927SAndroid Build Coastguard Worker    default:
462*61046927SAndroid Build Coastguard Worker       return NULL;
463*61046927SAndroid Build Coastguard Worker    }
464*61046927SAndroid Build Coastguard Worker 
465*61046927SAndroid Build Coastguard Worker    texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level];
466*61046927SAndroid Build Coastguard Worker    if (!texImage) {
467*61046927SAndroid Build Coastguard Worker       texImage = CALLOC_STRUCT(gl_texture_image);
468*61046927SAndroid Build Coastguard Worker       if (!texImage) {
469*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
470*61046927SAndroid Build Coastguard Worker          return NULL;
471*61046927SAndroid Build Coastguard Worker       }
472*61046927SAndroid Build Coastguard Worker       ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage;
473*61046927SAndroid Build Coastguard Worker       /* Set the 'back' pointer */
474*61046927SAndroid Build Coastguard Worker       texImage->TexObject = ctx->Texture.ProxyTex[texIndex];
475*61046927SAndroid Build Coastguard Worker    }
476*61046927SAndroid Build Coastguard Worker    return texImage;
477*61046927SAndroid Build Coastguard Worker }
478*61046927SAndroid Build Coastguard Worker 
479*61046927SAndroid Build Coastguard Worker 
480*61046927SAndroid Build Coastguard Worker /**
481*61046927SAndroid Build Coastguard Worker  * Get the maximum number of allowed mipmap levels.
482*61046927SAndroid Build Coastguard Worker  *
483*61046927SAndroid Build Coastguard Worker  * \param ctx GL context.
484*61046927SAndroid Build Coastguard Worker  * \param target texture target.
485*61046927SAndroid Build Coastguard Worker  *
486*61046927SAndroid Build Coastguard Worker  * \return the maximum number of allowed mipmap levels for the given
487*61046927SAndroid Build Coastguard Worker  * texture target, or zero if passed a bad target.
488*61046927SAndroid Build Coastguard Worker  *
489*61046927SAndroid Build Coastguard Worker  * \sa gl_constants.
490*61046927SAndroid Build Coastguard Worker  */
491*61046927SAndroid Build Coastguard Worker GLint
_mesa_max_texture_levels(const struct gl_context * ctx,GLenum target)492*61046927SAndroid Build Coastguard Worker _mesa_max_texture_levels(const struct gl_context *ctx, GLenum target)
493*61046927SAndroid Build Coastguard Worker {
494*61046927SAndroid Build Coastguard Worker    switch (target) {
495*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
496*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D:
497*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
498*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
499*61046927SAndroid Build Coastguard Worker       return ffs(util_next_power_of_two(ctx->Const.MaxTextureSize));
500*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
501*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_3D:
502*61046927SAndroid Build Coastguard Worker       return !(_mesa_is_gles2(ctx) && !ctx->Extensions.OES_texture_3D)
503*61046927SAndroid Build Coastguard Worker          ? ctx->Const.Max3DTextureLevels : 0;
504*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
505*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
506*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
507*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
508*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
509*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
510*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
511*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
512*61046927SAndroid Build Coastguard Worker       return ctx->Const.MaxCubeTextureLevels;
513*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_RECTANGLE_NV:
514*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_RECTANGLE_NV:
515*61046927SAndroid Build Coastguard Worker       return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
516*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY_EXT:
517*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
518*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY_EXT:
519*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
520*61046927SAndroid Build Coastguard Worker       return ctx->Extensions.EXT_texture_array
521*61046927SAndroid Build Coastguard Worker          ? ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)) : 0;
522*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
523*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
524*61046927SAndroid Build Coastguard Worker       return _mesa_has_texture_cube_map_array(ctx)
525*61046927SAndroid Build Coastguard Worker          ? ctx->Const.MaxCubeTextureLevels : 0;
526*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_BUFFER:
527*61046927SAndroid Build Coastguard Worker       return (_mesa_has_ARB_texture_buffer_object(ctx) ||
528*61046927SAndroid Build Coastguard Worker               _mesa_has_OES_texture_buffer(ctx)) ? 1 : 0;
529*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
530*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
531*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
532*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
533*61046927SAndroid Build Coastguard Worker       return (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx))
534*61046927SAndroid Build Coastguard Worker          && ctx->Extensions.ARB_texture_multisample
535*61046927SAndroid Build Coastguard Worker          ? 1 : 0;
536*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_EXTERNAL_OES:
537*61046927SAndroid Build Coastguard Worker       return _mesa_has_OES_EGL_image_external(ctx) ? 1 : 0;
538*61046927SAndroid Build Coastguard Worker    default:
539*61046927SAndroid Build Coastguard Worker       return 0; /* bad target */
540*61046927SAndroid Build Coastguard Worker    }
541*61046927SAndroid Build Coastguard Worker }
542*61046927SAndroid Build Coastguard Worker 
543*61046927SAndroid Build Coastguard Worker 
544*61046927SAndroid Build Coastguard Worker /**
545*61046927SAndroid Build Coastguard Worker  * Return number of dimensions per mipmap level for the given texture target.
546*61046927SAndroid Build Coastguard Worker  */
547*61046927SAndroid Build Coastguard Worker GLint
_mesa_get_texture_dimensions(GLenum target)548*61046927SAndroid Build Coastguard Worker _mesa_get_texture_dimensions(GLenum target)
549*61046927SAndroid Build Coastguard Worker {
550*61046927SAndroid Build Coastguard Worker    switch (target) {
551*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
552*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D:
553*61046927SAndroid Build Coastguard Worker       return 1;
554*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
555*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_RECTANGLE:
556*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
557*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
558*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_RECTANGLE:
559*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
560*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
561*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
562*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
563*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
564*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
565*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
566*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY:
567*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D_ARRAY:
568*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_EXTERNAL_OES:
569*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
570*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
571*61046927SAndroid Build Coastguard Worker       return 2;
572*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
573*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_3D:
574*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY:
575*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY:
576*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
577*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
578*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
579*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
580*61046927SAndroid Build Coastguard Worker       return 3;
581*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_BUFFER:
582*61046927SAndroid Build Coastguard Worker       FALLTHROUGH;
583*61046927SAndroid Build Coastguard Worker    default:
584*61046927SAndroid Build Coastguard Worker       _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
585*61046927SAndroid Build Coastguard Worker                     target);
586*61046927SAndroid Build Coastguard Worker       return 2;
587*61046927SAndroid Build Coastguard Worker    }
588*61046927SAndroid Build Coastguard Worker }
589*61046927SAndroid Build Coastguard Worker 
590*61046927SAndroid Build Coastguard Worker 
591*61046927SAndroid Build Coastguard Worker /**
592*61046927SAndroid Build Coastguard Worker  * Check if a texture target can have more than one layer.
593*61046927SAndroid Build Coastguard Worker  */
594*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_tex_target_is_layered(GLenum target)595*61046927SAndroid Build Coastguard Worker _mesa_tex_target_is_layered(GLenum target)
596*61046927SAndroid Build Coastguard Worker {
597*61046927SAndroid Build Coastguard Worker    switch (target) {
598*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
599*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D:
600*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
601*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
602*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_RECTANGLE:
603*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_RECTANGLE:
604*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
605*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
606*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_BUFFER:
607*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
608*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
609*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
610*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
611*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
612*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
613*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_EXTERNAL_OES:
614*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
617*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_3D:
618*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
619*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
620*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY:
621*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D_ARRAY:
622*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY:
623*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY:
624*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
625*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
626*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
627*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
628*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
629*61046927SAndroid Build Coastguard Worker 
630*61046927SAndroid Build Coastguard Worker    default:
631*61046927SAndroid Build Coastguard Worker       assert(!"Invalid texture target.");
632*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
633*61046927SAndroid Build Coastguard Worker    }
634*61046927SAndroid Build Coastguard Worker }
635*61046927SAndroid Build Coastguard Worker 
636*61046927SAndroid Build Coastguard Worker 
637*61046927SAndroid Build Coastguard Worker /**
638*61046927SAndroid Build Coastguard Worker  * Return the number of layers present in the given level of an array,
639*61046927SAndroid Build Coastguard Worker  * cubemap or 3D texture.  If the texture is not layered return zero.
640*61046927SAndroid Build Coastguard Worker  */
641*61046927SAndroid Build Coastguard Worker GLuint
_mesa_get_texture_layers(const struct gl_texture_object * texObj,GLint level)642*61046927SAndroid Build Coastguard Worker _mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level)
643*61046927SAndroid Build Coastguard Worker {
644*61046927SAndroid Build Coastguard Worker    assert(level >= 0 && level < MAX_TEXTURE_LEVELS);
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker    switch (texObj->Target) {
647*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
648*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
649*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_RECTANGLE:
650*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
651*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_BUFFER:
652*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_EXTERNAL_OES:
653*61046927SAndroid Build Coastguard Worker       return 0;
654*61046927SAndroid Build Coastguard Worker 
655*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
656*61046927SAndroid Build Coastguard Worker       return 6;
657*61046927SAndroid Build Coastguard Worker 
658*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY: {
659*61046927SAndroid Build Coastguard Worker       struct gl_texture_image *img = texObj->Image[0][level];
660*61046927SAndroid Build Coastguard Worker       return img ? img->Height : 0;
661*61046927SAndroid Build Coastguard Worker    }
662*61046927SAndroid Build Coastguard Worker 
663*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
664*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY:
665*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
666*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: {
667*61046927SAndroid Build Coastguard Worker       struct gl_texture_image *img = texObj->Image[0][level];
668*61046927SAndroid Build Coastguard Worker       return img ? img->Depth : 0;
669*61046927SAndroid Build Coastguard Worker    }
670*61046927SAndroid Build Coastguard Worker 
671*61046927SAndroid Build Coastguard Worker    default:
672*61046927SAndroid Build Coastguard Worker       assert(!"Invalid texture target.");
673*61046927SAndroid Build Coastguard Worker       return 0;
674*61046927SAndroid Build Coastguard Worker    }
675*61046927SAndroid Build Coastguard Worker }
676*61046927SAndroid Build Coastguard Worker 
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker /**
679*61046927SAndroid Build Coastguard Worker  * Return the maximum number of mipmap levels for the given target
680*61046927SAndroid Build Coastguard Worker  * and the dimensions.
681*61046927SAndroid Build Coastguard Worker  * The dimensions are expected not to include the border.
682*61046927SAndroid Build Coastguard Worker  */
683*61046927SAndroid Build Coastguard Worker GLsizei
_mesa_get_tex_max_num_levels(GLenum target,GLsizei width,GLsizei height,GLsizei depth)684*61046927SAndroid Build Coastguard Worker _mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height,
685*61046927SAndroid Build Coastguard Worker                              GLsizei depth)
686*61046927SAndroid Build Coastguard Worker {
687*61046927SAndroid Build Coastguard Worker    GLsizei size;
688*61046927SAndroid Build Coastguard Worker 
689*61046927SAndroid Build Coastguard Worker    switch (target) {
690*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
691*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY:
692*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D:
693*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D_ARRAY:
694*61046927SAndroid Build Coastguard Worker       size = width;
695*61046927SAndroid Build Coastguard Worker       break;
696*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
697*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
698*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
699*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
700*61046927SAndroid Build Coastguard Worker       size = width;
701*61046927SAndroid Build Coastguard Worker       break;
702*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
703*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY:
704*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
705*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY:
706*61046927SAndroid Build Coastguard Worker       size = MAX2(width, height);
707*61046927SAndroid Build Coastguard Worker       break;
708*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
709*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_3D:
710*61046927SAndroid Build Coastguard Worker       size = MAX3(width, height, depth);
711*61046927SAndroid Build Coastguard Worker       break;
712*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_RECTANGLE:
713*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_EXTERNAL_OES:
714*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
715*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
716*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_RECTANGLE:
717*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
718*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
719*61046927SAndroid Build Coastguard Worker       return 1;
720*61046927SAndroid Build Coastguard Worker    default:
721*61046927SAndroid Build Coastguard Worker       assert(0);
722*61046927SAndroid Build Coastguard Worker       return 1;
723*61046927SAndroid Build Coastguard Worker    }
724*61046927SAndroid Build Coastguard Worker 
725*61046927SAndroid Build Coastguard Worker    return util_logbase2(size) + 1;
726*61046927SAndroid Build Coastguard Worker }
727*61046927SAndroid Build Coastguard Worker 
728*61046927SAndroid Build Coastguard Worker 
729*61046927SAndroid Build Coastguard Worker #if 000 /* not used anymore */
730*61046927SAndroid Build Coastguard Worker /*
731*61046927SAndroid Build Coastguard Worker  * glTexImage[123]D can accept a NULL image pointer.  In this case we
732*61046927SAndroid Build Coastguard Worker  * create a texture image with unspecified image contents per the OpenGL
733*61046927SAndroid Build Coastguard Worker  * spec.
734*61046927SAndroid Build Coastguard Worker  */
735*61046927SAndroid Build Coastguard Worker static GLubyte *
736*61046927SAndroid Build Coastguard Worker make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
737*61046927SAndroid Build Coastguard Worker {
738*61046927SAndroid Build Coastguard Worker    const GLint components = _mesa_components_in_format(format);
739*61046927SAndroid Build Coastguard Worker    const GLint numPixels = width * height * depth;
740*61046927SAndroid Build Coastguard Worker    GLubyte *data = (GLubyte *) malloc(numPixels * components * sizeof(GLubyte));
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
743*61046927SAndroid Build Coastguard Worker    /*
744*61046927SAndroid Build Coastguard Worker     * Let's see if anyone finds this.  If glTexImage2D() is called with
745*61046927SAndroid Build Coastguard Worker     * a NULL image pointer then load the texture image with something
746*61046927SAndroid Build Coastguard Worker     * interesting instead of leaving it indeterminate.
747*61046927SAndroid Build Coastguard Worker     */
748*61046927SAndroid Build Coastguard Worker    if (data) {
749*61046927SAndroid Build Coastguard Worker       static const char message[8][32] = {
750*61046927SAndroid Build Coastguard Worker          "   X   X  XXXXX   XXX     X    ",
751*61046927SAndroid Build Coastguard Worker          "   XX XX  X      X   X   X X   ",
752*61046927SAndroid Build Coastguard Worker          "   X X X  X      X      X   X  ",
753*61046927SAndroid Build Coastguard Worker          "   X   X  XXXX    XXX   XXXXX  ",
754*61046927SAndroid Build Coastguard Worker          "   X   X  X          X  X   X  ",
755*61046927SAndroid Build Coastguard Worker          "   X   X  X      X   X  X   X  ",
756*61046927SAndroid Build Coastguard Worker          "   X   X  XXXXX   XXX   X   X  ",
757*61046927SAndroid Build Coastguard Worker          "                               "
758*61046927SAndroid Build Coastguard Worker       };
759*61046927SAndroid Build Coastguard Worker 
760*61046927SAndroid Build Coastguard Worker       GLubyte *imgPtr = data;
761*61046927SAndroid Build Coastguard Worker       GLint h, i, j, k;
762*61046927SAndroid Build Coastguard Worker       for (h = 0; h < depth; h++) {
763*61046927SAndroid Build Coastguard Worker          for (i = 0; i < height; i++) {
764*61046927SAndroid Build Coastguard Worker             GLint srcRow = 7 - (i % 8);
765*61046927SAndroid Build Coastguard Worker             for (j = 0; j < width; j++) {
766*61046927SAndroid Build Coastguard Worker                GLint srcCol = j % 32;
767*61046927SAndroid Build Coastguard Worker                GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
768*61046927SAndroid Build Coastguard Worker                for (k = 0; k < components; k++) {
769*61046927SAndroid Build Coastguard Worker                   *imgPtr++ = texel;
770*61046927SAndroid Build Coastguard Worker                }
771*61046927SAndroid Build Coastguard Worker             }
772*61046927SAndroid Build Coastguard Worker          }
773*61046927SAndroid Build Coastguard Worker       }
774*61046927SAndroid Build Coastguard Worker    }
775*61046927SAndroid Build Coastguard Worker #endif
776*61046927SAndroid Build Coastguard Worker 
777*61046927SAndroid Build Coastguard Worker    return data;
778*61046927SAndroid Build Coastguard Worker }
779*61046927SAndroid Build Coastguard Worker #endif
780*61046927SAndroid Build Coastguard Worker 
781*61046927SAndroid Build Coastguard Worker 
782*61046927SAndroid Build Coastguard Worker 
783*61046927SAndroid Build Coastguard Worker /**
784*61046927SAndroid Build Coastguard Worker  * Set the size and format-related fields of a gl_texture_image struct
785*61046927SAndroid Build Coastguard Worker  * to zero.  This is used when a proxy texture test fails.
786*61046927SAndroid Build Coastguard Worker  */
787*61046927SAndroid Build Coastguard Worker static void
clear_teximage_fields(struct gl_texture_image * img)788*61046927SAndroid Build Coastguard Worker clear_teximage_fields(struct gl_texture_image *img)
789*61046927SAndroid Build Coastguard Worker {
790*61046927SAndroid Build Coastguard Worker    assert(img);
791*61046927SAndroid Build Coastguard Worker    img->_BaseFormat = 0;
792*61046927SAndroid Build Coastguard Worker    img->InternalFormat = 0;
793*61046927SAndroid Build Coastguard Worker    img->Border = 0;
794*61046927SAndroid Build Coastguard Worker    img->Width = 0;
795*61046927SAndroid Build Coastguard Worker    img->Height = 0;
796*61046927SAndroid Build Coastguard Worker    img->Depth = 0;
797*61046927SAndroid Build Coastguard Worker    img->Width2 = 0;
798*61046927SAndroid Build Coastguard Worker    img->Height2 = 0;
799*61046927SAndroid Build Coastguard Worker    img->Depth2 = 0;
800*61046927SAndroid Build Coastguard Worker    img->TexFormat = MESA_FORMAT_NONE;
801*61046927SAndroid Build Coastguard Worker    img->NumSamples = 0;
802*61046927SAndroid Build Coastguard Worker    img->FixedSampleLocations = GL_TRUE;
803*61046927SAndroid Build Coastguard Worker }
804*61046927SAndroid Build Coastguard Worker 
805*61046927SAndroid Build Coastguard Worker /**
806*61046927SAndroid Build Coastguard Worker  * Given a user-specified texture base format, the actual gallium texture
807*61046927SAndroid Build Coastguard Worker  * format and the current GL_DEPTH_MODE, return a texture swizzle.
808*61046927SAndroid Build Coastguard Worker  *
809*61046927SAndroid Build Coastguard Worker  * Consider the case where the user requests a GL_RGB internal texture
810*61046927SAndroid Build Coastguard Worker  * format the driver actually uses an RGBA format.  The A component should
811*61046927SAndroid Build Coastguard Worker  * be ignored and sampling from the texture should always return (r,g,b,1).
812*61046927SAndroid Build Coastguard Worker  * But if we rendered to the texture we might have written A values != 1.
813*61046927SAndroid Build Coastguard Worker  * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
814*61046927SAndroid Build Coastguard Worker  * This function computes the texture swizzle needed to get the expected
815*61046927SAndroid Build Coastguard Worker  * values.
816*61046927SAndroid Build Coastguard Worker  *
817*61046927SAndroid Build Coastguard Worker  * In the case of depth textures, the GL_DEPTH_MODE state determines the
818*61046927SAndroid Build Coastguard Worker  * texture swizzle.
819*61046927SAndroid Build Coastguard Worker  *
820*61046927SAndroid Build Coastguard Worker  * This result must be composed with the user-specified swizzle to get
821*61046927SAndroid Build Coastguard Worker  * the final swizzle.
822*61046927SAndroid Build Coastguard Worker  */
823*61046927SAndroid Build Coastguard Worker static unsigned
compute_texture_format_swizzle(GLenum baseFormat,GLenum depthMode,bool glsl130_or_later)824*61046927SAndroid Build Coastguard Worker compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
825*61046927SAndroid Build Coastguard Worker                                      bool glsl130_or_later)
826*61046927SAndroid Build Coastguard Worker {
827*61046927SAndroid Build Coastguard Worker    switch (baseFormat) {
828*61046927SAndroid Build Coastguard Worker    case GL_RGBA:
829*61046927SAndroid Build Coastguard Worker       return SWIZZLE_XYZW;
830*61046927SAndroid Build Coastguard Worker    case GL_RGB:
831*61046927SAndroid Build Coastguard Worker       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
832*61046927SAndroid Build Coastguard Worker    case GL_RG:
833*61046927SAndroid Build Coastguard Worker       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
834*61046927SAndroid Build Coastguard Worker    case GL_RED:
835*61046927SAndroid Build Coastguard Worker       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
836*61046927SAndroid Build Coastguard Worker                            SWIZZLE_ZERO, SWIZZLE_ONE);
837*61046927SAndroid Build Coastguard Worker    case GL_ALPHA:
838*61046927SAndroid Build Coastguard Worker       return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
839*61046927SAndroid Build Coastguard Worker                            SWIZZLE_ZERO, SWIZZLE_W);
840*61046927SAndroid Build Coastguard Worker    case GL_LUMINANCE:
841*61046927SAndroid Build Coastguard Worker       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
842*61046927SAndroid Build Coastguard Worker    case GL_LUMINANCE_ALPHA:
843*61046927SAndroid Build Coastguard Worker       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
844*61046927SAndroid Build Coastguard Worker    case GL_INTENSITY:
845*61046927SAndroid Build Coastguard Worker       return SWIZZLE_XXXX;
846*61046927SAndroid Build Coastguard Worker    case GL_STENCIL_INDEX:
847*61046927SAndroid Build Coastguard Worker    case GL_DEPTH_STENCIL:
848*61046927SAndroid Build Coastguard Worker    case GL_DEPTH_COMPONENT:
849*61046927SAndroid Build Coastguard Worker       /* Now examine the depth mode */
850*61046927SAndroid Build Coastguard Worker       switch (depthMode) {
851*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE:
852*61046927SAndroid Build Coastguard Worker          return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
853*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY:
854*61046927SAndroid Build Coastguard Worker          return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
855*61046927SAndroid Build Coastguard Worker       case GL_ALPHA:
856*61046927SAndroid Build Coastguard Worker          /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore
857*61046927SAndroid Build Coastguard Worker           * the depth mode and return float, while older shadow* functions
858*61046927SAndroid Build Coastguard Worker           * and ARB_fp instructions return vec4 according to the depth mode.
859*61046927SAndroid Build Coastguard Worker           *
860*61046927SAndroid Build Coastguard Worker           * The problem with the GLSL 1.30 functions is that GL_ALPHA forces
861*61046927SAndroid Build Coastguard Worker           * them to return 0, breaking them completely.
862*61046927SAndroid Build Coastguard Worker           *
863*61046927SAndroid Build Coastguard Worker           * A proper fix would increase code complexity and that's not worth
864*61046927SAndroid Build Coastguard Worker           * it for a rarely used feature such as the GL_ALPHA depth mode
865*61046927SAndroid Build Coastguard Worker           * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all
866*61046927SAndroid Build Coastguard Worker           * shaders that use GLSL 1.30 or later.
867*61046927SAndroid Build Coastguard Worker           *
868*61046927SAndroid Build Coastguard Worker           * BTW, it's required that sampler views are updated when
869*61046927SAndroid Build Coastguard Worker           * shaders change (check_sampler_swizzle takes care of that).
870*61046927SAndroid Build Coastguard Worker           */
871*61046927SAndroid Build Coastguard Worker          if (glsl130_or_later)
872*61046927SAndroid Build Coastguard Worker             return SWIZZLE_XXXX;
873*61046927SAndroid Build Coastguard Worker          else
874*61046927SAndroid Build Coastguard Worker             return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
875*61046927SAndroid Build Coastguard Worker                                  SWIZZLE_ZERO, SWIZZLE_X);
876*61046927SAndroid Build Coastguard Worker       case GL_RED:
877*61046927SAndroid Build Coastguard Worker          return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
878*61046927SAndroid Build Coastguard Worker                               SWIZZLE_ZERO, SWIZZLE_ONE);
879*61046927SAndroid Build Coastguard Worker       default:
880*61046927SAndroid Build Coastguard Worker          assert(!"Unexpected depthMode");
881*61046927SAndroid Build Coastguard Worker          return SWIZZLE_XYZW;
882*61046927SAndroid Build Coastguard Worker       }
883*61046927SAndroid Build Coastguard Worker    default:
884*61046927SAndroid Build Coastguard Worker       assert(!"Unexpected baseFormat");
885*61046927SAndroid Build Coastguard Worker       return SWIZZLE_XYZW;
886*61046927SAndroid Build Coastguard Worker    }
887*61046927SAndroid Build Coastguard Worker }
888*61046927SAndroid Build Coastguard Worker 
889*61046927SAndroid Build Coastguard Worker void
_mesa_update_teximage_format_swizzle(struct gl_context * ctx,struct gl_texture_image * img,GLenum depth_mode)890*61046927SAndroid Build Coastguard Worker _mesa_update_teximage_format_swizzle(struct gl_context *ctx,
891*61046927SAndroid Build Coastguard Worker                                      struct gl_texture_image *img,
892*61046927SAndroid Build Coastguard Worker                                      GLenum depth_mode)
893*61046927SAndroid Build Coastguard Worker {
894*61046927SAndroid Build Coastguard Worker    if (!img)
895*61046927SAndroid Build Coastguard Worker       return;
896*61046927SAndroid Build Coastguard Worker    img->FormatSwizzle = compute_texture_format_swizzle(img->_BaseFormat, depth_mode, false);
897*61046927SAndroid Build Coastguard Worker    img->FormatSwizzleGLSL130 = compute_texture_format_swizzle(img->_BaseFormat, depth_mode, true);
898*61046927SAndroid Build Coastguard Worker }
899*61046927SAndroid Build Coastguard Worker 
900*61046927SAndroid Build Coastguard Worker /**
901*61046927SAndroid Build Coastguard Worker  * Initialize basic fields of the gl_texture_image struct.
902*61046927SAndroid Build Coastguard Worker  *
903*61046927SAndroid Build Coastguard Worker  * \param ctx GL context.
904*61046927SAndroid Build Coastguard Worker  * \param img texture image structure to be initialized.
905*61046927SAndroid Build Coastguard Worker  * \param width image width.
906*61046927SAndroid Build Coastguard Worker  * \param height image height.
907*61046927SAndroid Build Coastguard Worker  * \param depth image depth.
908*61046927SAndroid Build Coastguard Worker  * \param border image border.
909*61046927SAndroid Build Coastguard Worker  * \param internalFormat internal format.
910*61046927SAndroid Build Coastguard Worker  * \param format  the actual hardware format (one of MESA_FORMAT_*)
911*61046927SAndroid Build Coastguard Worker  * \param numSamples  number of samples per texel, or zero for non-MS.
912*61046927SAndroid Build Coastguard Worker  * \param fixedSampleLocations  are sample locations fixed?
913*61046927SAndroid Build Coastguard Worker  *
914*61046927SAndroid Build Coastguard Worker  * Fills in the fields of \p img with the given information.
915*61046927SAndroid Build Coastguard Worker  * Note: width, height and depth include the border.
916*61046927SAndroid Build Coastguard Worker  */
917*61046927SAndroid Build Coastguard Worker void
_mesa_init_teximage_fields_ms(struct gl_context * ctx,struct gl_texture_image * img,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum internalFormat,mesa_format format,GLuint numSamples,GLboolean fixedSampleLocations)918*61046927SAndroid Build Coastguard Worker _mesa_init_teximage_fields_ms(struct gl_context *ctx,
919*61046927SAndroid Build Coastguard Worker                         struct gl_texture_image *img,
920*61046927SAndroid Build Coastguard Worker                         GLsizei width, GLsizei height, GLsizei depth,
921*61046927SAndroid Build Coastguard Worker                         GLint border, GLenum internalFormat,
922*61046927SAndroid Build Coastguard Worker                         mesa_format format,
923*61046927SAndroid Build Coastguard Worker                         GLuint numSamples, GLboolean fixedSampleLocations)
924*61046927SAndroid Build Coastguard Worker {
925*61046927SAndroid Build Coastguard Worker    const GLint base_format =_mesa_base_tex_format(ctx, internalFormat);
926*61046927SAndroid Build Coastguard Worker    GLenum target;
927*61046927SAndroid Build Coastguard Worker    assert(img);
928*61046927SAndroid Build Coastguard Worker    assert(width >= 0);
929*61046927SAndroid Build Coastguard Worker    assert(height >= 0);
930*61046927SAndroid Build Coastguard Worker    assert(depth >= 0);
931*61046927SAndroid Build Coastguard Worker 
932*61046927SAndroid Build Coastguard Worker    target = img->TexObject->Target;
933*61046927SAndroid Build Coastguard Worker    assert(base_format != -1);
934*61046927SAndroid Build Coastguard Worker    img->_BaseFormat = (GLenum16)base_format;
935*61046927SAndroid Build Coastguard Worker    img->InternalFormat = internalFormat;
936*61046927SAndroid Build Coastguard Worker    img->Border = border;
937*61046927SAndroid Build Coastguard Worker    img->Width = width;
938*61046927SAndroid Build Coastguard Worker    img->Height = height;
939*61046927SAndroid Build Coastguard Worker    img->Depth = depth;
940*61046927SAndroid Build Coastguard Worker 
941*61046927SAndroid Build Coastguard Worker    GLenum depth_mode = _mesa_is_desktop_gl_core(ctx) ? GL_RED : GL_LUMINANCE;
942*61046927SAndroid Build Coastguard Worker 
943*61046927SAndroid Build Coastguard Worker    /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures
944*61046927SAndroid Build Coastguard Worker     * with depth component data specified with a sized internal format.
945*61046927SAndroid Build Coastguard Worker     */
946*61046927SAndroid Build Coastguard Worker    if (_mesa_is_gles3(ctx) &&
947*61046927SAndroid Build Coastguard Worker        (base_format == GL_DEPTH_COMPONENT ||
948*61046927SAndroid Build Coastguard Worker         base_format == GL_DEPTH_STENCIL ||
949*61046927SAndroid Build Coastguard Worker         base_format == GL_STENCIL_INDEX)) {
950*61046927SAndroid Build Coastguard Worker       if (internalFormat != GL_DEPTH_COMPONENT &&
951*61046927SAndroid Build Coastguard Worker           internalFormat != GL_DEPTH_STENCIL &&
952*61046927SAndroid Build Coastguard Worker           internalFormat != GL_STENCIL_INDEX)
953*61046927SAndroid Build Coastguard Worker          depth_mode = GL_RED;
954*61046927SAndroid Build Coastguard Worker    }
955*61046927SAndroid Build Coastguard Worker    _mesa_update_teximage_format_swizzle(ctx, img, depth_mode);
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker    img->Width2 = width - 2 * border;
958*61046927SAndroid Build Coastguard Worker 
959*61046927SAndroid Build Coastguard Worker    switch(target) {
960*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
961*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_BUFFER:
962*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D:
963*61046927SAndroid Build Coastguard Worker       if (height == 0)
964*61046927SAndroid Build Coastguard Worker          img->Height2 = 0;
965*61046927SAndroid Build Coastguard Worker       else
966*61046927SAndroid Build Coastguard Worker          img->Height2 = 1;
967*61046927SAndroid Build Coastguard Worker       if (depth == 0)
968*61046927SAndroid Build Coastguard Worker          img->Depth2 = 0;
969*61046927SAndroid Build Coastguard Worker       else
970*61046927SAndroid Build Coastguard Worker          img->Depth2 = 1;
971*61046927SAndroid Build Coastguard Worker       break;
972*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY:
973*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D_ARRAY:
974*61046927SAndroid Build Coastguard Worker       img->Height2 = height; /* no border */
975*61046927SAndroid Build Coastguard Worker       if (depth == 0)
976*61046927SAndroid Build Coastguard Worker          img->Depth2 = 0;
977*61046927SAndroid Build Coastguard Worker       else
978*61046927SAndroid Build Coastguard Worker          img->Depth2 = 1;
979*61046927SAndroid Build Coastguard Worker       break;
980*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
981*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_RECTANGLE:
982*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
983*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
984*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
985*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
986*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
987*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
988*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
989*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_EXTERNAL_OES:
990*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
991*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_RECTANGLE:
992*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
993*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
994*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
995*61046927SAndroid Build Coastguard Worker       img->Height2 = height - 2 * border;
996*61046927SAndroid Build Coastguard Worker       if (depth == 0)
997*61046927SAndroid Build Coastguard Worker          img->Depth2 = 0;
998*61046927SAndroid Build Coastguard Worker       else
999*61046927SAndroid Build Coastguard Worker          img->Depth2 = 1;
1000*61046927SAndroid Build Coastguard Worker       break;
1001*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY:
1002*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY:
1003*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
1004*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1005*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1006*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
1007*61046927SAndroid Build Coastguard Worker       img->Height2 = height - 2 * border;
1008*61046927SAndroid Build Coastguard Worker       img->Depth2 = depth; /* no border */
1009*61046927SAndroid Build Coastguard Worker       break;
1010*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
1011*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_3D:
1012*61046927SAndroid Build Coastguard Worker       img->Height2 = height - 2 * border;
1013*61046927SAndroid Build Coastguard Worker       img->Depth2 = depth - 2 * border;
1014*61046927SAndroid Build Coastguard Worker       break;
1015*61046927SAndroid Build Coastguard Worker    default:
1016*61046927SAndroid Build Coastguard Worker       _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()",
1017*61046927SAndroid Build Coastguard Worker                     target);
1018*61046927SAndroid Build Coastguard Worker    }
1019*61046927SAndroid Build Coastguard Worker 
1020*61046927SAndroid Build Coastguard Worker    img->MaxNumLevels =
1021*61046927SAndroid Build Coastguard Worker       _mesa_get_tex_max_num_levels(target,
1022*61046927SAndroid Build Coastguard Worker                                    img->Width2, img->Height2, img->Depth2);
1023*61046927SAndroid Build Coastguard Worker    img->TexFormat = format;
1024*61046927SAndroid Build Coastguard Worker    img->NumSamples = numSamples;
1025*61046927SAndroid Build Coastguard Worker    img->FixedSampleLocations = fixedSampleLocations;
1026*61046927SAndroid Build Coastguard Worker }
1027*61046927SAndroid Build Coastguard Worker 
1028*61046927SAndroid Build Coastguard Worker 
1029*61046927SAndroid Build Coastguard Worker void
_mesa_init_teximage_fields(struct gl_context * ctx,struct gl_texture_image * img,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum internalFormat,mesa_format format)1030*61046927SAndroid Build Coastguard Worker _mesa_init_teximage_fields(struct gl_context *ctx,
1031*61046927SAndroid Build Coastguard Worker                            struct gl_texture_image *img,
1032*61046927SAndroid Build Coastguard Worker                            GLsizei width, GLsizei height, GLsizei depth,
1033*61046927SAndroid Build Coastguard Worker                            GLint border, GLenum internalFormat,
1034*61046927SAndroid Build Coastguard Worker                            mesa_format format)
1035*61046927SAndroid Build Coastguard Worker {
1036*61046927SAndroid Build Coastguard Worker    _mesa_init_teximage_fields_ms(ctx, img, width, height, depth, border,
1037*61046927SAndroid Build Coastguard Worker                                  internalFormat, format, 0, GL_TRUE);
1038*61046927SAndroid Build Coastguard Worker }
1039*61046927SAndroid Build Coastguard Worker 
1040*61046927SAndroid Build Coastguard Worker 
1041*61046927SAndroid Build Coastguard Worker /**
1042*61046927SAndroid Build Coastguard Worker  * Free and clear fields of the gl_texture_image struct.
1043*61046927SAndroid Build Coastguard Worker  *
1044*61046927SAndroid Build Coastguard Worker  * \param ctx GL context.
1045*61046927SAndroid Build Coastguard Worker  * \param texImage texture image structure to be cleared.
1046*61046927SAndroid Build Coastguard Worker  *
1047*61046927SAndroid Build Coastguard Worker  * After the call, \p texImage will have no data associated with it.  Its
1048*61046927SAndroid Build Coastguard Worker  * fields are cleared so that its parent object will test incomplete.
1049*61046927SAndroid Build Coastguard Worker  */
1050*61046927SAndroid Build Coastguard Worker void
_mesa_clear_texture_image(struct gl_context * ctx,struct gl_texture_image * texImage)1051*61046927SAndroid Build Coastguard Worker _mesa_clear_texture_image(struct gl_context *ctx,
1052*61046927SAndroid Build Coastguard Worker                           struct gl_texture_image *texImage)
1053*61046927SAndroid Build Coastguard Worker {
1054*61046927SAndroid Build Coastguard Worker    st_FreeTextureImageBuffer(ctx, texImage);
1055*61046927SAndroid Build Coastguard Worker    clear_teximage_fields(texImage);
1056*61046927SAndroid Build Coastguard Worker }
1057*61046927SAndroid Build Coastguard Worker 
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker /**
1060*61046927SAndroid Build Coastguard Worker  * Check the width, height, depth and border of a texture image are legal.
1061*61046927SAndroid Build Coastguard Worker  * Used by all the glTexImage, glCompressedTexImage and glCopyTexImage
1062*61046927SAndroid Build Coastguard Worker  * functions.
1063*61046927SAndroid Build Coastguard Worker  * The target and level parameters will have already been validated.
1064*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if size is OK, GL_FALSE otherwise.
1065*61046927SAndroid Build Coastguard Worker  */
1066*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_legal_texture_dimensions(struct gl_context * ctx,GLenum target,GLint level,GLint width,GLint height,GLint depth,GLint border)1067*61046927SAndroid Build Coastguard Worker _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
1068*61046927SAndroid Build Coastguard Worker                                GLint level, GLint width, GLint height,
1069*61046927SAndroid Build Coastguard Worker                                GLint depth, GLint border)
1070*61046927SAndroid Build Coastguard Worker {
1071*61046927SAndroid Build Coastguard Worker    GLint maxSize;
1072*61046927SAndroid Build Coastguard Worker 
1073*61046927SAndroid Build Coastguard Worker    switch (target) {
1074*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
1075*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D:
1076*61046927SAndroid Build Coastguard Worker       maxSize = ctx->Const.MaxTextureSize >> level;
1077*61046927SAndroid Build Coastguard Worker       if (width < 2 * border || width > 2 * border + maxSize)
1078*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1079*61046927SAndroid Build Coastguard Worker       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1080*61046927SAndroid Build Coastguard Worker          if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1081*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1082*61046927SAndroid Build Coastguard Worker       }
1083*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1084*61046927SAndroid Build Coastguard Worker 
1085*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
1086*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
1087*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
1088*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
1089*61046927SAndroid Build Coastguard Worker       maxSize = ctx->Const.MaxTextureSize >> level;
1090*61046927SAndroid Build Coastguard Worker       if (width < 2 * border || width > 2 * border + maxSize)
1091*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1092*61046927SAndroid Build Coastguard Worker       if (height < 2 * border || height > 2 * border + maxSize)
1093*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1094*61046927SAndroid Build Coastguard Worker       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1095*61046927SAndroid Build Coastguard Worker          if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1096*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1097*61046927SAndroid Build Coastguard Worker          if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1098*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1099*61046927SAndroid Build Coastguard Worker       }
1100*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1101*61046927SAndroid Build Coastguard Worker 
1102*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
1103*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_3D:
1104*61046927SAndroid Build Coastguard Worker       maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
1105*61046927SAndroid Build Coastguard Worker       maxSize >>= level;
1106*61046927SAndroid Build Coastguard Worker       if (width < 2 * border || width > 2 * border + maxSize)
1107*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1108*61046927SAndroid Build Coastguard Worker       if (height < 2 * border || height > 2 * border + maxSize)
1109*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1110*61046927SAndroid Build Coastguard Worker       if (depth < 2 * border || depth > 2 * border + maxSize)
1111*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1112*61046927SAndroid Build Coastguard Worker       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1113*61046927SAndroid Build Coastguard Worker          if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1114*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1115*61046927SAndroid Build Coastguard Worker          if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1116*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1117*61046927SAndroid Build Coastguard Worker          if (depth > 0 && !util_is_power_of_two_nonzero(depth - 2 * border))
1118*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1119*61046927SAndroid Build Coastguard Worker       }
1120*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1121*61046927SAndroid Build Coastguard Worker 
1122*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_RECTANGLE_NV:
1123*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_RECTANGLE_NV:
1124*61046927SAndroid Build Coastguard Worker       if (level != 0)
1125*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1126*61046927SAndroid Build Coastguard Worker       maxSize = ctx->Const.MaxTextureRectSize;
1127*61046927SAndroid Build Coastguard Worker       if (width < 0 || width > maxSize)
1128*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1129*61046927SAndroid Build Coastguard Worker       if (height < 0 || height > maxSize)
1130*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1131*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1132*61046927SAndroid Build Coastguard Worker 
1133*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
1134*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1135*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1136*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1137*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1138*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1139*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1140*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
1141*61046927SAndroid Build Coastguard Worker       maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
1142*61046927SAndroid Build Coastguard Worker       maxSize >>= level;
1143*61046927SAndroid Build Coastguard Worker       if (width != height)
1144*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1145*61046927SAndroid Build Coastguard Worker       if (width < 2 * border || width > 2 * border + maxSize)
1146*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1147*61046927SAndroid Build Coastguard Worker       if (height < 2 * border || height > 2 * border + maxSize)
1148*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1149*61046927SAndroid Build Coastguard Worker       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1150*61046927SAndroid Build Coastguard Worker          if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1151*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1152*61046927SAndroid Build Coastguard Worker          if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1153*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1154*61046927SAndroid Build Coastguard Worker       }
1155*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY_EXT:
1158*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1159*61046927SAndroid Build Coastguard Worker       maxSize = ctx->Const.MaxTextureSize >> level;
1160*61046927SAndroid Build Coastguard Worker       if (width < 2 * border || width > 2 * border + maxSize)
1161*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1162*61046927SAndroid Build Coastguard Worker       if (height < 0 || height > ctx->Const.MaxArrayTextureLayers)
1163*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1164*61046927SAndroid Build Coastguard Worker       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1165*61046927SAndroid Build Coastguard Worker          if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1166*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1167*61046927SAndroid Build Coastguard Worker       }
1168*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1169*61046927SAndroid Build Coastguard Worker 
1170*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY_EXT:
1171*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1172*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1173*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
1174*61046927SAndroid Build Coastguard Worker       maxSize = ctx->Const.MaxTextureSize >> level;
1175*61046927SAndroid Build Coastguard Worker       if (width < 2 * border || width > 2 * border + maxSize)
1176*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1177*61046927SAndroid Build Coastguard Worker       if (height < 2 * border || height > 2 * border + maxSize)
1178*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1179*61046927SAndroid Build Coastguard Worker       if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers)
1180*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1181*61046927SAndroid Build Coastguard Worker       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1182*61046927SAndroid Build Coastguard Worker          if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1183*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1184*61046927SAndroid Build Coastguard Worker          if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1185*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1186*61046927SAndroid Build Coastguard Worker       }
1187*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1188*61046927SAndroid Build Coastguard Worker 
1189*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
1190*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1191*61046927SAndroid Build Coastguard Worker       maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
1192*61046927SAndroid Build Coastguard Worker       if (width < 2 * border || width > 2 * border + maxSize)
1193*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1194*61046927SAndroid Build Coastguard Worker       if (height < 2 * border || height > 2 * border + maxSize)
1195*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1196*61046927SAndroid Build Coastguard Worker       if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers || depth % 6)
1197*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1198*61046927SAndroid Build Coastguard Worker       if (width != height)
1199*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1200*61046927SAndroid Build Coastguard Worker       if (level >= ctx->Const.MaxCubeTextureLevels)
1201*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1202*61046927SAndroid Build Coastguard Worker       if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1203*61046927SAndroid Build Coastguard Worker          if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1204*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1205*61046927SAndroid Build Coastguard Worker          if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1206*61046927SAndroid Build Coastguard Worker             return GL_FALSE;
1207*61046927SAndroid Build Coastguard Worker       }
1208*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1209*61046927SAndroid Build Coastguard Worker    default:
1210*61046927SAndroid Build Coastguard Worker       _mesa_problem(ctx, "Invalid target in _mesa_legal_texture_dimensions()");
1211*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
1212*61046927SAndroid Build Coastguard Worker    }
1213*61046927SAndroid Build Coastguard Worker }
1214*61046927SAndroid Build Coastguard Worker 
1215*61046927SAndroid Build Coastguard Worker static bool
error_check_subtexture_negative_dimensions(struct gl_context * ctx,GLuint dims,GLsizei subWidth,GLsizei subHeight,GLsizei subDepth,const char * func)1216*61046927SAndroid Build Coastguard Worker error_check_subtexture_negative_dimensions(struct gl_context *ctx,
1217*61046927SAndroid Build Coastguard Worker                                            GLuint dims,
1218*61046927SAndroid Build Coastguard Worker                                            GLsizei subWidth,
1219*61046927SAndroid Build Coastguard Worker                                            GLsizei subHeight,
1220*61046927SAndroid Build Coastguard Worker                                            GLsizei subDepth,
1221*61046927SAndroid Build Coastguard Worker                                            const char *func)
1222*61046927SAndroid Build Coastguard Worker {
1223*61046927SAndroid Build Coastguard Worker    /* Check size */
1224*61046927SAndroid Build Coastguard Worker    if (subWidth < 0) {
1225*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(width=%d)", func, subWidth);
1226*61046927SAndroid Build Coastguard Worker       return true;
1227*61046927SAndroid Build Coastguard Worker    }
1228*61046927SAndroid Build Coastguard Worker 
1229*61046927SAndroid Build Coastguard Worker    if (dims > 1 && subHeight < 0) {
1230*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(height=%d)", func, subHeight);
1231*61046927SAndroid Build Coastguard Worker       return true;
1232*61046927SAndroid Build Coastguard Worker    }
1233*61046927SAndroid Build Coastguard Worker 
1234*61046927SAndroid Build Coastguard Worker    if (dims > 2 && subDepth < 0) {
1235*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(depth=%d)", func, subDepth);
1236*61046927SAndroid Build Coastguard Worker       return true;
1237*61046927SAndroid Build Coastguard Worker    }
1238*61046927SAndroid Build Coastguard Worker 
1239*61046927SAndroid Build Coastguard Worker    return false;
1240*61046927SAndroid Build Coastguard Worker }
1241*61046927SAndroid Build Coastguard Worker 
1242*61046927SAndroid Build Coastguard Worker /**
1243*61046927SAndroid Build Coastguard Worker  * Do error checking of xoffset, yoffset, zoffset, width, height and depth
1244*61046927SAndroid Build Coastguard Worker  * for glTexSubImage, glCopyTexSubImage and glCompressedTexSubImage.
1245*61046927SAndroid Build Coastguard Worker  * \param destImage  the destination texture image.
1246*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if error found, GL_FALSE otherwise.
1247*61046927SAndroid Build Coastguard Worker  */
1248*61046927SAndroid Build Coastguard Worker static GLboolean
error_check_subtexture_dimensions(struct gl_context * ctx,GLuint dims,const struct gl_texture_image * destImage,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei subWidth,GLsizei subHeight,GLsizei subDepth,const char * func)1249*61046927SAndroid Build Coastguard Worker error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims,
1250*61046927SAndroid Build Coastguard Worker                                   const struct gl_texture_image *destImage,
1251*61046927SAndroid Build Coastguard Worker                                   GLint xoffset, GLint yoffset, GLint zoffset,
1252*61046927SAndroid Build Coastguard Worker                                   GLsizei subWidth, GLsizei subHeight,
1253*61046927SAndroid Build Coastguard Worker                                   GLsizei subDepth, const char *func)
1254*61046927SAndroid Build Coastguard Worker {
1255*61046927SAndroid Build Coastguard Worker    const GLenum target = destImage->TexObject->Target;
1256*61046927SAndroid Build Coastguard Worker    GLuint bw, bh, bd;
1257*61046927SAndroid Build Coastguard Worker 
1258*61046927SAndroid Build Coastguard Worker    /* check xoffset and width */
1259*61046927SAndroid Build Coastguard Worker    if (xoffset < - (GLint) destImage->Border) {
1260*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset)", func);
1261*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1262*61046927SAndroid Build Coastguard Worker    }
1263*61046927SAndroid Build Coastguard Worker 
1264*61046927SAndroid Build Coastguard Worker    if (xoffset + subWidth > (GLint) destImage->Width) {
1265*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset %d + width %d > %u)", func,
1266*61046927SAndroid Build Coastguard Worker                   xoffset, subWidth, destImage->Width);
1267*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1268*61046927SAndroid Build Coastguard Worker    }
1269*61046927SAndroid Build Coastguard Worker 
1270*61046927SAndroid Build Coastguard Worker    /* check yoffset and height */
1271*61046927SAndroid Build Coastguard Worker    if (dims > 1) {
1272*61046927SAndroid Build Coastguard Worker       GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border;
1273*61046927SAndroid Build Coastguard Worker       if (yoffset < -yBorder) {
1274*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset)", func);
1275*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1276*61046927SAndroid Build Coastguard Worker       }
1277*61046927SAndroid Build Coastguard Worker       if (yoffset + subHeight > (GLint) destImage->Height) {
1278*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset %d + height %d > %u)",
1279*61046927SAndroid Build Coastguard Worker                      func, yoffset, subHeight, destImage->Height);
1280*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1281*61046927SAndroid Build Coastguard Worker       }
1282*61046927SAndroid Build Coastguard Worker    }
1283*61046927SAndroid Build Coastguard Worker 
1284*61046927SAndroid Build Coastguard Worker    /* check zoffset and depth */
1285*61046927SAndroid Build Coastguard Worker    if (dims > 2) {
1286*61046927SAndroid Build Coastguard Worker       GLint depth;
1287*61046927SAndroid Build Coastguard Worker       GLint zBorder = (target == GL_TEXTURE_2D_ARRAY ||
1288*61046927SAndroid Build Coastguard Worker                        target == GL_TEXTURE_CUBE_MAP_ARRAY) ?
1289*61046927SAndroid Build Coastguard Worker                          0 : destImage->Border;
1290*61046927SAndroid Build Coastguard Worker 
1291*61046927SAndroid Build Coastguard Worker       if (zoffset < -zBorder) {
1292*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset)", func);
1293*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1294*61046927SAndroid Build Coastguard Worker       }
1295*61046927SAndroid Build Coastguard Worker 
1296*61046927SAndroid Build Coastguard Worker       depth = (GLint) destImage->Depth;
1297*61046927SAndroid Build Coastguard Worker       if (target == GL_TEXTURE_CUBE_MAP)
1298*61046927SAndroid Build Coastguard Worker          depth = 6;
1299*61046927SAndroid Build Coastguard Worker       if (zoffset + subDepth  > depth) {
1300*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset %d + depth %d > %u)",
1301*61046927SAndroid Build Coastguard Worker                      func, zoffset, subDepth, depth);
1302*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1303*61046927SAndroid Build Coastguard Worker       }
1304*61046927SAndroid Build Coastguard Worker    }
1305*61046927SAndroid Build Coastguard Worker 
1306*61046927SAndroid Build Coastguard Worker    /*
1307*61046927SAndroid Build Coastguard Worker     * The OpenGL spec (and GL_ARB_texture_compression) says only whole
1308*61046927SAndroid Build Coastguard Worker     * compressed texture images can be updated.  But, that restriction may be
1309*61046927SAndroid Build Coastguard Worker     * relaxed for particular compressed formats.  At this time, all the
1310*61046927SAndroid Build Coastguard Worker     * compressed formats supported by Mesa allow sub-textures to be updated
1311*61046927SAndroid Build Coastguard Worker     * along compressed block boundaries.
1312*61046927SAndroid Build Coastguard Worker     */
1313*61046927SAndroid Build Coastguard Worker    _mesa_get_format_block_size_3d(destImage->TexFormat, &bw, &bh, &bd);
1314*61046927SAndroid Build Coastguard Worker 
1315*61046927SAndroid Build Coastguard Worker    if (bw != 1 || bh != 1 || bd != 1) {
1316*61046927SAndroid Build Coastguard Worker       /* offset must be multiple of block size */
1317*61046927SAndroid Build Coastguard Worker       if ((xoffset % bw != 0) || (yoffset % bh != 0) || (zoffset % bd != 0)) {
1318*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
1319*61046927SAndroid Build Coastguard Worker                      "%s(xoffset = %d, yoffset = %d, zoffset = %d)",
1320*61046927SAndroid Build Coastguard Worker                      func, xoffset, yoffset, zoffset);
1321*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1322*61046927SAndroid Build Coastguard Worker       }
1323*61046927SAndroid Build Coastguard Worker 
1324*61046927SAndroid Build Coastguard Worker       /* The size must be a multiple of bw x bh, or we must be using a
1325*61046927SAndroid Build Coastguard Worker        * offset+size that exactly hits the edge of the image.  This
1326*61046927SAndroid Build Coastguard Worker        * is important for small mipmap levels (1x1, 2x1, etc) and for
1327*61046927SAndroid Build Coastguard Worker        * NPOT textures.
1328*61046927SAndroid Build Coastguard Worker        */
1329*61046927SAndroid Build Coastguard Worker       if ((subWidth % bw != 0) &&
1330*61046927SAndroid Build Coastguard Worker           (xoffset + subWidth != (GLint) destImage->Width)) {
1331*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
1332*61046927SAndroid Build Coastguard Worker                      "%s(width = %d)", func, subWidth);
1333*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1334*61046927SAndroid Build Coastguard Worker       }
1335*61046927SAndroid Build Coastguard Worker 
1336*61046927SAndroid Build Coastguard Worker       if ((subHeight % bh != 0) &&
1337*61046927SAndroid Build Coastguard Worker           (yoffset + subHeight != (GLint) destImage->Height)) {
1338*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
1339*61046927SAndroid Build Coastguard Worker                      "%s(height = %d)", func, subHeight);
1340*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1341*61046927SAndroid Build Coastguard Worker       }
1342*61046927SAndroid Build Coastguard Worker 
1343*61046927SAndroid Build Coastguard Worker       if ((subDepth % bd != 0) &&
1344*61046927SAndroid Build Coastguard Worker           (zoffset + subDepth != (GLint) destImage->Depth)) {
1345*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
1346*61046927SAndroid Build Coastguard Worker                      "%s(depth = %d)", func, subDepth);
1347*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1348*61046927SAndroid Build Coastguard Worker       }
1349*61046927SAndroid Build Coastguard Worker    }
1350*61046927SAndroid Build Coastguard Worker 
1351*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
1352*61046927SAndroid Build Coastguard Worker }
1353*61046927SAndroid Build Coastguard Worker 
1354*61046927SAndroid Build Coastguard Worker 
1355*61046927SAndroid Build Coastguard Worker 
1356*61046927SAndroid Build Coastguard Worker 
1357*61046927SAndroid Build Coastguard Worker /**
1358*61046927SAndroid Build Coastguard Worker  * This is the fallback for Driver.TestProxyTexImage() for doing device-
1359*61046927SAndroid Build Coastguard Worker  * specific texture image size checks.
1360*61046927SAndroid Build Coastguard Worker  *
1361*61046927SAndroid Build Coastguard Worker  * A hardware driver might override this function if, for example, the
1362*61046927SAndroid Build Coastguard Worker  * max 3D texture size is 512x512x64 (i.e. not a cube).
1363*61046927SAndroid Build Coastguard Worker  *
1364*61046927SAndroid Build Coastguard Worker  * Note that width, height, depth == 0 is not an error.  However, a
1365*61046927SAndroid Build Coastguard Worker  * texture with zero width/height/depth will be considered "incomplete"
1366*61046927SAndroid Build Coastguard Worker  * and texturing will effectively be disabled.
1367*61046927SAndroid Build Coastguard Worker  *
1368*61046927SAndroid Build Coastguard Worker  * \param target  any texture target/type
1369*61046927SAndroid Build Coastguard Worker  * \param numLevels  number of mipmap levels in the texture or 0 if not known
1370*61046927SAndroid Build Coastguard Worker  * \param level  as passed to glTexImage
1371*61046927SAndroid Build Coastguard Worker  * \param format  the MESA_FORMAT_x for the tex image
1372*61046927SAndroid Build Coastguard Worker  * \param numSamples  number of samples per texel
1373*61046927SAndroid Build Coastguard Worker  * \param width  as passed to glTexImage
1374*61046927SAndroid Build Coastguard Worker  * \param height  as passed to glTexImage
1375*61046927SAndroid Build Coastguard Worker  * \param depth  as passed to glTexImage
1376*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
1377*61046927SAndroid Build Coastguard Worker  */
1378*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_test_proxy_teximage(struct gl_context * ctx,GLenum target,GLuint numLevels,ASSERTED GLint level,mesa_format format,GLuint numSamples,GLint width,GLint height,GLint depth)1379*61046927SAndroid Build Coastguard Worker _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target,
1380*61046927SAndroid Build Coastguard Worker                           GLuint numLevels, ASSERTED GLint level,
1381*61046927SAndroid Build Coastguard Worker                           mesa_format format, GLuint numSamples,
1382*61046927SAndroid Build Coastguard Worker                           GLint width, GLint height, GLint depth)
1383*61046927SAndroid Build Coastguard Worker {
1384*61046927SAndroid Build Coastguard Worker    uint64_t bytes, mbytes;
1385*61046927SAndroid Build Coastguard Worker 
1386*61046927SAndroid Build Coastguard Worker    if (numLevels > 0) {
1387*61046927SAndroid Build Coastguard Worker       /* Compute total memory for a whole mipmap.  This is the path
1388*61046927SAndroid Build Coastguard Worker        * taken for glTexStorage(GL_PROXY_TEXTURE_x).
1389*61046927SAndroid Build Coastguard Worker        */
1390*61046927SAndroid Build Coastguard Worker       unsigned l;
1391*61046927SAndroid Build Coastguard Worker 
1392*61046927SAndroid Build Coastguard Worker       assert(level == 0);
1393*61046927SAndroid Build Coastguard Worker 
1394*61046927SAndroid Build Coastguard Worker       bytes = 0;
1395*61046927SAndroid Build Coastguard Worker 
1396*61046927SAndroid Build Coastguard Worker       for (l = 0; l < numLevels; l++) {
1397*61046927SAndroid Build Coastguard Worker          GLint nextWidth, nextHeight, nextDepth;
1398*61046927SAndroid Build Coastguard Worker 
1399*61046927SAndroid Build Coastguard Worker          bytes += _mesa_format_image_size64(format, width, height, depth);
1400*61046927SAndroid Build Coastguard Worker 
1401*61046927SAndroid Build Coastguard Worker          if (_mesa_next_mipmap_level_size(target, 0, width, height, depth,
1402*61046927SAndroid Build Coastguard Worker                                           &nextWidth, &nextHeight,
1403*61046927SAndroid Build Coastguard Worker                                           &nextDepth)) {
1404*61046927SAndroid Build Coastguard Worker             width = nextWidth;
1405*61046927SAndroid Build Coastguard Worker             height = nextHeight;
1406*61046927SAndroid Build Coastguard Worker             depth = nextDepth;
1407*61046927SAndroid Build Coastguard Worker          } else {
1408*61046927SAndroid Build Coastguard Worker             break;
1409*61046927SAndroid Build Coastguard Worker          }
1410*61046927SAndroid Build Coastguard Worker       }
1411*61046927SAndroid Build Coastguard Worker    } else {
1412*61046927SAndroid Build Coastguard Worker       /* We just compute the size of one mipmap level.  This is the path
1413*61046927SAndroid Build Coastguard Worker        * taken for glTexImage(GL_PROXY_TEXTURE_x).
1414*61046927SAndroid Build Coastguard Worker        */
1415*61046927SAndroid Build Coastguard Worker       bytes = _mesa_format_image_size64(format, width, height, depth);
1416*61046927SAndroid Build Coastguard Worker    }
1417*61046927SAndroid Build Coastguard Worker 
1418*61046927SAndroid Build Coastguard Worker    bytes *= _mesa_num_tex_faces(target);
1419*61046927SAndroid Build Coastguard Worker    bytes *= MAX2(1, numSamples);
1420*61046927SAndroid Build Coastguard Worker 
1421*61046927SAndroid Build Coastguard Worker    mbytes = bytes / (1024 * 1024); /* convert to MB */
1422*61046927SAndroid Build Coastguard Worker 
1423*61046927SAndroid Build Coastguard Worker    /* We just check if the image size is less than MaxTextureMbytes.
1424*61046927SAndroid Build Coastguard Worker     * Some drivers may do more specific checks.
1425*61046927SAndroid Build Coastguard Worker     */
1426*61046927SAndroid Build Coastguard Worker    return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
1427*61046927SAndroid Build Coastguard Worker }
1428*61046927SAndroid Build Coastguard Worker 
1429*61046927SAndroid Build Coastguard Worker 
1430*61046927SAndroid Build Coastguard Worker /**
1431*61046927SAndroid Build Coastguard Worker  * Return true if the format is only valid for glCompressedTexImage.
1432*61046927SAndroid Build Coastguard Worker  */
1433*61046927SAndroid Build Coastguard Worker static bool
compressedteximage_only_format(GLenum format)1434*61046927SAndroid Build Coastguard Worker compressedteximage_only_format(GLenum format)
1435*61046927SAndroid Build Coastguard Worker {
1436*61046927SAndroid Build Coastguard Worker    switch (format) {
1437*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_RGB8_OES:
1438*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_RGBA8_OES:
1439*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_R5_G6_B5_OES:
1440*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_RGBA4_OES:
1441*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_RGB5_A1_OES:
1442*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_RGB8_OES:
1443*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_RGBA8_OES:
1444*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_R5_G6_B5_OES:
1445*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_RGBA4_OES:
1446*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_RGB5_A1_OES:
1447*61046927SAndroid Build Coastguard Worker    case GL_ATC_RGB_AMD:
1448*61046927SAndroid Build Coastguard Worker    case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
1449*61046927SAndroid Build Coastguard Worker    case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
1450*61046927SAndroid Build Coastguard Worker       return true;
1451*61046927SAndroid Build Coastguard Worker    default:
1452*61046927SAndroid Build Coastguard Worker       return false;
1453*61046927SAndroid Build Coastguard Worker    }
1454*61046927SAndroid Build Coastguard Worker }
1455*61046927SAndroid Build Coastguard Worker 
1456*61046927SAndroid Build Coastguard Worker /**
1457*61046927SAndroid Build Coastguard Worker  * Return true if the format doesn't support online compression.
1458*61046927SAndroid Build Coastguard Worker  */
1459*61046927SAndroid Build Coastguard Worker bool
_mesa_format_no_online_compression(GLenum format)1460*61046927SAndroid Build Coastguard Worker _mesa_format_no_online_compression(GLenum format)
1461*61046927SAndroid Build Coastguard Worker {
1462*61046927SAndroid Build Coastguard Worker    return _mesa_is_astc_format(format) ||
1463*61046927SAndroid Build Coastguard Worker           _mesa_is_etc2_format(format) ||
1464*61046927SAndroid Build Coastguard Worker           compressedteximage_only_format(format);
1465*61046927SAndroid Build Coastguard Worker }
1466*61046927SAndroid Build Coastguard Worker 
1467*61046927SAndroid Build Coastguard Worker /* Writes to an GL error pointer if non-null and returns whether or not the
1468*61046927SAndroid Build Coastguard Worker  * error is GL_NO_ERROR */
1469*61046927SAndroid Build Coastguard Worker static bool
write_error(GLenum * err_ptr,GLenum error)1470*61046927SAndroid Build Coastguard Worker write_error(GLenum *err_ptr, GLenum error)
1471*61046927SAndroid Build Coastguard Worker {
1472*61046927SAndroid Build Coastguard Worker    if (err_ptr)
1473*61046927SAndroid Build Coastguard Worker       *err_ptr = error;
1474*61046927SAndroid Build Coastguard Worker 
1475*61046927SAndroid Build Coastguard Worker    return error == GL_NO_ERROR;
1476*61046927SAndroid Build Coastguard Worker }
1477*61046927SAndroid Build Coastguard Worker 
1478*61046927SAndroid Build Coastguard Worker /**
1479*61046927SAndroid Build Coastguard Worker  * Helper function to determine whether a target and specific compression
1480*61046927SAndroid Build Coastguard Worker  * format are supported. The error parameter returns GL_NO_ERROR if the
1481*61046927SAndroid Build Coastguard Worker  * target can be compressed. Otherwise it returns either GL_INVALID_OPERATION
1482*61046927SAndroid Build Coastguard Worker  * or GL_INVALID_ENUM, whichever is more appropriate.
1483*61046927SAndroid Build Coastguard Worker  */
1484*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_target_can_be_compressed(const struct gl_context * ctx,GLenum target,GLenum intFormat,GLenum * error)1485*61046927SAndroid Build Coastguard Worker _mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
1486*61046927SAndroid Build Coastguard Worker                                GLenum intFormat, GLenum *error)
1487*61046927SAndroid Build Coastguard Worker {
1488*61046927SAndroid Build Coastguard Worker    GLboolean target_can_be_compresed = GL_FALSE;
1489*61046927SAndroid Build Coastguard Worker    mesa_format format = _mesa_glenum_to_compressed_format(intFormat);
1490*61046927SAndroid Build Coastguard Worker    enum mesa_format_layout layout = _mesa_get_format_layout(format);
1491*61046927SAndroid Build Coastguard Worker 
1492*61046927SAndroid Build Coastguard Worker    switch (target) {
1493*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
1494*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D:
1495*61046927SAndroid Build Coastguard Worker       target_can_be_compresed = GL_TRUE; /* true for any compressed format so far */
1496*61046927SAndroid Build Coastguard Worker       break;
1497*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP:
1498*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
1499*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1500*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1501*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1502*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1503*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1504*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1505*61046927SAndroid Build Coastguard Worker       target_can_be_compresed = GL_TRUE;
1506*61046927SAndroid Build Coastguard Worker       break;
1507*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1508*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY_EXT:
1509*61046927SAndroid Build Coastguard Worker       target_can_be_compresed = ctx->Extensions.EXT_texture_array;
1510*61046927SAndroid Build Coastguard Worker       break;
1511*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1512*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
1513*61046927SAndroid Build Coastguard Worker       /* From the KHR_texture_compression_astc_hdr spec:
1514*61046927SAndroid Build Coastguard Worker        *
1515*61046927SAndroid Build Coastguard Worker        *     Add a second new column "3D Tex." which is empty for all non-ASTC
1516*61046927SAndroid Build Coastguard Worker        *     formats. If only the LDR profile is supported by the
1517*61046927SAndroid Build Coastguard Worker        *     implementation, this column is also empty for all ASTC formats. If
1518*61046927SAndroid Build Coastguard Worker        *     both the LDR and HDR profiles are supported only, this column is
1519*61046927SAndroid Build Coastguard Worker        *     checked for all ASTC formats.
1520*61046927SAndroid Build Coastguard Worker        *
1521*61046927SAndroid Build Coastguard Worker        *     Add a third new column "Cube Map Array Tex." which is empty for all
1522*61046927SAndroid Build Coastguard Worker        *     non-ASTC formats, and checked for all ASTC formats.
1523*61046927SAndroid Build Coastguard Worker        *
1524*61046927SAndroid Build Coastguard Worker        * and,
1525*61046927SAndroid Build Coastguard Worker        *
1526*61046927SAndroid Build Coastguard Worker        *     'An INVALID_OPERATION error is generated by CompressedTexImage3D
1527*61046927SAndroid Build Coastguard Worker        *      if <internalformat> is TEXTURE_CUBE_MAP_ARRAY and the
1528*61046927SAndroid Build Coastguard Worker        *      "Cube Map Array" column of table 8.19 is *not* checked, or if
1529*61046927SAndroid Build Coastguard Worker        *      <internalformat> is TEXTURE_3D and the "3D Tex." column of table
1530*61046927SAndroid Build Coastguard Worker        *      8.19 is *not* checked'
1531*61046927SAndroid Build Coastguard Worker        *
1532*61046927SAndroid Build Coastguard Worker        * The instances of <internalformat> above should say <target>.
1533*61046927SAndroid Build Coastguard Worker        *
1534*61046927SAndroid Build Coastguard Worker        * ETC2/EAC formats are the only alternative in GLES and thus such errors
1535*61046927SAndroid Build Coastguard Worker        * have already been handled by normal ETC2/EAC behavior.
1536*61046927SAndroid Build Coastguard Worker        */
1537*61046927SAndroid Build Coastguard Worker 
1538*61046927SAndroid Build Coastguard Worker       /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
1539*61046927SAndroid Build Coastguard Worker        *
1540*61046927SAndroid Build Coastguard Worker        *    "The ETC2/EAC texture compression algorithm supports only
1541*61046927SAndroid Build Coastguard Worker        *     two-dimensional images. If internalformat is an ETC2/EAC format,
1542*61046927SAndroid Build Coastguard Worker        *     glCompressedTexImage3D will generate an INVALID_OPERATION error if
1543*61046927SAndroid Build Coastguard Worker        *     target is not TEXTURE_2D_ARRAY."
1544*61046927SAndroid Build Coastguard Worker        *
1545*61046927SAndroid Build Coastguard Worker        * This should also be applicable for glTexStorage3D(). Other available
1546*61046927SAndroid Build Coastguard Worker        * targets for these functions are: TEXTURE_3D and TEXTURE_CUBE_MAP_ARRAY.
1547*61046927SAndroid Build Coastguard Worker        *
1548*61046927SAndroid Build Coastguard Worker        * Section 8.7, page 179 of OpenGL ES 3.2 adds:
1549*61046927SAndroid Build Coastguard Worker        *
1550*61046927SAndroid Build Coastguard Worker        *      An INVALID_OPERATION error is generated by CompressedTexImage3D
1551*61046927SAndroid Build Coastguard Worker        *      if internalformat is one of the the formats in table 8.17 and target is
1552*61046927SAndroid Build Coastguard Worker        *      not TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY or TEXTURE_3D.
1553*61046927SAndroid Build Coastguard Worker        *
1554*61046927SAndroid Build Coastguard Worker        *      An INVALID_OPERATION error is generated by CompressedTexImage3D
1555*61046927SAndroid Build Coastguard Worker        *      if internalformat is TEXTURE_CUBE_MAP_ARRAY and the “Cube Map
1556*61046927SAndroid Build Coastguard Worker        *      Array” column of table 8.17 is not checked, or if internalformat
1557*61046927SAndroid Build Coastguard Worker        *      is TEXTURE_- 3D and the “3D Tex.” column of table 8.17 is not
1558*61046927SAndroid Build Coastguard Worker        *      checked.
1559*61046927SAndroid Build Coastguard Worker        *
1560*61046927SAndroid Build Coastguard Worker        * The instances of <internalformat> above should say <target>.
1561*61046927SAndroid Build Coastguard Worker        *
1562*61046927SAndroid Build Coastguard Worker        * Such table 8.17 has checked "Cube Map Array" column for all the
1563*61046927SAndroid Build Coastguard Worker        * cases. So in practice, TEXTURE_CUBE_MAP_ARRAY is now valid for OpenGL ES 3.2
1564*61046927SAndroid Build Coastguard Worker        */
1565*61046927SAndroid Build Coastguard Worker       if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx) &&
1566*61046927SAndroid Build Coastguard Worker           !_mesa_is_gles32(ctx))
1567*61046927SAndroid Build Coastguard Worker             return write_error(error, GL_INVALID_OPERATION);
1568*61046927SAndroid Build Coastguard Worker       target_can_be_compresed = _mesa_has_texture_cube_map_array(ctx);
1569*61046927SAndroid Build Coastguard Worker       break;
1570*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
1571*61046927SAndroid Build Coastguard Worker       switch (layout) {
1572*61046927SAndroid Build Coastguard Worker       case MESA_FORMAT_LAYOUT_ETC2:
1573*61046927SAndroid Build Coastguard Worker       case MESA_FORMAT_LAYOUT_RGTC:
1574*61046927SAndroid Build Coastguard Worker          /* From the OpenGL 4.4 compatibility spec:
1575*61046927SAndroid Build Coastguard Worker           *      An INVALID_OPERATION error is generated by TexImage3D if
1576*61046927SAndroid Build Coastguard Worker           *      internalformat is one of the EAC, ETC2, or RGTC compressed
1577*61046927SAndroid Build Coastguard Worker           *      formats and either border is non-zero, or target is not
1578*61046927SAndroid Build Coastguard Worker           *      TEXTURE_2D_ARRAY.
1579*61046927SAndroid Build Coastguard Worker           */
1580*61046927SAndroid Build Coastguard Worker          return write_error(error, GL_INVALID_OPERATION);
1581*61046927SAndroid Build Coastguard Worker       case MESA_FORMAT_LAYOUT_BPTC:
1582*61046927SAndroid Build Coastguard Worker          target_can_be_compresed = ctx->Extensions.ARB_texture_compression_bptc;
1583*61046927SAndroid Build Coastguard Worker          break;
1584*61046927SAndroid Build Coastguard Worker       case MESA_FORMAT_LAYOUT_S3TC:
1585*61046927SAndroid Build Coastguard Worker          /* From the EXT_texture_compression_s3tc spec:
1586*61046927SAndroid Build Coastguard Worker           *
1587*61046927SAndroid Build Coastguard Worker           *      In extended OpenGL ES 3.0.2 these new tokens are also accepted by the
1588*61046927SAndroid Build Coastguard Worker           *      <internalformat> parameter of TexImage3D, CompressedTexImage3D,
1589*61046927SAndroid Build Coastguard Worker           *      TexStorage2D, TexStorage3D and the <format> parameter of
1590*61046927SAndroid Build Coastguard Worker           *      CompressedTexSubImage3D.
1591*61046927SAndroid Build Coastguard Worker           *
1592*61046927SAndroid Build Coastguard Worker           * The spec does not clarify whether the same applies to newer desktop GL versions
1593*61046927SAndroid Build Coastguard Worker           * (where 3D textures were introduced), check compatibility ext to be safe.
1594*61046927SAndroid Build Coastguard Worker           */
1595*61046927SAndroid Build Coastguard Worker          target_can_be_compresed =
1596*61046927SAndroid Build Coastguard Worker             ctx->Extensions.EXT_texture_compression_s3tc &&
1597*61046927SAndroid Build Coastguard Worker             _mesa_is_gles3_compatible(ctx);
1598*61046927SAndroid Build Coastguard Worker          break;
1599*61046927SAndroid Build Coastguard Worker       case MESA_FORMAT_LAYOUT_ASTC:
1600*61046927SAndroid Build Coastguard Worker          target_can_be_compresed =
1601*61046927SAndroid Build Coastguard Worker             ctx->Extensions.KHR_texture_compression_astc_hdr ||
1602*61046927SAndroid Build Coastguard Worker             ctx->Extensions.KHR_texture_compression_astc_sliced_3d;
1603*61046927SAndroid Build Coastguard Worker 
1604*61046927SAndroid Build Coastguard Worker          /* Throw an INVALID_OPERATION error if the target is TEXTURE_3D and
1605*61046927SAndroid Build Coastguard Worker           * neither of the above extensions are supported. See comment in
1606*61046927SAndroid Build Coastguard Worker           * switch case GL_TEXTURE_CUBE_MAP_ARRAY for more info.
1607*61046927SAndroid Build Coastguard Worker           */
1608*61046927SAndroid Build Coastguard Worker          if (!target_can_be_compresed)
1609*61046927SAndroid Build Coastguard Worker             return write_error(error, GL_INVALID_OPERATION);
1610*61046927SAndroid Build Coastguard Worker          break;
1611*61046927SAndroid Build Coastguard Worker       default:
1612*61046927SAndroid Build Coastguard Worker          break;
1613*61046927SAndroid Build Coastguard Worker       }
1614*61046927SAndroid Build Coastguard Worker       FALLTHROUGH;
1615*61046927SAndroid Build Coastguard Worker    default:
1616*61046927SAndroid Build Coastguard Worker       break;
1617*61046927SAndroid Build Coastguard Worker    }
1618*61046927SAndroid Build Coastguard Worker    return write_error(error,
1619*61046927SAndroid Build Coastguard Worker                       target_can_be_compresed ? GL_NO_ERROR : GL_INVALID_ENUM);
1620*61046927SAndroid Build Coastguard Worker }
1621*61046927SAndroid Build Coastguard Worker 
1622*61046927SAndroid Build Coastguard Worker 
1623*61046927SAndroid Build Coastguard Worker /**
1624*61046927SAndroid Build Coastguard Worker  * Check if the given texture target value is legal for a
1625*61046927SAndroid Build Coastguard Worker  * glTexImage1/2/3D call.
1626*61046927SAndroid Build Coastguard Worker  */
1627*61046927SAndroid Build Coastguard Worker static GLboolean
legal_teximage_target(struct gl_context * ctx,GLuint dims,GLenum target)1628*61046927SAndroid Build Coastguard Worker legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
1629*61046927SAndroid Build Coastguard Worker {
1630*61046927SAndroid Build Coastguard Worker    switch (dims) {
1631*61046927SAndroid Build Coastguard Worker    case 1:
1632*61046927SAndroid Build Coastguard Worker       switch (target) {
1633*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_1D:
1634*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_1D:
1635*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx);
1636*61046927SAndroid Build Coastguard Worker       default:
1637*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1638*61046927SAndroid Build Coastguard Worker       }
1639*61046927SAndroid Build Coastguard Worker    case 2:
1640*61046927SAndroid Build Coastguard Worker       switch (target) {
1641*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_2D:
1642*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1643*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_2D:
1644*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx);
1645*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_CUBE_MAP:
1646*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx);
1647*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1648*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1649*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1650*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1651*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1652*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1653*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1654*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_RECTANGLE_NV:
1655*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_RECTANGLE_NV:
1656*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx)
1657*61046927SAndroid Build Coastguard Worker             && ctx->Extensions.NV_texture_rectangle;
1658*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_1D_ARRAY_EXT:
1659*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1660*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
1661*61046927SAndroid Build Coastguard Worker       default:
1662*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1663*61046927SAndroid Build Coastguard Worker       }
1664*61046927SAndroid Build Coastguard Worker    case 3:
1665*61046927SAndroid Build Coastguard Worker       switch (target) {
1666*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_3D:
1667*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1668*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_3D:
1669*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx);
1670*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_2D_ARRAY_EXT:
1671*61046927SAndroid Build Coastguard Worker          return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array)
1672*61046927SAndroid Build Coastguard Worker             || _mesa_is_gles3(ctx);
1673*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1674*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
1675*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_ARRAY:
1676*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1677*61046927SAndroid Build Coastguard Worker          return _mesa_has_texture_cube_map_array(ctx);
1678*61046927SAndroid Build Coastguard Worker       default:
1679*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1680*61046927SAndroid Build Coastguard Worker       }
1681*61046927SAndroid Build Coastguard Worker    default:
1682*61046927SAndroid Build Coastguard Worker       _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
1683*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
1684*61046927SAndroid Build Coastguard Worker    }
1685*61046927SAndroid Build Coastguard Worker }
1686*61046927SAndroid Build Coastguard Worker 
1687*61046927SAndroid Build Coastguard Worker 
1688*61046927SAndroid Build Coastguard Worker /**
1689*61046927SAndroid Build Coastguard Worker  * Check if the given texture target value is legal for a
1690*61046927SAndroid Build Coastguard Worker  * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
1691*61046927SAndroid Build Coastguard Worker  * The difference compared to legal_teximage_target() above is that
1692*61046927SAndroid Build Coastguard Worker  * proxy targets are not supported.
1693*61046927SAndroid Build Coastguard Worker  */
1694*61046927SAndroid Build Coastguard Worker static GLboolean
legal_texsubimage_target(struct gl_context * ctx,GLuint dims,GLenum target,bool dsa)1695*61046927SAndroid Build Coastguard Worker legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target,
1696*61046927SAndroid Build Coastguard Worker                          bool dsa)
1697*61046927SAndroid Build Coastguard Worker {
1698*61046927SAndroid Build Coastguard Worker    switch (dims) {
1699*61046927SAndroid Build Coastguard Worker    case 1:
1700*61046927SAndroid Build Coastguard Worker       return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D;
1701*61046927SAndroid Build Coastguard Worker    case 2:
1702*61046927SAndroid Build Coastguard Worker       switch (target) {
1703*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_2D:
1704*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1705*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1706*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1707*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1708*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1709*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1710*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1711*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1712*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_RECTANGLE_NV:
1713*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx)
1714*61046927SAndroid Build Coastguard Worker             && ctx->Extensions.NV_texture_rectangle;
1715*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_1D_ARRAY_EXT:
1716*61046927SAndroid Build Coastguard Worker          return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
1717*61046927SAndroid Build Coastguard Worker       default:
1718*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1719*61046927SAndroid Build Coastguard Worker       }
1720*61046927SAndroid Build Coastguard Worker    case 3:
1721*61046927SAndroid Build Coastguard Worker       switch (target) {
1722*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_3D:
1723*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
1724*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_2D_ARRAY_EXT:
1725*61046927SAndroid Build Coastguard Worker          return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array)
1726*61046927SAndroid Build Coastguard Worker             || _mesa_is_gles3(ctx);
1727*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_ARRAY:
1728*61046927SAndroid Build Coastguard Worker       case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1729*61046927SAndroid Build Coastguard Worker          return _mesa_has_texture_cube_map_array(ctx);
1730*61046927SAndroid Build Coastguard Worker 
1731*61046927SAndroid Build Coastguard Worker       /* Table 8.15 of the OpenGL 4.5 core profile spec
1732*61046927SAndroid Build Coastguard Worker        * (20141030) says that TEXTURE_CUBE_MAP is valid for TextureSubImage3D
1733*61046927SAndroid Build Coastguard Worker        * and CopyTextureSubImage3D.
1734*61046927SAndroid Build Coastguard Worker        */
1735*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP:
1736*61046927SAndroid Build Coastguard Worker          return dsa;
1737*61046927SAndroid Build Coastguard Worker       default:
1738*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
1739*61046927SAndroid Build Coastguard Worker       }
1740*61046927SAndroid Build Coastguard Worker    default:
1741*61046927SAndroid Build Coastguard Worker       _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
1742*61046927SAndroid Build Coastguard Worker                     dims);
1743*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
1744*61046927SAndroid Build Coastguard Worker    }
1745*61046927SAndroid Build Coastguard Worker }
1746*61046927SAndroid Build Coastguard Worker 
1747*61046927SAndroid Build Coastguard Worker 
1748*61046927SAndroid Build Coastguard Worker /**
1749*61046927SAndroid Build Coastguard Worker  * Helper function to determine if a texture object is mutable (in terms
1750*61046927SAndroid Build Coastguard Worker  * of GL_ARB_texture_storage/GL_ARB_bindless_texture).
1751*61046927SAndroid Build Coastguard Worker  */
1752*61046927SAndroid Build Coastguard Worker static GLboolean
mutable_tex_object(struct gl_texture_object * texObj)1753*61046927SAndroid Build Coastguard Worker mutable_tex_object(struct gl_texture_object *texObj)
1754*61046927SAndroid Build Coastguard Worker {
1755*61046927SAndroid Build Coastguard Worker    if (!texObj)
1756*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
1757*61046927SAndroid Build Coastguard Worker 
1758*61046927SAndroid Build Coastguard Worker    if (texObj->HandleAllocated) {
1759*61046927SAndroid Build Coastguard Worker       /* The ARB_bindless_texture spec says:
1760*61046927SAndroid Build Coastguard Worker        *
1761*61046927SAndroid Build Coastguard Worker        * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
1762*61046927SAndroid Build Coastguard Worker        *  CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
1763*61046927SAndroid Build Coastguard Worker        *  functions defined in terms of these, if the texture object to be
1764*61046927SAndroid Build Coastguard Worker        *  modified is referenced by one or more texture or image handles."
1765*61046927SAndroid Build Coastguard Worker        */
1766*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
1767*61046927SAndroid Build Coastguard Worker    }
1768*61046927SAndroid Build Coastguard Worker 
1769*61046927SAndroid Build Coastguard Worker    return !texObj->Immutable;
1770*61046927SAndroid Build Coastguard Worker }
1771*61046927SAndroid Build Coastguard Worker 
1772*61046927SAndroid Build Coastguard Worker 
1773*61046927SAndroid Build Coastguard Worker /**
1774*61046927SAndroid Build Coastguard Worker  * Return expected size of a compressed texture.
1775*61046927SAndroid Build Coastguard Worker  */
1776*61046927SAndroid Build Coastguard Worker static GLuint
compressed_tex_size(GLsizei width,GLsizei height,GLsizei depth,GLenum glformat)1777*61046927SAndroid Build Coastguard Worker compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
1778*61046927SAndroid Build Coastguard Worker                     GLenum glformat)
1779*61046927SAndroid Build Coastguard Worker {
1780*61046927SAndroid Build Coastguard Worker    mesa_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
1781*61046927SAndroid Build Coastguard Worker    return _mesa_format_image_size(mesaFormat, width, height, depth);
1782*61046927SAndroid Build Coastguard Worker }
1783*61046927SAndroid Build Coastguard Worker 
1784*61046927SAndroid Build Coastguard Worker /**
1785*61046927SAndroid Build Coastguard Worker  * Verify that a texture format is valid with a particular target
1786*61046927SAndroid Build Coastguard Worker  *
1787*61046927SAndroid Build Coastguard Worker  * In particular, textures with base format of \c GL_DEPTH_COMPONENT or
1788*61046927SAndroid Build Coastguard Worker  * \c GL_DEPTH_STENCIL are only valid with certain, context dependent texture
1789*61046927SAndroid Build Coastguard Worker  * targets.
1790*61046927SAndroid Build Coastguard Worker  *
1791*61046927SAndroid Build Coastguard Worker  * \param ctx             GL context
1792*61046927SAndroid Build Coastguard Worker  * \param target          Texture target
1793*61046927SAndroid Build Coastguard Worker  * \param internalFormat  Internal format of the texture image
1794*61046927SAndroid Build Coastguard Worker  *
1795*61046927SAndroid Build Coastguard Worker  * \returns true if the combination is legal, false otherwise.
1796*61046927SAndroid Build Coastguard Worker  */
1797*61046927SAndroid Build Coastguard Worker bool
_mesa_legal_texture_base_format_for_target(struct gl_context * ctx,GLenum target,GLenum internalFormat)1798*61046927SAndroid Build Coastguard Worker _mesa_legal_texture_base_format_for_target(struct gl_context *ctx,
1799*61046927SAndroid Build Coastguard Worker                                            GLenum target, GLenum internalFormat)
1800*61046927SAndroid Build Coastguard Worker {
1801*61046927SAndroid Build Coastguard Worker    if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT
1802*61046927SAndroid Build Coastguard Worker        || _mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_STENCIL
1803*61046927SAndroid Build Coastguard Worker        || _mesa_base_tex_format(ctx, internalFormat) == GL_STENCIL_INDEX) {
1804*61046927SAndroid Build Coastguard Worker       /* Section 3.8.3 (Texture Image Specification) of the OpenGL 3.3 Core
1805*61046927SAndroid Build Coastguard Worker        * Profile spec says:
1806*61046927SAndroid Build Coastguard Worker        *
1807*61046927SAndroid Build Coastguard Worker        *     "Textures with a base internal format of DEPTH_COMPONENT or
1808*61046927SAndroid Build Coastguard Worker        *     DEPTH_STENCIL are supported by texture image specification
1809*61046927SAndroid Build Coastguard Worker        *     commands only if target is TEXTURE_1D, TEXTURE_2D,
1810*61046927SAndroid Build Coastguard Worker        *     TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_RECTANGLE,
1811*61046927SAndroid Build Coastguard Worker        *     TEXTURE_CUBE_MAP, PROXY_TEXTURE_1D, PROXY_TEXTURE_2D,
1812*61046927SAndroid Build Coastguard Worker        *     PROXY_TEXTURE_1D_ARRAY, PROXY_TEXTURE_2D_ARRAY,
1813*61046927SAndroid Build Coastguard Worker        *     PROXY_TEXTURE_RECTANGLE, or PROXY_TEXTURE_CUBE_MAP. Using these
1814*61046927SAndroid Build Coastguard Worker        *     formats in conjunction with any other target will result in an
1815*61046927SAndroid Build Coastguard Worker        *     INVALID_OPERATION error."
1816*61046927SAndroid Build Coastguard Worker        *
1817*61046927SAndroid Build Coastguard Worker        * Cubemaps are only supported with desktop OpenGL version >= 3.0,
1818*61046927SAndroid Build Coastguard Worker        * EXT_gpu_shader4, or, on OpenGL ES 2.0+, OES_depth_texture_cube_map.
1819*61046927SAndroid Build Coastguard Worker        */
1820*61046927SAndroid Build Coastguard Worker       if (target != GL_TEXTURE_1D &&
1821*61046927SAndroid Build Coastguard Worker           target != GL_PROXY_TEXTURE_1D &&
1822*61046927SAndroid Build Coastguard Worker           target != GL_TEXTURE_2D &&
1823*61046927SAndroid Build Coastguard Worker           target != GL_PROXY_TEXTURE_2D &&
1824*61046927SAndroid Build Coastguard Worker           target != GL_TEXTURE_1D_ARRAY &&
1825*61046927SAndroid Build Coastguard Worker           target != GL_PROXY_TEXTURE_1D_ARRAY &&
1826*61046927SAndroid Build Coastguard Worker           target != GL_TEXTURE_2D_ARRAY &&
1827*61046927SAndroid Build Coastguard Worker           target != GL_PROXY_TEXTURE_2D_ARRAY &&
1828*61046927SAndroid Build Coastguard Worker           target != GL_TEXTURE_RECTANGLE_ARB &&
1829*61046927SAndroid Build Coastguard Worker           target != GL_PROXY_TEXTURE_RECTANGLE_ARB &&
1830*61046927SAndroid Build Coastguard Worker          !((_mesa_is_cube_face(target) ||
1831*61046927SAndroid Build Coastguard Worker             target == GL_TEXTURE_CUBE_MAP ||
1832*61046927SAndroid Build Coastguard Worker             target == GL_PROXY_TEXTURE_CUBE_MAP) &&
1833*61046927SAndroid Build Coastguard Worker            (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4
1834*61046927SAndroid Build Coastguard Worker             || (_mesa_is_gles2(ctx) && ctx->Extensions.OES_depth_texture_cube_map))) &&
1835*61046927SAndroid Build Coastguard Worker           !((target == GL_TEXTURE_CUBE_MAP_ARRAY ||
1836*61046927SAndroid Build Coastguard Worker              target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) &&
1837*61046927SAndroid Build Coastguard Worker             _mesa_has_texture_cube_map_array(ctx))) {
1838*61046927SAndroid Build Coastguard Worker          return false;
1839*61046927SAndroid Build Coastguard Worker       }
1840*61046927SAndroid Build Coastguard Worker    }
1841*61046927SAndroid Build Coastguard Worker 
1842*61046927SAndroid Build Coastguard Worker    return true;
1843*61046927SAndroid Build Coastguard Worker }
1844*61046927SAndroid Build Coastguard Worker 
1845*61046927SAndroid Build Coastguard Worker static bool
texture_formats_agree(GLenum internalFormat,GLenum format)1846*61046927SAndroid Build Coastguard Worker texture_formats_agree(GLenum internalFormat,
1847*61046927SAndroid Build Coastguard Worker                       GLenum format)
1848*61046927SAndroid Build Coastguard Worker {
1849*61046927SAndroid Build Coastguard Worker    GLboolean colorFormat;
1850*61046927SAndroid Build Coastguard Worker    GLboolean is_format_depth_or_depthstencil;
1851*61046927SAndroid Build Coastguard Worker    GLboolean is_internalFormat_depth_or_depthstencil;
1852*61046927SAndroid Build Coastguard Worker 
1853*61046927SAndroid Build Coastguard Worker    /* Even though there are no color-index textures, we still have to support
1854*61046927SAndroid Build Coastguard Worker     * uploading color-index data and remapping it to RGB via the
1855*61046927SAndroid Build Coastguard Worker     * GL_PIXEL_MAP_I_TO_[RGBA] tables.
1856*61046927SAndroid Build Coastguard Worker     */
1857*61046927SAndroid Build Coastguard Worker    const GLboolean indexFormat = (format == GL_COLOR_INDEX);
1858*61046927SAndroid Build Coastguard Worker 
1859*61046927SAndroid Build Coastguard Worker    is_internalFormat_depth_or_depthstencil =
1860*61046927SAndroid Build Coastguard Worker       _mesa_is_depth_format(internalFormat) ||
1861*61046927SAndroid Build Coastguard Worker       _mesa_is_depthstencil_format(internalFormat);
1862*61046927SAndroid Build Coastguard Worker 
1863*61046927SAndroid Build Coastguard Worker    is_format_depth_or_depthstencil =
1864*61046927SAndroid Build Coastguard Worker       _mesa_is_depth_format(format) ||
1865*61046927SAndroid Build Coastguard Worker       _mesa_is_depthstencil_format(format);
1866*61046927SAndroid Build Coastguard Worker 
1867*61046927SAndroid Build Coastguard Worker    colorFormat = _mesa_is_color_format(format);
1868*61046927SAndroid Build Coastguard Worker 
1869*61046927SAndroid Build Coastguard Worker    if (_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat)
1870*61046927SAndroid Build Coastguard Worker       return false;
1871*61046927SAndroid Build Coastguard Worker 
1872*61046927SAndroid Build Coastguard Worker    if (is_internalFormat_depth_or_depthstencil !=
1873*61046927SAndroid Build Coastguard Worker        is_format_depth_or_depthstencil)
1874*61046927SAndroid Build Coastguard Worker       return false;
1875*61046927SAndroid Build Coastguard Worker 
1876*61046927SAndroid Build Coastguard Worker    if (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format))
1877*61046927SAndroid Build Coastguard Worker       return false;
1878*61046927SAndroid Build Coastguard Worker 
1879*61046927SAndroid Build Coastguard Worker    return true;
1880*61046927SAndroid Build Coastguard Worker }
1881*61046927SAndroid Build Coastguard Worker 
1882*61046927SAndroid Build Coastguard Worker /**
1883*61046927SAndroid Build Coastguard Worker  * Test the combination of format, type and internal format arguments of
1884*61046927SAndroid Build Coastguard Worker  * different texture operations on GLES.
1885*61046927SAndroid Build Coastguard Worker  *
1886*61046927SAndroid Build Coastguard Worker  * \param ctx GL context.
1887*61046927SAndroid Build Coastguard Worker  * \param format pixel data format given by the user.
1888*61046927SAndroid Build Coastguard Worker  * \param type pixel data type given by the user.
1889*61046927SAndroid Build Coastguard Worker  * \param internalFormat internal format given by the user.
1890*61046927SAndroid Build Coastguard Worker  * \param callerName name of the caller function to print in the error message
1891*61046927SAndroid Build Coastguard Worker  *
1892*61046927SAndroid Build Coastguard Worker  * \return true if a error is found, false otherwise
1893*61046927SAndroid Build Coastguard Worker  *
1894*61046927SAndroid Build Coastguard Worker  * Currently, it is used by texture_error_check() and texsubimage_error_check().
1895*61046927SAndroid Build Coastguard Worker  */
1896*61046927SAndroid Build Coastguard Worker static bool
texture_format_error_check_gles(struct gl_context * ctx,GLenum format,GLenum type,GLenum internalFormat,const char * callerName)1897*61046927SAndroid Build Coastguard Worker texture_format_error_check_gles(struct gl_context *ctx, GLenum format,
1898*61046927SAndroid Build Coastguard Worker                                 GLenum type, GLenum internalFormat, const char *callerName)
1899*61046927SAndroid Build Coastguard Worker {
1900*61046927SAndroid Build Coastguard Worker    GLenum err = _mesa_gles_error_check_format_and_type(ctx, format, type,
1901*61046927SAndroid Build Coastguard Worker                                                        internalFormat);
1902*61046927SAndroid Build Coastguard Worker    if (err != GL_NO_ERROR) {
1903*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, err,
1904*61046927SAndroid Build Coastguard Worker                   "%s(format = %s, type = %s, internalformat = %s)",
1905*61046927SAndroid Build Coastguard Worker                   callerName, _mesa_enum_to_string(format),
1906*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(type),
1907*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(internalFormat));
1908*61046927SAndroid Build Coastguard Worker       return true;
1909*61046927SAndroid Build Coastguard Worker    }
1910*61046927SAndroid Build Coastguard Worker 
1911*61046927SAndroid Build Coastguard Worker    return false;
1912*61046927SAndroid Build Coastguard Worker }
1913*61046927SAndroid Build Coastguard Worker 
1914*61046927SAndroid Build Coastguard Worker /**
1915*61046927SAndroid Build Coastguard Worker  * Test the glTexImage[123]D() parameters for errors.
1916*61046927SAndroid Build Coastguard Worker  *
1917*61046927SAndroid Build Coastguard Worker  * \param ctx GL context.
1918*61046927SAndroid Build Coastguard Worker  * \param dimensions texture image dimensions (must be 1, 2 or 3).
1919*61046927SAndroid Build Coastguard Worker  * \param target texture target given by the user (already validated).
1920*61046927SAndroid Build Coastguard Worker  * \param level image level given by the user.
1921*61046927SAndroid Build Coastguard Worker  * \param internalFormat internal format given by the user.
1922*61046927SAndroid Build Coastguard Worker  * \param format pixel data format given by the user.
1923*61046927SAndroid Build Coastguard Worker  * \param type pixel data type given by the user.
1924*61046927SAndroid Build Coastguard Worker  * \param width image width given by the user.
1925*61046927SAndroid Build Coastguard Worker  * \param height image height given by the user.
1926*61046927SAndroid Build Coastguard Worker  * \param depth image depth given by the user.
1927*61046927SAndroid Build Coastguard Worker  * \param border image border given by the user.
1928*61046927SAndroid Build Coastguard Worker  *
1929*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if a error is found, GL_FALSE otherwise
1930*61046927SAndroid Build Coastguard Worker  *
1931*61046927SAndroid Build Coastguard Worker  * Verifies each of the parameters against the constants specified in
1932*61046927SAndroid Build Coastguard Worker  * __struct gl_contextRec::Const and the supported extensions, and according
1933*61046927SAndroid Build Coastguard Worker  * to the OpenGL specification.
1934*61046927SAndroid Build Coastguard Worker  * Note that we don't fully error-check the width, height, depth values
1935*61046927SAndroid Build Coastguard Worker  * here.  That's done in _mesa_legal_texture_dimensions() which is used
1936*61046927SAndroid Build Coastguard Worker  * by several other GL entrypoints.  Plus, texture dims have a special
1937*61046927SAndroid Build Coastguard Worker  * interaction with proxy textures.
1938*61046927SAndroid Build Coastguard Worker  */
1939*61046927SAndroid Build Coastguard Worker static GLboolean
texture_error_check(struct gl_context * ctx,GLuint dimensions,GLenum target,struct gl_texture_object * texObj,GLint level,GLint internalFormat,GLenum format,GLenum type,GLint width,GLint height,GLint depth,GLint border,const GLvoid * pixels)1940*61046927SAndroid Build Coastguard Worker texture_error_check( struct gl_context *ctx,
1941*61046927SAndroid Build Coastguard Worker                      GLuint dimensions, GLenum target,
1942*61046927SAndroid Build Coastguard Worker                      struct gl_texture_object* texObj,
1943*61046927SAndroid Build Coastguard Worker                      GLint level, GLint internalFormat,
1944*61046927SAndroid Build Coastguard Worker                      GLenum format, GLenum type,
1945*61046927SAndroid Build Coastguard Worker                      GLint width, GLint height,
1946*61046927SAndroid Build Coastguard Worker                      GLint depth, GLint border,
1947*61046927SAndroid Build Coastguard Worker                      const GLvoid *pixels )
1948*61046927SAndroid Build Coastguard Worker {
1949*61046927SAndroid Build Coastguard Worker    GLenum err;
1950*61046927SAndroid Build Coastguard Worker 
1951*61046927SAndroid Build Coastguard Worker    /* Note: for proxy textures, some error conditions immediately generate
1952*61046927SAndroid Build Coastguard Worker     * a GL error in the usual way.  But others do not generate a GL error.
1953*61046927SAndroid Build Coastguard Worker     * Instead, they cause the width, height, depth, format fields of the
1954*61046927SAndroid Build Coastguard Worker     * texture image to be zeroed-out.  The GL spec seems to indicate that the
1955*61046927SAndroid Build Coastguard Worker     * zero-out behaviour is only used in cases related to memory allocation.
1956*61046927SAndroid Build Coastguard Worker     */
1957*61046927SAndroid Build Coastguard Worker 
1958*61046927SAndroid Build Coastguard Worker    /* level check */
1959*61046927SAndroid Build Coastguard Worker    if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
1960*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
1961*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(level=%d)", dimensions, level);
1962*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1963*61046927SAndroid Build Coastguard Worker    }
1964*61046927SAndroid Build Coastguard Worker 
1965*61046927SAndroid Build Coastguard Worker    /* Check border */
1966*61046927SAndroid Build Coastguard Worker    if (border < 0 || border > 1 ||
1967*61046927SAndroid Build Coastguard Worker        ((ctx->API != API_OPENGL_COMPAT ||
1968*61046927SAndroid Build Coastguard Worker          target == GL_TEXTURE_RECTANGLE_NV ||
1969*61046927SAndroid Build Coastguard Worker          target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
1970*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
1971*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(border=%d)", dimensions, border);
1972*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1973*61046927SAndroid Build Coastguard Worker    }
1974*61046927SAndroid Build Coastguard Worker 
1975*61046927SAndroid Build Coastguard Worker    if (width < 0 || height < 0 || depth < 0) {
1976*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
1977*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(width, height or depth < 0)", dimensions);
1978*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1979*61046927SAndroid Build Coastguard Worker    }
1980*61046927SAndroid Build Coastguard Worker 
1981*61046927SAndroid Build Coastguard Worker    /* Check incoming image format and type */
1982*61046927SAndroid Build Coastguard Worker    err = _mesa_error_check_format_and_type(ctx, format, type);
1983*61046927SAndroid Build Coastguard Worker    if (err != GL_NO_ERROR) {
1984*61046927SAndroid Build Coastguard Worker       /* Prior to OpenGL-ES 2.0, an INVALID_VALUE is expected instead of
1985*61046927SAndroid Build Coastguard Worker        * INVALID_ENUM. From page 73 OpenGL ES 1.1 spec:
1986*61046927SAndroid Build Coastguard Worker        *
1987*61046927SAndroid Build Coastguard Worker        *     "Specifying a value for internalformat that is not one of the
1988*61046927SAndroid Build Coastguard Worker        *      above (acceptable) values generates the error INVALID VALUE."
1989*61046927SAndroid Build Coastguard Worker        */
1990*61046927SAndroid Build Coastguard Worker       if (err == GL_INVALID_ENUM && _mesa_is_gles1(ctx))
1991*61046927SAndroid Build Coastguard Worker          err = GL_INVALID_VALUE;
1992*61046927SAndroid Build Coastguard Worker 
1993*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, err,
1994*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(incompatible format = %s, type = %s)",
1995*61046927SAndroid Build Coastguard Worker                   dimensions, _mesa_enum_to_string(format),
1996*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(type));
1997*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
1998*61046927SAndroid Build Coastguard Worker    }
1999*61046927SAndroid Build Coastguard Worker 
2000*61046927SAndroid Build Coastguard Worker    /* Check internalFormat */
2001*61046927SAndroid Build Coastguard Worker    if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
2002*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
2003*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(internalFormat=%s)",
2004*61046927SAndroid Build Coastguard Worker                   dimensions, _mesa_enum_to_string(internalFormat));
2005*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2006*61046927SAndroid Build Coastguard Worker    }
2007*61046927SAndroid Build Coastguard Worker 
2008*61046927SAndroid Build Coastguard Worker    /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
2009*61046927SAndroid Build Coastguard Worker     * combinations of format, internalFormat, and type that can be used.
2010*61046927SAndroid Build Coastguard Worker     * Formats and types that require additional extensions (e.g., GL_FLOAT
2011*61046927SAndroid Build Coastguard Worker     * requires GL_OES_texture_float) are filtered elsewhere.
2012*61046927SAndroid Build Coastguard Worker     */
2013*61046927SAndroid Build Coastguard Worker    char bufCallerName[20];
2014*61046927SAndroid Build Coastguard Worker    snprintf(bufCallerName, 20, "glTexImage%dD", dimensions);
2015*61046927SAndroid Build Coastguard Worker    if (_mesa_is_gles(ctx) &&
2016*61046927SAndroid Build Coastguard Worker        texture_format_error_check_gles(ctx, format, type,
2017*61046927SAndroid Build Coastguard Worker                                        internalFormat, bufCallerName)) {
2018*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2019*61046927SAndroid Build Coastguard Worker    }
2020*61046927SAndroid Build Coastguard Worker 
2021*61046927SAndroid Build Coastguard Worker    /* validate the bound PBO, if any */
2022*61046927SAndroid Build Coastguard Worker    if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack,
2023*61046927SAndroid Build Coastguard Worker                                   width, height, depth, format, type,
2024*61046927SAndroid Build Coastguard Worker                                   INT_MAX, pixels, "glTexImage")) {
2025*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2026*61046927SAndroid Build Coastguard Worker    }
2027*61046927SAndroid Build Coastguard Worker 
2028*61046927SAndroid Build Coastguard Worker    /* make sure internal format and format basically agree */
2029*61046927SAndroid Build Coastguard Worker    if (!texture_formats_agree(internalFormat, format)) {
2030*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2031*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(incompatible internalFormat = %s, format = %s)",
2032*61046927SAndroid Build Coastguard Worker                   dimensions, _mesa_enum_to_string(internalFormat),
2033*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(format));
2034*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2035*61046927SAndroid Build Coastguard Worker    }
2036*61046927SAndroid Build Coastguard Worker 
2037*61046927SAndroid Build Coastguard Worker    /* additional checks for ycbcr textures */
2038*61046927SAndroid Build Coastguard Worker    if (internalFormat == GL_YCBCR_MESA) {
2039*61046927SAndroid Build Coastguard Worker       assert(ctx->Extensions.MESA_ycbcr_texture);
2040*61046927SAndroid Build Coastguard Worker       if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
2041*61046927SAndroid Build Coastguard Worker           type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
2042*61046927SAndroid Build Coastguard Worker          char message[100];
2043*61046927SAndroid Build Coastguard Worker          snprintf(message, sizeof(message),
2044*61046927SAndroid Build Coastguard Worker                         "glTexImage%dD(format/type YCBCR mismatch)",
2045*61046927SAndroid Build Coastguard Worker                         dimensions);
2046*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
2047*61046927SAndroid Build Coastguard Worker          return GL_TRUE; /* error */
2048*61046927SAndroid Build Coastguard Worker       }
2049*61046927SAndroid Build Coastguard Worker       if (target != GL_TEXTURE_2D &&
2050*61046927SAndroid Build Coastguard Worker           target != GL_PROXY_TEXTURE_2D &&
2051*61046927SAndroid Build Coastguard Worker           target != GL_TEXTURE_RECTANGLE_NV &&
2052*61046927SAndroid Build Coastguard Worker           target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
2053*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_ENUM,
2054*61046927SAndroid Build Coastguard Worker                      "glTexImage%dD(bad target for YCbCr texture)",
2055*61046927SAndroid Build Coastguard Worker                      dimensions);
2056*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2057*61046927SAndroid Build Coastguard Worker       }
2058*61046927SAndroid Build Coastguard Worker       if (border != 0) {
2059*61046927SAndroid Build Coastguard Worker          char message[100];
2060*61046927SAndroid Build Coastguard Worker          snprintf(message, sizeof(message),
2061*61046927SAndroid Build Coastguard Worker                         "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
2062*61046927SAndroid Build Coastguard Worker                         dimensions, border);
2063*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
2064*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2065*61046927SAndroid Build Coastguard Worker       }
2066*61046927SAndroid Build Coastguard Worker    }
2067*61046927SAndroid Build Coastguard Worker 
2068*61046927SAndroid Build Coastguard Worker    /* additional checks for depth textures */
2069*61046927SAndroid Build Coastguard Worker    if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalFormat)) {
2070*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2071*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(bad target for texture)", dimensions);
2072*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2073*61046927SAndroid Build Coastguard Worker    }
2074*61046927SAndroid Build Coastguard Worker 
2075*61046927SAndroid Build Coastguard Worker    /* additional checks for compressed textures */
2076*61046927SAndroid Build Coastguard Worker    if (_mesa_is_compressed_format(ctx, internalFormat)) {
2077*61046927SAndroid Build Coastguard Worker       GLenum err;
2078*61046927SAndroid Build Coastguard Worker       if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) {
2079*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, err,
2080*61046927SAndroid Build Coastguard Worker                      "glTexImage%dD(target can't be compressed)", dimensions);
2081*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2082*61046927SAndroid Build Coastguard Worker       }
2083*61046927SAndroid Build Coastguard Worker       if (_mesa_format_no_online_compression(internalFormat)) {
2084*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2085*61046927SAndroid Build Coastguard Worker                      "glTexImage%dD(no compression for format)", dimensions);
2086*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2087*61046927SAndroid Build Coastguard Worker       }
2088*61046927SAndroid Build Coastguard Worker       if (border != 0) {
2089*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2090*61046927SAndroid Build Coastguard Worker                      "glTexImage%dD(border!=0)", dimensions);
2091*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2092*61046927SAndroid Build Coastguard Worker       }
2093*61046927SAndroid Build Coastguard Worker    }
2094*61046927SAndroid Build Coastguard Worker 
2095*61046927SAndroid Build Coastguard Worker    /* additional checks for integer textures */
2096*61046927SAndroid Build Coastguard Worker    if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) &&
2097*61046927SAndroid Build Coastguard Worker        (_mesa_is_enum_format_integer(format) !=
2098*61046927SAndroid Build Coastguard Worker         _mesa_is_enum_format_integer(internalFormat))) {
2099*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2100*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(integer/non-integer format mismatch)",
2101*61046927SAndroid Build Coastguard Worker                   dimensions);
2102*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2103*61046927SAndroid Build Coastguard Worker    }
2104*61046927SAndroid Build Coastguard Worker 
2105*61046927SAndroid Build Coastguard Worker    if (!mutable_tex_object(texObj)) {
2106*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2107*61046927SAndroid Build Coastguard Worker                   "glTexImage%dD(immutable texture)", dimensions);
2108*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2109*61046927SAndroid Build Coastguard Worker    }
2110*61046927SAndroid Build Coastguard Worker 
2111*61046927SAndroid Build Coastguard Worker    /* if we get here, the parameters are OK */
2112*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
2113*61046927SAndroid Build Coastguard Worker }
2114*61046927SAndroid Build Coastguard Worker 
2115*61046927SAndroid Build Coastguard Worker 
2116*61046927SAndroid Build Coastguard Worker /**
2117*61046927SAndroid Build Coastguard Worker  * Error checking for glCompressedTexImage[123]D().
2118*61046927SAndroid Build Coastguard Worker  * Note that the width, height and depth values are not fully error checked
2119*61046927SAndroid Build Coastguard Worker  * here.
2120*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if a error is found, GL_FALSE otherwise
2121*61046927SAndroid Build Coastguard Worker  */
2122*61046927SAndroid Build Coastguard Worker static GLenum
compressed_texture_error_check(struct gl_context * ctx,GLint dimensions,GLenum target,struct gl_texture_object * texObj,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * data)2123*61046927SAndroid Build Coastguard Worker compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
2124*61046927SAndroid Build Coastguard Worker                                GLenum target, struct gl_texture_object* texObj,
2125*61046927SAndroid Build Coastguard Worker                                GLint level, GLenum internalFormat, GLsizei width,
2126*61046927SAndroid Build Coastguard Worker                                GLsizei height, GLsizei depth, GLint border,
2127*61046927SAndroid Build Coastguard Worker                                GLsizei imageSize, const GLvoid *data)
2128*61046927SAndroid Build Coastguard Worker {
2129*61046927SAndroid Build Coastguard Worker    const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
2130*61046927SAndroid Build Coastguard Worker    GLint expectedSize;
2131*61046927SAndroid Build Coastguard Worker    GLenum error = GL_NO_ERROR;
2132*61046927SAndroid Build Coastguard Worker    char *reason = ""; /* no error */
2133*61046927SAndroid Build Coastguard Worker 
2134*61046927SAndroid Build Coastguard Worker    if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &error)) {
2135*61046927SAndroid Build Coastguard Worker       reason = "target";
2136*61046927SAndroid Build Coastguard Worker       goto error;
2137*61046927SAndroid Build Coastguard Worker    }
2138*61046927SAndroid Build Coastguard Worker 
2139*61046927SAndroid Build Coastguard Worker    /* This will detect any invalid internalFormat value */
2140*61046927SAndroid Build Coastguard Worker    if (!_mesa_is_compressed_format(ctx, internalFormat)) {
2141*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM,
2142*61046927SAndroid Build Coastguard Worker                   "glCompressedTexImage%dD(internalFormat=%s)",
2143*61046927SAndroid Build Coastguard Worker                   dimensions, _mesa_enum_to_string(internalFormat));
2144*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2145*61046927SAndroid Build Coastguard Worker    }
2146*61046927SAndroid Build Coastguard Worker 
2147*61046927SAndroid Build Coastguard Worker    /* validate the bound PBO, if any */
2148*61046927SAndroid Build Coastguard Worker    if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, &ctx->Unpack,
2149*61046927SAndroid Build Coastguard Worker                                              imageSize, data,
2150*61046927SAndroid Build Coastguard Worker                                              "glCompressedTexImage")) {
2151*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2152*61046927SAndroid Build Coastguard Worker    }
2153*61046927SAndroid Build Coastguard Worker 
2154*61046927SAndroid Build Coastguard Worker    switch (internalFormat) {
2155*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_RGB8_OES:
2156*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_RGBA8_OES:
2157*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_R5_G6_B5_OES:
2158*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_RGBA4_OES:
2159*61046927SAndroid Build Coastguard Worker    case GL_PALETTE4_RGB5_A1_OES:
2160*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_RGB8_OES:
2161*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_RGBA8_OES:
2162*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_R5_G6_B5_OES:
2163*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_RGBA4_OES:
2164*61046927SAndroid Build Coastguard Worker    case GL_PALETTE8_RGB5_A1_OES:
2165*61046927SAndroid Build Coastguard Worker       /* check level (note that level should be zero or less!) */
2166*61046927SAndroid Build Coastguard Worker       if (level > 0 || level < -maxLevels) {
2167*61046927SAndroid Build Coastguard Worker          reason = "level";
2168*61046927SAndroid Build Coastguard Worker          error = GL_INVALID_VALUE;
2169*61046927SAndroid Build Coastguard Worker          goto error;
2170*61046927SAndroid Build Coastguard Worker       }
2171*61046927SAndroid Build Coastguard Worker 
2172*61046927SAndroid Build Coastguard Worker       if (dimensions != 2) {
2173*61046927SAndroid Build Coastguard Worker          reason = "compressed paletted textures must be 2D";
2174*61046927SAndroid Build Coastguard Worker          error = GL_INVALID_OPERATION;
2175*61046927SAndroid Build Coastguard Worker          goto error;
2176*61046927SAndroid Build Coastguard Worker       }
2177*61046927SAndroid Build Coastguard Worker 
2178*61046927SAndroid Build Coastguard Worker       /* Figure out the expected texture size (in bytes).  This will be
2179*61046927SAndroid Build Coastguard Worker        * checked against the actual size later.
2180*61046927SAndroid Build Coastguard Worker        */
2181*61046927SAndroid Build Coastguard Worker       expectedSize = _mesa_cpal_compressed_size(level, internalFormat,
2182*61046927SAndroid Build Coastguard Worker                                                 width, height);
2183*61046927SAndroid Build Coastguard Worker 
2184*61046927SAndroid Build Coastguard Worker       /* This is for the benefit of the TestProxyTexImage below.  It expects
2185*61046927SAndroid Build Coastguard Worker        * level to be non-negative.  OES_compressed_paletted_texture uses a
2186*61046927SAndroid Build Coastguard Worker        * weird mechanism where the level specified to glCompressedTexImage2D
2187*61046927SAndroid Build Coastguard Worker        * is -(n-1) number of levels in the texture, and the data specifies the
2188*61046927SAndroid Build Coastguard Worker        * complete mipmap stack.  This is done to ensure the palette is the
2189*61046927SAndroid Build Coastguard Worker        * same for all levels.
2190*61046927SAndroid Build Coastguard Worker        */
2191*61046927SAndroid Build Coastguard Worker       level = -level;
2192*61046927SAndroid Build Coastguard Worker       break;
2193*61046927SAndroid Build Coastguard Worker 
2194*61046927SAndroid Build Coastguard Worker    default:
2195*61046927SAndroid Build Coastguard Worker       /* check level */
2196*61046927SAndroid Build Coastguard Worker       if (level < 0 || level >= maxLevels) {
2197*61046927SAndroid Build Coastguard Worker          reason = "level";
2198*61046927SAndroid Build Coastguard Worker          error = GL_INVALID_VALUE;
2199*61046927SAndroid Build Coastguard Worker          goto error;
2200*61046927SAndroid Build Coastguard Worker       }
2201*61046927SAndroid Build Coastguard Worker 
2202*61046927SAndroid Build Coastguard Worker       /* Figure out the expected texture size (in bytes).  This will be
2203*61046927SAndroid Build Coastguard Worker        * checked against the actual size later.
2204*61046927SAndroid Build Coastguard Worker        */
2205*61046927SAndroid Build Coastguard Worker       expectedSize = compressed_tex_size(width, height, depth, internalFormat);
2206*61046927SAndroid Build Coastguard Worker       break;
2207*61046927SAndroid Build Coastguard Worker    }
2208*61046927SAndroid Build Coastguard Worker 
2209*61046927SAndroid Build Coastguard Worker    /* This should really never fail */
2210*61046927SAndroid Build Coastguard Worker    if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
2211*61046927SAndroid Build Coastguard Worker       reason = "internalFormat";
2212*61046927SAndroid Build Coastguard Worker       error = GL_INVALID_ENUM;
2213*61046927SAndroid Build Coastguard Worker       goto error;
2214*61046927SAndroid Build Coastguard Worker    }
2215*61046927SAndroid Build Coastguard Worker 
2216*61046927SAndroid Build Coastguard Worker    /* No compressed formats support borders at this time */
2217*61046927SAndroid Build Coastguard Worker    if (border != 0) {
2218*61046927SAndroid Build Coastguard Worker       reason = "border != 0";
2219*61046927SAndroid Build Coastguard Worker       error = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_VALUE;
2220*61046927SAndroid Build Coastguard Worker       goto error;
2221*61046927SAndroid Build Coastguard Worker    }
2222*61046927SAndroid Build Coastguard Worker 
2223*61046927SAndroid Build Coastguard Worker    /* Check for invalid pixel storage modes */
2224*61046927SAndroid Build Coastguard Worker    if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions,
2225*61046927SAndroid Build Coastguard Worker                                                    &ctx->Unpack,
2226*61046927SAndroid Build Coastguard Worker                                                    "glCompressedTexImage")) {
2227*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
2228*61046927SAndroid Build Coastguard Worker    }
2229*61046927SAndroid Build Coastguard Worker 
2230*61046927SAndroid Build Coastguard Worker    /* check image size in bytes */
2231*61046927SAndroid Build Coastguard Worker    if (expectedSize != imageSize) {
2232*61046927SAndroid Build Coastguard Worker       /* Per GL_ARB_texture_compression:  GL_INVALID_VALUE is generated [...]
2233*61046927SAndroid Build Coastguard Worker        * if <imageSize> is not consistent with the format, dimensions, and
2234*61046927SAndroid Build Coastguard Worker        * contents of the specified image.
2235*61046927SAndroid Build Coastguard Worker        */
2236*61046927SAndroid Build Coastguard Worker       reason = "imageSize inconsistent with width/height/format";
2237*61046927SAndroid Build Coastguard Worker       error = GL_INVALID_VALUE;
2238*61046927SAndroid Build Coastguard Worker       goto error;
2239*61046927SAndroid Build Coastguard Worker    }
2240*61046927SAndroid Build Coastguard Worker 
2241*61046927SAndroid Build Coastguard Worker    if (!mutable_tex_object(texObj)) {
2242*61046927SAndroid Build Coastguard Worker       reason = "immutable texture";
2243*61046927SAndroid Build Coastguard Worker       error = GL_INVALID_OPERATION;
2244*61046927SAndroid Build Coastguard Worker       goto error;
2245*61046927SAndroid Build Coastguard Worker    }
2246*61046927SAndroid Build Coastguard Worker 
2247*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
2248*61046927SAndroid Build Coastguard Worker 
2249*61046927SAndroid Build Coastguard Worker error:
2250*61046927SAndroid Build Coastguard Worker    /* Note: not all error paths exit through here. */
2251*61046927SAndroid Build Coastguard Worker    _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)",
2252*61046927SAndroid Build Coastguard Worker                dimensions, reason);
2253*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
2254*61046927SAndroid Build Coastguard Worker }
2255*61046927SAndroid Build Coastguard Worker 
2256*61046927SAndroid Build Coastguard Worker 
2257*61046927SAndroid Build Coastguard Worker 
2258*61046927SAndroid Build Coastguard Worker /**
2259*61046927SAndroid Build Coastguard Worker  * Test glTexSubImage[123]D() parameters for errors.
2260*61046927SAndroid Build Coastguard Worker  *
2261*61046927SAndroid Build Coastguard Worker  * \param ctx GL context.
2262*61046927SAndroid Build Coastguard Worker  * \param dimensions texture image dimensions (must be 1, 2 or 3).
2263*61046927SAndroid Build Coastguard Worker  * \param target texture target given by the user (already validated)
2264*61046927SAndroid Build Coastguard Worker  * \param level image level given by the user.
2265*61046927SAndroid Build Coastguard Worker  * \param xoffset sub-image x offset given by the user.
2266*61046927SAndroid Build Coastguard Worker  * \param yoffset sub-image y offset given by the user.
2267*61046927SAndroid Build Coastguard Worker  * \param zoffset sub-image z offset given by the user.
2268*61046927SAndroid Build Coastguard Worker  * \param format pixel data format given by the user.
2269*61046927SAndroid Build Coastguard Worker  * \param type pixel data type given by the user.
2270*61046927SAndroid Build Coastguard Worker  * \param width image width given by the user.
2271*61046927SAndroid Build Coastguard Worker  * \param height image height given by the user.
2272*61046927SAndroid Build Coastguard Worker  * \param depth image depth given by the user.
2273*61046927SAndroid Build Coastguard Worker  *
2274*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2275*61046927SAndroid Build Coastguard Worker  *
2276*61046927SAndroid Build Coastguard Worker  * Verifies each of the parameters against the constants specified in
2277*61046927SAndroid Build Coastguard Worker  * __struct gl_contextRec::Const and the supported extensions, and according
2278*61046927SAndroid Build Coastguard Worker  * to the OpenGL specification.
2279*61046927SAndroid Build Coastguard Worker  */
2280*61046927SAndroid Build Coastguard Worker static GLboolean
texsubimage_error_check(struct gl_context * ctx,GLuint dimensions,struct gl_texture_object * texObj,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,GLenum format,GLenum type,const GLvoid * pixels,const char * callerName)2281*61046927SAndroid Build Coastguard Worker texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
2282*61046927SAndroid Build Coastguard Worker                         struct gl_texture_object *texObj,
2283*61046927SAndroid Build Coastguard Worker                         GLenum target, GLint level,
2284*61046927SAndroid Build Coastguard Worker                         GLint xoffset, GLint yoffset, GLint zoffset,
2285*61046927SAndroid Build Coastguard Worker                         GLint width, GLint height, GLint depth,
2286*61046927SAndroid Build Coastguard Worker                         GLenum format, GLenum type, const GLvoid *pixels,
2287*61046927SAndroid Build Coastguard Worker                         const char *callerName)
2288*61046927SAndroid Build Coastguard Worker {
2289*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
2290*61046927SAndroid Build Coastguard Worker    GLenum err;
2291*61046927SAndroid Build Coastguard Worker 
2292*61046927SAndroid Build Coastguard Worker    if (!texObj) {
2293*61046927SAndroid Build Coastguard Worker       /* must be out of memory */
2294*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", callerName);
2295*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2296*61046927SAndroid Build Coastguard Worker    }
2297*61046927SAndroid Build Coastguard Worker 
2298*61046927SAndroid Build Coastguard Worker    /* level check */
2299*61046927SAndroid Build Coastguard Worker    if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
2300*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level);
2301*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2302*61046927SAndroid Build Coastguard Worker    }
2303*61046927SAndroid Build Coastguard Worker 
2304*61046927SAndroid Build Coastguard Worker    if (error_check_subtexture_negative_dimensions(ctx, dimensions,
2305*61046927SAndroid Build Coastguard Worker                                                   width, height, depth,
2306*61046927SAndroid Build Coastguard Worker                                                   callerName)) {
2307*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2308*61046927SAndroid Build Coastguard Worker    }
2309*61046927SAndroid Build Coastguard Worker 
2310*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
2311*61046927SAndroid Build Coastguard Worker    if (!texImage) {
2312*61046927SAndroid Build Coastguard Worker       /* non-existant texture level */
2313*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)",
2314*61046927SAndroid Build Coastguard Worker                   callerName, level);
2315*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2316*61046927SAndroid Build Coastguard Worker    }
2317*61046927SAndroid Build Coastguard Worker 
2318*61046927SAndroid Build Coastguard Worker    err = _mesa_error_check_format_and_type(ctx, format, type);
2319*61046927SAndroid Build Coastguard Worker    if (err != GL_NO_ERROR) {
2320*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, err,
2321*61046927SAndroid Build Coastguard Worker                   "%s(incompatible format = %s, type = %s)",
2322*61046927SAndroid Build Coastguard Worker                   callerName, _mesa_enum_to_string(format),
2323*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(type));
2324*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2325*61046927SAndroid Build Coastguard Worker    }
2326*61046927SAndroid Build Coastguard Worker 
2327*61046927SAndroid Build Coastguard Worker    if (!texture_formats_agree(texImage->InternalFormat, format)) {
2328*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2329*61046927SAndroid Build Coastguard Worker                   "%s(incompatible internalFormat = %s, format = %s)",
2330*61046927SAndroid Build Coastguard Worker                   callerName,
2331*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texImage->InternalFormat),
2332*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(format));
2333*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2334*61046927SAndroid Build Coastguard Worker    }
2335*61046927SAndroid Build Coastguard Worker 
2336*61046927SAndroid Build Coastguard Worker    GLenum internalFormat = _mesa_is_gles(ctx) ?
2337*61046927SAndroid Build Coastguard Worker       oes_float_internal_format(ctx, texImage->InternalFormat, type) :
2338*61046927SAndroid Build Coastguard Worker       texImage->InternalFormat;
2339*61046927SAndroid Build Coastguard Worker 
2340*61046927SAndroid Build Coastguard Worker    /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
2341*61046927SAndroid Build Coastguard Worker     * combinations of format, internalFormat, and type that can be used.
2342*61046927SAndroid Build Coastguard Worker     * Formats and types that require additional extensions (e.g., GL_FLOAT
2343*61046927SAndroid Build Coastguard Worker     * requires GL_OES_texture_float) are filtered elsewhere.
2344*61046927SAndroid Build Coastguard Worker     */
2345*61046927SAndroid Build Coastguard Worker    if (_mesa_is_gles(ctx) &&
2346*61046927SAndroid Build Coastguard Worker        texture_format_error_check_gles(ctx, format, type,
2347*61046927SAndroid Build Coastguard Worker                                        internalFormat, callerName)) {
2348*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2349*61046927SAndroid Build Coastguard Worker    }
2350*61046927SAndroid Build Coastguard Worker 
2351*61046927SAndroid Build Coastguard Worker    /* validate the bound PBO, if any */
2352*61046927SAndroid Build Coastguard Worker    if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack,
2353*61046927SAndroid Build Coastguard Worker                                   width, height, depth, format, type,
2354*61046927SAndroid Build Coastguard Worker                                   INT_MAX, pixels, callerName)) {
2355*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2356*61046927SAndroid Build Coastguard Worker    }
2357*61046927SAndroid Build Coastguard Worker 
2358*61046927SAndroid Build Coastguard Worker    if (error_check_subtexture_dimensions(ctx, dimensions,
2359*61046927SAndroid Build Coastguard Worker                                          texImage, xoffset, yoffset, zoffset,
2360*61046927SAndroid Build Coastguard Worker                                          width, height, depth, callerName)) {
2361*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2362*61046927SAndroid Build Coastguard Worker    }
2363*61046927SAndroid Build Coastguard Worker 
2364*61046927SAndroid Build Coastguard Worker    if (_mesa_is_format_compressed(texImage->TexFormat)) {
2365*61046927SAndroid Build Coastguard Worker       if (_mesa_format_no_online_compression(texImage->InternalFormat)) {
2366*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2367*61046927SAndroid Build Coastguard Worker                "%s(no compression for format)", callerName);
2368*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2369*61046927SAndroid Build Coastguard Worker       }
2370*61046927SAndroid Build Coastguard Worker    }
2371*61046927SAndroid Build Coastguard Worker 
2372*61046927SAndroid Build Coastguard Worker    if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
2373*61046927SAndroid Build Coastguard Worker       /* both source and dest must be integer-valued, or neither */
2374*61046927SAndroid Build Coastguard Worker       if (_mesa_is_format_integer_color(texImage->TexFormat) !=
2375*61046927SAndroid Build Coastguard Worker           _mesa_is_enum_format_integer(format)) {
2376*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2377*61046927SAndroid Build Coastguard Worker                      "%s(integer/non-integer format mismatch)", callerName);
2378*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2379*61046927SAndroid Build Coastguard Worker       }
2380*61046927SAndroid Build Coastguard Worker    }
2381*61046927SAndroid Build Coastguard Worker 
2382*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
2383*61046927SAndroid Build Coastguard Worker }
2384*61046927SAndroid Build Coastguard Worker 
2385*61046927SAndroid Build Coastguard Worker 
2386*61046927SAndroid Build Coastguard Worker /**
2387*61046927SAndroid Build Coastguard Worker  * Test glCopyTexImage[12]D() parameters for errors.
2388*61046927SAndroid Build Coastguard Worker  *
2389*61046927SAndroid Build Coastguard Worker  * \param ctx GL context.
2390*61046927SAndroid Build Coastguard Worker  * \param dimensions texture image dimensions (must be 1, 2 or 3).
2391*61046927SAndroid Build Coastguard Worker  * \param target texture target given by the user.
2392*61046927SAndroid Build Coastguard Worker  * \param level image level given by the user.
2393*61046927SAndroid Build Coastguard Worker  * \param internalFormat internal format given by the user.
2394*61046927SAndroid Build Coastguard Worker  * \param width image width given by the user.
2395*61046927SAndroid Build Coastguard Worker  * \param height image height given by the user.
2396*61046927SAndroid Build Coastguard Worker  * \param border texture border.
2397*61046927SAndroid Build Coastguard Worker  *
2398*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2399*61046927SAndroid Build Coastguard Worker  *
2400*61046927SAndroid Build Coastguard Worker  * Verifies each of the parameters against the constants specified in
2401*61046927SAndroid Build Coastguard Worker  * __struct gl_contextRec::Const and the supported extensions, and according
2402*61046927SAndroid Build Coastguard Worker  * to the OpenGL specification.
2403*61046927SAndroid Build Coastguard Worker  */
2404*61046927SAndroid Build Coastguard Worker static GLboolean
copytexture_error_check(struct gl_context * ctx,GLuint dimensions,GLenum target,struct gl_texture_object * texObj,GLint level,GLint internalFormat,GLint border)2405*61046927SAndroid Build Coastguard Worker copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
2406*61046927SAndroid Build Coastguard Worker                          GLenum target, struct gl_texture_object* texObj,
2407*61046927SAndroid Build Coastguard Worker                          GLint level, GLint internalFormat, GLint border )
2408*61046927SAndroid Build Coastguard Worker {
2409*61046927SAndroid Build Coastguard Worker    GLint baseFormat;
2410*61046927SAndroid Build Coastguard Worker    GLint rb_base_format;
2411*61046927SAndroid Build Coastguard Worker    struct gl_renderbuffer *rb;
2412*61046927SAndroid Build Coastguard Worker    GLenum rb_internal_format;
2413*61046927SAndroid Build Coastguard Worker 
2414*61046927SAndroid Build Coastguard Worker    /* level check */
2415*61046927SAndroid Build Coastguard Worker    if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
2416*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
2417*61046927SAndroid Build Coastguard Worker                   "glCopyTexImage%dD(level=%d)", dimensions, level);
2418*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2419*61046927SAndroid Build Coastguard Worker    }
2420*61046927SAndroid Build Coastguard Worker 
2421*61046927SAndroid Build Coastguard Worker    /* Check that the source buffer is complete */
2422*61046927SAndroid Build Coastguard Worker    if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
2423*61046927SAndroid Build Coastguard Worker       if (ctx->ReadBuffer->_Status == 0) {
2424*61046927SAndroid Build Coastguard Worker          _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2425*61046927SAndroid Build Coastguard Worker       }
2426*61046927SAndroid Build Coastguard Worker       if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2427*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2428*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(invalid readbuffer)", dimensions);
2429*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2430*61046927SAndroid Build Coastguard Worker       }
2431*61046927SAndroid Build Coastguard Worker 
2432*61046927SAndroid Build Coastguard Worker       if (!ctx->st_opts->allow_multisampled_copyteximage &&
2433*61046927SAndroid Build Coastguard Worker           ctx->ReadBuffer->Visual.samples > 0) {
2434*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2435*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(multisample FBO)", dimensions);
2436*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2437*61046927SAndroid Build Coastguard Worker       }
2438*61046927SAndroid Build Coastguard Worker    }
2439*61046927SAndroid Build Coastguard Worker 
2440*61046927SAndroid Build Coastguard Worker    /* Check border */
2441*61046927SAndroid Build Coastguard Worker    if (border < 0 || border > 1 ||
2442*61046927SAndroid Build Coastguard Worker        ((ctx->API != API_OPENGL_COMPAT ||
2443*61046927SAndroid Build Coastguard Worker          target == GL_TEXTURE_RECTANGLE_NV ||
2444*61046927SAndroid Build Coastguard Worker          target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
2445*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
2446*61046927SAndroid Build Coastguard Worker                   "glCopyTexImage%dD(border=%d)", dimensions, border);
2447*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2448*61046927SAndroid Build Coastguard Worker    }
2449*61046927SAndroid Build Coastguard Worker 
2450*61046927SAndroid Build Coastguard Worker    /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
2451*61046927SAndroid Build Coastguard Worker     * internalFormat.
2452*61046927SAndroid Build Coastguard Worker     */
2453*61046927SAndroid Build Coastguard Worker    if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
2454*61046927SAndroid Build Coastguard Worker       switch (internalFormat) {
2455*61046927SAndroid Build Coastguard Worker       case GL_ALPHA:
2456*61046927SAndroid Build Coastguard Worker       case GL_RGB:
2457*61046927SAndroid Build Coastguard Worker       case GL_RGBA:
2458*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE:
2459*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA:
2460*61046927SAndroid Build Coastguard Worker 
2461*61046927SAndroid Build Coastguard Worker       /* Added by GL_OES_required_internalformat (always enabled) in table 3.4.y.*/
2462*61046927SAndroid Build Coastguard Worker       case GL_ALPHA8:
2463*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE8:
2464*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE8_ALPHA8:
2465*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE4_ALPHA4:
2466*61046927SAndroid Build Coastguard Worker       case GL_RGB565:
2467*61046927SAndroid Build Coastguard Worker       case GL_RGB8:
2468*61046927SAndroid Build Coastguard Worker       case GL_RGBA4:
2469*61046927SAndroid Build Coastguard Worker       case GL_RGB5_A1:
2470*61046927SAndroid Build Coastguard Worker       case GL_RGBA8:
2471*61046927SAndroid Build Coastguard Worker       case GL_DEPTH_COMPONENT16:
2472*61046927SAndroid Build Coastguard Worker       case GL_DEPTH_COMPONENT24:
2473*61046927SAndroid Build Coastguard Worker       case GL_DEPTH_COMPONENT32:
2474*61046927SAndroid Build Coastguard Worker       case GL_DEPTH24_STENCIL8:
2475*61046927SAndroid Build Coastguard Worker       case GL_RGB10:
2476*61046927SAndroid Build Coastguard Worker       case GL_RGB10_A2:
2477*61046927SAndroid Build Coastguard Worker          break;
2478*61046927SAndroid Build Coastguard Worker 
2479*61046927SAndroid Build Coastguard Worker       case GL_RED:
2480*61046927SAndroid Build Coastguard Worker       case GL_RG:
2481*61046927SAndroid Build Coastguard Worker          /* GL_EXT_texture_rg adds support for GL_RED and GL_RG as an internal
2482*61046927SAndroid Build Coastguard Worker           * format
2483*61046927SAndroid Build Coastguard Worker           */
2484*61046927SAndroid Build Coastguard Worker          if (_mesa_has_EXT_texture_rg(ctx))
2485*61046927SAndroid Build Coastguard Worker             break;
2486*61046927SAndroid Build Coastguard Worker 
2487*61046927SAndroid Build Coastguard Worker       FALLTHROUGH;
2488*61046927SAndroid Build Coastguard Worker       default:
2489*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_ENUM,
2490*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2491*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(internalFormat));
2492*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2493*61046927SAndroid Build Coastguard Worker       }
2494*61046927SAndroid Build Coastguard Worker    } else {
2495*61046927SAndroid Build Coastguard Worker       /*
2496*61046927SAndroid Build Coastguard Worker        * Section 8.6 (Alternate Texture Image Specification Commands) of the
2497*61046927SAndroid Build Coastguard Worker        * OpenGL 4.5 (Compatibility Profile) spec says:
2498*61046927SAndroid Build Coastguard Worker        *
2499*61046927SAndroid Build Coastguard Worker        *     "Parameters level, internalformat, and border are specified using
2500*61046927SAndroid Build Coastguard Worker        *     the same values, with the same meanings, as the corresponding
2501*61046927SAndroid Build Coastguard Worker        *     arguments of TexImage2D, except that internalformat may not be
2502*61046927SAndroid Build Coastguard Worker        *     specified as 1, 2, 3, or 4."
2503*61046927SAndroid Build Coastguard Worker        */
2504*61046927SAndroid Build Coastguard Worker       if (internalFormat >= 1 && internalFormat <= 4) {
2505*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_ENUM,
2506*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(internalFormat=%d)", dimensions,
2507*61046927SAndroid Build Coastguard Worker                      internalFormat);
2508*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2509*61046927SAndroid Build Coastguard Worker       }
2510*61046927SAndroid Build Coastguard Worker    }
2511*61046927SAndroid Build Coastguard Worker 
2512*61046927SAndroid Build Coastguard Worker    baseFormat = _mesa_base_tex_format(ctx, internalFormat);
2513*61046927SAndroid Build Coastguard Worker    if (baseFormat < 0) {
2514*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM,
2515*61046927SAndroid Build Coastguard Worker                   "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2516*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(internalFormat));
2517*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2518*61046927SAndroid Build Coastguard Worker    }
2519*61046927SAndroid Build Coastguard Worker 
2520*61046927SAndroid Build Coastguard Worker    rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
2521*61046927SAndroid Build Coastguard Worker    if (rb == NULL) {
2522*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2523*61046927SAndroid Build Coastguard Worker                   "glCopyTexImage%dD(read buffer)", dimensions);
2524*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2525*61046927SAndroid Build Coastguard Worker    }
2526*61046927SAndroid Build Coastguard Worker 
2527*61046927SAndroid Build Coastguard Worker    rb_internal_format = rb->InternalFormat;
2528*61046927SAndroid Build Coastguard Worker    rb_base_format = _mesa_base_tex_format(ctx, rb->InternalFormat);
2529*61046927SAndroid Build Coastguard Worker    if (_mesa_is_color_format(internalFormat)) {
2530*61046927SAndroid Build Coastguard Worker       if (rb_base_format < 0) {
2531*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE,
2532*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2533*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(internalFormat));
2534*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2535*61046927SAndroid Build Coastguard Worker       }
2536*61046927SAndroid Build Coastguard Worker    }
2537*61046927SAndroid Build Coastguard Worker 
2538*61046927SAndroid Build Coastguard Worker    if (_mesa_is_gles(ctx)) {
2539*61046927SAndroid Build Coastguard Worker       bool valid = true;
2540*61046927SAndroid Build Coastguard Worker       if (_mesa_components_in_format(baseFormat) >
2541*61046927SAndroid Build Coastguard Worker           _mesa_components_in_format(rb_base_format)) {
2542*61046927SAndroid Build Coastguard Worker          valid = false;
2543*61046927SAndroid Build Coastguard Worker       }
2544*61046927SAndroid Build Coastguard Worker       if (baseFormat == GL_DEPTH_COMPONENT ||
2545*61046927SAndroid Build Coastguard Worker           baseFormat == GL_DEPTH_STENCIL ||
2546*61046927SAndroid Build Coastguard Worker           baseFormat == GL_STENCIL_INDEX ||
2547*61046927SAndroid Build Coastguard Worker           rb_base_format == GL_DEPTH_COMPONENT ||
2548*61046927SAndroid Build Coastguard Worker           rb_base_format == GL_DEPTH_STENCIL ||
2549*61046927SAndroid Build Coastguard Worker           rb_base_format == GL_STENCIL_INDEX ||
2550*61046927SAndroid Build Coastguard Worker           ((baseFormat == GL_LUMINANCE_ALPHA ||
2551*61046927SAndroid Build Coastguard Worker             baseFormat == GL_ALPHA) &&
2552*61046927SAndroid Build Coastguard Worker            rb_base_format != GL_RGBA) ||
2553*61046927SAndroid Build Coastguard Worker           internalFormat == GL_RGB9_E5) {
2554*61046927SAndroid Build Coastguard Worker          valid = false;
2555*61046927SAndroid Build Coastguard Worker       }
2556*61046927SAndroid Build Coastguard Worker       if (internalFormat == GL_RGB9_E5) {
2557*61046927SAndroid Build Coastguard Worker          valid = false;
2558*61046927SAndroid Build Coastguard Worker       }
2559*61046927SAndroid Build Coastguard Worker       if (!valid) {
2560*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2561*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2562*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(internalFormat));
2563*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2564*61046927SAndroid Build Coastguard Worker       }
2565*61046927SAndroid Build Coastguard Worker    }
2566*61046927SAndroid Build Coastguard Worker 
2567*61046927SAndroid Build Coastguard Worker    if (_mesa_is_gles3(ctx)) {
2568*61046927SAndroid Build Coastguard Worker       bool rb_is_srgb = (ctx->Extensions.EXT_sRGB &&
2569*61046927SAndroid Build Coastguard Worker                          _mesa_is_format_srgb(rb->Format));
2570*61046927SAndroid Build Coastguard Worker       bool dst_is_srgb = false;
2571*61046927SAndroid Build Coastguard Worker 
2572*61046927SAndroid Build Coastguard Worker       if (_mesa_get_linear_internalformat(internalFormat) != internalFormat) {
2573*61046927SAndroid Build Coastguard Worker          dst_is_srgb = true;
2574*61046927SAndroid Build Coastguard Worker       }
2575*61046927SAndroid Build Coastguard Worker 
2576*61046927SAndroid Build Coastguard Worker       if (rb_is_srgb != dst_is_srgb) {
2577*61046927SAndroid Build Coastguard Worker          /* Page 137 (page 149 of the PDF) in section 3.8.5 of the
2578*61046927SAndroid Build Coastguard Worker           * OpenGLES 3.0.0 spec says:
2579*61046927SAndroid Build Coastguard Worker           *
2580*61046927SAndroid Build Coastguard Worker           *     "The error INVALID_OPERATION is also generated if the
2581*61046927SAndroid Build Coastguard Worker           *     value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the
2582*61046927SAndroid Build Coastguard Worker           *     framebuffer attachment corresponding to the read buffer
2583*61046927SAndroid Build Coastguard Worker           *     is LINEAR (see section 6.1.13) and internalformat is
2584*61046927SAndroid Build Coastguard Worker           *     one of the sRGB formats described in section 3.8.16, or
2585*61046927SAndroid Build Coastguard Worker           *     if the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is
2586*61046927SAndroid Build Coastguard Worker           *     SRGB and internalformat is not one of the sRGB formats."
2587*61046927SAndroid Build Coastguard Worker           */
2588*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2589*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(srgb usage mismatch)", dimensions);
2590*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2591*61046927SAndroid Build Coastguard Worker       }
2592*61046927SAndroid Build Coastguard Worker 
2593*61046927SAndroid Build Coastguard Worker       /* Page 139, Table 3.15 of OpenGL ES 3.0 spec does not define ReadPixels
2594*61046927SAndroid Build Coastguard Worker        * types for SNORM formats. Also, conversion to SNORM formats is not
2595*61046927SAndroid Build Coastguard Worker        * allowed by Table 3.2 on Page 110.
2596*61046927SAndroid Build Coastguard Worker        */
2597*61046927SAndroid Build Coastguard Worker       if (!_mesa_has_EXT_render_snorm(ctx) &&
2598*61046927SAndroid Build Coastguard Worker           _mesa_is_enum_format_snorm(internalFormat)) {
2599*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2600*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2601*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(internalFormat));
2602*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2603*61046927SAndroid Build Coastguard Worker       }
2604*61046927SAndroid Build Coastguard Worker    }
2605*61046927SAndroid Build Coastguard Worker 
2606*61046927SAndroid Build Coastguard Worker    if (!_mesa_source_buffer_exists(ctx, baseFormat)) {
2607*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2608*61046927SAndroid Build Coastguard Worker                   "glCopyTexImage%dD(missing readbuffer)", dimensions);
2609*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2610*61046927SAndroid Build Coastguard Worker    }
2611*61046927SAndroid Build Coastguard Worker 
2612*61046927SAndroid Build Coastguard Worker    /* From the EXT_texture_integer spec:
2613*61046927SAndroid Build Coastguard Worker     *
2614*61046927SAndroid Build Coastguard Worker     *     "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
2615*61046927SAndroid Build Coastguard Worker     *      if the texture internalformat is an integer format and the read color
2616*61046927SAndroid Build Coastguard Worker     *      buffer is not an integer format, or if the internalformat is not an
2617*61046927SAndroid Build Coastguard Worker     *      integer format and the read color buffer is an integer format."
2618*61046927SAndroid Build Coastguard Worker     */
2619*61046927SAndroid Build Coastguard Worker    if (_mesa_is_color_format(internalFormat)) {
2620*61046927SAndroid Build Coastguard Worker       bool is_int = _mesa_is_enum_format_integer(internalFormat);
2621*61046927SAndroid Build Coastguard Worker       bool is_rbint = _mesa_is_enum_format_integer(rb_internal_format);
2622*61046927SAndroid Build Coastguard Worker       bool is_unorm = _mesa_is_enum_format_unorm(internalFormat);
2623*61046927SAndroid Build Coastguard Worker       bool is_rbunorm = _mesa_is_enum_format_unorm(rb_internal_format);
2624*61046927SAndroid Build Coastguard Worker       if (is_int || is_rbint) {
2625*61046927SAndroid Build Coastguard Worker          if (is_int != is_rbint) {
2626*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_OPERATION,
2627*61046927SAndroid Build Coastguard Worker                         "glCopyTexImage%dD(integer vs non-integer)", dimensions);
2628*61046927SAndroid Build Coastguard Worker             return GL_TRUE;
2629*61046927SAndroid Build Coastguard Worker          } else if (_mesa_is_gles(ctx) &&
2630*61046927SAndroid Build Coastguard Worker                     _mesa_is_enum_format_unsigned_int(internalFormat) !=
2631*61046927SAndroid Build Coastguard Worker                       _mesa_is_enum_format_unsigned_int(rb_internal_format)) {
2632*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_OPERATION,
2633*61046927SAndroid Build Coastguard Worker                         "glCopyTexImage%dD(signed vs unsigned integer)",
2634*61046927SAndroid Build Coastguard Worker                         dimensions);
2635*61046927SAndroid Build Coastguard Worker             return GL_TRUE;
2636*61046927SAndroid Build Coastguard Worker          }
2637*61046927SAndroid Build Coastguard Worker       }
2638*61046927SAndroid Build Coastguard Worker 
2639*61046927SAndroid Build Coastguard Worker       /* From page 138 of OpenGL ES 3.0 spec:
2640*61046927SAndroid Build Coastguard Worker        *    "The error INVALID_OPERATION is generated if floating-point RGBA
2641*61046927SAndroid Build Coastguard Worker        *    data is required; if signed integer RGBA data is required and the
2642*61046927SAndroid Build Coastguard Worker        *    format of the current color buffer is not signed integer; if
2643*61046927SAndroid Build Coastguard Worker        *    unsigned integer RGBA data is required and the format of the
2644*61046927SAndroid Build Coastguard Worker        *    current color buffer is not unsigned integer; or if fixed-point
2645*61046927SAndroid Build Coastguard Worker        *    RGBA data is required and the format of the current color buffer
2646*61046927SAndroid Build Coastguard Worker        *    is not fixed-point.
2647*61046927SAndroid Build Coastguard Worker        */
2648*61046927SAndroid Build Coastguard Worker       if (_mesa_is_gles(ctx) && is_unorm != is_rbunorm)
2649*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_OPERATION,
2650*61046927SAndroid Build Coastguard Worker                         "glCopyTexImage%dD(unorm vs non-unorm)", dimensions);
2651*61046927SAndroid Build Coastguard Worker    }
2652*61046927SAndroid Build Coastguard Worker 
2653*61046927SAndroid Build Coastguard Worker    if (_mesa_is_compressed_format(ctx, internalFormat)) {
2654*61046927SAndroid Build Coastguard Worker       GLenum err;
2655*61046927SAndroid Build Coastguard Worker       if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) {
2656*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, err,
2657*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(target can't be compressed)", dimensions);
2658*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2659*61046927SAndroid Build Coastguard Worker       }
2660*61046927SAndroid Build Coastguard Worker       if (_mesa_format_no_online_compression(internalFormat)) {
2661*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2662*61046927SAndroid Build Coastguard Worker                "glCopyTexImage%dD(no compression for format)", dimensions);
2663*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2664*61046927SAndroid Build Coastguard Worker       }
2665*61046927SAndroid Build Coastguard Worker       if (border != 0) {
2666*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2667*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%dD(border!=0)", dimensions);
2668*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2669*61046927SAndroid Build Coastguard Worker       }
2670*61046927SAndroid Build Coastguard Worker    }
2671*61046927SAndroid Build Coastguard Worker 
2672*61046927SAndroid Build Coastguard Worker    if (!mutable_tex_object(texObj)) {
2673*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2674*61046927SAndroid Build Coastguard Worker                   "glCopyTexImage%dD(immutable texture)", dimensions);
2675*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2676*61046927SAndroid Build Coastguard Worker    }
2677*61046927SAndroid Build Coastguard Worker 
2678*61046927SAndroid Build Coastguard Worker    /* if we get here, the parameters are OK */
2679*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
2680*61046927SAndroid Build Coastguard Worker }
2681*61046927SAndroid Build Coastguard Worker 
2682*61046927SAndroid Build Coastguard Worker 
2683*61046927SAndroid Build Coastguard Worker /**
2684*61046927SAndroid Build Coastguard Worker  * Test glCopyTexSubImage[12]D() parameters for errors.
2685*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2686*61046927SAndroid Build Coastguard Worker  */
2687*61046927SAndroid Build Coastguard Worker static GLboolean
copytexsubimage_error_check(struct gl_context * ctx,GLuint dimensions,const struct gl_texture_object * texObj,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,const char * caller)2688*61046927SAndroid Build Coastguard Worker copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
2689*61046927SAndroid Build Coastguard Worker                             const struct gl_texture_object *texObj,
2690*61046927SAndroid Build Coastguard Worker                             GLenum target, GLint level,
2691*61046927SAndroid Build Coastguard Worker                             GLint xoffset, GLint yoffset, GLint zoffset,
2692*61046927SAndroid Build Coastguard Worker                             GLint width, GLint height, const char *caller)
2693*61046927SAndroid Build Coastguard Worker {
2694*61046927SAndroid Build Coastguard Worker    assert(texObj);
2695*61046927SAndroid Build Coastguard Worker 
2696*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
2697*61046927SAndroid Build Coastguard Worker 
2698*61046927SAndroid Build Coastguard Worker    /* Check that the source buffer is complete */
2699*61046927SAndroid Build Coastguard Worker    if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
2700*61046927SAndroid Build Coastguard Worker       if (ctx->ReadBuffer->_Status == 0) {
2701*61046927SAndroid Build Coastguard Worker          _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2702*61046927SAndroid Build Coastguard Worker       }
2703*61046927SAndroid Build Coastguard Worker       if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2704*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2705*61046927SAndroid Build Coastguard Worker                      "%s(invalid readbuffer)", caller);
2706*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2707*61046927SAndroid Build Coastguard Worker       }
2708*61046927SAndroid Build Coastguard Worker 
2709*61046927SAndroid Build Coastguard Worker       /**
2710*61046927SAndroid Build Coastguard Worker        * From the GL_EXT_multisampled_render_to_texture spec:
2711*61046927SAndroid Build Coastguard Worker        *
2712*61046927SAndroid Build Coastguard Worker        * "An INVALID_OPERATION error is generated by CopyTexSubImage3D,
2713*61046927SAndroid Build Coastguard Worker        * CopyTexImage2D, or CopyTexSubImage2D if [...] the value of
2714*61046927SAndroid Build Coastguard Worker        * READ_FRAMEBUFFER_BINDING is non-zero, and:
2715*61046927SAndroid Build Coastguard Worker        *   - the read buffer selects an attachment that has no image attached,
2716*61046927SAndroid Build Coastguard Worker        *     or
2717*61046927SAndroid Build Coastguard Worker        *   - the value of SAMPLE_BUFFERS for the read framebuffer is one."
2718*61046927SAndroid Build Coastguard Worker        *
2719*61046927SAndroid Build Coastguard Worker        * [...]
2720*61046927SAndroid Build Coastguard Worker        * These errors do not apply to textures and renderbuffers that have
2721*61046927SAndroid Build Coastguard Worker        * associated multisample data specified by the mechanisms described in
2722*61046927SAndroid Build Coastguard Worker        * this extension, i.e., the above operations are allowed even when
2723*61046927SAndroid Build Coastguard Worker        * SAMPLE_BUFFERS is non-zero for renderbuffers created via Renderbuffer-
2724*61046927SAndroid Build Coastguard Worker        * StorageMultisampleEXT or textures attached via FramebufferTexture2D-
2725*61046927SAndroid Build Coastguard Worker        * MultisampleEXT.
2726*61046927SAndroid Build Coastguard Worker        */
2727*61046927SAndroid Build Coastguard Worker       if (!ctx->st_opts->allow_multisampled_copyteximage &&
2728*61046927SAndroid Build Coastguard Worker           ctx->ReadBuffer->Visual.samples > 0 &&
2729*61046927SAndroid Build Coastguard Worker           !_mesa_has_rtt_samples(ctx->ReadBuffer)) {
2730*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(multisample FBO)",
2731*61046927SAndroid Build Coastguard Worker                      caller);
2732*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2733*61046927SAndroid Build Coastguard Worker       }
2734*61046927SAndroid Build Coastguard Worker    }
2735*61046927SAndroid Build Coastguard Worker 
2736*61046927SAndroid Build Coastguard Worker    /* Check level */
2737*61046927SAndroid Build Coastguard Worker    if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
2738*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", caller, level);
2739*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2740*61046927SAndroid Build Coastguard Worker    }
2741*61046927SAndroid Build Coastguard Worker 
2742*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
2743*61046927SAndroid Build Coastguard Worker    if (!texImage) {
2744*61046927SAndroid Build Coastguard Worker       /* destination image does not exist */
2745*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2746*61046927SAndroid Build Coastguard Worker                   "%s(invalid texture level %d)", caller, level);
2747*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2748*61046927SAndroid Build Coastguard Worker    }
2749*61046927SAndroid Build Coastguard Worker 
2750*61046927SAndroid Build Coastguard Worker    if (error_check_subtexture_negative_dimensions(ctx, dimensions,
2751*61046927SAndroid Build Coastguard Worker                                                   width, height, 1, caller)) {
2752*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2753*61046927SAndroid Build Coastguard Worker    }
2754*61046927SAndroid Build Coastguard Worker 
2755*61046927SAndroid Build Coastguard Worker    if (error_check_subtexture_dimensions(ctx, dimensions, texImage,
2756*61046927SAndroid Build Coastguard Worker                                          xoffset, yoffset, zoffset,
2757*61046927SAndroid Build Coastguard Worker                                          width, height, 1, caller)) {
2758*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2759*61046927SAndroid Build Coastguard Worker    }
2760*61046927SAndroid Build Coastguard Worker 
2761*61046927SAndroid Build Coastguard Worker    if (_mesa_is_format_compressed(texImage->TexFormat)) {
2762*61046927SAndroid Build Coastguard Worker       if (_mesa_format_no_online_compression(texImage->InternalFormat)) {
2763*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2764*61046927SAndroid Build Coastguard Worker                "%s(no compression for format)", caller);
2765*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2766*61046927SAndroid Build Coastguard Worker       }
2767*61046927SAndroid Build Coastguard Worker    }
2768*61046927SAndroid Build Coastguard Worker 
2769*61046927SAndroid Build Coastguard Worker    if (texImage->InternalFormat == GL_YCBCR_MESA) {
2770*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", caller);
2771*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2772*61046927SAndroid Build Coastguard Worker    }
2773*61046927SAndroid Build Coastguard Worker 
2774*61046927SAndroid Build Coastguard Worker    /* From OpenGL ES 3.2 spec, section 8.6:
2775*61046927SAndroid Build Coastguard Worker     *
2776*61046927SAndroid Build Coastguard Worker     *     "An INVALID_OPERATION error is generated by CopyTexSubImage3D,
2777*61046927SAndroid Build Coastguard Worker     *      CopyTexImage2D, or CopyTexSubImage2D if the internalformat of the
2778*61046927SAndroid Build Coastguard Worker     *      texture image being (re)specified is RGB9_E5"
2779*61046927SAndroid Build Coastguard Worker     */
2780*61046927SAndroid Build Coastguard Worker    if (texImage->InternalFormat == GL_RGB9_E5 &&
2781*61046927SAndroid Build Coastguard Worker        !_mesa_is_desktop_gl(ctx)) {
2782*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2783*61046927SAndroid Build Coastguard Worker                   "%s(invalid internal format %s)", caller,
2784*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texImage->InternalFormat));
2785*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2786*61046927SAndroid Build Coastguard Worker    }
2787*61046927SAndroid Build Coastguard Worker 
2788*61046927SAndroid Build Coastguard Worker    if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) {
2789*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
2790*61046927SAndroid Build Coastguard Worker                   "%s(missing readbuffer, format=%s)", caller,
2791*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texImage->_BaseFormat));
2792*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2793*61046927SAndroid Build Coastguard Worker    }
2794*61046927SAndroid Build Coastguard Worker 
2795*61046927SAndroid Build Coastguard Worker    /* From the EXT_texture_integer spec:
2796*61046927SAndroid Build Coastguard Worker     *
2797*61046927SAndroid Build Coastguard Worker     *     "INVALID_OPERATION is generated by CopyTexImage* and
2798*61046927SAndroid Build Coastguard Worker     *     CopyTexSubImage* if the texture internalformat is an integer format
2799*61046927SAndroid Build Coastguard Worker     *     and the read color buffer is not an integer format, or if the
2800*61046927SAndroid Build Coastguard Worker     *     internalformat is not an integer format and the read color buffer
2801*61046927SAndroid Build Coastguard Worker     *     is an integer format."
2802*61046927SAndroid Build Coastguard Worker     */
2803*61046927SAndroid Build Coastguard Worker    if (_mesa_is_color_format(texImage->InternalFormat)) {
2804*61046927SAndroid Build Coastguard Worker       struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
2805*61046927SAndroid Build Coastguard Worker 
2806*61046927SAndroid Build Coastguard Worker       if (_mesa_is_format_integer_color(rb->Format) !=
2807*61046927SAndroid Build Coastguard Worker           _mesa_is_format_integer_color(texImage->TexFormat)) {
2808*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
2809*61046927SAndroid Build Coastguard Worker                      "%s(integer vs non-integer)", caller);
2810*61046927SAndroid Build Coastguard Worker          return GL_TRUE;
2811*61046927SAndroid Build Coastguard Worker       }
2812*61046927SAndroid Build Coastguard Worker    }
2813*61046927SAndroid Build Coastguard Worker 
2814*61046927SAndroid Build Coastguard Worker    /* In the ES 3.2 specification's Table 8.13 (Valid CopyTexImage source
2815*61046927SAndroid Build Coastguard Worker     * framebuffer/destination texture base internal format combinations),
2816*61046927SAndroid Build Coastguard Worker     * all the entries for stencil are left blank (unsupported).
2817*61046927SAndroid Build Coastguard Worker     */
2818*61046927SAndroid Build Coastguard Worker    if (_mesa_is_gles(ctx) && _mesa_is_stencil_format(texImage->_BaseFormat)) {
2819*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(stencil disallowed)", caller);
2820*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
2821*61046927SAndroid Build Coastguard Worker    }
2822*61046927SAndroid Build Coastguard Worker 
2823*61046927SAndroid Build Coastguard Worker    /* if we get here, the parameters are OK */
2824*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
2825*61046927SAndroid Build Coastguard Worker }
2826*61046927SAndroid Build Coastguard Worker 
2827*61046927SAndroid Build Coastguard Worker 
2828*61046927SAndroid Build Coastguard Worker /** Callback info for walking over FBO hash table */
2829*61046927SAndroid Build Coastguard Worker struct cb_info
2830*61046927SAndroid Build Coastguard Worker {
2831*61046927SAndroid Build Coastguard Worker    struct gl_context *ctx;
2832*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
2833*61046927SAndroid Build Coastguard Worker    GLuint level, face;
2834*61046927SAndroid Build Coastguard Worker };
2835*61046927SAndroid Build Coastguard Worker 
2836*61046927SAndroid Build Coastguard Worker 
2837*61046927SAndroid Build Coastguard Worker /**
2838*61046927SAndroid Build Coastguard Worker  * Check render to texture callback.  Called from _mesa_HashWalk().
2839*61046927SAndroid Build Coastguard Worker  */
2840*61046927SAndroid Build Coastguard Worker static void
check_rtt_cb(void * data,void * userData)2841*61046927SAndroid Build Coastguard Worker check_rtt_cb(void *data, void *userData)
2842*61046927SAndroid Build Coastguard Worker {
2843*61046927SAndroid Build Coastguard Worker    struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2844*61046927SAndroid Build Coastguard Worker    const struct cb_info *info = (struct cb_info *) userData;
2845*61046927SAndroid Build Coastguard Worker    struct gl_context *ctx = info->ctx;
2846*61046927SAndroid Build Coastguard Worker    const struct gl_texture_object *texObj = info->texObj;
2847*61046927SAndroid Build Coastguard Worker    const GLuint level = info->level, face = info->face;
2848*61046927SAndroid Build Coastguard Worker 
2849*61046927SAndroid Build Coastguard Worker    /* If this is a user-created FBO */
2850*61046927SAndroid Build Coastguard Worker    if (_mesa_is_user_fbo(fb)) {
2851*61046927SAndroid Build Coastguard Worker       GLuint i;
2852*61046927SAndroid Build Coastguard Worker       /* check if any of the FBO's attachments point to 'texObj' */
2853*61046927SAndroid Build Coastguard Worker       for (i = 0; i < BUFFER_COUNT; i++) {
2854*61046927SAndroid Build Coastguard Worker          struct gl_renderbuffer_attachment *att = fb->Attachment + i;
2855*61046927SAndroid Build Coastguard Worker          if (att->Type == GL_TEXTURE &&
2856*61046927SAndroid Build Coastguard Worker              att->Texture == texObj &&
2857*61046927SAndroid Build Coastguard Worker              att->TextureLevel == level &&
2858*61046927SAndroid Build Coastguard Worker              att->CubeMapFace == face) {
2859*61046927SAndroid Build Coastguard Worker             _mesa_update_texture_renderbuffer(ctx, fb, att);
2860*61046927SAndroid Build Coastguard Worker             assert(att->Renderbuffer->TexImage);
2861*61046927SAndroid Build Coastguard Worker             /* Mark fb status as indeterminate to force re-validation */
2862*61046927SAndroid Build Coastguard Worker             fb->_Status = 0;
2863*61046927SAndroid Build Coastguard Worker 
2864*61046927SAndroid Build Coastguard Worker             /* Make sure that the revalidation actually happens if this is
2865*61046927SAndroid Build Coastguard Worker              * being done to currently-bound buffers.
2866*61046927SAndroid Build Coastguard Worker              */
2867*61046927SAndroid Build Coastguard Worker             if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer)
2868*61046927SAndroid Build Coastguard Worker                ctx->NewState |= _NEW_BUFFERS;
2869*61046927SAndroid Build Coastguard Worker          }
2870*61046927SAndroid Build Coastguard Worker       }
2871*61046927SAndroid Build Coastguard Worker    }
2872*61046927SAndroid Build Coastguard Worker }
2873*61046927SAndroid Build Coastguard Worker 
2874*61046927SAndroid Build Coastguard Worker 
2875*61046927SAndroid Build Coastguard Worker /**
2876*61046927SAndroid Build Coastguard Worker  * When a texture image is specified we have to check if it's bound to
2877*61046927SAndroid Build Coastguard Worker  * any framebuffer objects (render to texture) in order to detect changes
2878*61046927SAndroid Build Coastguard Worker  * in size or format since that effects FBO completeness.
2879*61046927SAndroid Build Coastguard Worker  * Any FBOs rendering into the texture must be re-validated.
2880*61046927SAndroid Build Coastguard Worker  */
2881*61046927SAndroid Build Coastguard Worker void
_mesa_update_fbo_texture(struct gl_context * ctx,struct gl_texture_object * texObj,GLuint face,GLuint level)2882*61046927SAndroid Build Coastguard Worker _mesa_update_fbo_texture(struct gl_context *ctx,
2883*61046927SAndroid Build Coastguard Worker                          struct gl_texture_object *texObj,
2884*61046927SAndroid Build Coastguard Worker                          GLuint face, GLuint level)
2885*61046927SAndroid Build Coastguard Worker {
2886*61046927SAndroid Build Coastguard Worker    /* Only check this texture if it's been marked as RenderToTexture */
2887*61046927SAndroid Build Coastguard Worker    if (texObj->_RenderToTexture) {
2888*61046927SAndroid Build Coastguard Worker       struct cb_info info;
2889*61046927SAndroid Build Coastguard Worker       info.ctx = ctx;
2890*61046927SAndroid Build Coastguard Worker       info.texObj = texObj;
2891*61046927SAndroid Build Coastguard Worker       info.level = level;
2892*61046927SAndroid Build Coastguard Worker       info.face = face;
2893*61046927SAndroid Build Coastguard Worker       _mesa_HashWalk(&ctx->Shared->FrameBuffers, check_rtt_cb, &info);
2894*61046927SAndroid Build Coastguard Worker    }
2895*61046927SAndroid Build Coastguard Worker }
2896*61046927SAndroid Build Coastguard Worker 
2897*61046927SAndroid Build Coastguard Worker 
2898*61046927SAndroid Build Coastguard Worker /**
2899*61046927SAndroid Build Coastguard Worker  * If the texture object's GenerateMipmap flag is set and we've
2900*61046927SAndroid Build Coastguard Worker  * changed the texture base level image, regenerate the rest of the
2901*61046927SAndroid Build Coastguard Worker  * mipmap levels now.
2902*61046927SAndroid Build Coastguard Worker  */
2903*61046927SAndroid Build Coastguard Worker static inline void
check_gen_mipmap(struct gl_context * ctx,GLenum target,struct gl_texture_object * texObj,GLint level)2904*61046927SAndroid Build Coastguard Worker check_gen_mipmap(struct gl_context *ctx, GLenum target,
2905*61046927SAndroid Build Coastguard Worker                  struct gl_texture_object *texObj, GLint level)
2906*61046927SAndroid Build Coastguard Worker {
2907*61046927SAndroid Build Coastguard Worker    if (texObj->Attrib.GenerateMipmap &&
2908*61046927SAndroid Build Coastguard Worker        level == texObj->Attrib.BaseLevel &&
2909*61046927SAndroid Build Coastguard Worker        level < texObj->Attrib.MaxLevel) {
2910*61046927SAndroid Build Coastguard Worker       st_generate_mipmap(ctx, target, texObj);
2911*61046927SAndroid Build Coastguard Worker    }
2912*61046927SAndroid Build Coastguard Worker }
2913*61046927SAndroid Build Coastguard Worker 
2914*61046927SAndroid Build Coastguard Worker 
2915*61046927SAndroid Build Coastguard Worker /** Debug helper: override the user-requested internal format */
2916*61046927SAndroid Build Coastguard Worker static GLenum
override_internal_format(GLenum internalFormat,UNUSED GLint width,UNUSED GLint height)2917*61046927SAndroid Build Coastguard Worker override_internal_format(GLenum internalFormat, UNUSED GLint width,
2918*61046927SAndroid Build Coastguard Worker                          UNUSED GLint height)
2919*61046927SAndroid Build Coastguard Worker {
2920*61046927SAndroid Build Coastguard Worker #if 0
2921*61046927SAndroid Build Coastguard Worker    if (internalFormat == GL_RGBA16F_ARB ||
2922*61046927SAndroid Build Coastguard Worker        internalFormat == GL_RGBA32F_ARB) {
2923*61046927SAndroid Build Coastguard Worker       printf("Convert rgba float tex to int %d x %d\n", width, height);
2924*61046927SAndroid Build Coastguard Worker       return GL_RGBA;
2925*61046927SAndroid Build Coastguard Worker    }
2926*61046927SAndroid Build Coastguard Worker    else if (internalFormat == GL_RGB16F_ARB ||
2927*61046927SAndroid Build Coastguard Worker             internalFormat == GL_RGB32F_ARB) {
2928*61046927SAndroid Build Coastguard Worker       printf("Convert rgb float tex to int %d x %d\n", width, height);
2929*61046927SAndroid Build Coastguard Worker       return GL_RGB;
2930*61046927SAndroid Build Coastguard Worker    }
2931*61046927SAndroid Build Coastguard Worker    else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB ||
2932*61046927SAndroid Build Coastguard Worker             internalFormat == GL_LUMINANCE_ALPHA32F_ARB) {
2933*61046927SAndroid Build Coastguard Worker       printf("Convert luminance float tex to int %d x %d\n", width, height);
2934*61046927SAndroid Build Coastguard Worker       return GL_LUMINANCE_ALPHA;
2935*61046927SAndroid Build Coastguard Worker    }
2936*61046927SAndroid Build Coastguard Worker    else if (internalFormat == GL_LUMINANCE16F_ARB ||
2937*61046927SAndroid Build Coastguard Worker             internalFormat == GL_LUMINANCE32F_ARB) {
2938*61046927SAndroid Build Coastguard Worker       printf("Convert luminance float tex to int %d x %d\n", width, height);
2939*61046927SAndroid Build Coastguard Worker       return GL_LUMINANCE;
2940*61046927SAndroid Build Coastguard Worker    }
2941*61046927SAndroid Build Coastguard Worker    else if (internalFormat == GL_ALPHA16F_ARB ||
2942*61046927SAndroid Build Coastguard Worker             internalFormat == GL_ALPHA32F_ARB) {
2943*61046927SAndroid Build Coastguard Worker       printf("Convert luminance float tex to int %d x %d\n", width, height);
2944*61046927SAndroid Build Coastguard Worker       return GL_ALPHA;
2945*61046927SAndroid Build Coastguard Worker    }
2946*61046927SAndroid Build Coastguard Worker    /*
2947*61046927SAndroid Build Coastguard Worker    else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
2948*61046927SAndroid Build Coastguard Worker       internalFormat = GL_RGBA;
2949*61046927SAndroid Build Coastguard Worker    }
2950*61046927SAndroid Build Coastguard Worker    */
2951*61046927SAndroid Build Coastguard Worker    else {
2952*61046927SAndroid Build Coastguard Worker       return internalFormat;
2953*61046927SAndroid Build Coastguard Worker    }
2954*61046927SAndroid Build Coastguard Worker #else
2955*61046927SAndroid Build Coastguard Worker    return internalFormat;
2956*61046927SAndroid Build Coastguard Worker #endif
2957*61046927SAndroid Build Coastguard Worker }
2958*61046927SAndroid Build Coastguard Worker 
2959*61046927SAndroid Build Coastguard Worker 
2960*61046927SAndroid Build Coastguard Worker /**
2961*61046927SAndroid Build Coastguard Worker  * Choose the actual hardware format for a texture image.
2962*61046927SAndroid Build Coastguard Worker  * Try to use the same format as the previous image level when possible.
2963*61046927SAndroid Build Coastguard Worker  * Otherwise, ask the driver for the best format.
2964*61046927SAndroid Build Coastguard Worker  * It's important to try to choose a consistant format for all levels
2965*61046927SAndroid Build Coastguard Worker  * for efficient texture memory layout/allocation.  In particular, this
2966*61046927SAndroid Build Coastguard Worker  * comes up during automatic mipmap generation.
2967*61046927SAndroid Build Coastguard Worker  */
2968*61046927SAndroid Build Coastguard Worker mesa_format
_mesa_choose_texture_format(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum target,GLint level,GLenum internalFormat,GLenum format,GLenum type)2969*61046927SAndroid Build Coastguard Worker _mesa_choose_texture_format(struct gl_context *ctx,
2970*61046927SAndroid Build Coastguard Worker                             struct gl_texture_object *texObj,
2971*61046927SAndroid Build Coastguard Worker                             GLenum target, GLint level,
2972*61046927SAndroid Build Coastguard Worker                             GLenum internalFormat, GLenum format, GLenum type)
2973*61046927SAndroid Build Coastguard Worker {
2974*61046927SAndroid Build Coastguard Worker    mesa_format f = MESA_FORMAT_NONE;
2975*61046927SAndroid Build Coastguard Worker 
2976*61046927SAndroid Build Coastguard Worker    /* see if we've already chosen a format for the previous level */
2977*61046927SAndroid Build Coastguard Worker    if (level > 0) {
2978*61046927SAndroid Build Coastguard Worker       struct gl_texture_image *prevImage =
2979*61046927SAndroid Build Coastguard Worker          _mesa_select_tex_image(texObj, target, level - 1);
2980*61046927SAndroid Build Coastguard Worker       /* See if the prev level is defined and has an internal format which
2981*61046927SAndroid Build Coastguard Worker        * matches the new internal format.
2982*61046927SAndroid Build Coastguard Worker        */
2983*61046927SAndroid Build Coastguard Worker       if (prevImage &&
2984*61046927SAndroid Build Coastguard Worker           prevImage->Width > 0 &&
2985*61046927SAndroid Build Coastguard Worker           prevImage->InternalFormat == internalFormat) {
2986*61046927SAndroid Build Coastguard Worker          /* use the same format */
2987*61046927SAndroid Build Coastguard Worker          assert(prevImage->TexFormat != MESA_FORMAT_NONE);
2988*61046927SAndroid Build Coastguard Worker          return prevImage->TexFormat;
2989*61046927SAndroid Build Coastguard Worker       }
2990*61046927SAndroid Build Coastguard Worker    }
2991*61046927SAndroid Build Coastguard Worker 
2992*61046927SAndroid Build Coastguard Worker    f = st_ChooseTextureFormat(ctx, target, internalFormat,
2993*61046927SAndroid Build Coastguard Worker                               format, type);
2994*61046927SAndroid Build Coastguard Worker    assert(f != MESA_FORMAT_NONE);
2995*61046927SAndroid Build Coastguard Worker    return f;
2996*61046927SAndroid Build Coastguard Worker }
2997*61046927SAndroid Build Coastguard Worker 
2998*61046927SAndroid Build Coastguard Worker 
2999*61046927SAndroid Build Coastguard Worker /**
3000*61046927SAndroid Build Coastguard Worker  * Adjust pixel unpack params and image dimensions to strip off the
3001*61046927SAndroid Build Coastguard Worker  * one-pixel texture border.
3002*61046927SAndroid Build Coastguard Worker  *
3003*61046927SAndroid Build Coastguard Worker  * Gallium and intel don't support texture borders.  They've seldem been used
3004*61046927SAndroid Build Coastguard Worker  * and seldom been implemented correctly anyway.
3005*61046927SAndroid Build Coastguard Worker  *
3006*61046927SAndroid Build Coastguard Worker  * \param unpackNew returns the new pixel unpack parameters
3007*61046927SAndroid Build Coastguard Worker  */
3008*61046927SAndroid Build Coastguard Worker static void
strip_texture_border(GLenum target,GLint * width,GLint * height,GLint * depth,const struct gl_pixelstore_attrib * unpack,struct gl_pixelstore_attrib * unpackNew)3009*61046927SAndroid Build Coastguard Worker strip_texture_border(GLenum target,
3010*61046927SAndroid Build Coastguard Worker                      GLint *width, GLint *height, GLint *depth,
3011*61046927SAndroid Build Coastguard Worker                      const struct gl_pixelstore_attrib *unpack,
3012*61046927SAndroid Build Coastguard Worker                      struct gl_pixelstore_attrib *unpackNew)
3013*61046927SAndroid Build Coastguard Worker {
3014*61046927SAndroid Build Coastguard Worker    assert(width);
3015*61046927SAndroid Build Coastguard Worker    assert(height);
3016*61046927SAndroid Build Coastguard Worker    assert(depth);
3017*61046927SAndroid Build Coastguard Worker 
3018*61046927SAndroid Build Coastguard Worker    *unpackNew = *unpack;
3019*61046927SAndroid Build Coastguard Worker 
3020*61046927SAndroid Build Coastguard Worker    if (unpackNew->RowLength == 0)
3021*61046927SAndroid Build Coastguard Worker       unpackNew->RowLength = *width;
3022*61046927SAndroid Build Coastguard Worker 
3023*61046927SAndroid Build Coastguard Worker    if (unpackNew->ImageHeight == 0)
3024*61046927SAndroid Build Coastguard Worker       unpackNew->ImageHeight = *height;
3025*61046927SAndroid Build Coastguard Worker 
3026*61046927SAndroid Build Coastguard Worker    assert(*width >= 3);
3027*61046927SAndroid Build Coastguard Worker    unpackNew->SkipPixels++;  /* skip the border */
3028*61046927SAndroid Build Coastguard Worker    *width = *width - 2;      /* reduce the width by two border pixels */
3029*61046927SAndroid Build Coastguard Worker 
3030*61046927SAndroid Build Coastguard Worker    /* The min height of a texture with a border is 3 */
3031*61046927SAndroid Build Coastguard Worker    if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) {
3032*61046927SAndroid Build Coastguard Worker       unpackNew->SkipRows++;  /* skip the border */
3033*61046927SAndroid Build Coastguard Worker       *height = *height - 2;  /* reduce the height by two border pixels */
3034*61046927SAndroid Build Coastguard Worker    }
3035*61046927SAndroid Build Coastguard Worker 
3036*61046927SAndroid Build Coastguard Worker    if (*depth >= 3 &&
3037*61046927SAndroid Build Coastguard Worker        target != GL_TEXTURE_2D_ARRAY &&
3038*61046927SAndroid Build Coastguard Worker        target != GL_TEXTURE_CUBE_MAP_ARRAY) {
3039*61046927SAndroid Build Coastguard Worker       unpackNew->SkipImages++;  /* skip the border */
3040*61046927SAndroid Build Coastguard Worker       *depth = *depth - 2;      /* reduce the depth by two border pixels */
3041*61046927SAndroid Build Coastguard Worker    }
3042*61046927SAndroid Build Coastguard Worker }
3043*61046927SAndroid Build Coastguard Worker 
3044*61046927SAndroid Build Coastguard Worker static struct gl_texture_object *
lookup_texture_ext_dsa(struct gl_context * ctx,GLenum target,GLuint texture,const char * caller)3045*61046927SAndroid Build Coastguard Worker lookup_texture_ext_dsa(struct gl_context *ctx, GLenum target, GLuint texture,
3046*61046927SAndroid Build Coastguard Worker                        const char *caller)
3047*61046927SAndroid Build Coastguard Worker {
3048*61046927SAndroid Build Coastguard Worker    GLenum boundTarget;
3049*61046927SAndroid Build Coastguard Worker    switch (target) {
3050*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3051*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3052*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3053*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3054*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3055*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3056*61046927SAndroid Build Coastguard Worker       boundTarget = GL_TEXTURE_CUBE_MAP;
3057*61046927SAndroid Build Coastguard Worker       break;
3058*61046927SAndroid Build Coastguard Worker    default:
3059*61046927SAndroid Build Coastguard Worker       boundTarget = target;
3060*61046927SAndroid Build Coastguard Worker       break;
3061*61046927SAndroid Build Coastguard Worker    }
3062*61046927SAndroid Build Coastguard Worker 
3063*61046927SAndroid Build Coastguard Worker    int targetIndex = _mesa_tex_target_to_index(ctx, boundTarget);
3064*61046927SAndroid Build Coastguard Worker    if (targetIndex < 0) {
3065*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s(target = %s)", caller,
3066*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target));
3067*61046927SAndroid Build Coastguard Worker             return NULL;
3068*61046927SAndroid Build Coastguard Worker    }
3069*61046927SAndroid Build Coastguard Worker    assert(targetIndex < NUM_TEXTURE_TARGETS);
3070*61046927SAndroid Build Coastguard Worker 
3071*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
3072*61046927SAndroid Build Coastguard Worker    if (texture == 0) {
3073*61046927SAndroid Build Coastguard Worker       /* Use a default texture object */
3074*61046927SAndroid Build Coastguard Worker       texObj = ctx->Shared->DefaultTex[targetIndex];
3075*61046927SAndroid Build Coastguard Worker       assert(texObj);
3076*61046927SAndroid Build Coastguard Worker    } else {
3077*61046927SAndroid Build Coastguard Worker       texObj = _mesa_lookup_texture(ctx, texture);
3078*61046927SAndroid Build Coastguard Worker       if (!texObj && _mesa_is_desktop_gl_core(ctx)) {
3079*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller);
3080*61046927SAndroid Build Coastguard Worker          return NULL;
3081*61046927SAndroid Build Coastguard Worker       }
3082*61046927SAndroid Build Coastguard Worker 
3083*61046927SAndroid Build Coastguard Worker       if (!texObj) {
3084*61046927SAndroid Build Coastguard Worker          texObj = _mesa_new_texture_object(ctx, texture, boundTarget);
3085*61046927SAndroid Build Coastguard Worker          if (!texObj) {
3086*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
3087*61046927SAndroid Build Coastguard Worker             return NULL;
3088*61046927SAndroid Build Coastguard Worker          }
3089*61046927SAndroid Build Coastguard Worker 
3090*61046927SAndroid Build Coastguard Worker          /* insert into hash table */
3091*61046927SAndroid Build Coastguard Worker          _mesa_HashInsert(&ctx->Shared->TexObjects, texObj->Name, texObj);
3092*61046927SAndroid Build Coastguard Worker       }
3093*61046927SAndroid Build Coastguard Worker 
3094*61046927SAndroid Build Coastguard Worker       if (texObj->Target != boundTarget) {
3095*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s != %s)",
3096*61046927SAndroid Build Coastguard Worker                      caller, _mesa_enum_to_string(texObj->Target),
3097*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(target));
3098*61046927SAndroid Build Coastguard Worker          return NULL;
3099*61046927SAndroid Build Coastguard Worker       }
3100*61046927SAndroid Build Coastguard Worker    }
3101*61046927SAndroid Build Coastguard Worker 
3102*61046927SAndroid Build Coastguard Worker    return texObj;
3103*61046927SAndroid Build Coastguard Worker }
3104*61046927SAndroid Build Coastguard Worker 
3105*61046927SAndroid Build Coastguard Worker /**
3106*61046927SAndroid Build Coastguard Worker  * Common code to implement all the glTexImage1D/2D/3D functions,
3107*61046927SAndroid Build Coastguard Worker  * glCompressedTexImage1D/2D/3D and glTextureImage1D/2D/3DEXT
3108*61046927SAndroid Build Coastguard Worker  * \param compressed  only GL_TRUE for glCompressedTexImage1D/2D/3D calls.
3109*61046927SAndroid Build Coastguard Worker  * \param format  the user's image format (only used if !compressed)
3110*61046927SAndroid Build Coastguard Worker  * \param type  the user's image type (only used if !compressed)
3111*61046927SAndroid Build Coastguard Worker  * \param imageSize  only used for glCompressedTexImage1D/2D/3D calls.
3112*61046927SAndroid Build Coastguard Worker  */
3113*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
teximage(struct gl_context * ctx,GLboolean compressed,GLuint dims,struct gl_texture_object * texObj,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei imageSize,const GLvoid * pixels,bool no_error)3114*61046927SAndroid Build Coastguard Worker teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
3115*61046927SAndroid Build Coastguard Worker          struct gl_texture_object *texObj,
3116*61046927SAndroid Build Coastguard Worker          GLenum target, GLint level, GLint internalFormat,
3117*61046927SAndroid Build Coastguard Worker          GLsizei width, GLsizei height, GLsizei depth,
3118*61046927SAndroid Build Coastguard Worker          GLint border, GLenum format, GLenum type,
3119*61046927SAndroid Build Coastguard Worker          GLsizei imageSize, const GLvoid *pixels, bool no_error)
3120*61046927SAndroid Build Coastguard Worker {
3121*61046927SAndroid Build Coastguard Worker    const char *func = compressed ? "glCompressedTexImage" : "glTexImage";
3122*61046927SAndroid Build Coastguard Worker    struct gl_pixelstore_attrib unpack_no_border;
3123*61046927SAndroid Build Coastguard Worker    const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
3124*61046927SAndroid Build Coastguard Worker    mesa_format texFormat;
3125*61046927SAndroid Build Coastguard Worker    bool dimensionsOK = true, sizeOK = true;
3126*61046927SAndroid Build Coastguard Worker 
3127*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
3128*61046927SAndroid Build Coastguard Worker 
3129*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) {
3130*61046927SAndroid Build Coastguard Worker       if (compressed)
3131*61046927SAndroid Build Coastguard Worker          _mesa_debug(ctx,
3132*61046927SAndroid Build Coastguard Worker                      "glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n",
3133*61046927SAndroid Build Coastguard Worker                      dims,
3134*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(target), level,
3135*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(internalFormat),
3136*61046927SAndroid Build Coastguard Worker                      width, height, depth, border, pixels);
3137*61046927SAndroid Build Coastguard Worker       else
3138*61046927SAndroid Build Coastguard Worker          _mesa_debug(ctx,
3139*61046927SAndroid Build Coastguard Worker                      "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
3140*61046927SAndroid Build Coastguard Worker                      dims,
3141*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(target), level,
3142*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(internalFormat),
3143*61046927SAndroid Build Coastguard Worker                      width, height, depth, border,
3144*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(format),
3145*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(type), pixels);
3146*61046927SAndroid Build Coastguard Worker    }
3147*61046927SAndroid Build Coastguard Worker 
3148*61046927SAndroid Build Coastguard Worker    internalFormat = override_internal_format(internalFormat, width, height);
3149*61046927SAndroid Build Coastguard Worker 
3150*61046927SAndroid Build Coastguard Worker    if (!no_error &&
3151*61046927SAndroid Build Coastguard Worker        /* target error checking */
3152*61046927SAndroid Build Coastguard Worker        !legal_teximage_target(ctx, dims, target)) {
3153*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
3154*61046927SAndroid Build Coastguard Worker                   func, dims, _mesa_enum_to_string(target));
3155*61046927SAndroid Build Coastguard Worker       return;
3156*61046927SAndroid Build Coastguard Worker    }
3157*61046927SAndroid Build Coastguard Worker 
3158*61046927SAndroid Build Coastguard Worker    if (!texObj)
3159*61046927SAndroid Build Coastguard Worker       texObj = _mesa_get_current_tex_object(ctx, target);
3160*61046927SAndroid Build Coastguard Worker 
3161*61046927SAndroid Build Coastguard Worker    if (!no_error) {
3162*61046927SAndroid Build Coastguard Worker       /* general error checking */
3163*61046927SAndroid Build Coastguard Worker       if (compressed) {
3164*61046927SAndroid Build Coastguard Worker          if (compressed_texture_error_check(ctx, dims, target, texObj,
3165*61046927SAndroid Build Coastguard Worker                                             level, internalFormat,
3166*61046927SAndroid Build Coastguard Worker                                             width, height, depth,
3167*61046927SAndroid Build Coastguard Worker                                             border, imageSize, pixels))
3168*61046927SAndroid Build Coastguard Worker             return;
3169*61046927SAndroid Build Coastguard Worker       } else {
3170*61046927SAndroid Build Coastguard Worker          if (texture_error_check(ctx, dims, target, texObj, level, internalFormat,
3171*61046927SAndroid Build Coastguard Worker                                  format, type, width, height, depth, border,
3172*61046927SAndroid Build Coastguard Worker                                  pixels))
3173*61046927SAndroid Build Coastguard Worker             return;
3174*61046927SAndroid Build Coastguard Worker       }
3175*61046927SAndroid Build Coastguard Worker    }
3176*61046927SAndroid Build Coastguard Worker    assert(texObj);
3177*61046927SAndroid Build Coastguard Worker 
3178*61046927SAndroid Build Coastguard Worker    /* Here we convert a cpal compressed image into a regular glTexImage2D
3179*61046927SAndroid Build Coastguard Worker     * call by decompressing the texture.  If we really want to support cpal
3180*61046927SAndroid Build Coastguard Worker     * textures in any driver this would have to be changed.
3181*61046927SAndroid Build Coastguard Worker     */
3182*61046927SAndroid Build Coastguard Worker    if (_mesa_is_gles1(ctx) && compressed && dims == 2) {
3183*61046927SAndroid Build Coastguard Worker       switch (internalFormat) {
3184*61046927SAndroid Build Coastguard Worker       case GL_PALETTE4_RGB8_OES:
3185*61046927SAndroid Build Coastguard Worker       case GL_PALETTE4_RGBA8_OES:
3186*61046927SAndroid Build Coastguard Worker       case GL_PALETTE4_R5_G6_B5_OES:
3187*61046927SAndroid Build Coastguard Worker       case GL_PALETTE4_RGBA4_OES:
3188*61046927SAndroid Build Coastguard Worker       case GL_PALETTE4_RGB5_A1_OES:
3189*61046927SAndroid Build Coastguard Worker       case GL_PALETTE8_RGB8_OES:
3190*61046927SAndroid Build Coastguard Worker       case GL_PALETTE8_RGBA8_OES:
3191*61046927SAndroid Build Coastguard Worker       case GL_PALETTE8_R5_G6_B5_OES:
3192*61046927SAndroid Build Coastguard Worker       case GL_PALETTE8_RGBA4_OES:
3193*61046927SAndroid Build Coastguard Worker       case GL_PALETTE8_RGB5_A1_OES:
3194*61046927SAndroid Build Coastguard Worker          _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
3195*61046927SAndroid Build Coastguard Worker                                           width, height, imageSize, pixels);
3196*61046927SAndroid Build Coastguard Worker          return;
3197*61046927SAndroid Build Coastguard Worker       }
3198*61046927SAndroid Build Coastguard Worker    }
3199*61046927SAndroid Build Coastguard Worker 
3200*61046927SAndroid Build Coastguard Worker    if (compressed) {
3201*61046927SAndroid Build Coastguard Worker       /* For glCompressedTexImage() the driver has no choice about the
3202*61046927SAndroid Build Coastguard Worker        * texture format since we'll never transcode the user's compressed
3203*61046927SAndroid Build Coastguard Worker        * image data.  The internalFormat was error checked earlier.
3204*61046927SAndroid Build Coastguard Worker        */
3205*61046927SAndroid Build Coastguard Worker       texFormat = _mesa_glenum_to_compressed_format(internalFormat);
3206*61046927SAndroid Build Coastguard Worker    }
3207*61046927SAndroid Build Coastguard Worker    else {
3208*61046927SAndroid Build Coastguard Worker       /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized
3209*61046927SAndroid Build Coastguard Worker        * internal floating point format for the given base format.
3210*61046927SAndroid Build Coastguard Worker        */
3211*61046927SAndroid Build Coastguard Worker       if (_mesa_is_gles(ctx) && format == internalFormat) {
3212*61046927SAndroid Build Coastguard Worker          if (type == GL_FLOAT) {
3213*61046927SAndroid Build Coastguard Worker             texObj->_IsFloat = GL_TRUE;
3214*61046927SAndroid Build Coastguard Worker          } else if (type == GL_HALF_FLOAT_OES || type == GL_HALF_FLOAT) {
3215*61046927SAndroid Build Coastguard Worker             texObj->_IsHalfFloat = GL_TRUE;
3216*61046927SAndroid Build Coastguard Worker          }
3217*61046927SAndroid Build Coastguard Worker 
3218*61046927SAndroid Build Coastguard Worker          internalFormat = adjust_for_oes_float_texture(ctx, format, type);
3219*61046927SAndroid Build Coastguard Worker       }
3220*61046927SAndroid Build Coastguard Worker 
3221*61046927SAndroid Build Coastguard Worker       texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
3222*61046927SAndroid Build Coastguard Worker                                               internalFormat, format, type);
3223*61046927SAndroid Build Coastguard Worker    }
3224*61046927SAndroid Build Coastguard Worker 
3225*61046927SAndroid Build Coastguard Worker    assert(texFormat != MESA_FORMAT_NONE);
3226*61046927SAndroid Build Coastguard Worker 
3227*61046927SAndroid Build Coastguard Worker    if (!no_error) {
3228*61046927SAndroid Build Coastguard Worker       /* check that width, height, depth are legal for the mipmap level */
3229*61046927SAndroid Build Coastguard Worker       dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, level, width,
3230*61046927SAndroid Build Coastguard Worker                                                     height, depth, border);
3231*61046927SAndroid Build Coastguard Worker 
3232*61046927SAndroid Build Coastguard Worker       /* check that the texture won't take too much memory, etc */
3233*61046927SAndroid Build Coastguard Worker       sizeOK = st_TestProxyTexImage(ctx, proxy_target(target),
3234*61046927SAndroid Build Coastguard Worker                                     0, level, texFormat, 1,
3235*61046927SAndroid Build Coastguard Worker                                     width, height, depth);
3236*61046927SAndroid Build Coastguard Worker    }
3237*61046927SAndroid Build Coastguard Worker 
3238*61046927SAndroid Build Coastguard Worker    if (_mesa_is_proxy_texture(target)) {
3239*61046927SAndroid Build Coastguard Worker       /* Proxy texture: just clear or set state depending on error checking */
3240*61046927SAndroid Build Coastguard Worker       struct gl_texture_image *texImage =
3241*61046927SAndroid Build Coastguard Worker          get_proxy_tex_image(ctx, target, level);
3242*61046927SAndroid Build Coastguard Worker 
3243*61046927SAndroid Build Coastguard Worker       if (!texImage)
3244*61046927SAndroid Build Coastguard Worker          return;  /* GL_OUT_OF_MEMORY already recorded */
3245*61046927SAndroid Build Coastguard Worker 
3246*61046927SAndroid Build Coastguard Worker       if (dimensionsOK && sizeOK) {
3247*61046927SAndroid Build Coastguard Worker          _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
3248*61046927SAndroid Build Coastguard Worker                                     border, internalFormat, texFormat);
3249*61046927SAndroid Build Coastguard Worker       }
3250*61046927SAndroid Build Coastguard Worker       else {
3251*61046927SAndroid Build Coastguard Worker          clear_teximage_fields(texImage);
3252*61046927SAndroid Build Coastguard Worker       }
3253*61046927SAndroid Build Coastguard Worker    }
3254*61046927SAndroid Build Coastguard Worker    else {
3255*61046927SAndroid Build Coastguard Worker       /* non-proxy target */
3256*61046927SAndroid Build Coastguard Worker       const GLuint face = _mesa_tex_target_to_face(target);
3257*61046927SAndroid Build Coastguard Worker       struct gl_texture_image *texImage;
3258*61046927SAndroid Build Coastguard Worker 
3259*61046927SAndroid Build Coastguard Worker       if (!dimensionsOK) {
3260*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE,
3261*61046927SAndroid Build Coastguard Worker                      "%s%uD(invalid width=%d or height=%d or depth=%d)",
3262*61046927SAndroid Build Coastguard Worker                      func, dims, width, height, depth);
3263*61046927SAndroid Build Coastguard Worker          return;
3264*61046927SAndroid Build Coastguard Worker       }
3265*61046927SAndroid Build Coastguard Worker 
3266*61046927SAndroid Build Coastguard Worker       if (!sizeOK) {
3267*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_OUT_OF_MEMORY,
3268*61046927SAndroid Build Coastguard Worker                      "%s%uD(image too large: %d x %d x %d, %s format)",
3269*61046927SAndroid Build Coastguard Worker                      func, dims, width, height, depth,
3270*61046927SAndroid Build Coastguard Worker                      _mesa_enum_to_string(internalFormat));
3271*61046927SAndroid Build Coastguard Worker          return;
3272*61046927SAndroid Build Coastguard Worker       }
3273*61046927SAndroid Build Coastguard Worker 
3274*61046927SAndroid Build Coastguard Worker       /* Allow a hardware driver to just strip out the border, to provide
3275*61046927SAndroid Build Coastguard Worker        * reliable but slightly incorrect hardware rendering instead of
3276*61046927SAndroid Build Coastguard Worker        * rarely-tested software fallback rendering.
3277*61046927SAndroid Build Coastguard Worker        */
3278*61046927SAndroid Build Coastguard Worker       if (border) {
3279*61046927SAndroid Build Coastguard Worker          strip_texture_border(target, &width, &height, &depth, unpack,
3280*61046927SAndroid Build Coastguard Worker                               &unpack_no_border);
3281*61046927SAndroid Build Coastguard Worker          border = 0;
3282*61046927SAndroid Build Coastguard Worker          unpack = &unpack_no_border;
3283*61046927SAndroid Build Coastguard Worker       }
3284*61046927SAndroid Build Coastguard Worker 
3285*61046927SAndroid Build Coastguard Worker       _mesa_update_pixel(ctx);
3286*61046927SAndroid Build Coastguard Worker 
3287*61046927SAndroid Build Coastguard Worker       _mesa_lock_texture(ctx, texObj);
3288*61046927SAndroid Build Coastguard Worker       {
3289*61046927SAndroid Build Coastguard Worker          texObj->External = GL_FALSE;
3290*61046927SAndroid Build Coastguard Worker 
3291*61046927SAndroid Build Coastguard Worker          texImage = _mesa_get_tex_image(ctx, texObj, target, level);
3292*61046927SAndroid Build Coastguard Worker 
3293*61046927SAndroid Build Coastguard Worker          if (!texImage) {
3294*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
3295*61046927SAndroid Build Coastguard Worker          }
3296*61046927SAndroid Build Coastguard Worker          else {
3297*61046927SAndroid Build Coastguard Worker             st_FreeTextureImageBuffer(ctx, texImage);
3298*61046927SAndroid Build Coastguard Worker 
3299*61046927SAndroid Build Coastguard Worker             _mesa_init_teximage_fields(ctx, texImage,
3300*61046927SAndroid Build Coastguard Worker                                        width, height, depth,
3301*61046927SAndroid Build Coastguard Worker                                        border, internalFormat, texFormat);
3302*61046927SAndroid Build Coastguard Worker 
3303*61046927SAndroid Build Coastguard Worker             /* Give the texture to the driver.  <pixels> may be null. */
3304*61046927SAndroid Build Coastguard Worker             if (width > 0 && height > 0 && depth > 0) {
3305*61046927SAndroid Build Coastguard Worker                if (compressed) {
3306*61046927SAndroid Build Coastguard Worker                   st_CompressedTexImage(ctx, dims, texImage,
3307*61046927SAndroid Build Coastguard Worker                                         imageSize, pixels);
3308*61046927SAndroid Build Coastguard Worker                }
3309*61046927SAndroid Build Coastguard Worker                else {
3310*61046927SAndroid Build Coastguard Worker                   st_TexImage(ctx, dims, texImage, format,
3311*61046927SAndroid Build Coastguard Worker                               type, pixels, unpack);
3312*61046927SAndroid Build Coastguard Worker                }
3313*61046927SAndroid Build Coastguard Worker             }
3314*61046927SAndroid Build Coastguard Worker 
3315*61046927SAndroid Build Coastguard Worker             check_gen_mipmap(ctx, target, texObj, level);
3316*61046927SAndroid Build Coastguard Worker 
3317*61046927SAndroid Build Coastguard Worker             _mesa_update_fbo_texture(ctx, texObj, face, level);
3318*61046927SAndroid Build Coastguard Worker 
3319*61046927SAndroid Build Coastguard Worker             _mesa_dirty_texobj(ctx, texObj);
3320*61046927SAndroid Build Coastguard Worker             /* only apply depthMode swizzle if it was explicitly changed */
3321*61046927SAndroid Build Coastguard Worker             GLenum depth_mode = _mesa_is_desktop_gl_core(ctx) ? GL_RED : GL_LUMINANCE;
3322*61046927SAndroid Build Coastguard Worker             if (texObj->Attrib.DepthMode != depth_mode)
3323*61046927SAndroid Build Coastguard Worker                _mesa_update_teximage_format_swizzle(ctx, texObj->Image[0][texObj->Attrib.BaseLevel], texObj->Attrib.DepthMode);
3324*61046927SAndroid Build Coastguard Worker             _mesa_update_texture_object_swizzle(ctx, texObj);
3325*61046927SAndroid Build Coastguard Worker          }
3326*61046927SAndroid Build Coastguard Worker       }
3327*61046927SAndroid Build Coastguard Worker       _mesa_unlock_texture(ctx, texObj);
3328*61046927SAndroid Build Coastguard Worker    }
3329*61046927SAndroid Build Coastguard Worker }
3330*61046927SAndroid Build Coastguard Worker 
3331*61046927SAndroid Build Coastguard Worker 
3332*61046927SAndroid Build Coastguard Worker /* This is a wrapper around teximage() so that we can force the KHR_no_error
3333*61046927SAndroid Build Coastguard Worker  * logic to be inlined without inlining the function into all the callers.
3334*61046927SAndroid Build Coastguard Worker  */
3335*61046927SAndroid Build Coastguard Worker static void
teximage_err(struct gl_context * ctx,GLboolean compressed,GLuint dims,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei imageSize,const GLvoid * pixels)3336*61046927SAndroid Build Coastguard Worker teximage_err(struct gl_context *ctx, GLboolean compressed, GLuint dims,
3337*61046927SAndroid Build Coastguard Worker              GLenum target, GLint level, GLint internalFormat,
3338*61046927SAndroid Build Coastguard Worker              GLsizei width, GLsizei height, GLsizei depth,
3339*61046927SAndroid Build Coastguard Worker              GLint border, GLenum format, GLenum type,
3340*61046927SAndroid Build Coastguard Worker              GLsizei imageSize, const GLvoid *pixels)
3341*61046927SAndroid Build Coastguard Worker {
3342*61046927SAndroid Build Coastguard Worker    teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height,
3343*61046927SAndroid Build Coastguard Worker             depth, border, format, type, imageSize, pixels, false);
3344*61046927SAndroid Build Coastguard Worker }
3345*61046927SAndroid Build Coastguard Worker 
3346*61046927SAndroid Build Coastguard Worker 
3347*61046927SAndroid Build Coastguard Worker static void
teximage_no_error(struct gl_context * ctx,GLboolean compressed,GLuint dims,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei imageSize,const GLvoid * pixels)3348*61046927SAndroid Build Coastguard Worker teximage_no_error(struct gl_context *ctx, GLboolean compressed, GLuint dims,
3349*61046927SAndroid Build Coastguard Worker                   GLenum target, GLint level, GLint internalFormat,
3350*61046927SAndroid Build Coastguard Worker                   GLsizei width, GLsizei height, GLsizei depth,
3351*61046927SAndroid Build Coastguard Worker                   GLint border, GLenum format, GLenum type,
3352*61046927SAndroid Build Coastguard Worker                   GLsizei imageSize, const GLvoid *pixels)
3353*61046927SAndroid Build Coastguard Worker {
3354*61046927SAndroid Build Coastguard Worker    teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height,
3355*61046927SAndroid Build Coastguard Worker             depth, border, format, type, imageSize, pixels, true);
3356*61046927SAndroid Build Coastguard Worker }
3357*61046927SAndroid Build Coastguard Worker 
3358*61046927SAndroid Build Coastguard Worker 
3359*61046927SAndroid Build Coastguard Worker /*
3360*61046927SAndroid Build Coastguard Worker  * Called from the API.  Note that width includes the border.
3361*61046927SAndroid Build Coastguard Worker  */
3362*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexImage1D(GLenum target,GLint level,GLint internalFormat,GLsizei width,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3363*61046927SAndroid Build Coastguard Worker _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
3364*61046927SAndroid Build Coastguard Worker                   GLsizei width, GLint border, GLenum format,
3365*61046927SAndroid Build Coastguard Worker                   GLenum type, const GLvoid *pixels )
3366*61046927SAndroid Build Coastguard Worker {
3367*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3368*61046927SAndroid Build Coastguard Worker    teximage_err(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1,
3369*61046927SAndroid Build Coastguard Worker                 border, format, type, 0, pixels);
3370*61046927SAndroid Build Coastguard Worker }
3371*61046927SAndroid Build Coastguard Worker 
3372*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureImage1DEXT(GLuint texture,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3373*61046927SAndroid Build Coastguard Worker _mesa_TextureImage1DEXT(GLuint texture, GLenum target, GLint level,
3374*61046927SAndroid Build Coastguard Worker                       GLint internalFormat, GLsizei width, GLint border,
3375*61046927SAndroid Build Coastguard Worker                       GLenum format, GLenum type, const GLvoid *pixels )
3376*61046927SAndroid Build Coastguard Worker {
3377*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
3378*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3379*61046927SAndroid Build Coastguard Worker 
3380*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
3381*61046927SAndroid Build Coastguard Worker                                            "glTextureImage1DEXT");
3382*61046927SAndroid Build Coastguard Worker    if (!texObj)
3383*61046927SAndroid Build Coastguard Worker       return;
3384*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat,
3385*61046927SAndroid Build Coastguard Worker             width, 1, 1, border, format, type, 0, pixels, false);
3386*61046927SAndroid Build Coastguard Worker }
3387*61046927SAndroid Build Coastguard Worker 
3388*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MultiTexImage1DEXT(GLenum texunit,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3389*61046927SAndroid Build Coastguard Worker _mesa_MultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level,
3390*61046927SAndroid Build Coastguard Worker                          GLint internalFormat, GLsizei width, GLint border,
3391*61046927SAndroid Build Coastguard Worker                          GLenum format, GLenum type, const GLvoid *pixels )
3392*61046927SAndroid Build Coastguard Worker {
3393*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
3394*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3395*61046927SAndroid Build Coastguard Worker 
3396*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
3397*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
3398*61046927SAndroid Build Coastguard Worker                                                    true,
3399*61046927SAndroid Build Coastguard Worker                                                    "glMultiTexImage1DEXT");
3400*61046927SAndroid Build Coastguard Worker    if (!texObj)
3401*61046927SAndroid Build Coastguard Worker       return;
3402*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat, width, 1, 1,
3403*61046927SAndroid Build Coastguard Worker                 border, format, type, 0, pixels, false);
3404*61046927SAndroid Build Coastguard Worker }
3405*61046927SAndroid Build Coastguard Worker 
3406*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexImage2D(GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3407*61046927SAndroid Build Coastguard Worker _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
3408*61046927SAndroid Build Coastguard Worker                   GLsizei width, GLsizei height, GLint border,
3409*61046927SAndroid Build Coastguard Worker                   GLenum format, GLenum type,
3410*61046927SAndroid Build Coastguard Worker                   const GLvoid *pixels )
3411*61046927SAndroid Build Coastguard Worker {
3412*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3413*61046927SAndroid Build Coastguard Worker    teximage_err(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1,
3414*61046927SAndroid Build Coastguard Worker                 border, format, type, 0, pixels);
3415*61046927SAndroid Build Coastguard Worker }
3416*61046927SAndroid Build Coastguard Worker 
3417*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureImage2DEXT(GLuint texture,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3418*61046927SAndroid Build Coastguard Worker _mesa_TextureImage2DEXT(GLuint texture, GLenum target, GLint level,
3419*61046927SAndroid Build Coastguard Worker                       GLint internalFormat, GLsizei width, GLsizei height,
3420*61046927SAndroid Build Coastguard Worker                       GLint border,
3421*61046927SAndroid Build Coastguard Worker                       GLenum format, GLenum type, const GLvoid *pixels )
3422*61046927SAndroid Build Coastguard Worker {
3423*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
3424*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3425*61046927SAndroid Build Coastguard Worker 
3426*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
3427*61046927SAndroid Build Coastguard Worker                                            "glTextureImage2DEXT");
3428*61046927SAndroid Build Coastguard Worker    if (!texObj)
3429*61046927SAndroid Build Coastguard Worker       return;
3430*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat,
3431*61046927SAndroid Build Coastguard Worker             width, height, 1, border, format, type, 0, pixels, false);
3432*61046927SAndroid Build Coastguard Worker }
3433*61046927SAndroid Build Coastguard Worker 
3434*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MultiTexImage2DEXT(GLenum texunit,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3435*61046927SAndroid Build Coastguard Worker _mesa_MultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level,
3436*61046927SAndroid Build Coastguard Worker                          GLint internalFormat, GLsizei width, GLsizei height,
3437*61046927SAndroid Build Coastguard Worker                          GLint border,
3438*61046927SAndroid Build Coastguard Worker                          GLenum format, GLenum type, const GLvoid *pixels )
3439*61046927SAndroid Build Coastguard Worker {
3440*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
3441*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3442*61046927SAndroid Build Coastguard Worker 
3443*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
3444*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
3445*61046927SAndroid Build Coastguard Worker                                                    true,
3446*61046927SAndroid Build Coastguard Worker                                                    "glMultiTexImage2DEXT");
3447*61046927SAndroid Build Coastguard Worker    if (!texObj)
3448*61046927SAndroid Build Coastguard Worker       return;
3449*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat, width, height, 1,
3450*61046927SAndroid Build Coastguard Worker                 border, format, type, 0, pixels, false);
3451*61046927SAndroid Build Coastguard Worker }
3452*61046927SAndroid Build Coastguard Worker 
3453*61046927SAndroid Build Coastguard Worker /*
3454*61046927SAndroid Build Coastguard Worker  * Called by the API or display list executor.
3455*61046927SAndroid Build Coastguard Worker  * Note that width and height include the border.
3456*61046927SAndroid Build Coastguard Worker  */
3457*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexImage3D(GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3458*61046927SAndroid Build Coastguard Worker _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
3459*61046927SAndroid Build Coastguard Worker                   GLsizei width, GLsizei height, GLsizei depth,
3460*61046927SAndroid Build Coastguard Worker                   GLint border, GLenum format, GLenum type,
3461*61046927SAndroid Build Coastguard Worker                   const GLvoid *pixels )
3462*61046927SAndroid Build Coastguard Worker {
3463*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3464*61046927SAndroid Build Coastguard Worker    teximage_err(ctx, GL_FALSE, 3, target, level, internalFormat,
3465*61046927SAndroid Build Coastguard Worker                 width, height, depth, border, format, type, 0, pixels);
3466*61046927SAndroid Build Coastguard Worker }
3467*61046927SAndroid Build Coastguard Worker 
3468*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureImage3DEXT(GLuint texture,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3469*61046927SAndroid Build Coastguard Worker _mesa_TextureImage3DEXT(GLuint texture, GLenum target, GLint level,
3470*61046927SAndroid Build Coastguard Worker                       GLint internalFormat, GLsizei width, GLsizei height,
3471*61046927SAndroid Build Coastguard Worker                       GLsizei depth, GLint border,
3472*61046927SAndroid Build Coastguard Worker                       GLenum format, GLenum type, const GLvoid *pixels )
3473*61046927SAndroid Build Coastguard Worker {
3474*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
3475*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3476*61046927SAndroid Build Coastguard Worker 
3477*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
3478*61046927SAndroid Build Coastguard Worker                                            "glTextureImage3DEXT");
3479*61046927SAndroid Build Coastguard Worker    if (!texObj)
3480*61046927SAndroid Build Coastguard Worker       return;
3481*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat,
3482*61046927SAndroid Build Coastguard Worker             width, height, depth, border, format, type, 0, pixels, false);
3483*61046927SAndroid Build Coastguard Worker }
3484*61046927SAndroid Build Coastguard Worker 
3485*61046927SAndroid Build Coastguard Worker 
3486*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MultiTexImage3DEXT(GLenum texunit,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3487*61046927SAndroid Build Coastguard Worker _mesa_MultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level,
3488*61046927SAndroid Build Coastguard Worker                          GLint internalFormat, GLsizei width, GLsizei height,
3489*61046927SAndroid Build Coastguard Worker                          GLsizei depth, GLint border, GLenum format, GLenum type,
3490*61046927SAndroid Build Coastguard Worker                          const GLvoid *pixels )
3491*61046927SAndroid Build Coastguard Worker {
3492*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
3493*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3494*61046927SAndroid Build Coastguard Worker 
3495*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
3496*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
3497*61046927SAndroid Build Coastguard Worker                                                    true,
3498*61046927SAndroid Build Coastguard Worker                                                    "glMultiTexImage3DEXT");
3499*61046927SAndroid Build Coastguard Worker    if (!texObj)
3500*61046927SAndroid Build Coastguard Worker       return;
3501*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat,
3502*61046927SAndroid Build Coastguard Worker                 width, height, depth, border, format, type, 0, pixels, false);
3503*61046927SAndroid Build Coastguard Worker }
3504*61046927SAndroid Build Coastguard Worker 
3505*61046927SAndroid Build Coastguard Worker 
3506*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexImage1D_no_error(GLenum target,GLint level,GLint internalFormat,GLsizei width,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3507*61046927SAndroid Build Coastguard Worker _mesa_TexImage1D_no_error(GLenum target, GLint level, GLint internalFormat,
3508*61046927SAndroid Build Coastguard Worker                           GLsizei width, GLint border, GLenum format,
3509*61046927SAndroid Build Coastguard Worker                           GLenum type, const GLvoid *pixels)
3510*61046927SAndroid Build Coastguard Worker {
3511*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3512*61046927SAndroid Build Coastguard Worker    teximage_no_error(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1,
3513*61046927SAndroid Build Coastguard Worker                      1, border, format, type, 0, pixels);
3514*61046927SAndroid Build Coastguard Worker }
3515*61046927SAndroid Build Coastguard Worker 
3516*61046927SAndroid Build Coastguard Worker 
3517*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexImage2D_no_error(GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3518*61046927SAndroid Build Coastguard Worker _mesa_TexImage2D_no_error(GLenum target, GLint level, GLint internalFormat,
3519*61046927SAndroid Build Coastguard Worker                           GLsizei width, GLsizei height, GLint border,
3520*61046927SAndroid Build Coastguard Worker                           GLenum format, GLenum type, const GLvoid *pixels)
3521*61046927SAndroid Build Coastguard Worker {
3522*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3523*61046927SAndroid Build Coastguard Worker    teximage_no_error(ctx, GL_FALSE, 2, target, level, internalFormat, width,
3524*61046927SAndroid Build Coastguard Worker                      height, 1, border, format, type, 0, pixels);
3525*61046927SAndroid Build Coastguard Worker }
3526*61046927SAndroid Build Coastguard Worker 
3527*61046927SAndroid Build Coastguard Worker 
3528*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexImage3D_no_error(GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)3529*61046927SAndroid Build Coastguard Worker _mesa_TexImage3D_no_error(GLenum target, GLint level, GLint internalFormat,
3530*61046927SAndroid Build Coastguard Worker                           GLsizei width, GLsizei height, GLsizei depth,
3531*61046927SAndroid Build Coastguard Worker                           GLint border, GLenum format, GLenum type,
3532*61046927SAndroid Build Coastguard Worker                           const GLvoid *pixels )
3533*61046927SAndroid Build Coastguard Worker {
3534*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3535*61046927SAndroid Build Coastguard Worker    teximage_no_error(ctx, GL_FALSE, 3, target, level, internalFormat,
3536*61046927SAndroid Build Coastguard Worker                      width, height, depth, border, format, type, 0, pixels);
3537*61046927SAndroid Build Coastguard Worker }
3538*61046927SAndroid Build Coastguard Worker 
3539*61046927SAndroid Build Coastguard Worker /*
3540*61046927SAndroid Build Coastguard Worker  * Helper used by __mesa_EGLImageTargetTexture2DOES and
3541*61046927SAndroid Build Coastguard Worker  * _mesa_EGLImageTargetTexStorageEXT.
3542*61046927SAndroid Build Coastguard Worker  */
3543*61046927SAndroid Build Coastguard Worker static void
egl_image_target_texture(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum target,GLeglImageOES image,bool tex_storage,bool tex_compression,const char * caller)3544*61046927SAndroid Build Coastguard Worker egl_image_target_texture(struct gl_context *ctx,
3545*61046927SAndroid Build Coastguard Worker                          struct gl_texture_object *texObj, GLenum target,
3546*61046927SAndroid Build Coastguard Worker                          GLeglImageOES image, bool tex_storage,
3547*61046927SAndroid Build Coastguard Worker                          bool tex_compression, const char *caller)
3548*61046927SAndroid Build Coastguard Worker {
3549*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
3550*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
3551*61046927SAndroid Build Coastguard Worker 
3552*61046927SAndroid Build Coastguard Worker    if (!texObj)
3553*61046927SAndroid Build Coastguard Worker       texObj = _mesa_get_current_tex_object(ctx, target);
3554*61046927SAndroid Build Coastguard Worker    if (!texObj)
3555*61046927SAndroid Build Coastguard Worker       return;
3556*61046927SAndroid Build Coastguard Worker 
3557*61046927SAndroid Build Coastguard Worker    if (!image || !st_validate_egl_image(ctx, image)) {
3558*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image);
3559*61046927SAndroid Build Coastguard Worker       return;
3560*61046927SAndroid Build Coastguard Worker    }
3561*61046927SAndroid Build Coastguard Worker 
3562*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
3563*61046927SAndroid Build Coastguard Worker 
3564*61046927SAndroid Build Coastguard Worker    if (texObj->Immutable) {
3565*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture is immutable)", caller);
3566*61046927SAndroid Build Coastguard Worker       _mesa_unlock_texture(ctx, texObj);
3567*61046927SAndroid Build Coastguard Worker       return;
3568*61046927SAndroid Build Coastguard Worker    }
3569*61046927SAndroid Build Coastguard Worker 
3570*61046927SAndroid Build Coastguard Worker    texImage = _mesa_get_tex_image(ctx, texObj, target, 0);
3571*61046927SAndroid Build Coastguard Worker    if (!texImage) {
3572*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
3573*61046927SAndroid Build Coastguard Worker    } else {
3574*61046927SAndroid Build Coastguard Worker       st_FreeTextureImageBuffer(ctx, texImage);
3575*61046927SAndroid Build Coastguard Worker 
3576*61046927SAndroid Build Coastguard Worker       texObj->External = GL_TRUE;
3577*61046927SAndroid Build Coastguard Worker 
3578*61046927SAndroid Build Coastguard Worker       struct st_egl_image stimg;
3579*61046927SAndroid Build Coastguard Worker       bool native_supported;
3580*61046927SAndroid Build Coastguard Worker       if (!st_get_egl_image(ctx, image, PIPE_BIND_SAMPLER_VIEW, tex_compression,
3581*61046927SAndroid Build Coastguard Worker                             caller, &stimg, &native_supported)) {
3582*61046927SAndroid Build Coastguard Worker          _mesa_unlock_texture(ctx, texObj);
3583*61046927SAndroid Build Coastguard Worker          return;
3584*61046927SAndroid Build Coastguard Worker       }
3585*61046927SAndroid Build Coastguard Worker 
3586*61046927SAndroid Build Coastguard Worker       if (tex_storage) {
3587*61046927SAndroid Build Coastguard Worker          /* EXT_EGL_image_storage
3588*61046927SAndroid Build Coastguard Worker           * If the EGL image was created using EGL_EXT_image_dma_buf_import,
3589*61046927SAndroid Build Coastguard Worker           * then the following applies:
3590*61046927SAndroid Build Coastguard Worker           *    - <target> must be GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES.
3591*61046927SAndroid Build Coastguard Worker           *    Otherwise, the error INVALID_OPERATION is generated.
3592*61046927SAndroid Build Coastguard Worker           */
3593*61046927SAndroid Build Coastguard Worker          if (stimg.imported_dmabuf &&
3594*61046927SAndroid Build Coastguard Worker              !(target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES)) {
3595*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_OPERATION,
3596*61046927SAndroid Build Coastguard Worker                         "%s(texture is imported from dmabuf)", caller);
3597*61046927SAndroid Build Coastguard Worker             pipe_resource_reference(&stimg.texture, NULL);
3598*61046927SAndroid Build Coastguard Worker             _mesa_unlock_texture(ctx, texObj);
3599*61046927SAndroid Build Coastguard Worker             return;
3600*61046927SAndroid Build Coastguard Worker          }
3601*61046927SAndroid Build Coastguard Worker          st_bind_egl_image(ctx, texObj, texImage, &stimg, true, native_supported);
3602*61046927SAndroid Build Coastguard Worker       } else {
3603*61046927SAndroid Build Coastguard Worker          st_bind_egl_image(ctx, texObj, texImage, &stimg,
3604*61046927SAndroid Build Coastguard Worker                            target != GL_TEXTURE_EXTERNAL_OES, native_supported);
3605*61046927SAndroid Build Coastguard Worker       }
3606*61046927SAndroid Build Coastguard Worker 
3607*61046927SAndroid Build Coastguard Worker       pipe_resource_reference(&stimg.texture, NULL);
3608*61046927SAndroid Build Coastguard Worker 
3609*61046927SAndroid Build Coastguard Worker       _mesa_dirty_texobj(ctx, texObj);
3610*61046927SAndroid Build Coastguard Worker    }
3611*61046927SAndroid Build Coastguard Worker 
3612*61046927SAndroid Build Coastguard Worker    if (tex_storage)
3613*61046927SAndroid Build Coastguard Worker       _mesa_set_texture_view_state(ctx, texObj, target, 1);
3614*61046927SAndroid Build Coastguard Worker 
3615*61046927SAndroid Build Coastguard Worker    _mesa_update_fbo_texture(ctx, texObj, 0, 0);
3616*61046927SAndroid Build Coastguard Worker 
3617*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
3618*61046927SAndroid Build Coastguard Worker }
3619*61046927SAndroid Build Coastguard Worker 
3620*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_EGLImageTargetTexture2DOES(GLenum target,GLeglImageOES image)3621*61046927SAndroid Build Coastguard Worker _mesa_EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
3622*61046927SAndroid Build Coastguard Worker {
3623*61046927SAndroid Build Coastguard Worker    const char *func = "glEGLImageTargetTexture2D";
3624*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3625*61046927SAndroid Build Coastguard Worker 
3626*61046927SAndroid Build Coastguard Worker    bool valid_target;
3627*61046927SAndroid Build Coastguard Worker    switch (target) {
3628*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
3629*61046927SAndroid Build Coastguard Worker       valid_target = _mesa_has_OES_EGL_image(ctx);
3630*61046927SAndroid Build Coastguard Worker       break;
3631*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_EXTERNAL_OES:
3632*61046927SAndroid Build Coastguard Worker       valid_target = _mesa_has_OES_EGL_image_external(ctx);
3633*61046927SAndroid Build Coastguard Worker       break;
3634*61046927SAndroid Build Coastguard Worker    default:
3635*61046927SAndroid Build Coastguard Worker       valid_target = false;
3636*61046927SAndroid Build Coastguard Worker       break;
3637*61046927SAndroid Build Coastguard Worker    }
3638*61046927SAndroid Build Coastguard Worker 
3639*61046927SAndroid Build Coastguard Worker    if (valid_target) {
3640*61046927SAndroid Build Coastguard Worker       egl_image_target_texture(ctx, NULL, target, image, false, false, func);
3641*61046927SAndroid Build Coastguard Worker    } else {
3642*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%d)", func, target);
3643*61046927SAndroid Build Coastguard Worker    }
3644*61046927SAndroid Build Coastguard Worker }
3645*61046927SAndroid Build Coastguard Worker 
3646*61046927SAndroid Build Coastguard Worker static bool
parse_surface_compression(GLint attrib,bool * compression)3647*61046927SAndroid Build Coastguard Worker parse_surface_compression(GLint attrib, bool *compression)
3648*61046927SAndroid Build Coastguard Worker {
3649*61046927SAndroid Build Coastguard Worker    switch (attrib) {
3650*61046927SAndroid Build Coastguard Worker    case GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT:
3651*61046927SAndroid Build Coastguard Worker       *compression = true;
3652*61046927SAndroid Build Coastguard Worker       break;
3653*61046927SAndroid Build Coastguard Worker    case GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT:
3654*61046927SAndroid Build Coastguard Worker       *compression = false;
3655*61046927SAndroid Build Coastguard Worker       break;
3656*61046927SAndroid Build Coastguard Worker    default:
3657*61046927SAndroid Build Coastguard Worker       return false;
3658*61046927SAndroid Build Coastguard Worker    }
3659*61046927SAndroid Build Coastguard Worker    return true;
3660*61046927SAndroid Build Coastguard Worker }
3661*61046927SAndroid Build Coastguard Worker 
3662*61046927SAndroid Build Coastguard Worker 
3663*61046927SAndroid Build Coastguard Worker static void
egl_image_target_texture_storage(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum target,GLeglImageOES image,const GLint * attrib_list,const char * caller)3664*61046927SAndroid Build Coastguard Worker egl_image_target_texture_storage(struct gl_context *ctx,
3665*61046927SAndroid Build Coastguard Worker                                  struct gl_texture_object *texObj, GLenum target,
3666*61046927SAndroid Build Coastguard Worker                                  GLeglImageOES image, const GLint *attrib_list,
3667*61046927SAndroid Build Coastguard Worker                                  const char *caller)
3668*61046927SAndroid Build Coastguard Worker {
3669*61046927SAndroid Build Coastguard Worker    bool tex_compression = false;
3670*61046927SAndroid Build Coastguard Worker 
3671*61046927SAndroid Build Coastguard Worker    /*
3672*61046927SAndroid Build Coastguard Worker     * EXT_EGL_image_storage_compression:
3673*61046927SAndroid Build Coastguard Worker     *
3674*61046927SAndroid Build Coastguard Worker     * Attributes that can be specified in <attrib_list> include
3675*61046927SAndroid Build Coastguard Worker     * SURFACE_COMPRESSION_EXT.
3676*61046927SAndroid Build Coastguard Worker     */
3677*61046927SAndroid Build Coastguard Worker    for (int i = 0; attrib_list && attrib_list[i] != GL_NONE; ++i) {
3678*61046927SAndroid Build Coastguard Worker       switch (attrib_list[i]) {
3679*61046927SAndroid Build Coastguard Worker       case GL_SURFACE_COMPRESSION_EXT:
3680*61046927SAndroid Build Coastguard Worker          if (!parse_surface_compression(attrib_list[++i], &tex_compression)) {
3681*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image);
3682*61046927SAndroid Build Coastguard Worker             return;
3683*61046927SAndroid Build Coastguard Worker          }
3684*61046927SAndroid Build Coastguard Worker          break;
3685*61046927SAndroid Build Coastguard Worker       default:
3686*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image);
3687*61046927SAndroid Build Coastguard Worker          return;
3688*61046927SAndroid Build Coastguard Worker       }
3689*61046927SAndroid Build Coastguard Worker    }
3690*61046927SAndroid Build Coastguard Worker 
3691*61046927SAndroid Build Coastguard Worker    /*
3692*61046927SAndroid Build Coastguard Worker     * <target> must be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY,
3693*61046927SAndroid Build Coastguard Worker     * GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY. On
3694*61046927SAndroid Build Coastguard Worker     * OpenGL implementations (non-ES), <target> can also be GL_TEXTURE_1D or
3695*61046927SAndroid Build Coastguard Worker     * GL_TEXTURE_1D_ARRAY.
3696*61046927SAndroid Build Coastguard Worker     * If the implementation supports OES_EGL_image_external, <target> can be
3697*61046927SAndroid Build Coastguard Worker     * GL_TEXTURE_EXTERNAL_OES.
3698*61046927SAndroid Build Coastguard Worker     */
3699*61046927SAndroid Build Coastguard Worker    bool valid_target;
3700*61046927SAndroid Build Coastguard Worker    switch (target) {
3701*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D:
3702*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_ARRAY:
3703*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_3D:
3704*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP:
3705*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_CUBE_MAP_ARRAY:
3706*61046927SAndroid Build Coastguard Worker       valid_target = true;
3707*61046927SAndroid Build Coastguard Worker       break;
3708*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D:
3709*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_1D_ARRAY:
3710*61046927SAndroid Build Coastguard Worker       /* No eglImageOES for 1D textures */
3711*61046927SAndroid Build Coastguard Worker       valid_target = !_mesa_is_gles(ctx);
3712*61046927SAndroid Build Coastguard Worker       break;
3713*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_EXTERNAL_OES:
3714*61046927SAndroid Build Coastguard Worker       valid_target = _mesa_has_OES_EGL_image_external(ctx);
3715*61046927SAndroid Build Coastguard Worker       break;
3716*61046927SAndroid Build Coastguard Worker    default:
3717*61046927SAndroid Build Coastguard Worker       valid_target = false;
3718*61046927SAndroid Build Coastguard Worker       break;
3719*61046927SAndroid Build Coastguard Worker    }
3720*61046927SAndroid Build Coastguard Worker 
3721*61046927SAndroid Build Coastguard Worker    if (valid_target) {
3722*61046927SAndroid Build Coastguard Worker       egl_image_target_texture(ctx, texObj, target, image, true,
3723*61046927SAndroid Build Coastguard Worker                                tex_compression, caller);
3724*61046927SAndroid Build Coastguard Worker    } else {
3725*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target=%d)", caller, target);
3726*61046927SAndroid Build Coastguard Worker    }
3727*61046927SAndroid Build Coastguard Worker 
3728*61046927SAndroid Build Coastguard Worker }
3729*61046927SAndroid Build Coastguard Worker 
3730*61046927SAndroid Build Coastguard Worker 
3731*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_EGLImageTargetTexStorageEXT(GLenum target,GLeglImageOES image,const GLint * attrib_list)3732*61046927SAndroid Build Coastguard Worker _mesa_EGLImageTargetTexStorageEXT(GLenum target, GLeglImageOES image,
3733*61046927SAndroid Build Coastguard Worker                                   const GLint *attrib_list)
3734*61046927SAndroid Build Coastguard Worker {
3735*61046927SAndroid Build Coastguard Worker    const char *func = "glEGLImageTargetTexStorageEXT";
3736*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3737*61046927SAndroid Build Coastguard Worker 
3738*61046927SAndroid Build Coastguard Worker    if (!(_mesa_is_desktop_gl(ctx) && ctx->Version >= 42) &&
3739*61046927SAndroid Build Coastguard Worker        !_mesa_is_gles3(ctx) && !_mesa_has_ARB_texture_storage(ctx)) {
3740*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
3741*61046927SAndroid Build Coastguard Worker          "OpenGL 4.2, OpenGL ES 3.0 or ARB_texture_storage required");
3742*61046927SAndroid Build Coastguard Worker       return;
3743*61046927SAndroid Build Coastguard Worker    }
3744*61046927SAndroid Build Coastguard Worker 
3745*61046927SAndroid Build Coastguard Worker    egl_image_target_texture_storage(ctx, NULL, target, image, attrib_list,
3746*61046927SAndroid Build Coastguard Worker                                     func);
3747*61046927SAndroid Build Coastguard Worker }
3748*61046927SAndroid Build Coastguard Worker 
3749*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_EGLImageTargetTextureStorageEXT(GLuint texture,GLeglImageOES image,const GLint * attrib_list)3750*61046927SAndroid Build Coastguard Worker _mesa_EGLImageTargetTextureStorageEXT(GLuint texture, GLeglImageOES image,
3751*61046927SAndroid Build Coastguard Worker                                       const GLint *attrib_list)
3752*61046927SAndroid Build Coastguard Worker {
3753*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
3754*61046927SAndroid Build Coastguard Worker    const char *func = "glEGLImageTargetTextureStorageEXT";
3755*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
3756*61046927SAndroid Build Coastguard Worker 
3757*61046927SAndroid Build Coastguard Worker    if (!_mesa_has_ARB_direct_state_access(ctx) &&
3758*61046927SAndroid Build Coastguard Worker        !_mesa_has_EXT_direct_state_access(ctx)) {
3759*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "direct access not supported");
3760*61046927SAndroid Build Coastguard Worker       return;
3761*61046927SAndroid Build Coastguard Worker    }
3762*61046927SAndroid Build Coastguard Worker 
3763*61046927SAndroid Build Coastguard Worker    if (!(_mesa_is_desktop_gl(ctx) && ctx->Version >= 42) &&
3764*61046927SAndroid Build Coastguard Worker        !_mesa_is_gles3(ctx) && !_mesa_has_ARB_texture_storage(ctx)) {
3765*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
3766*61046927SAndroid Build Coastguard Worker          "OpenGL 4.2, OpenGL ES 3.0 or ARB_texture_storage required");
3767*61046927SAndroid Build Coastguard Worker       return;
3768*61046927SAndroid Build Coastguard Worker    }
3769*61046927SAndroid Build Coastguard Worker 
3770*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture, func);
3771*61046927SAndroid Build Coastguard Worker    if (!texObj)
3772*61046927SAndroid Build Coastguard Worker       return;
3773*61046927SAndroid Build Coastguard Worker 
3774*61046927SAndroid Build Coastguard Worker    egl_image_target_texture_storage(ctx, texObj, texObj->Target, image,
3775*61046927SAndroid Build Coastguard Worker                                     attrib_list, func);
3776*61046927SAndroid Build Coastguard Worker }
3777*61046927SAndroid Build Coastguard Worker 
3778*61046927SAndroid Build Coastguard Worker /**
3779*61046927SAndroid Build Coastguard Worker  * Helper that implements the glTexSubImage1/2/3D()
3780*61046927SAndroid Build Coastguard Worker  * and glTextureSubImage1/2/3D() functions.
3781*61046927SAndroid Build Coastguard Worker  */
3782*61046927SAndroid Build Coastguard Worker static void
texture_sub_image(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,struct gl_texture_image * texImage,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)3783*61046927SAndroid Build Coastguard Worker texture_sub_image(struct gl_context *ctx, GLuint dims,
3784*61046927SAndroid Build Coastguard Worker                   struct gl_texture_object *texObj,
3785*61046927SAndroid Build Coastguard Worker                   struct gl_texture_image *texImage,
3786*61046927SAndroid Build Coastguard Worker                   GLenum target, GLint level,
3787*61046927SAndroid Build Coastguard Worker                   GLint xoffset, GLint yoffset, GLint zoffset,
3788*61046927SAndroid Build Coastguard Worker                   GLsizei width, GLsizei height, GLsizei depth,
3789*61046927SAndroid Build Coastguard Worker                   GLenum format, GLenum type, const GLvoid *pixels)
3790*61046927SAndroid Build Coastguard Worker {
3791*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
3792*61046927SAndroid Build Coastguard Worker 
3793*61046927SAndroid Build Coastguard Worker    _mesa_update_pixel(ctx);
3794*61046927SAndroid Build Coastguard Worker 
3795*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
3796*61046927SAndroid Build Coastguard Worker    {
3797*61046927SAndroid Build Coastguard Worker       if (width > 0 && height > 0 && depth > 0) {
3798*61046927SAndroid Build Coastguard Worker          /* If we have a border, offset=-1 is legal.  Bias by border width. */
3799*61046927SAndroid Build Coastguard Worker          switch (dims) {
3800*61046927SAndroid Build Coastguard Worker          case 3:
3801*61046927SAndroid Build Coastguard Worker             if (target != GL_TEXTURE_2D_ARRAY)
3802*61046927SAndroid Build Coastguard Worker                zoffset += texImage->Border;
3803*61046927SAndroid Build Coastguard Worker             FALLTHROUGH;
3804*61046927SAndroid Build Coastguard Worker          case 2:
3805*61046927SAndroid Build Coastguard Worker             if (target != GL_TEXTURE_1D_ARRAY)
3806*61046927SAndroid Build Coastguard Worker                yoffset += texImage->Border;
3807*61046927SAndroid Build Coastguard Worker             FALLTHROUGH;
3808*61046927SAndroid Build Coastguard Worker          case 1:
3809*61046927SAndroid Build Coastguard Worker             xoffset += texImage->Border;
3810*61046927SAndroid Build Coastguard Worker          }
3811*61046927SAndroid Build Coastguard Worker 
3812*61046927SAndroid Build Coastguard Worker          st_TexSubImage(ctx, dims, texImage,
3813*61046927SAndroid Build Coastguard Worker                         xoffset, yoffset, zoffset,
3814*61046927SAndroid Build Coastguard Worker                         width, height, depth,
3815*61046927SAndroid Build Coastguard Worker                         format, type, pixels, &ctx->Unpack);
3816*61046927SAndroid Build Coastguard Worker 
3817*61046927SAndroid Build Coastguard Worker          check_gen_mipmap(ctx, target, texObj, level);
3818*61046927SAndroid Build Coastguard Worker 
3819*61046927SAndroid Build Coastguard Worker          /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
3820*61046927SAndroid Build Coastguard Worker           * the texel data, not the texture format, size, etc.
3821*61046927SAndroid Build Coastguard Worker           */
3822*61046927SAndroid Build Coastguard Worker       }
3823*61046927SAndroid Build Coastguard Worker    }
3824*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
3825*61046927SAndroid Build Coastguard Worker }
3826*61046927SAndroid Build Coastguard Worker 
3827*61046927SAndroid Build Coastguard Worker /**
3828*61046927SAndroid Build Coastguard Worker  * Implement all the glTexSubImage1/2/3D() functions.
3829*61046927SAndroid Build Coastguard Worker  * Must split this out this way because of GL_TEXTURE_CUBE_MAP.
3830*61046927SAndroid Build Coastguard Worker  */
3831*61046927SAndroid Build Coastguard Worker static void
texsubimage_err(struct gl_context * ctx,GLuint dims,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels,const char * callerName)3832*61046927SAndroid Build Coastguard Worker texsubimage_err(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
3833*61046927SAndroid Build Coastguard Worker                 GLint xoffset, GLint yoffset, GLint zoffset,
3834*61046927SAndroid Build Coastguard Worker                 GLsizei width, GLsizei height, GLsizei depth,
3835*61046927SAndroid Build Coastguard Worker                 GLenum format, GLenum type, const GLvoid *pixels,
3836*61046927SAndroid Build Coastguard Worker                 const char *callerName)
3837*61046927SAndroid Build Coastguard Worker {
3838*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
3839*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
3840*61046927SAndroid Build Coastguard Worker 
3841*61046927SAndroid Build Coastguard Worker    /* check target (proxies not allowed) */
3842*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, dims, target, false)) {
3843*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
3844*61046927SAndroid Build Coastguard Worker                   dims, _mesa_enum_to_string(target));
3845*61046927SAndroid Build Coastguard Worker       return;
3846*61046927SAndroid Build Coastguard Worker    }
3847*61046927SAndroid Build Coastguard Worker 
3848*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_current_tex_object(ctx, target);
3849*61046927SAndroid Build Coastguard Worker    if (!texObj)
3850*61046927SAndroid Build Coastguard Worker       return;
3851*61046927SAndroid Build Coastguard Worker 
3852*61046927SAndroid Build Coastguard Worker    if (texsubimage_error_check(ctx, dims, texObj, target, level,
3853*61046927SAndroid Build Coastguard Worker                                xoffset, yoffset, zoffset,
3854*61046927SAndroid Build Coastguard Worker                                width, height, depth, format, type,
3855*61046927SAndroid Build Coastguard Worker                                pixels, callerName)) {
3856*61046927SAndroid Build Coastguard Worker       return;   /* error was detected */
3857*61046927SAndroid Build Coastguard Worker    }
3858*61046927SAndroid Build Coastguard Worker 
3859*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
3860*61046927SAndroid Build Coastguard Worker    /* texsubimage_error_check ensures that texImage is not NULL */
3861*61046927SAndroid Build Coastguard Worker 
3862*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3863*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
3864*61046927SAndroid Build Coastguard Worker                   dims,
3865*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target), level,
3866*61046927SAndroid Build Coastguard Worker                   xoffset, yoffset, zoffset, width, height, depth,
3867*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(format),
3868*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(type), pixels);
3869*61046927SAndroid Build Coastguard Worker 
3870*61046927SAndroid Build Coastguard Worker    texture_sub_image(ctx, dims, texObj, texImage, target, level,
3871*61046927SAndroid Build Coastguard Worker                      xoffset, yoffset, zoffset, width, height, depth,
3872*61046927SAndroid Build Coastguard Worker                      format, type, pixels);
3873*61046927SAndroid Build Coastguard Worker }
3874*61046927SAndroid Build Coastguard Worker 
3875*61046927SAndroid Build Coastguard Worker 
3876*61046927SAndroid Build Coastguard Worker static void
texsubimage(struct gl_context * ctx,GLuint dims,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)3877*61046927SAndroid Build Coastguard Worker texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
3878*61046927SAndroid Build Coastguard Worker             GLint xoffset, GLint yoffset, GLint zoffset,
3879*61046927SAndroid Build Coastguard Worker             GLsizei width, GLsizei height, GLsizei depth,
3880*61046927SAndroid Build Coastguard Worker             GLenum format, GLenum type, const GLvoid *pixels)
3881*61046927SAndroid Build Coastguard Worker {
3882*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
3883*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
3884*61046927SAndroid Build Coastguard Worker 
3885*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_current_tex_object(ctx, target);
3886*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
3887*61046927SAndroid Build Coastguard Worker 
3888*61046927SAndroid Build Coastguard Worker    texture_sub_image(ctx, dims, texObj, texImage, target, level,
3889*61046927SAndroid Build Coastguard Worker                      xoffset, yoffset, zoffset, width, height, depth,
3890*61046927SAndroid Build Coastguard Worker                      format, type, pixels);
3891*61046927SAndroid Build Coastguard Worker }
3892*61046927SAndroid Build Coastguard Worker 
3893*61046927SAndroid Build Coastguard Worker 
3894*61046927SAndroid Build Coastguard Worker /**
3895*61046927SAndroid Build Coastguard Worker  * Implement all the glTextureSubImage1/2/3D() functions.
3896*61046927SAndroid Build Coastguard Worker  * Must split this out this way because of GL_TEXTURE_CUBE_MAP.
3897*61046927SAndroid Build Coastguard Worker  */
3898*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
texturesubimage(struct gl_context * ctx,GLuint dims,GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels,const char * callerName,bool no_error,bool ext_dsa)3899*61046927SAndroid Build Coastguard Worker texturesubimage(struct gl_context *ctx, GLuint dims,
3900*61046927SAndroid Build Coastguard Worker                 GLuint texture, GLenum target, GLint level,
3901*61046927SAndroid Build Coastguard Worker                 GLint xoffset, GLint yoffset, GLint zoffset,
3902*61046927SAndroid Build Coastguard Worker                 GLsizei width, GLsizei height, GLsizei depth,
3903*61046927SAndroid Build Coastguard Worker                 GLenum format, GLenum type, const GLvoid *pixels,
3904*61046927SAndroid Build Coastguard Worker                 const char *callerName, bool no_error, bool ext_dsa)
3905*61046927SAndroid Build Coastguard Worker {
3906*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
3907*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
3908*61046927SAndroid Build Coastguard Worker    int i;
3909*61046927SAndroid Build Coastguard Worker 
3910*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3911*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx,
3912*61046927SAndroid Build Coastguard Worker                   "glTextureSubImage%uD %d %d %d %d %d %d %d %d %s %s %p\n",
3913*61046927SAndroid Build Coastguard Worker                   dims, texture, level,
3914*61046927SAndroid Build Coastguard Worker                   xoffset, yoffset, zoffset, width, height, depth,
3915*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(format),
3916*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(type), pixels);
3917*61046927SAndroid Build Coastguard Worker 
3918*61046927SAndroid Build Coastguard Worker    /* Get the texture object by Name. */
3919*61046927SAndroid Build Coastguard Worker    if (!no_error) {
3920*61046927SAndroid Build Coastguard Worker       if (!ext_dsa) {
3921*61046927SAndroid Build Coastguard Worker          texObj = _mesa_lookup_texture_err(ctx, texture, callerName);
3922*61046927SAndroid Build Coastguard Worker       } else {
3923*61046927SAndroid Build Coastguard Worker          texObj = lookup_texture_ext_dsa(ctx, target, texture, callerName);
3924*61046927SAndroid Build Coastguard Worker       }
3925*61046927SAndroid Build Coastguard Worker       if (!texObj)
3926*61046927SAndroid Build Coastguard Worker          return;
3927*61046927SAndroid Build Coastguard Worker    } else {
3928*61046927SAndroid Build Coastguard Worker       texObj = _mesa_lookup_texture(ctx, texture);
3929*61046927SAndroid Build Coastguard Worker    }
3930*61046927SAndroid Build Coastguard Worker 
3931*61046927SAndroid Build Coastguard Worker    if (!no_error) {
3932*61046927SAndroid Build Coastguard Worker       /* check target (proxies not allowed) */
3933*61046927SAndroid Build Coastguard Worker       if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) {
3934*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target=%s)",
3935*61046927SAndroid Build Coastguard Worker                      callerName, _mesa_enum_to_string(texObj->Target));
3936*61046927SAndroid Build Coastguard Worker          return;
3937*61046927SAndroid Build Coastguard Worker       }
3938*61046927SAndroid Build Coastguard Worker 
3939*61046927SAndroid Build Coastguard Worker       if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level,
3940*61046927SAndroid Build Coastguard Worker                                   xoffset, yoffset, zoffset,
3941*61046927SAndroid Build Coastguard Worker                                   width, height, depth, format, type,
3942*61046927SAndroid Build Coastguard Worker                                   pixels, callerName)) {
3943*61046927SAndroid Build Coastguard Worker          return;   /* error was detected */
3944*61046927SAndroid Build Coastguard Worker       }
3945*61046927SAndroid Build Coastguard Worker    }
3946*61046927SAndroid Build Coastguard Worker 
3947*61046927SAndroid Build Coastguard Worker    /* Must handle special case GL_TEXTURE_CUBE_MAP. */
3948*61046927SAndroid Build Coastguard Worker    if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
3949*61046927SAndroid Build Coastguard Worker       intptr_t imageStride;
3950*61046927SAndroid Build Coastguard Worker 
3951*61046927SAndroid Build Coastguard Worker       /*
3952*61046927SAndroid Build Coastguard Worker        * What do we do if the user created a texture with the following code
3953*61046927SAndroid Build Coastguard Worker        * and then called this function with its handle?
3954*61046927SAndroid Build Coastguard Worker        *
3955*61046927SAndroid Build Coastguard Worker        *    GLuint tex;
3956*61046927SAndroid Build Coastguard Worker        *    glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex);
3957*61046927SAndroid Build Coastguard Worker        *    glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
3958*61046927SAndroid Build Coastguard Worker        *    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...);
3959*61046927SAndroid Build Coastguard Worker        *    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...);
3960*61046927SAndroid Build Coastguard Worker        *    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...);
3961*61046927SAndroid Build Coastguard Worker        *    // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the
3962*61046927SAndroid Build Coastguard Worker        *    // wrong format, or given the wrong size, etc.
3963*61046927SAndroid Build Coastguard Worker        *    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...);
3964*61046927SAndroid Build Coastguard Worker        *    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...);
3965*61046927SAndroid Build Coastguard Worker        *
3966*61046927SAndroid Build Coastguard Worker        * A bug has been filed against the spec for this case.  In the
3967*61046927SAndroid Build Coastguard Worker        * meantime, we will check for cube completeness.
3968*61046927SAndroid Build Coastguard Worker        *
3969*61046927SAndroid Build Coastguard Worker        * According to Section 8.17 Texture Completeness in the OpenGL 4.5
3970*61046927SAndroid Build Coastguard Worker        * Core Profile spec (30.10.2014):
3971*61046927SAndroid Build Coastguard Worker        *    "[A] cube map texture is cube complete if the
3972*61046927SAndroid Build Coastguard Worker        *    following conditions all hold true: The [base level] texture
3973*61046927SAndroid Build Coastguard Worker        *    images of each of the six cube map faces have identical, positive,
3974*61046927SAndroid Build Coastguard Worker        *    and square dimensions. The [base level] images were each specified
3975*61046927SAndroid Build Coastguard Worker        *    with the same internal format."
3976*61046927SAndroid Build Coastguard Worker        *
3977*61046927SAndroid Build Coastguard Worker        * It seems reasonable to check for cube completeness of an arbitrary
3978*61046927SAndroid Build Coastguard Worker        * level here so that the image data has a consistent format and size.
3979*61046927SAndroid Build Coastguard Worker        */
3980*61046927SAndroid Build Coastguard Worker       if (!no_error && !_mesa_cube_level_complete(texObj, level)) {
3981*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
3982*61046927SAndroid Build Coastguard Worker                      "glTextureSubImage%uD(cube map incomplete)",
3983*61046927SAndroid Build Coastguard Worker                      dims);
3984*61046927SAndroid Build Coastguard Worker          return;
3985*61046927SAndroid Build Coastguard Worker       }
3986*61046927SAndroid Build Coastguard Worker 
3987*61046927SAndroid Build Coastguard Worker       imageStride = _mesa_image_image_stride(&ctx->Unpack, width, height,
3988*61046927SAndroid Build Coastguard Worker                                              format, type);
3989*61046927SAndroid Build Coastguard Worker       /* Copy in each face. */
3990*61046927SAndroid Build Coastguard Worker       for (i = zoffset; i < zoffset + depth; ++i) {
3991*61046927SAndroid Build Coastguard Worker          texImage = texObj->Image[i][level];
3992*61046927SAndroid Build Coastguard Worker          assert(texImage);
3993*61046927SAndroid Build Coastguard Worker 
3994*61046927SAndroid Build Coastguard Worker          texture_sub_image(ctx, 3, texObj, texImage, texObj->Target,
3995*61046927SAndroid Build Coastguard Worker                            level, xoffset, yoffset, 0,
3996*61046927SAndroid Build Coastguard Worker                            width, height, 1, format,
3997*61046927SAndroid Build Coastguard Worker                            type, pixels);
3998*61046927SAndroid Build Coastguard Worker          pixels = (GLubyte *) pixels + imageStride;
3999*61046927SAndroid Build Coastguard Worker       }
4000*61046927SAndroid Build Coastguard Worker    }
4001*61046927SAndroid Build Coastguard Worker    else {
4002*61046927SAndroid Build Coastguard Worker       texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
4003*61046927SAndroid Build Coastguard Worker       assert(texImage);
4004*61046927SAndroid Build Coastguard Worker 
4005*61046927SAndroid Build Coastguard Worker       texture_sub_image(ctx, dims, texObj, texImage, texObj->Target,
4006*61046927SAndroid Build Coastguard Worker                         level, xoffset, yoffset, zoffset,
4007*61046927SAndroid Build Coastguard Worker                         width, height, depth, format,
4008*61046927SAndroid Build Coastguard Worker                         type, pixels);
4009*61046927SAndroid Build Coastguard Worker    }
4010*61046927SAndroid Build Coastguard Worker }
4011*61046927SAndroid Build Coastguard Worker 
4012*61046927SAndroid Build Coastguard Worker 
4013*61046927SAndroid Build Coastguard Worker static void
texturesubimage_error(struct gl_context * ctx,GLuint dims,GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels,const char * callerName,bool ext_dsa)4014*61046927SAndroid Build Coastguard Worker texturesubimage_error(struct gl_context *ctx, GLuint dims,
4015*61046927SAndroid Build Coastguard Worker                       GLuint texture, GLenum target, GLint level,
4016*61046927SAndroid Build Coastguard Worker                       GLint xoffset, GLint yoffset, GLint zoffset,
4017*61046927SAndroid Build Coastguard Worker                       GLsizei width, GLsizei height, GLsizei depth,
4018*61046927SAndroid Build Coastguard Worker                       GLenum format, GLenum type, const GLvoid *pixels,
4019*61046927SAndroid Build Coastguard Worker                       const char *callerName, bool ext_dsa)
4020*61046927SAndroid Build Coastguard Worker {
4021*61046927SAndroid Build Coastguard Worker    texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset,
4022*61046927SAndroid Build Coastguard Worker                    zoffset, width, height, depth, format, type, pixels,
4023*61046927SAndroid Build Coastguard Worker                    callerName, false, ext_dsa);
4024*61046927SAndroid Build Coastguard Worker }
4025*61046927SAndroid Build Coastguard Worker 
4026*61046927SAndroid Build Coastguard Worker 
4027*61046927SAndroid Build Coastguard Worker static void
texturesubimage_no_error(struct gl_context * ctx,GLuint dims,GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels,const char * callerName,bool ext_dsa)4028*61046927SAndroid Build Coastguard Worker texturesubimage_no_error(struct gl_context *ctx, GLuint dims,
4029*61046927SAndroid Build Coastguard Worker                          GLuint texture, GLenum target, GLint level,
4030*61046927SAndroid Build Coastguard Worker                          GLint xoffset, GLint yoffset, GLint zoffset,
4031*61046927SAndroid Build Coastguard Worker                          GLsizei width, GLsizei height, GLsizei depth,
4032*61046927SAndroid Build Coastguard Worker                          GLenum format, GLenum type, const GLvoid *pixels,
4033*61046927SAndroid Build Coastguard Worker                          const char *callerName, bool ext_dsa)
4034*61046927SAndroid Build Coastguard Worker {
4035*61046927SAndroid Build Coastguard Worker    texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset,
4036*61046927SAndroid Build Coastguard Worker                    zoffset, width, height, depth, format, type, pixels,
4037*61046927SAndroid Build Coastguard Worker                    callerName, true, ext_dsa);
4038*61046927SAndroid Build Coastguard Worker }
4039*61046927SAndroid Build Coastguard Worker 
4040*61046927SAndroid Build Coastguard Worker 
4041*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexSubImage1D_no_error(GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLenum type,const GLvoid * pixels)4042*61046927SAndroid Build Coastguard Worker _mesa_TexSubImage1D_no_error(GLenum target, GLint level,
4043*61046927SAndroid Build Coastguard Worker                              GLint xoffset, GLsizei width,
4044*61046927SAndroid Build Coastguard Worker                              GLenum format, GLenum type,
4045*61046927SAndroid Build Coastguard Worker                              const GLvoid *pixels)
4046*61046927SAndroid Build Coastguard Worker {
4047*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4048*61046927SAndroid Build Coastguard Worker    texsubimage(ctx, 1, target, level,
4049*61046927SAndroid Build Coastguard Worker                xoffset, 0, 0,
4050*61046927SAndroid Build Coastguard Worker                width, 1, 1,
4051*61046927SAndroid Build Coastguard Worker                format, type, pixels);
4052*61046927SAndroid Build Coastguard Worker }
4053*61046927SAndroid Build Coastguard Worker 
4054*61046927SAndroid Build Coastguard Worker 
4055*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexSubImage1D(GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLenum type,const GLvoid * pixels)4056*61046927SAndroid Build Coastguard Worker _mesa_TexSubImage1D( GLenum target, GLint level,
4057*61046927SAndroid Build Coastguard Worker                      GLint xoffset, GLsizei width,
4058*61046927SAndroid Build Coastguard Worker                      GLenum format, GLenum type,
4059*61046927SAndroid Build Coastguard Worker                      const GLvoid *pixels )
4060*61046927SAndroid Build Coastguard Worker {
4061*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4062*61046927SAndroid Build Coastguard Worker    texsubimage_err(ctx, 1, target, level,
4063*61046927SAndroid Build Coastguard Worker                    xoffset, 0, 0,
4064*61046927SAndroid Build Coastguard Worker                    width, 1, 1,
4065*61046927SAndroid Build Coastguard Worker                    format, type, pixels, "glTexSubImage1D");
4066*61046927SAndroid Build Coastguard Worker }
4067*61046927SAndroid Build Coastguard Worker 
4068*61046927SAndroid Build Coastguard Worker 
4069*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexSubImage2D_no_error(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4070*61046927SAndroid Build Coastguard Worker _mesa_TexSubImage2D_no_error(GLenum target, GLint level,
4071*61046927SAndroid Build Coastguard Worker                              GLint xoffset, GLint yoffset,
4072*61046927SAndroid Build Coastguard Worker                              GLsizei width, GLsizei height,
4073*61046927SAndroid Build Coastguard Worker                              GLenum format, GLenum type,
4074*61046927SAndroid Build Coastguard Worker                              const GLvoid *pixels)
4075*61046927SAndroid Build Coastguard Worker {
4076*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4077*61046927SAndroid Build Coastguard Worker    texsubimage(ctx, 2, target, level,
4078*61046927SAndroid Build Coastguard Worker                xoffset, yoffset, 0,
4079*61046927SAndroid Build Coastguard Worker                width, height, 1,
4080*61046927SAndroid Build Coastguard Worker                format, type, pixels);
4081*61046927SAndroid Build Coastguard Worker }
4082*61046927SAndroid Build Coastguard Worker 
4083*61046927SAndroid Build Coastguard Worker 
4084*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4085*61046927SAndroid Build Coastguard Worker _mesa_TexSubImage2D( GLenum target, GLint level,
4086*61046927SAndroid Build Coastguard Worker                      GLint xoffset, GLint yoffset,
4087*61046927SAndroid Build Coastguard Worker                      GLsizei width, GLsizei height,
4088*61046927SAndroid Build Coastguard Worker                      GLenum format, GLenum type,
4089*61046927SAndroid Build Coastguard Worker                      const GLvoid *pixels )
4090*61046927SAndroid Build Coastguard Worker {
4091*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4092*61046927SAndroid Build Coastguard Worker    texsubimage_err(ctx, 2, target, level,
4093*61046927SAndroid Build Coastguard Worker                    xoffset, yoffset, 0,
4094*61046927SAndroid Build Coastguard Worker                    width, height, 1,
4095*61046927SAndroid Build Coastguard Worker                    format, type, pixels, "glTexSubImage2D");
4096*61046927SAndroid Build Coastguard Worker }
4097*61046927SAndroid Build Coastguard Worker 
4098*61046927SAndroid Build Coastguard Worker 
4099*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexSubImage3D_no_error(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)4100*61046927SAndroid Build Coastguard Worker _mesa_TexSubImage3D_no_error(GLenum target, GLint level,
4101*61046927SAndroid Build Coastguard Worker                              GLint xoffset, GLint yoffset, GLint zoffset,
4102*61046927SAndroid Build Coastguard Worker                              GLsizei width, GLsizei height, GLsizei depth,
4103*61046927SAndroid Build Coastguard Worker                              GLenum format, GLenum type,
4104*61046927SAndroid Build Coastguard Worker                              const GLvoid *pixels)
4105*61046927SAndroid Build Coastguard Worker {
4106*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4107*61046927SAndroid Build Coastguard Worker    texsubimage(ctx, 3, target, level,
4108*61046927SAndroid Build Coastguard Worker                xoffset, yoffset, zoffset,
4109*61046927SAndroid Build Coastguard Worker                width, height, depth,
4110*61046927SAndroid Build Coastguard Worker                format, type, pixels);
4111*61046927SAndroid Build Coastguard Worker }
4112*61046927SAndroid Build Coastguard Worker 
4113*61046927SAndroid Build Coastguard Worker 
4114*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)4115*61046927SAndroid Build Coastguard Worker _mesa_TexSubImage3D( GLenum target, GLint level,
4116*61046927SAndroid Build Coastguard Worker                      GLint xoffset, GLint yoffset, GLint zoffset,
4117*61046927SAndroid Build Coastguard Worker                      GLsizei width, GLsizei height, GLsizei depth,
4118*61046927SAndroid Build Coastguard Worker                      GLenum format, GLenum type,
4119*61046927SAndroid Build Coastguard Worker                      const GLvoid *pixels )
4120*61046927SAndroid Build Coastguard Worker {
4121*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4122*61046927SAndroid Build Coastguard Worker    texsubimage_err(ctx, 3, target, level,
4123*61046927SAndroid Build Coastguard Worker                    xoffset, yoffset, zoffset,
4124*61046927SAndroid Build Coastguard Worker                    width, height, depth,
4125*61046927SAndroid Build Coastguard Worker                    format, type, pixels, "glTexSubImage3D");
4126*61046927SAndroid Build Coastguard Worker }
4127*61046927SAndroid Build Coastguard Worker 
4128*61046927SAndroid Build Coastguard Worker 
4129*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage1D_no_error(GLuint texture,GLint level,GLint xoffset,GLsizei width,GLenum format,GLenum type,const GLvoid * pixels)4130*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset,
4131*61046927SAndroid Build Coastguard Worker                                  GLsizei width, GLenum format, GLenum type,
4132*61046927SAndroid Build Coastguard Worker                                  const GLvoid *pixels)
4133*61046927SAndroid Build Coastguard Worker {
4134*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4135*61046927SAndroid Build Coastguard Worker    texturesubimage_no_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width,
4136*61046927SAndroid Build Coastguard Worker                             1, 1, format, type, pixels, "glTextureSubImage1D",
4137*61046927SAndroid Build Coastguard Worker                             false);
4138*61046927SAndroid Build Coastguard Worker }
4139*61046927SAndroid Build Coastguard Worker 
4140*61046927SAndroid Build Coastguard Worker 
4141*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage1DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLenum type,const GLvoid * pixels)4142*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level,
4143*61046927SAndroid Build Coastguard Worker                         GLint xoffset, GLsizei width,
4144*61046927SAndroid Build Coastguard Worker                         GLenum format, GLenum type,
4145*61046927SAndroid Build Coastguard Worker                         const GLvoid *pixels)
4146*61046927SAndroid Build Coastguard Worker {
4147*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4148*61046927SAndroid Build Coastguard Worker    texturesubimage_error(ctx, 1, texture, target, level, xoffset, 0, 0, width, 1,
4149*61046927SAndroid Build Coastguard Worker                          1, format, type, pixels, "glTextureSubImage1DEXT",
4150*61046927SAndroid Build Coastguard Worker                          false);
4151*61046927SAndroid Build Coastguard Worker }
4152*61046927SAndroid Build Coastguard Worker 
4153*61046927SAndroid Build Coastguard Worker 
4154*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MultiTexSubImage1DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLenum type,const GLvoid * pixels)4155*61046927SAndroid Build Coastguard Worker _mesa_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level,
4156*61046927SAndroid Build Coastguard Worker                             GLint xoffset, GLsizei width,
4157*61046927SAndroid Build Coastguard Worker                             GLenum format, GLenum type,
4158*61046927SAndroid Build Coastguard Worker                             const GLvoid *pixels)
4159*61046927SAndroid Build Coastguard Worker {
4160*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4161*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
4162*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
4163*61046927SAndroid Build Coastguard Worker 
4164*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
4165*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
4166*61046927SAndroid Build Coastguard Worker                                                    false,
4167*61046927SAndroid Build Coastguard Worker                                                    "glMultiTexImage1DEXT");
4168*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
4169*61046927SAndroid Build Coastguard Worker 
4170*61046927SAndroid Build Coastguard Worker    texture_sub_image(ctx, 1, texObj, texImage, target, level,
4171*61046927SAndroid Build Coastguard Worker                      xoffset, 0, 0, width, 1, 1,
4172*61046927SAndroid Build Coastguard Worker                      format, type, pixels);
4173*61046927SAndroid Build Coastguard Worker }
4174*61046927SAndroid Build Coastguard Worker 
4175*61046927SAndroid Build Coastguard Worker 
4176*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage1D(GLuint texture,GLint level,GLint xoffset,GLsizei width,GLenum format,GLenum type,const GLvoid * pixels)4177*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage1D(GLuint texture, GLint level,
4178*61046927SAndroid Build Coastguard Worker                         GLint xoffset, GLsizei width,
4179*61046927SAndroid Build Coastguard Worker                         GLenum format, GLenum type,
4180*61046927SAndroid Build Coastguard Worker                         const GLvoid *pixels)
4181*61046927SAndroid Build Coastguard Worker {
4182*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4183*61046927SAndroid Build Coastguard Worker    texturesubimage_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width, 1,
4184*61046927SAndroid Build Coastguard Worker                          1, format, type, pixels, "glTextureSubImage1D",
4185*61046927SAndroid Build Coastguard Worker                          false);
4186*61046927SAndroid Build Coastguard Worker }
4187*61046927SAndroid Build Coastguard Worker 
4188*61046927SAndroid Build Coastguard Worker 
4189*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage2D_no_error(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4190*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset,
4191*61046927SAndroid Build Coastguard Worker                                  GLint yoffset, GLsizei width, GLsizei height,
4192*61046927SAndroid Build Coastguard Worker                                  GLenum format, GLenum type,
4193*61046927SAndroid Build Coastguard Worker                                  const GLvoid *pixels)
4194*61046927SAndroid Build Coastguard Worker {
4195*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4196*61046927SAndroid Build Coastguard Worker    texturesubimage_no_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0,
4197*61046927SAndroid Build Coastguard Worker                             width, height, 1, format, type, pixels,
4198*61046927SAndroid Build Coastguard Worker                             "glTextureSubImage2D", false);
4199*61046927SAndroid Build Coastguard Worker }
4200*61046927SAndroid Build Coastguard Worker 
4201*61046927SAndroid Build Coastguard Worker 
4202*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage2DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4203*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
4204*61046927SAndroid Build Coastguard Worker                            GLint xoffset, GLint yoffset, GLsizei width,
4205*61046927SAndroid Build Coastguard Worker                            GLsizei height, GLenum format, GLenum type,
4206*61046927SAndroid Build Coastguard Worker                            const GLvoid *pixels)
4207*61046927SAndroid Build Coastguard Worker {
4208*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4209*61046927SAndroid Build Coastguard Worker    texturesubimage_error(ctx, 2, texture, target, level, xoffset, yoffset, 0,
4210*61046927SAndroid Build Coastguard Worker                          width, height, 1, format, type, pixels,
4211*61046927SAndroid Build Coastguard Worker                          "glTextureSubImage2DEXT", true);
4212*61046927SAndroid Build Coastguard Worker }
4213*61046927SAndroid Build Coastguard Worker 
4214*61046927SAndroid Build Coastguard Worker 
4215*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MultiTexSubImage2DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4216*61046927SAndroid Build Coastguard Worker _mesa_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level,
4217*61046927SAndroid Build Coastguard Worker                             GLint xoffset, GLint yoffset, GLsizei width,
4218*61046927SAndroid Build Coastguard Worker                             GLsizei height, GLenum format, GLenum type,
4219*61046927SAndroid Build Coastguard Worker                             const GLvoid *pixels)
4220*61046927SAndroid Build Coastguard Worker {
4221*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4222*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
4223*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
4224*61046927SAndroid Build Coastguard Worker 
4225*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
4226*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
4227*61046927SAndroid Build Coastguard Worker                                                    false,
4228*61046927SAndroid Build Coastguard Worker                                                    "glMultiTexImage2DEXT");
4229*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
4230*61046927SAndroid Build Coastguard Worker 
4231*61046927SAndroid Build Coastguard Worker    texture_sub_image(ctx, 2, texObj, texImage, target, level,
4232*61046927SAndroid Build Coastguard Worker                      xoffset, yoffset, 0, width, height, 1,
4233*61046927SAndroid Build Coastguard Worker                      format, type, pixels);
4234*61046927SAndroid Build Coastguard Worker }
4235*61046927SAndroid Build Coastguard Worker 
4236*61046927SAndroid Build Coastguard Worker 
4237*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage2D(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4238*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage2D(GLuint texture, GLint level,
4239*61046927SAndroid Build Coastguard Worker                         GLint xoffset, GLint yoffset,
4240*61046927SAndroid Build Coastguard Worker                         GLsizei width, GLsizei height,
4241*61046927SAndroid Build Coastguard Worker                         GLenum format, GLenum type,
4242*61046927SAndroid Build Coastguard Worker                         const GLvoid *pixels)
4243*61046927SAndroid Build Coastguard Worker {
4244*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4245*61046927SAndroid Build Coastguard Worker    texturesubimage_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0,
4246*61046927SAndroid Build Coastguard Worker                          width, height, 1, format, type, pixels,
4247*61046927SAndroid Build Coastguard Worker                          "glTextureSubImage2D", false);
4248*61046927SAndroid Build Coastguard Worker }
4249*61046927SAndroid Build Coastguard Worker 
4250*61046927SAndroid Build Coastguard Worker 
4251*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage3D_no_error(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)4252*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset,
4253*61046927SAndroid Build Coastguard Worker                                  GLint yoffset, GLint zoffset, GLsizei width,
4254*61046927SAndroid Build Coastguard Worker                                  GLsizei height, GLsizei depth, GLenum format,
4255*61046927SAndroid Build Coastguard Worker                                  GLenum type, const GLvoid *pixels)
4256*61046927SAndroid Build Coastguard Worker {
4257*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4258*61046927SAndroid Build Coastguard Worker    texturesubimage_no_error(ctx, 3, texture, 0, level, xoffset, yoffset,
4259*61046927SAndroid Build Coastguard Worker                             zoffset, width, height, depth, format, type,
4260*61046927SAndroid Build Coastguard Worker                             pixels, "glTextureSubImage3D", false);
4261*61046927SAndroid Build Coastguard Worker }
4262*61046927SAndroid Build Coastguard Worker 
4263*61046927SAndroid Build Coastguard Worker 
4264*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage3DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)4265*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage3DEXT(GLuint texture, GLenum target, GLint level,
4266*61046927SAndroid Build Coastguard Worker                            GLint xoffset, GLint yoffset, GLint zoffset,
4267*61046927SAndroid Build Coastguard Worker                            GLsizei width, GLsizei height, GLsizei depth,
4268*61046927SAndroid Build Coastguard Worker                            GLenum format, GLenum type, const GLvoid *pixels)
4269*61046927SAndroid Build Coastguard Worker {
4270*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4271*61046927SAndroid Build Coastguard Worker    texturesubimage_error(ctx, 3, texture, target, level, xoffset, yoffset,
4272*61046927SAndroid Build Coastguard Worker                          zoffset, width, height, depth, format, type,
4273*61046927SAndroid Build Coastguard Worker                          pixels, "glTextureSubImage3DEXT", true);
4274*61046927SAndroid Build Coastguard Worker }
4275*61046927SAndroid Build Coastguard Worker 
4276*61046927SAndroid Build Coastguard Worker 
4277*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MultiTexSubImage3DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)4278*61046927SAndroid Build Coastguard Worker _mesa_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level,
4279*61046927SAndroid Build Coastguard Worker                            GLint xoffset, GLint yoffset, GLint zoffset,
4280*61046927SAndroid Build Coastguard Worker                            GLsizei width, GLsizei height, GLsizei depth,
4281*61046927SAndroid Build Coastguard Worker                            GLenum format, GLenum type, const GLvoid *pixels)
4282*61046927SAndroid Build Coastguard Worker {
4283*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4284*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
4285*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
4286*61046927SAndroid Build Coastguard Worker 
4287*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
4288*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
4289*61046927SAndroid Build Coastguard Worker                                                    false,
4290*61046927SAndroid Build Coastguard Worker                                                    "glMultiTexImage3DEXT");
4291*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
4292*61046927SAndroid Build Coastguard Worker 
4293*61046927SAndroid Build Coastguard Worker    texture_sub_image(ctx, 3, texObj, texImage, target, level,
4294*61046927SAndroid Build Coastguard Worker                      xoffset, yoffset, zoffset, width, height, depth,
4295*61046927SAndroid Build Coastguard Worker                      format, type, pixels);
4296*61046927SAndroid Build Coastguard Worker }
4297*61046927SAndroid Build Coastguard Worker 
4298*61046927SAndroid Build Coastguard Worker 
4299*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureSubImage3D(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)4300*61046927SAndroid Build Coastguard Worker _mesa_TextureSubImage3D(GLuint texture, GLint level,
4301*61046927SAndroid Build Coastguard Worker                         GLint xoffset, GLint yoffset, GLint zoffset,
4302*61046927SAndroid Build Coastguard Worker                         GLsizei width, GLsizei height, GLsizei depth,
4303*61046927SAndroid Build Coastguard Worker                         GLenum format, GLenum type,
4304*61046927SAndroid Build Coastguard Worker                         const GLvoid *pixels)
4305*61046927SAndroid Build Coastguard Worker {
4306*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4307*61046927SAndroid Build Coastguard Worker    texturesubimage_error(ctx, 3, texture, 0, level, xoffset, yoffset, zoffset,
4308*61046927SAndroid Build Coastguard Worker                          width, height, depth, format, type, pixels,
4309*61046927SAndroid Build Coastguard Worker                          "glTextureSubImage3D", false);
4310*61046927SAndroid Build Coastguard Worker }
4311*61046927SAndroid Build Coastguard Worker 
4312*61046927SAndroid Build Coastguard Worker 
4313*61046927SAndroid Build Coastguard Worker /**
4314*61046927SAndroid Build Coastguard Worker  * For glCopyTexSubImage, return the source renderbuffer to copy texel data
4315*61046927SAndroid Build Coastguard Worker  * from.  This depends on whether the texture contains color or depth values.
4316*61046927SAndroid Build Coastguard Worker  */
4317*61046927SAndroid Build Coastguard Worker static struct gl_renderbuffer *
get_copy_tex_image_source(struct gl_context * ctx,mesa_format texFormat)4318*61046927SAndroid Build Coastguard Worker get_copy_tex_image_source(struct gl_context *ctx, mesa_format texFormat)
4319*61046927SAndroid Build Coastguard Worker {
4320*61046927SAndroid Build Coastguard Worker    if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) {
4321*61046927SAndroid Build Coastguard Worker       /* reading from depth/stencil buffer */
4322*61046927SAndroid Build Coastguard Worker       return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
4323*61046927SAndroid Build Coastguard Worker    } else if (_mesa_get_format_bits(texFormat, GL_STENCIL_BITS) > 0) {
4324*61046927SAndroid Build Coastguard Worker       return ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
4325*61046927SAndroid Build Coastguard Worker    } else {
4326*61046927SAndroid Build Coastguard Worker       /* copying from color buffer */
4327*61046927SAndroid Build Coastguard Worker       return ctx->ReadBuffer->_ColorReadBuffer;
4328*61046927SAndroid Build Coastguard Worker    }
4329*61046927SAndroid Build Coastguard Worker }
4330*61046927SAndroid Build Coastguard Worker 
4331*61046927SAndroid Build Coastguard Worker 
4332*61046927SAndroid Build Coastguard Worker static void
copytexsubimage_by_slice(struct gl_context * ctx,struct gl_texture_image * texImage,GLuint dims,GLint xoffset,GLint yoffset,GLint zoffset,struct gl_renderbuffer * rb,GLint x,GLint y,GLsizei width,GLsizei height)4333*61046927SAndroid Build Coastguard Worker copytexsubimage_by_slice(struct gl_context *ctx,
4334*61046927SAndroid Build Coastguard Worker                          struct gl_texture_image *texImage,
4335*61046927SAndroid Build Coastguard Worker                          GLuint dims,
4336*61046927SAndroid Build Coastguard Worker                          GLint xoffset, GLint yoffset, GLint zoffset,
4337*61046927SAndroid Build Coastguard Worker                          struct gl_renderbuffer *rb,
4338*61046927SAndroid Build Coastguard Worker                          GLint x, GLint y,
4339*61046927SAndroid Build Coastguard Worker                          GLsizei width, GLsizei height)
4340*61046927SAndroid Build Coastguard Worker {
4341*61046927SAndroid Build Coastguard Worker    if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
4342*61046927SAndroid Build Coastguard Worker       int slice;
4343*61046927SAndroid Build Coastguard Worker 
4344*61046927SAndroid Build Coastguard Worker       /* For 1D arrays, we copy each scanline of the source rectangle into the
4345*61046927SAndroid Build Coastguard Worker        * next array slice.
4346*61046927SAndroid Build Coastguard Worker        */
4347*61046927SAndroid Build Coastguard Worker       assert(zoffset == 0);
4348*61046927SAndroid Build Coastguard Worker 
4349*61046927SAndroid Build Coastguard Worker       for (slice = 0; slice < height; slice++) {
4350*61046927SAndroid Build Coastguard Worker          assert(yoffset + slice < texImage->Height);
4351*61046927SAndroid Build Coastguard Worker          st_CopyTexSubImage(ctx, 2, texImage,
4352*61046927SAndroid Build Coastguard Worker                             xoffset, 0, yoffset + slice,
4353*61046927SAndroid Build Coastguard Worker                             rb, x, y + slice, width, 1);
4354*61046927SAndroid Build Coastguard Worker       }
4355*61046927SAndroid Build Coastguard Worker    } else {
4356*61046927SAndroid Build Coastguard Worker       st_CopyTexSubImage(ctx, dims, texImage,
4357*61046927SAndroid Build Coastguard Worker                          xoffset, yoffset, zoffset,
4358*61046927SAndroid Build Coastguard Worker                          rb, x, y, width, height);
4359*61046927SAndroid Build Coastguard Worker    }
4360*61046927SAndroid Build Coastguard Worker }
4361*61046927SAndroid Build Coastguard Worker 
4362*61046927SAndroid Build Coastguard Worker 
4363*61046927SAndroid Build Coastguard Worker static GLboolean
formats_differ_in_component_sizes(mesa_format f1,mesa_format f2)4364*61046927SAndroid Build Coastguard Worker formats_differ_in_component_sizes(mesa_format f1, mesa_format f2)
4365*61046927SAndroid Build Coastguard Worker {
4366*61046927SAndroid Build Coastguard Worker    GLint f1_r_bits = _mesa_get_format_bits(f1, GL_RED_BITS);
4367*61046927SAndroid Build Coastguard Worker    GLint f1_g_bits = _mesa_get_format_bits(f1, GL_GREEN_BITS);
4368*61046927SAndroid Build Coastguard Worker    GLint f1_b_bits = _mesa_get_format_bits(f1, GL_BLUE_BITS);
4369*61046927SAndroid Build Coastguard Worker    GLint f1_a_bits = _mesa_get_format_bits(f1, GL_ALPHA_BITS);
4370*61046927SAndroid Build Coastguard Worker 
4371*61046927SAndroid Build Coastguard Worker    GLint f2_r_bits = _mesa_get_format_bits(f2, GL_RED_BITS);
4372*61046927SAndroid Build Coastguard Worker    GLint f2_g_bits = _mesa_get_format_bits(f2, GL_GREEN_BITS);
4373*61046927SAndroid Build Coastguard Worker    GLint f2_b_bits = _mesa_get_format_bits(f2, GL_BLUE_BITS);
4374*61046927SAndroid Build Coastguard Worker    GLint f2_a_bits = _mesa_get_format_bits(f2, GL_ALPHA_BITS);
4375*61046927SAndroid Build Coastguard Worker 
4376*61046927SAndroid Build Coastguard Worker    if ((f1_r_bits && f2_r_bits && f1_r_bits != f2_r_bits)
4377*61046927SAndroid Build Coastguard Worker        || (f1_g_bits && f2_g_bits && f1_g_bits != f2_g_bits)
4378*61046927SAndroid Build Coastguard Worker        || (f1_b_bits && f2_b_bits && f1_b_bits != f2_b_bits)
4379*61046927SAndroid Build Coastguard Worker        || (f1_a_bits && f2_a_bits && f1_a_bits != f2_a_bits))
4380*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
4381*61046927SAndroid Build Coastguard Worker 
4382*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
4383*61046927SAndroid Build Coastguard Worker }
4384*61046927SAndroid Build Coastguard Worker 
4385*61046927SAndroid Build Coastguard Worker 
4386*61046927SAndroid Build Coastguard Worker /**
4387*61046927SAndroid Build Coastguard Worker  * Check if the given texture format and size arguments match those
4388*61046927SAndroid Build Coastguard Worker  * of the texture image.
4389*61046927SAndroid Build Coastguard Worker  * \param return true if arguments match, false otherwise.
4390*61046927SAndroid Build Coastguard Worker  */
4391*61046927SAndroid Build Coastguard Worker static bool
can_avoid_reallocation(const struct gl_texture_image * texImage,GLenum internalFormat,mesa_format texFormat,GLsizei width,GLsizei height,GLint border)4392*61046927SAndroid Build Coastguard Worker can_avoid_reallocation(const struct gl_texture_image *texImage,
4393*61046927SAndroid Build Coastguard Worker                        GLenum internalFormat,
4394*61046927SAndroid Build Coastguard Worker                        mesa_format texFormat, GLsizei width,
4395*61046927SAndroid Build Coastguard Worker                        GLsizei height, GLint border)
4396*61046927SAndroid Build Coastguard Worker {
4397*61046927SAndroid Build Coastguard Worker    if (texImage->InternalFormat != internalFormat)
4398*61046927SAndroid Build Coastguard Worker       return false;
4399*61046927SAndroid Build Coastguard Worker    if (texImage->TexFormat != texFormat)
4400*61046927SAndroid Build Coastguard Worker       return false;
4401*61046927SAndroid Build Coastguard Worker    if (texImage->Border != border)
4402*61046927SAndroid Build Coastguard Worker       return false;
4403*61046927SAndroid Build Coastguard Worker    if (texImage->Width2 != width)
4404*61046927SAndroid Build Coastguard Worker       return false;
4405*61046927SAndroid Build Coastguard Worker    if (texImage->Height2 != height)
4406*61046927SAndroid Build Coastguard Worker       return false;
4407*61046927SAndroid Build Coastguard Worker    return true;
4408*61046927SAndroid Build Coastguard Worker }
4409*61046927SAndroid Build Coastguard Worker 
4410*61046927SAndroid Build Coastguard Worker 
4411*61046927SAndroid Build Coastguard Worker /**
4412*61046927SAndroid Build Coastguard Worker  * Implementation for glCopyTex(ture)SubImage1/2/3D() functions.
4413*61046927SAndroid Build Coastguard Worker  */
4414*61046927SAndroid Build Coastguard Worker static void
copy_texture_sub_image(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)4415*61046927SAndroid Build Coastguard Worker copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
4416*61046927SAndroid Build Coastguard Worker                        struct gl_texture_object *texObj,
4417*61046927SAndroid Build Coastguard Worker                        GLenum target, GLint level,
4418*61046927SAndroid Build Coastguard Worker                        GLint xoffset, GLint yoffset, GLint zoffset,
4419*61046927SAndroid Build Coastguard Worker                        GLint x, GLint y, GLsizei width, GLsizei height)
4420*61046927SAndroid Build Coastguard Worker {
4421*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
4422*61046927SAndroid Build Coastguard Worker 
4423*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
4424*61046927SAndroid Build Coastguard Worker 
4425*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
4426*61046927SAndroid Build Coastguard Worker 
4427*61046927SAndroid Build Coastguard Worker    /* If we have a border, offset=-1 is legal.  Bias by border width. */
4428*61046927SAndroid Build Coastguard Worker    switch (dims) {
4429*61046927SAndroid Build Coastguard Worker    case 3:
4430*61046927SAndroid Build Coastguard Worker       if (target != GL_TEXTURE_2D_ARRAY)
4431*61046927SAndroid Build Coastguard Worker          zoffset += texImage->Border;
4432*61046927SAndroid Build Coastguard Worker       FALLTHROUGH;
4433*61046927SAndroid Build Coastguard Worker    case 2:
4434*61046927SAndroid Build Coastguard Worker       if (target != GL_TEXTURE_1D_ARRAY)
4435*61046927SAndroid Build Coastguard Worker          yoffset += texImage->Border;
4436*61046927SAndroid Build Coastguard Worker       FALLTHROUGH;
4437*61046927SAndroid Build Coastguard Worker    case 1:
4438*61046927SAndroid Build Coastguard Worker       xoffset += texImage->Border;
4439*61046927SAndroid Build Coastguard Worker    }
4440*61046927SAndroid Build Coastguard Worker 
4441*61046927SAndroid Build Coastguard Worker    if (ctx->Const.NoClippingOnCopyTex ||
4442*61046927SAndroid Build Coastguard Worker        _mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
4443*61046927SAndroid Build Coastguard Worker                                   &width, &height)) {
4444*61046927SAndroid Build Coastguard Worker       struct gl_renderbuffer *srcRb =
4445*61046927SAndroid Build Coastguard Worker          get_copy_tex_image_source(ctx, texImage->TexFormat);
4446*61046927SAndroid Build Coastguard Worker 
4447*61046927SAndroid Build Coastguard Worker       copytexsubimage_by_slice(ctx, texImage, dims, xoffset, yoffset, zoffset,
4448*61046927SAndroid Build Coastguard Worker                                srcRb, x, y, width, height);
4449*61046927SAndroid Build Coastguard Worker 
4450*61046927SAndroid Build Coastguard Worker       check_gen_mipmap(ctx, target, texObj, level);
4451*61046927SAndroid Build Coastguard Worker 
4452*61046927SAndroid Build Coastguard Worker       /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
4453*61046927SAndroid Build Coastguard Worker        * the texel data, not the texture format, size, etc.
4454*61046927SAndroid Build Coastguard Worker        */
4455*61046927SAndroid Build Coastguard Worker    }
4456*61046927SAndroid Build Coastguard Worker 
4457*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
4458*61046927SAndroid Build Coastguard Worker }
4459*61046927SAndroid Build Coastguard Worker 
4460*61046927SAndroid Build Coastguard Worker 
4461*61046927SAndroid Build Coastguard Worker static void
copy_texture_sub_image_err(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height,const char * caller)4462*61046927SAndroid Build Coastguard Worker copy_texture_sub_image_err(struct gl_context *ctx, GLuint dims,
4463*61046927SAndroid Build Coastguard Worker                            struct gl_texture_object *texObj,
4464*61046927SAndroid Build Coastguard Worker                            GLenum target, GLint level,
4465*61046927SAndroid Build Coastguard Worker                            GLint xoffset, GLint yoffset, GLint zoffset,
4466*61046927SAndroid Build Coastguard Worker                            GLint x, GLint y, GLsizei width, GLsizei height,
4467*61046927SAndroid Build Coastguard Worker                            const char *caller)
4468*61046927SAndroid Build Coastguard Worker {
4469*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
4470*61046927SAndroid Build Coastguard Worker 
4471*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
4472*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller,
4473*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target),
4474*61046927SAndroid Build Coastguard Worker                   level, xoffset, yoffset, zoffset, x, y, width, height);
4475*61046927SAndroid Build Coastguard Worker 
4476*61046927SAndroid Build Coastguard Worker    _mesa_update_pixel(ctx);
4477*61046927SAndroid Build Coastguard Worker 
4478*61046927SAndroid Build Coastguard Worker    if (ctx->NewState & _NEW_BUFFERS)
4479*61046927SAndroid Build Coastguard Worker       _mesa_update_state(ctx);
4480*61046927SAndroid Build Coastguard Worker 
4481*61046927SAndroid Build Coastguard Worker    if (copytexsubimage_error_check(ctx, dims, texObj, target, level,
4482*61046927SAndroid Build Coastguard Worker                                    xoffset, yoffset, zoffset,
4483*61046927SAndroid Build Coastguard Worker                                    width, height, caller)) {
4484*61046927SAndroid Build Coastguard Worker       return;
4485*61046927SAndroid Build Coastguard Worker    }
4486*61046927SAndroid Build Coastguard Worker 
4487*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset,
4488*61046927SAndroid Build Coastguard Worker                           zoffset, x, y, width, height);
4489*61046927SAndroid Build Coastguard Worker }
4490*61046927SAndroid Build Coastguard Worker 
4491*61046927SAndroid Build Coastguard Worker 
4492*61046927SAndroid Build Coastguard Worker static void
copy_texture_sub_image_no_error(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)4493*61046927SAndroid Build Coastguard Worker copy_texture_sub_image_no_error(struct gl_context *ctx, GLuint dims,
4494*61046927SAndroid Build Coastguard Worker                                 struct gl_texture_object *texObj,
4495*61046927SAndroid Build Coastguard Worker                                 GLenum target, GLint level,
4496*61046927SAndroid Build Coastguard Worker                                 GLint xoffset, GLint yoffset, GLint zoffset,
4497*61046927SAndroid Build Coastguard Worker                                 GLint x, GLint y, GLsizei width, GLsizei height)
4498*61046927SAndroid Build Coastguard Worker {
4499*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
4500*61046927SAndroid Build Coastguard Worker 
4501*61046927SAndroid Build Coastguard Worker    _mesa_update_pixel(ctx);
4502*61046927SAndroid Build Coastguard Worker 
4503*61046927SAndroid Build Coastguard Worker    if (ctx->NewState & _NEW_BUFFERS)
4504*61046927SAndroid Build Coastguard Worker       _mesa_update_state(ctx);
4505*61046927SAndroid Build Coastguard Worker 
4506*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset,
4507*61046927SAndroid Build Coastguard Worker                           zoffset, x, y, width, height);
4508*61046927SAndroid Build Coastguard Worker }
4509*61046927SAndroid Build Coastguard Worker 
4510*61046927SAndroid Build Coastguard Worker 
4511*61046927SAndroid Build Coastguard Worker /**
4512*61046927SAndroid Build Coastguard Worker  * Implement the glCopyTexImage1/2D() functions.
4513*61046927SAndroid Build Coastguard Worker  */
4514*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
copyteximage(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border,bool no_error)4515*61046927SAndroid Build Coastguard Worker copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texObj,
4516*61046927SAndroid Build Coastguard Worker              GLenum target, GLint level, GLenum internalFormat,
4517*61046927SAndroid Build Coastguard Worker              GLint x, GLint y, GLsizei width, GLsizei height, GLint border,
4518*61046927SAndroid Build Coastguard Worker              bool no_error)
4519*61046927SAndroid Build Coastguard Worker {
4520*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
4521*61046927SAndroid Build Coastguard Worker    mesa_format texFormat;
4522*61046927SAndroid Build Coastguard Worker 
4523*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
4524*61046927SAndroid Build Coastguard Worker 
4525*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
4526*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
4527*61046927SAndroid Build Coastguard Worker                   dims,
4528*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target), level,
4529*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(internalFormat),
4530*61046927SAndroid Build Coastguard Worker                   x, y, width, height, border);
4531*61046927SAndroid Build Coastguard Worker 
4532*61046927SAndroid Build Coastguard Worker    _mesa_update_pixel(ctx);
4533*61046927SAndroid Build Coastguard Worker 
4534*61046927SAndroid Build Coastguard Worker    if (ctx->NewState & _NEW_BUFFERS)
4535*61046927SAndroid Build Coastguard Worker       _mesa_update_state(ctx);
4536*61046927SAndroid Build Coastguard Worker 
4537*61046927SAndroid Build Coastguard Worker    /* check target */
4538*61046927SAndroid Build Coastguard Worker    if (!no_error && !legal_texsubimage_target(ctx, dims, target, false)) {
4539*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
4540*61046927SAndroid Build Coastguard Worker                   dims, _mesa_enum_to_string(target));
4541*61046927SAndroid Build Coastguard Worker       return;
4542*61046927SAndroid Build Coastguard Worker    }
4543*61046927SAndroid Build Coastguard Worker 
4544*61046927SAndroid Build Coastguard Worker    if (!texObj)
4545*61046927SAndroid Build Coastguard Worker       texObj = _mesa_get_current_tex_object(ctx, target);
4546*61046927SAndroid Build Coastguard Worker 
4547*61046927SAndroid Build Coastguard Worker    if (!no_error) {
4548*61046927SAndroid Build Coastguard Worker       if (copytexture_error_check(ctx, dims, target, texObj, level,
4549*61046927SAndroid Build Coastguard Worker                                   internalFormat, border))
4550*61046927SAndroid Build Coastguard Worker          return;
4551*61046927SAndroid Build Coastguard Worker 
4552*61046927SAndroid Build Coastguard Worker       if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height,
4553*61046927SAndroid Build Coastguard Worker                                           1, border)) {
4554*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE,
4555*61046927SAndroid Build Coastguard Worker                      "glCopyTexImage%uD(invalid width=%d or height=%d)",
4556*61046927SAndroid Build Coastguard Worker                      dims, width, height);
4557*61046927SAndroid Build Coastguard Worker          return;
4558*61046927SAndroid Build Coastguard Worker       }
4559*61046927SAndroid Build Coastguard Worker    }
4560*61046927SAndroid Build Coastguard Worker 
4561*61046927SAndroid Build Coastguard Worker    assert(texObj);
4562*61046927SAndroid Build Coastguard Worker 
4563*61046927SAndroid Build Coastguard Worker    texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
4564*61046927SAndroid Build Coastguard Worker                                            internalFormat, GL_NONE, GL_NONE);
4565*61046927SAndroid Build Coastguard Worker 
4566*61046927SAndroid Build Coastguard Worker    /* First check if reallocating the texture buffer can be avoided.
4567*61046927SAndroid Build Coastguard Worker     * Without the realloc the copy can be 20x faster.
4568*61046927SAndroid Build Coastguard Worker     */
4569*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
4570*61046927SAndroid Build Coastguard Worker    {
4571*61046927SAndroid Build Coastguard Worker       texImage = _mesa_select_tex_image(texObj, target, level);
4572*61046927SAndroid Build Coastguard Worker       if (texImage && can_avoid_reallocation(texImage, internalFormat, texFormat,
4573*61046927SAndroid Build Coastguard Worker                                              width, height, border)) {
4574*61046927SAndroid Build Coastguard Worker          _mesa_unlock_texture(ctx, texObj);
4575*61046927SAndroid Build Coastguard Worker          if (no_error) {
4576*61046927SAndroid Build Coastguard Worker             copy_texture_sub_image_no_error(ctx, dims, texObj, target, level, 0,
4577*61046927SAndroid Build Coastguard Worker                                             0, 0, x, y, width, height);
4578*61046927SAndroid Build Coastguard Worker          } else {
4579*61046927SAndroid Build Coastguard Worker             copy_texture_sub_image_err(ctx, dims, texObj, target, level, 0, 0,
4580*61046927SAndroid Build Coastguard Worker                                        0, x, y, width, height,"CopyTexImage");
4581*61046927SAndroid Build Coastguard Worker          }
4582*61046927SAndroid Build Coastguard Worker          return;
4583*61046927SAndroid Build Coastguard Worker       }
4584*61046927SAndroid Build Coastguard Worker    }
4585*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
4586*61046927SAndroid Build Coastguard Worker    _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_LOW, "glCopyTexImage "
4587*61046927SAndroid Build Coastguard Worker                     "can't avoid reallocating texture storage\n");
4588*61046927SAndroid Build Coastguard Worker 
4589*61046927SAndroid Build Coastguard Worker    if (!no_error && _mesa_is_gles3(ctx)) {
4590*61046927SAndroid Build Coastguard Worker       struct gl_renderbuffer *rb =
4591*61046927SAndroid Build Coastguard Worker          _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
4592*61046927SAndroid Build Coastguard Worker 
4593*61046927SAndroid Build Coastguard Worker       if (_mesa_is_enum_format_unsized(internalFormat)) {
4594*61046927SAndroid Build Coastguard Worker       /* Conversion from GL_RGB10_A2 source buffer format is not allowed in
4595*61046927SAndroid Build Coastguard Worker        * OpenGL ES 3.0. Khronos bug# 9807.
4596*61046927SAndroid Build Coastguard Worker        */
4597*61046927SAndroid Build Coastguard Worker          if (rb->InternalFormat == GL_RGB10_A2) {
4598*61046927SAndroid Build Coastguard Worker                _mesa_error(ctx, GL_INVALID_OPERATION,
4599*61046927SAndroid Build Coastguard Worker                            "glCopyTexImage%uD(Reading from GL_RGB10_A2 buffer"
4600*61046927SAndroid Build Coastguard Worker                            " and writing to unsized internal format)", dims);
4601*61046927SAndroid Build Coastguard Worker                return;
4602*61046927SAndroid Build Coastguard Worker          }
4603*61046927SAndroid Build Coastguard Worker       }
4604*61046927SAndroid Build Coastguard Worker       else {
4605*61046927SAndroid Build Coastguard Worker          /* From Page 139 of OpenGL ES 3.0 spec:
4606*61046927SAndroid Build Coastguard Worker          *    "If internalformat is sized, the internal format of the new texel
4607*61046927SAndroid Build Coastguard Worker          *    array is internalformat, and this is also the new texel array’s
4608*61046927SAndroid Build Coastguard Worker          *    effective internal format. If the component sizes of internalformat
4609*61046927SAndroid Build Coastguard Worker          *    do not exactly match the corresponding component sizes of the source
4610*61046927SAndroid Build Coastguard Worker          *    buffer’s effective internal format, described below, an
4611*61046927SAndroid Build Coastguard Worker          *    INVALID_OPERATION error is generated. If internalformat is unsized,
4612*61046927SAndroid Build Coastguard Worker          *    the internal format of the new texel array is the effective internal
4613*61046927SAndroid Build Coastguard Worker          *    format of the source buffer, and this is also the new texel array’s
4614*61046927SAndroid Build Coastguard Worker          *    effective internal format.
4615*61046927SAndroid Build Coastguard Worker          */
4616*61046927SAndroid Build Coastguard Worker          enum pipe_format rb_format = st_choose_format(ctx->st, rb->InternalFormat,
4617*61046927SAndroid Build Coastguard Worker                                                        GL_NONE, GL_NONE,
4618*61046927SAndroid Build Coastguard Worker                                                        PIPE_TEXTURE_2D, 0, 0, 0,
4619*61046927SAndroid Build Coastguard Worker                                                        false, false);
4620*61046927SAndroid Build Coastguard Worker          enum pipe_format new_format = st_choose_format(ctx->st, internalFormat,
4621*61046927SAndroid Build Coastguard Worker                                                         GL_NONE, GL_NONE,
4622*61046927SAndroid Build Coastguard Worker                                                         PIPE_TEXTURE_2D, 0, 0, 0,
4623*61046927SAndroid Build Coastguard Worker                                                         false, false);
4624*61046927SAndroid Build Coastguard Worker          /* this comparison must be done on the API format, not the driver format */
4625*61046927SAndroid Build Coastguard Worker          if (formats_differ_in_component_sizes (new_format, rb_format)) {
4626*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_OPERATION,
4627*61046927SAndroid Build Coastguard Worker                         "glCopyTexImage%uD(component size changed in"
4628*61046927SAndroid Build Coastguard Worker                         " internal format)", dims);
4629*61046927SAndroid Build Coastguard Worker             return;
4630*61046927SAndroid Build Coastguard Worker          }
4631*61046927SAndroid Build Coastguard Worker       }
4632*61046927SAndroid Build Coastguard Worker    }
4633*61046927SAndroid Build Coastguard Worker 
4634*61046927SAndroid Build Coastguard Worker    assert(texFormat != MESA_FORMAT_NONE);
4635*61046927SAndroid Build Coastguard Worker 
4636*61046927SAndroid Build Coastguard Worker    if (!st_TestProxyTexImage(ctx, proxy_target(target),
4637*61046927SAndroid Build Coastguard Worker                              0, level, texFormat, 1,
4638*61046927SAndroid Build Coastguard Worker                              width, height, 1)) {
4639*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_OUT_OF_MEMORY,
4640*61046927SAndroid Build Coastguard Worker                   "glCopyTexImage%uD(image too large)", dims);
4641*61046927SAndroid Build Coastguard Worker       return;
4642*61046927SAndroid Build Coastguard Worker    }
4643*61046927SAndroid Build Coastguard Worker 
4644*61046927SAndroid Build Coastguard Worker    if (border) {
4645*61046927SAndroid Build Coastguard Worker       x += border;
4646*61046927SAndroid Build Coastguard Worker       width -= border * 2;
4647*61046927SAndroid Build Coastguard Worker       if (dims == 2) {
4648*61046927SAndroid Build Coastguard Worker          y += border;
4649*61046927SAndroid Build Coastguard Worker          height -= border * 2;
4650*61046927SAndroid Build Coastguard Worker       }
4651*61046927SAndroid Build Coastguard Worker       border = 0;
4652*61046927SAndroid Build Coastguard Worker    }
4653*61046927SAndroid Build Coastguard Worker 
4654*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
4655*61046927SAndroid Build Coastguard Worker    {
4656*61046927SAndroid Build Coastguard Worker       texObj->External = GL_FALSE;
4657*61046927SAndroid Build Coastguard Worker       texImage = _mesa_get_tex_image(ctx, texObj, target, level);
4658*61046927SAndroid Build Coastguard Worker 
4659*61046927SAndroid Build Coastguard Worker       if (!texImage) {
4660*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
4661*61046927SAndroid Build Coastguard Worker       }
4662*61046927SAndroid Build Coastguard Worker       else {
4663*61046927SAndroid Build Coastguard Worker          GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0;
4664*61046927SAndroid Build Coastguard Worker          const GLuint face = _mesa_tex_target_to_face(target);
4665*61046927SAndroid Build Coastguard Worker 
4666*61046927SAndroid Build Coastguard Worker          /* Free old texture image */
4667*61046927SAndroid Build Coastguard Worker          st_FreeTextureImageBuffer(ctx, texImage);
4668*61046927SAndroid Build Coastguard Worker 
4669*61046927SAndroid Build Coastguard Worker          _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
4670*61046927SAndroid Build Coastguard Worker                                     border, internalFormat, texFormat);
4671*61046927SAndroid Build Coastguard Worker 
4672*61046927SAndroid Build Coastguard Worker          if (width && height) {
4673*61046927SAndroid Build Coastguard Worker             /* Allocate texture memory (no pixel data yet) */
4674*61046927SAndroid Build Coastguard Worker             st_AllocTextureImageBuffer(ctx, texImage);
4675*61046927SAndroid Build Coastguard Worker 
4676*61046927SAndroid Build Coastguard Worker             if (ctx->Const.NoClippingOnCopyTex ||
4677*61046927SAndroid Build Coastguard Worker                 _mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
4678*61046927SAndroid Build Coastguard Worker                                            &width, &height)) {
4679*61046927SAndroid Build Coastguard Worker                struct gl_renderbuffer *srcRb =
4680*61046927SAndroid Build Coastguard Worker                   get_copy_tex_image_source(ctx, texImage->TexFormat);
4681*61046927SAndroid Build Coastguard Worker 
4682*61046927SAndroid Build Coastguard Worker                copytexsubimage_by_slice(ctx, texImage, dims,
4683*61046927SAndroid Build Coastguard Worker                                         dstX, dstY, dstZ,
4684*61046927SAndroid Build Coastguard Worker                                         srcRb, srcX, srcY, width, height);
4685*61046927SAndroid Build Coastguard Worker             }
4686*61046927SAndroid Build Coastguard Worker 
4687*61046927SAndroid Build Coastguard Worker             check_gen_mipmap(ctx, target, texObj, level);
4688*61046927SAndroid Build Coastguard Worker          }
4689*61046927SAndroid Build Coastguard Worker 
4690*61046927SAndroid Build Coastguard Worker          _mesa_update_fbo_texture(ctx, texObj, face, level);
4691*61046927SAndroid Build Coastguard Worker 
4692*61046927SAndroid Build Coastguard Worker          _mesa_dirty_texobj(ctx, texObj);
4693*61046927SAndroid Build Coastguard Worker          _mesa_update_texture_object_swizzle(ctx, texObj);
4694*61046927SAndroid Build Coastguard Worker       }
4695*61046927SAndroid Build Coastguard Worker    }
4696*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
4697*61046927SAndroid Build Coastguard Worker }
4698*61046927SAndroid Build Coastguard Worker 
4699*61046927SAndroid Build Coastguard Worker 
4700*61046927SAndroid Build Coastguard Worker static void
copyteximage_err(struct gl_context * ctx,GLuint dims,GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)4701*61046927SAndroid Build Coastguard Worker copyteximage_err(struct gl_context *ctx, GLuint dims,
4702*61046927SAndroid Build Coastguard Worker                  GLenum target,
4703*61046927SAndroid Build Coastguard Worker                  GLint level, GLenum internalFormat, GLint x, GLint y,
4704*61046927SAndroid Build Coastguard Worker                  GLsizei width, GLsizei height, GLint border)
4705*61046927SAndroid Build Coastguard Worker {
4706*61046927SAndroid Build Coastguard Worker    copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height,
4707*61046927SAndroid Build Coastguard Worker                 border, false);
4708*61046927SAndroid Build Coastguard Worker }
4709*61046927SAndroid Build Coastguard Worker 
4710*61046927SAndroid Build Coastguard Worker 
4711*61046927SAndroid Build Coastguard Worker static void
copyteximage_no_error(struct gl_context * ctx,GLuint dims,GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)4712*61046927SAndroid Build Coastguard Worker copyteximage_no_error(struct gl_context *ctx, GLuint dims, GLenum target,
4713*61046927SAndroid Build Coastguard Worker                       GLint level, GLenum internalFormat, GLint x, GLint y,
4714*61046927SAndroid Build Coastguard Worker                       GLsizei width, GLsizei height, GLint border)
4715*61046927SAndroid Build Coastguard Worker {
4716*61046927SAndroid Build Coastguard Worker    copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height,
4717*61046927SAndroid Build Coastguard Worker                 border, true);
4718*61046927SAndroid Build Coastguard Worker }
4719*61046927SAndroid Build Coastguard Worker 
4720*61046927SAndroid Build Coastguard Worker 
4721*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexImage1D(GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLint border)4722*61046927SAndroid Build Coastguard Worker _mesa_CopyTexImage1D( GLenum target, GLint level,
4723*61046927SAndroid Build Coastguard Worker                       GLenum internalFormat,
4724*61046927SAndroid Build Coastguard Worker                       GLint x, GLint y,
4725*61046927SAndroid Build Coastguard Worker                       GLsizei width, GLint border )
4726*61046927SAndroid Build Coastguard Worker {
4727*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4728*61046927SAndroid Build Coastguard Worker    copyteximage_err(ctx, 1, target, level, internalFormat, x, y, width, 1,
4729*61046927SAndroid Build Coastguard Worker                     border);
4730*61046927SAndroid Build Coastguard Worker }
4731*61046927SAndroid Build Coastguard Worker 
4732*61046927SAndroid Build Coastguard Worker 
4733*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureImage1DEXT(GLuint texture,GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLint border)4734*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureImage1DEXT( GLuint texture, GLenum target, GLint level,
4735*61046927SAndroid Build Coastguard Worker                              GLenum internalFormat,
4736*61046927SAndroid Build Coastguard Worker                              GLint x, GLint y,
4737*61046927SAndroid Build Coastguard Worker                              GLsizei width, GLint border )
4738*61046927SAndroid Build Coastguard Worker {
4739*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4740*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj =
4741*61046927SAndroid Build Coastguard Worker       _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
4742*61046927SAndroid Build Coastguard Worker                                      "glCopyTextureImage1DEXT");
4743*61046927SAndroid Build Coastguard Worker    if (!texObj)
4744*61046927SAndroid Build Coastguard Worker       return;
4745*61046927SAndroid Build Coastguard Worker    copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1,
4746*61046927SAndroid Build Coastguard Worker                 border, false);
4747*61046927SAndroid Build Coastguard Worker }
4748*61046927SAndroid Build Coastguard Worker 
4749*61046927SAndroid Build Coastguard Worker 
4750*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyMultiTexImage1DEXT(GLenum texunit,GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLint border)4751*61046927SAndroid Build Coastguard Worker _mesa_CopyMultiTexImage1DEXT( GLenum texunit, GLenum target, GLint level,
4752*61046927SAndroid Build Coastguard Worker                               GLenum internalFormat,
4753*61046927SAndroid Build Coastguard Worker                               GLint x, GLint y,
4754*61046927SAndroid Build Coastguard Worker                               GLsizei width, GLint border )
4755*61046927SAndroid Build Coastguard Worker {
4756*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4757*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj =
4758*61046927SAndroid Build Coastguard Worker       _mesa_get_texobj_by_target_and_texunit(ctx, target,
4759*61046927SAndroid Build Coastguard Worker                                              texunit - GL_TEXTURE0,
4760*61046927SAndroid Build Coastguard Worker                                              false,
4761*61046927SAndroid Build Coastguard Worker                                              "glCopyMultiTexImage1DEXT");
4762*61046927SAndroid Build Coastguard Worker    if (!texObj)
4763*61046927SAndroid Build Coastguard Worker       return;
4764*61046927SAndroid Build Coastguard Worker    copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1,
4765*61046927SAndroid Build Coastguard Worker                 border, false);
4766*61046927SAndroid Build Coastguard Worker }
4767*61046927SAndroid Build Coastguard Worker 
4768*61046927SAndroid Build Coastguard Worker 
4769*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexImage2D(GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)4770*61046927SAndroid Build Coastguard Worker _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
4771*61046927SAndroid Build Coastguard Worker                       GLint x, GLint y, GLsizei width, GLsizei height,
4772*61046927SAndroid Build Coastguard Worker                       GLint border )
4773*61046927SAndroid Build Coastguard Worker {
4774*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4775*61046927SAndroid Build Coastguard Worker    copyteximage_err(ctx, 2, target, level, internalFormat,
4776*61046927SAndroid Build Coastguard Worker                     x, y, width, height, border);
4777*61046927SAndroid Build Coastguard Worker }
4778*61046927SAndroid Build Coastguard Worker 
4779*61046927SAndroid Build Coastguard Worker 
4780*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureImage2DEXT(GLuint texture,GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)4781*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureImage2DEXT( GLuint texture, GLenum target, GLint level,
4782*61046927SAndroid Build Coastguard Worker                              GLenum internalFormat,
4783*61046927SAndroid Build Coastguard Worker                              GLint x, GLint y,
4784*61046927SAndroid Build Coastguard Worker                              GLsizei width, GLsizei height,
4785*61046927SAndroid Build Coastguard Worker                              GLint border )
4786*61046927SAndroid Build Coastguard Worker {
4787*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4788*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj =
4789*61046927SAndroid Build Coastguard Worker       _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
4790*61046927SAndroid Build Coastguard Worker                                      "glCopyTextureImage2DEXT");
4791*61046927SAndroid Build Coastguard Worker    if (!texObj)
4792*61046927SAndroid Build Coastguard Worker       return;
4793*61046927SAndroid Build Coastguard Worker    copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height,
4794*61046927SAndroid Build Coastguard Worker                 border, false);
4795*61046927SAndroid Build Coastguard Worker }
4796*61046927SAndroid Build Coastguard Worker 
4797*61046927SAndroid Build Coastguard Worker 
4798*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyMultiTexImage2DEXT(GLenum texunit,GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)4799*61046927SAndroid Build Coastguard Worker _mesa_CopyMultiTexImage2DEXT( GLenum texunit, GLenum target, GLint level,
4800*61046927SAndroid Build Coastguard Worker                               GLenum internalFormat,
4801*61046927SAndroid Build Coastguard Worker                               GLint x, GLint y,
4802*61046927SAndroid Build Coastguard Worker                               GLsizei width, GLsizei height, GLint border )
4803*61046927SAndroid Build Coastguard Worker {
4804*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4805*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj =
4806*61046927SAndroid Build Coastguard Worker       _mesa_get_texobj_by_target_and_texunit(ctx, target,
4807*61046927SAndroid Build Coastguard Worker                                              texunit - GL_TEXTURE0,
4808*61046927SAndroid Build Coastguard Worker                                              false,
4809*61046927SAndroid Build Coastguard Worker                                              "glCopyMultiTexImage2DEXT");
4810*61046927SAndroid Build Coastguard Worker    if (!texObj)
4811*61046927SAndroid Build Coastguard Worker       return;
4812*61046927SAndroid Build Coastguard Worker    copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height,
4813*61046927SAndroid Build Coastguard Worker                 border, false);
4814*61046927SAndroid Build Coastguard Worker }
4815*61046927SAndroid Build Coastguard Worker 
4816*61046927SAndroid Build Coastguard Worker 
4817*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexImage1D_no_error(GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLint border)4818*61046927SAndroid Build Coastguard Worker _mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat,
4819*61046927SAndroid Build Coastguard Worker                               GLint x, GLint y, GLsizei width, GLint border)
4820*61046927SAndroid Build Coastguard Worker {
4821*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4822*61046927SAndroid Build Coastguard Worker    copyteximage_no_error(ctx, 1, target, level, internalFormat, x, y, width, 1,
4823*61046927SAndroid Build Coastguard Worker                          border);
4824*61046927SAndroid Build Coastguard Worker }
4825*61046927SAndroid Build Coastguard Worker 
4826*61046927SAndroid Build Coastguard Worker 
4827*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexImage2D_no_error(GLenum target,GLint level,GLenum internalFormat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)4828*61046927SAndroid Build Coastguard Worker _mesa_CopyTexImage2D_no_error(GLenum target, GLint level, GLenum internalFormat,
4829*61046927SAndroid Build Coastguard Worker                               GLint x, GLint y, GLsizei width, GLsizei height,
4830*61046927SAndroid Build Coastguard Worker                               GLint border)
4831*61046927SAndroid Build Coastguard Worker {
4832*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4833*61046927SAndroid Build Coastguard Worker    copyteximage_no_error(ctx, 2, target, level, internalFormat,
4834*61046927SAndroid Build Coastguard Worker                          x, y, width, height, border);
4835*61046927SAndroid Build Coastguard Worker }
4836*61046927SAndroid Build Coastguard Worker 
4837*61046927SAndroid Build Coastguard Worker 
4838*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexSubImage1D(GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsizei width)4839*61046927SAndroid Build Coastguard Worker _mesa_CopyTexSubImage1D(GLenum target, GLint level,
4840*61046927SAndroid Build Coastguard Worker                         GLint xoffset, GLint x, GLint y, GLsizei width)
4841*61046927SAndroid Build Coastguard Worker {
4842*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
4843*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTexSubImage1D";
4844*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4845*61046927SAndroid Build Coastguard Worker 
4846*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). Target must be checked prior to
4847*61046927SAndroid Build Coastguard Worker     * calling _mesa_get_current_tex_object.
4848*61046927SAndroid Build Coastguard Worker     */
4849*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 1, target, false)) {
4850*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
4851*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target));
4852*61046927SAndroid Build Coastguard Worker       return;
4853*61046927SAndroid Build Coastguard Worker    }
4854*61046927SAndroid Build Coastguard Worker 
4855*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_current_tex_object(ctx, target);
4856*61046927SAndroid Build Coastguard Worker    if (!texObj)
4857*61046927SAndroid Build Coastguard Worker       return;
4858*61046927SAndroid Build Coastguard Worker 
4859*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 1, texObj, target, level, xoffset, 0, 0,
4860*61046927SAndroid Build Coastguard Worker                               x, y, width, 1, self);
4861*61046927SAndroid Build Coastguard Worker }
4862*61046927SAndroid Build Coastguard Worker 
4863*61046927SAndroid Build Coastguard Worker 
4864*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)4865*61046927SAndroid Build Coastguard Worker _mesa_CopyTexSubImage2D(GLenum target, GLint level,
4866*61046927SAndroid Build Coastguard Worker                         GLint xoffset, GLint yoffset,
4867*61046927SAndroid Build Coastguard Worker                         GLint x, GLint y, GLsizei width, GLsizei height)
4868*61046927SAndroid Build Coastguard Worker {
4869*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
4870*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTexSubImage2D";
4871*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4872*61046927SAndroid Build Coastguard Worker 
4873*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). Target must be checked prior to
4874*61046927SAndroid Build Coastguard Worker     * calling _mesa_get_current_tex_object.
4875*61046927SAndroid Build Coastguard Worker     */
4876*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 2, target, false)) {
4877*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
4878*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target));
4879*61046927SAndroid Build Coastguard Worker       return;
4880*61046927SAndroid Build Coastguard Worker    }
4881*61046927SAndroid Build Coastguard Worker 
4882*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_current_tex_object(ctx, target);
4883*61046927SAndroid Build Coastguard Worker    if (!texObj)
4884*61046927SAndroid Build Coastguard Worker       return;
4885*61046927SAndroid Build Coastguard Worker 
4886*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 2, texObj, target, level, xoffset, yoffset,
4887*61046927SAndroid Build Coastguard Worker                               0, x, y, width, height, self);
4888*61046927SAndroid Build Coastguard Worker }
4889*61046927SAndroid Build Coastguard Worker 
4890*61046927SAndroid Build Coastguard Worker 
4891*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)4892*61046927SAndroid Build Coastguard Worker _mesa_CopyTexSubImage3D(GLenum target, GLint level,
4893*61046927SAndroid Build Coastguard Worker                         GLint xoffset, GLint yoffset, GLint zoffset,
4894*61046927SAndroid Build Coastguard Worker                         GLint x, GLint y, GLsizei width, GLsizei height)
4895*61046927SAndroid Build Coastguard Worker {
4896*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
4897*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTexSubImage3D";
4898*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4899*61046927SAndroid Build Coastguard Worker 
4900*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). Target must be checked prior to
4901*61046927SAndroid Build Coastguard Worker     * calling _mesa_get_current_tex_object.
4902*61046927SAndroid Build Coastguard Worker     */
4903*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 3, target, false)) {
4904*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
4905*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target));
4906*61046927SAndroid Build Coastguard Worker       return;
4907*61046927SAndroid Build Coastguard Worker    }
4908*61046927SAndroid Build Coastguard Worker 
4909*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_current_tex_object(ctx, target);
4910*61046927SAndroid Build Coastguard Worker    if (!texObj)
4911*61046927SAndroid Build Coastguard Worker       return;
4912*61046927SAndroid Build Coastguard Worker 
4913*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 3, texObj, target, level, xoffset, yoffset,
4914*61046927SAndroid Build Coastguard Worker                               zoffset, x, y, width, height, self);
4915*61046927SAndroid Build Coastguard Worker }
4916*61046927SAndroid Build Coastguard Worker 
4917*61046927SAndroid Build Coastguard Worker 
4918*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage1D(GLuint texture,GLint level,GLint xoffset,GLint x,GLint y,GLsizei width)4919*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage1D(GLuint texture, GLint level,
4920*61046927SAndroid Build Coastguard Worker                             GLint xoffset, GLint x, GLint y, GLsizei width)
4921*61046927SAndroid Build Coastguard Worker {
4922*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
4923*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTextureSubImage1D";
4924*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4925*61046927SAndroid Build Coastguard Worker 
4926*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture, self);
4927*61046927SAndroid Build Coastguard Worker    if (!texObj)
4928*61046927SAndroid Build Coastguard Worker       return;
4929*61046927SAndroid Build Coastguard Worker 
4930*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). */
4931*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) {
4932*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
4933*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texObj->Target));
4934*61046927SAndroid Build Coastguard Worker       return;
4935*61046927SAndroid Build Coastguard Worker    }
4936*61046927SAndroid Build Coastguard Worker 
4937*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0,
4938*61046927SAndroid Build Coastguard Worker                               0, x, y, width, 1, self);
4939*61046927SAndroid Build Coastguard Worker }
4940*61046927SAndroid Build Coastguard Worker 
4941*61046927SAndroid Build Coastguard Worker 
4942*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage1DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsizei width)4943*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level,
4944*61046927SAndroid Build Coastguard Worker                                GLint xoffset, GLint x, GLint y, GLsizei width)
4945*61046927SAndroid Build Coastguard Worker {
4946*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
4947*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTextureSubImage1DEXT";
4948*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4949*61046927SAndroid Build Coastguard Worker 
4950*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
4951*61046927SAndroid Build Coastguard Worker                                            self);
4952*61046927SAndroid Build Coastguard Worker    if (!texObj)
4953*61046927SAndroid Build Coastguard Worker       return;
4954*61046927SAndroid Build Coastguard Worker 
4955*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). */
4956*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) {
4957*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
4958*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texObj->Target));
4959*61046927SAndroid Build Coastguard Worker       return;
4960*61046927SAndroid Build Coastguard Worker    }
4961*61046927SAndroid Build Coastguard Worker 
4962*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0,
4963*61046927SAndroid Build Coastguard Worker                               0, x, y, width, 1, self);
4964*61046927SAndroid Build Coastguard Worker }
4965*61046927SAndroid Build Coastguard Worker 
4966*61046927SAndroid Build Coastguard Worker 
4967*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyMultiTexSubImage1DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsizei width)4968*61046927SAndroid Build Coastguard Worker _mesa_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level,
4969*61046927SAndroid Build Coastguard Worker                                 GLint xoffset, GLint x, GLint y, GLsizei width)
4970*61046927SAndroid Build Coastguard Worker {
4971*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
4972*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyMultiTexSubImage1DEXT";
4973*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4974*61046927SAndroid Build Coastguard Worker 
4975*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
4976*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
4977*61046927SAndroid Build Coastguard Worker                                                    false, self);
4978*61046927SAndroid Build Coastguard Worker    if (!texObj)
4979*61046927SAndroid Build Coastguard Worker       return;
4980*61046927SAndroid Build Coastguard Worker 
4981*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0,
4982*61046927SAndroid Build Coastguard Worker                               0, x, y, width, 1, self);
4983*61046927SAndroid Build Coastguard Worker }
4984*61046927SAndroid Build Coastguard Worker 
4985*61046927SAndroid Build Coastguard Worker 
4986*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage2D(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)4987*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage2D(GLuint texture, GLint level,
4988*61046927SAndroid Build Coastguard Worker                             GLint xoffset, GLint yoffset,
4989*61046927SAndroid Build Coastguard Worker                             GLint x, GLint y, GLsizei width, GLsizei height)
4990*61046927SAndroid Build Coastguard Worker {
4991*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
4992*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTextureSubImage2D";
4993*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
4994*61046927SAndroid Build Coastguard Worker 
4995*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture, self);
4996*61046927SAndroid Build Coastguard Worker    if (!texObj)
4997*61046927SAndroid Build Coastguard Worker       return;
4998*61046927SAndroid Build Coastguard Worker 
4999*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). */
5000*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) {
5001*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
5002*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texObj->Target));
5003*61046927SAndroid Build Coastguard Worker       return;
5004*61046927SAndroid Build Coastguard Worker    }
5005*61046927SAndroid Build Coastguard Worker 
5006*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset,
5007*61046927SAndroid Build Coastguard Worker                               yoffset, 0, x, y, width, height, self);
5008*61046927SAndroid Build Coastguard Worker }
5009*61046927SAndroid Build Coastguard Worker 
5010*61046927SAndroid Build Coastguard Worker 
5011*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage2DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)5012*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
5013*61046927SAndroid Build Coastguard Worker                                GLint xoffset, GLint yoffset,
5014*61046927SAndroid Build Coastguard Worker                                GLint x, GLint y, GLsizei width, GLsizei height)
5015*61046927SAndroid Build Coastguard Worker {
5016*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
5017*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTextureSubImage2DEXT";
5018*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5019*61046927SAndroid Build Coastguard Worker 
5020*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self);
5021*61046927SAndroid Build Coastguard Worker    if (!texObj)
5022*61046927SAndroid Build Coastguard Worker       return;
5023*61046927SAndroid Build Coastguard Worker 
5024*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). */
5025*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) {
5026*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
5027*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texObj->Target));
5028*61046927SAndroid Build Coastguard Worker       return;
5029*61046927SAndroid Build Coastguard Worker    }
5030*61046927SAndroid Build Coastguard Worker 
5031*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset,
5032*61046927SAndroid Build Coastguard Worker                               yoffset, 0, x, y, width, height, self);
5033*61046927SAndroid Build Coastguard Worker }
5034*61046927SAndroid Build Coastguard Worker 
5035*61046927SAndroid Build Coastguard Worker 
5036*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyMultiTexSubImage2DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)5037*61046927SAndroid Build Coastguard Worker _mesa_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level,
5038*61046927SAndroid Build Coastguard Worker                                GLint xoffset, GLint yoffset,
5039*61046927SAndroid Build Coastguard Worker                                GLint x, GLint y, GLsizei width, GLsizei height)
5040*61046927SAndroid Build Coastguard Worker {
5041*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
5042*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyMultiTexSubImage2DEXT";
5043*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5044*61046927SAndroid Build Coastguard Worker 
5045*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5046*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
5047*61046927SAndroid Build Coastguard Worker                                                    false, self);
5048*61046927SAndroid Build Coastguard Worker    if (!texObj)
5049*61046927SAndroid Build Coastguard Worker       return;
5050*61046927SAndroid Build Coastguard Worker 
5051*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset,
5052*61046927SAndroid Build Coastguard Worker                               yoffset, 0, x, y, width, height, self);
5053*61046927SAndroid Build Coastguard Worker }
5054*61046927SAndroid Build Coastguard Worker 
5055*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage3D(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)5056*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage3D(GLuint texture, GLint level,
5057*61046927SAndroid Build Coastguard Worker                             GLint xoffset, GLint yoffset, GLint zoffset,
5058*61046927SAndroid Build Coastguard Worker                             GLint x, GLint y, GLsizei width, GLsizei height)
5059*61046927SAndroid Build Coastguard Worker {
5060*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
5061*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTextureSubImage3D";
5062*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5063*61046927SAndroid Build Coastguard Worker 
5064*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture, self);
5065*61046927SAndroid Build Coastguard Worker    if (!texObj)
5066*61046927SAndroid Build Coastguard Worker       return;
5067*61046927SAndroid Build Coastguard Worker 
5068*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). */
5069*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) {
5070*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
5071*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texObj->Target));
5072*61046927SAndroid Build Coastguard Worker       return;
5073*61046927SAndroid Build Coastguard Worker    }
5074*61046927SAndroid Build Coastguard Worker 
5075*61046927SAndroid Build Coastguard Worker    if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
5076*61046927SAndroid Build Coastguard Worker       /* Act like CopyTexSubImage2D */
5077*61046927SAndroid Build Coastguard Worker       copy_texture_sub_image_err(ctx, 2, texObj,
5078*61046927SAndroid Build Coastguard Worker                                 GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
5079*61046927SAndroid Build Coastguard Worker                                 level, xoffset, yoffset, 0, x, y, width, height,
5080*61046927SAndroid Build Coastguard Worker                                 self);
5081*61046927SAndroid Build Coastguard Worker    }
5082*61046927SAndroid Build Coastguard Worker    else
5083*61046927SAndroid Build Coastguard Worker       copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset,
5084*61046927SAndroid Build Coastguard Worker                                  yoffset, zoffset, x, y, width, height, self);
5085*61046927SAndroid Build Coastguard Worker }
5086*61046927SAndroid Build Coastguard Worker 
5087*61046927SAndroid Build Coastguard Worker 
5088*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage3DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)5089*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level,
5090*61046927SAndroid Build Coastguard Worker                                GLint xoffset, GLint yoffset, GLint zoffset,
5091*61046927SAndroid Build Coastguard Worker                                GLint x, GLint y, GLsizei width, GLsizei height)
5092*61046927SAndroid Build Coastguard Worker {
5093*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
5094*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyTextureSubImage3D";
5095*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5096*61046927SAndroid Build Coastguard Worker 
5097*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self);
5098*61046927SAndroid Build Coastguard Worker    if (!texObj)
5099*61046927SAndroid Build Coastguard Worker       return;
5100*61046927SAndroid Build Coastguard Worker 
5101*61046927SAndroid Build Coastguard Worker    /* Check target (proxies not allowed). */
5102*61046927SAndroid Build Coastguard Worker    if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) {
5103*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
5104*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(texObj->Target));
5105*61046927SAndroid Build Coastguard Worker       return;
5106*61046927SAndroid Build Coastguard Worker    }
5107*61046927SAndroid Build Coastguard Worker 
5108*61046927SAndroid Build Coastguard Worker    if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
5109*61046927SAndroid Build Coastguard Worker       /* Act like CopyTexSubImage2D */
5110*61046927SAndroid Build Coastguard Worker       copy_texture_sub_image_err(ctx, 2, texObj,
5111*61046927SAndroid Build Coastguard Worker                                 GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
5112*61046927SAndroid Build Coastguard Worker                                 level, xoffset, yoffset, 0, x, y, width, height,
5113*61046927SAndroid Build Coastguard Worker                                 self);
5114*61046927SAndroid Build Coastguard Worker    }
5115*61046927SAndroid Build Coastguard Worker    else
5116*61046927SAndroid Build Coastguard Worker       copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset,
5117*61046927SAndroid Build Coastguard Worker                                  yoffset, zoffset, x, y, width, height, self);
5118*61046927SAndroid Build Coastguard Worker }
5119*61046927SAndroid Build Coastguard Worker 
5120*61046927SAndroid Build Coastguard Worker 
5121*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyMultiTexSubImage3DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)5122*61046927SAndroid Build Coastguard Worker _mesa_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level,
5123*61046927SAndroid Build Coastguard Worker                                 GLint xoffset, GLint yoffset, GLint zoffset,
5124*61046927SAndroid Build Coastguard Worker                                 GLint x, GLint y, GLsizei width, GLsizei height)
5125*61046927SAndroid Build Coastguard Worker {
5126*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj;
5127*61046927SAndroid Build Coastguard Worker    const char *self = "glCopyMultiTexSubImage3D";
5128*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5129*61046927SAndroid Build Coastguard Worker 
5130*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5131*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
5132*61046927SAndroid Build Coastguard Worker                                                    false, self);
5133*61046927SAndroid Build Coastguard Worker    if (!texObj)
5134*61046927SAndroid Build Coastguard Worker       return;
5135*61046927SAndroid Build Coastguard Worker 
5136*61046927SAndroid Build Coastguard Worker    if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
5137*61046927SAndroid Build Coastguard Worker       /* Act like CopyTexSubImage2D */
5138*61046927SAndroid Build Coastguard Worker       copy_texture_sub_image_err(ctx, 2, texObj,
5139*61046927SAndroid Build Coastguard Worker                                 GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
5140*61046927SAndroid Build Coastguard Worker                                 level, xoffset, yoffset, 0, x, y, width, height,
5141*61046927SAndroid Build Coastguard Worker                                 self);
5142*61046927SAndroid Build Coastguard Worker    }
5143*61046927SAndroid Build Coastguard Worker    else
5144*61046927SAndroid Build Coastguard Worker       copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset,
5145*61046927SAndroid Build Coastguard Worker                                  yoffset, zoffset, x, y, width, height, self);
5146*61046927SAndroid Build Coastguard Worker }
5147*61046927SAndroid Build Coastguard Worker 
5148*61046927SAndroid Build Coastguard Worker 
5149*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexSubImage1D_no_error(GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsizei width)5150*61046927SAndroid Build Coastguard Worker _mesa_CopyTexSubImage1D_no_error(GLenum target, GLint level, GLint xoffset,
5151*61046927SAndroid Build Coastguard Worker                                  GLint x, GLint y, GLsizei width)
5152*61046927SAndroid Build Coastguard Worker {
5153*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5154*61046927SAndroid Build Coastguard Worker 
5155*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
5156*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_no_error(ctx, 1, texObj, target, level, xoffset, 0, 0,
5157*61046927SAndroid Build Coastguard Worker                                    x, y, width, 1);
5158*61046927SAndroid Build Coastguard Worker }
5159*61046927SAndroid Build Coastguard Worker 
5160*61046927SAndroid Build Coastguard Worker 
5161*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexSubImage2D_no_error(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)5162*61046927SAndroid Build Coastguard Worker _mesa_CopyTexSubImage2D_no_error(GLenum target, GLint level, GLint xoffset,
5163*61046927SAndroid Build Coastguard Worker                                  GLint yoffset, GLint x, GLint y, GLsizei width,
5164*61046927SAndroid Build Coastguard Worker                                  GLsizei height)
5165*61046927SAndroid Build Coastguard Worker {
5166*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5167*61046927SAndroid Build Coastguard Worker 
5168*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
5169*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_no_error(ctx, 2, texObj, target, level, xoffset,
5170*61046927SAndroid Build Coastguard Worker                                    yoffset, 0, x, y, width, height);
5171*61046927SAndroid Build Coastguard Worker }
5172*61046927SAndroid Build Coastguard Worker 
5173*61046927SAndroid Build Coastguard Worker 
5174*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTexSubImage3D_no_error(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)5175*61046927SAndroid Build Coastguard Worker _mesa_CopyTexSubImage3D_no_error(GLenum target, GLint level, GLint xoffset,
5176*61046927SAndroid Build Coastguard Worker                                  GLint yoffset, GLint zoffset, GLint x, GLint y,
5177*61046927SAndroid Build Coastguard Worker                                  GLsizei width, GLsizei height)
5178*61046927SAndroid Build Coastguard Worker {
5179*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5180*61046927SAndroid Build Coastguard Worker 
5181*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
5182*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_no_error(ctx, 3, texObj, target, level, xoffset,
5183*61046927SAndroid Build Coastguard Worker                                    yoffset, zoffset, x, y, width, height);
5184*61046927SAndroid Build Coastguard Worker }
5185*61046927SAndroid Build Coastguard Worker 
5186*61046927SAndroid Build Coastguard Worker 
5187*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage1D_no_error(GLuint texture,GLint level,GLint xoffset,GLint x,GLint y,GLsizei width)5188*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset,
5189*61046927SAndroid Build Coastguard Worker                                      GLint x, GLint y, GLsizei width)
5190*61046927SAndroid Build Coastguard Worker {
5191*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5192*61046927SAndroid Build Coastguard Worker 
5193*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
5194*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_no_error(ctx, 1, texObj, texObj->Target, level,
5195*61046927SAndroid Build Coastguard Worker                                    xoffset, 0, 0, x, y, width, 1);
5196*61046927SAndroid Build Coastguard Worker }
5197*61046927SAndroid Build Coastguard Worker 
5198*61046927SAndroid Build Coastguard Worker 
5199*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage2D_no_error(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)5200*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset,
5201*61046927SAndroid Build Coastguard Worker                                      GLint yoffset, GLint x, GLint y,
5202*61046927SAndroid Build Coastguard Worker                                      GLsizei width, GLsizei height)
5203*61046927SAndroid Build Coastguard Worker {
5204*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5205*61046927SAndroid Build Coastguard Worker 
5206*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
5207*61046927SAndroid Build Coastguard Worker    copy_texture_sub_image_no_error(ctx, 2, texObj, texObj->Target, level,
5208*61046927SAndroid Build Coastguard Worker                                    xoffset, yoffset, 0, x, y, width, height);
5209*61046927SAndroid Build Coastguard Worker }
5210*61046927SAndroid Build Coastguard Worker 
5211*61046927SAndroid Build Coastguard Worker 
5212*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyTextureSubImage3D_no_error(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)5213*61046927SAndroid Build Coastguard Worker _mesa_CopyTextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset,
5214*61046927SAndroid Build Coastguard Worker                                      GLint yoffset, GLint zoffset, GLint x,
5215*61046927SAndroid Build Coastguard Worker                                      GLint y, GLsizei width, GLsizei height)
5216*61046927SAndroid Build Coastguard Worker {
5217*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5218*61046927SAndroid Build Coastguard Worker 
5219*61046927SAndroid Build Coastguard Worker    struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
5220*61046927SAndroid Build Coastguard Worker    if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
5221*61046927SAndroid Build Coastguard Worker       /* Act like CopyTexSubImage2D */
5222*61046927SAndroid Build Coastguard Worker       copy_texture_sub_image_no_error(ctx, 2, texObj,
5223*61046927SAndroid Build Coastguard Worker                                       GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
5224*61046927SAndroid Build Coastguard Worker                                       level, xoffset, yoffset, 0, x, y, width,
5225*61046927SAndroid Build Coastguard Worker                                       height);
5226*61046927SAndroid Build Coastguard Worker    }
5227*61046927SAndroid Build Coastguard Worker    else
5228*61046927SAndroid Build Coastguard Worker       copy_texture_sub_image_no_error(ctx, 3, texObj, texObj->Target, level,
5229*61046927SAndroid Build Coastguard Worker                                       xoffset, yoffset, zoffset, x, y, width,
5230*61046927SAndroid Build Coastguard Worker                                       height);
5231*61046927SAndroid Build Coastguard Worker }
5232*61046927SAndroid Build Coastguard Worker 
5233*61046927SAndroid Build Coastguard Worker 
5234*61046927SAndroid Build Coastguard Worker static bool
check_clear_tex_image(struct gl_context * ctx,const char * function,struct gl_texture_image * texImage,GLenum format,GLenum type,const void * data,GLubyte * clearValue)5235*61046927SAndroid Build Coastguard Worker check_clear_tex_image(struct gl_context *ctx,
5236*61046927SAndroid Build Coastguard Worker                       const char *function,
5237*61046927SAndroid Build Coastguard Worker                       struct gl_texture_image *texImage,
5238*61046927SAndroid Build Coastguard Worker                       GLenum format, GLenum type,
5239*61046927SAndroid Build Coastguard Worker                       const void *data,
5240*61046927SAndroid Build Coastguard Worker                       GLubyte *clearValue)
5241*61046927SAndroid Build Coastguard Worker {
5242*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj = texImage->TexObject;
5243*61046927SAndroid Build Coastguard Worker    static const GLubyte zeroData[MAX_PIXEL_BYTES];
5244*61046927SAndroid Build Coastguard Worker    GLenum internalFormat = texImage->InternalFormat;
5245*61046927SAndroid Build Coastguard Worker    GLenum err;
5246*61046927SAndroid Build Coastguard Worker 
5247*61046927SAndroid Build Coastguard Worker    if (texObj->Target == GL_TEXTURE_BUFFER) {
5248*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
5249*61046927SAndroid Build Coastguard Worker                   "%s(buffer texture)", function);
5250*61046927SAndroid Build Coastguard Worker       return false;
5251*61046927SAndroid Build Coastguard Worker    }
5252*61046927SAndroid Build Coastguard Worker 
5253*61046927SAndroid Build Coastguard Worker    if (_mesa_is_compressed_format(ctx, internalFormat)) {
5254*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
5255*61046927SAndroid Build Coastguard Worker                   "%s(compressed texture)", function);
5256*61046927SAndroid Build Coastguard Worker       return false;
5257*61046927SAndroid Build Coastguard Worker    }
5258*61046927SAndroid Build Coastguard Worker 
5259*61046927SAndroid Build Coastguard Worker    err = _mesa_error_check_format_and_type(ctx, format, type);
5260*61046927SAndroid Build Coastguard Worker    if (err != GL_NO_ERROR) {
5261*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, err,
5262*61046927SAndroid Build Coastguard Worker                   "%s(incompatible format = %s, type = %s)",
5263*61046927SAndroid Build Coastguard Worker                   function,
5264*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(format),
5265*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(type));
5266*61046927SAndroid Build Coastguard Worker       return false;
5267*61046927SAndroid Build Coastguard Worker    }
5268*61046927SAndroid Build Coastguard Worker 
5269*61046927SAndroid Build Coastguard Worker    /* make sure internal format and format basically agree */
5270*61046927SAndroid Build Coastguard Worker    if (!texture_formats_agree(internalFormat, format)) {
5271*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
5272*61046927SAndroid Build Coastguard Worker                   "%s(incompatible internalFormat = %s, format = %s)",
5273*61046927SAndroid Build Coastguard Worker                   function,
5274*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(internalFormat),
5275*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(format));
5276*61046927SAndroid Build Coastguard Worker       return false;
5277*61046927SAndroid Build Coastguard Worker    }
5278*61046927SAndroid Build Coastguard Worker 
5279*61046927SAndroid Build Coastguard Worker    if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
5280*61046927SAndroid Build Coastguard Worker       /* both source and dest must be integer-valued, or neither */
5281*61046927SAndroid Build Coastguard Worker       if (_mesa_is_format_integer_color(texImage->TexFormat) !=
5282*61046927SAndroid Build Coastguard Worker           _mesa_is_enum_format_integer(format)) {
5283*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
5284*61046927SAndroid Build Coastguard Worker                      "%s(integer/non-integer format mismatch)",
5285*61046927SAndroid Build Coastguard Worker                      function);
5286*61046927SAndroid Build Coastguard Worker          return false;
5287*61046927SAndroid Build Coastguard Worker       }
5288*61046927SAndroid Build Coastguard Worker    }
5289*61046927SAndroid Build Coastguard Worker 
5290*61046927SAndroid Build Coastguard Worker    if (!_mesa_texstore(ctx,
5291*61046927SAndroid Build Coastguard Worker                        1, /* dims */
5292*61046927SAndroid Build Coastguard Worker                        texImage->_BaseFormat,
5293*61046927SAndroid Build Coastguard Worker                        texImage->TexFormat,
5294*61046927SAndroid Build Coastguard Worker                        0, /* dstRowStride */
5295*61046927SAndroid Build Coastguard Worker                        &clearValue,
5296*61046927SAndroid Build Coastguard Worker                        1, 1, 1, /* srcWidth/Height/Depth */
5297*61046927SAndroid Build Coastguard Worker                        format, type,
5298*61046927SAndroid Build Coastguard Worker                        data ? data : zeroData,
5299*61046927SAndroid Build Coastguard Worker                        &ctx->DefaultPacking)) {
5300*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function);
5301*61046927SAndroid Build Coastguard Worker       return false;
5302*61046927SAndroid Build Coastguard Worker    }
5303*61046927SAndroid Build Coastguard Worker 
5304*61046927SAndroid Build Coastguard Worker    return true;
5305*61046927SAndroid Build Coastguard Worker }
5306*61046927SAndroid Build Coastguard Worker 
5307*61046927SAndroid Build Coastguard Worker 
5308*61046927SAndroid Build Coastguard Worker static struct gl_texture_object *
get_tex_obj_for_clear(struct gl_context * ctx,const char * function,GLuint texture)5309*61046927SAndroid Build Coastguard Worker get_tex_obj_for_clear(struct gl_context *ctx,
5310*61046927SAndroid Build Coastguard Worker                       const char *function,
5311*61046927SAndroid Build Coastguard Worker                       GLuint texture)
5312*61046927SAndroid Build Coastguard Worker {
5313*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
5314*61046927SAndroid Build Coastguard Worker 
5315*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture, function);
5316*61046927SAndroid Build Coastguard Worker    if (!texObj)
5317*61046927SAndroid Build Coastguard Worker       return NULL;
5318*61046927SAndroid Build Coastguard Worker 
5319*61046927SAndroid Build Coastguard Worker    if (texObj->Target == 0) {
5320*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unbound tex)", function);
5321*61046927SAndroid Build Coastguard Worker       return NULL;
5322*61046927SAndroid Build Coastguard Worker    }
5323*61046927SAndroid Build Coastguard Worker 
5324*61046927SAndroid Build Coastguard Worker    return texObj;
5325*61046927SAndroid Build Coastguard Worker }
5326*61046927SAndroid Build Coastguard Worker 
5327*61046927SAndroid Build Coastguard Worker 
5328*61046927SAndroid Build Coastguard Worker /**
5329*61046927SAndroid Build Coastguard Worker  * For clearing cube textures, the zoffset and depth parameters indicate
5330*61046927SAndroid Build Coastguard Worker  * which cube map faces are to be cleared.  This is the one case where we
5331*61046927SAndroid Build Coastguard Worker  * need to be concerned with multiple gl_texture_images.  This function
5332*61046927SAndroid Build Coastguard Worker  * returns the array of texture images to clear for cube maps, or one
5333*61046927SAndroid Build Coastguard Worker  * texture image otherwise.
5334*61046927SAndroid Build Coastguard Worker  * \return number of texture images, 0 for error, 6 for cube, 1 otherwise.
5335*61046927SAndroid Build Coastguard Worker  */
5336*61046927SAndroid Build Coastguard Worker static int
get_tex_images_for_clear(struct gl_context * ctx,const char * function,struct gl_texture_object * texObj,GLint level,struct gl_texture_image ** texImages)5337*61046927SAndroid Build Coastguard Worker get_tex_images_for_clear(struct gl_context *ctx,
5338*61046927SAndroid Build Coastguard Worker                          const char *function,
5339*61046927SAndroid Build Coastguard Worker                          struct gl_texture_object *texObj,
5340*61046927SAndroid Build Coastguard Worker                          GLint level,
5341*61046927SAndroid Build Coastguard Worker                          struct gl_texture_image **texImages)
5342*61046927SAndroid Build Coastguard Worker {
5343*61046927SAndroid Build Coastguard Worker    GLenum target;
5344*61046927SAndroid Build Coastguard Worker    int numFaces, i;
5345*61046927SAndroid Build Coastguard Worker 
5346*61046927SAndroid Build Coastguard Worker    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
5347*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
5348*61046927SAndroid Build Coastguard Worker       return 0;
5349*61046927SAndroid Build Coastguard Worker    }
5350*61046927SAndroid Build Coastguard Worker 
5351*61046927SAndroid Build Coastguard Worker    if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
5352*61046927SAndroid Build Coastguard Worker       target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
5353*61046927SAndroid Build Coastguard Worker       numFaces = MAX_FACES;
5354*61046927SAndroid Build Coastguard Worker    }
5355*61046927SAndroid Build Coastguard Worker    else {
5356*61046927SAndroid Build Coastguard Worker       target = texObj->Target;
5357*61046927SAndroid Build Coastguard Worker       numFaces = 1;
5358*61046927SAndroid Build Coastguard Worker    }
5359*61046927SAndroid Build Coastguard Worker 
5360*61046927SAndroid Build Coastguard Worker    for (i = 0; i < numFaces; i++) {
5361*61046927SAndroid Build Coastguard Worker       texImages[i] = _mesa_select_tex_image(texObj, target + i, level);
5362*61046927SAndroid Build Coastguard Worker       if (texImages[i] == NULL) {
5363*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
5364*61046927SAndroid Build Coastguard Worker          return 0;
5365*61046927SAndroid Build Coastguard Worker       }
5366*61046927SAndroid Build Coastguard Worker    }
5367*61046927SAndroid Build Coastguard Worker 
5368*61046927SAndroid Build Coastguard Worker    return numFaces;
5369*61046927SAndroid Build Coastguard Worker }
5370*61046927SAndroid Build Coastguard Worker 
5371*61046927SAndroid Build Coastguard Worker 
5372*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearTexSubImage(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * data)5373*61046927SAndroid Build Coastguard Worker _mesa_ClearTexSubImage(GLuint texture, GLint level,
5374*61046927SAndroid Build Coastguard Worker                        GLint xoffset, GLint yoffset, GLint zoffset,
5375*61046927SAndroid Build Coastguard Worker                        GLsizei width, GLsizei height, GLsizei depth,
5376*61046927SAndroid Build Coastguard Worker                        GLenum format, GLenum type, const void *data)
5377*61046927SAndroid Build Coastguard Worker {
5378*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5379*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
5380*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImages[MAX_FACES];
5381*61046927SAndroid Build Coastguard Worker    GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES];
5382*61046927SAndroid Build Coastguard Worker    int i, numImages;
5383*61046927SAndroid Build Coastguard Worker    int minDepth, maxDepth;
5384*61046927SAndroid Build Coastguard Worker 
5385*61046927SAndroid Build Coastguard Worker    texObj = get_tex_obj_for_clear(ctx, "glClearTexSubImage", texture);
5386*61046927SAndroid Build Coastguard Worker 
5387*61046927SAndroid Build Coastguard Worker    if (texObj == NULL)
5388*61046927SAndroid Build Coastguard Worker       return;
5389*61046927SAndroid Build Coastguard Worker 
5390*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
5391*61046927SAndroid Build Coastguard Worker 
5392*61046927SAndroid Build Coastguard Worker    numImages = get_tex_images_for_clear(ctx, "glClearTexSubImage",
5393*61046927SAndroid Build Coastguard Worker                                         texObj, level, texImages);
5394*61046927SAndroid Build Coastguard Worker    if (numImages == 0)
5395*61046927SAndroid Build Coastguard Worker       goto out;
5396*61046927SAndroid Build Coastguard Worker 
5397*61046927SAndroid Build Coastguard Worker    if (numImages == 1) {
5398*61046927SAndroid Build Coastguard Worker       minDepth = -(int) texImages[0]->Border;
5399*61046927SAndroid Build Coastguard Worker       maxDepth = texImages[0]->Depth;
5400*61046927SAndroid Build Coastguard Worker    } else {
5401*61046927SAndroid Build Coastguard Worker       assert(numImages == MAX_FACES);
5402*61046927SAndroid Build Coastguard Worker       minDepth = 0;
5403*61046927SAndroid Build Coastguard Worker       maxDepth = numImages;
5404*61046927SAndroid Build Coastguard Worker    }
5405*61046927SAndroid Build Coastguard Worker 
5406*61046927SAndroid Build Coastguard Worker    if (xoffset < -(GLint) texImages[0]->Border ||
5407*61046927SAndroid Build Coastguard Worker        yoffset < -(GLint) texImages[0]->Border ||
5408*61046927SAndroid Build Coastguard Worker        zoffset < minDepth ||
5409*61046927SAndroid Build Coastguard Worker        width < 0 ||
5410*61046927SAndroid Build Coastguard Worker        height < 0 ||
5411*61046927SAndroid Build Coastguard Worker        depth < 0 ||
5412*61046927SAndroid Build Coastguard Worker        xoffset + width > texImages[0]->Width ||
5413*61046927SAndroid Build Coastguard Worker        yoffset + height > texImages[0]->Height ||
5414*61046927SAndroid Build Coastguard Worker        zoffset + depth > maxDepth) {
5415*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
5416*61046927SAndroid Build Coastguard Worker                   "glClearSubTexImage(invalid dimensions)");
5417*61046927SAndroid Build Coastguard Worker       goto out;
5418*61046927SAndroid Build Coastguard Worker    }
5419*61046927SAndroid Build Coastguard Worker 
5420*61046927SAndroid Build Coastguard Worker    if (numImages == 1) {
5421*61046927SAndroid Build Coastguard Worker       if (check_clear_tex_image(ctx, "glClearTexSubImage", texImages[0],
5422*61046927SAndroid Build Coastguard Worker                                 format, type, data, clearValue[0])) {
5423*61046927SAndroid Build Coastguard Worker          st_ClearTexSubImage(ctx,
5424*61046927SAndroid Build Coastguard Worker                              texImages[0],
5425*61046927SAndroid Build Coastguard Worker                              xoffset, yoffset, zoffset,
5426*61046927SAndroid Build Coastguard Worker                              width, height, depth,
5427*61046927SAndroid Build Coastguard Worker                              data ? clearValue[0] : NULL);
5428*61046927SAndroid Build Coastguard Worker       }
5429*61046927SAndroid Build Coastguard Worker    } else {
5430*61046927SAndroid Build Coastguard Worker       /* loop over cube face images */
5431*61046927SAndroid Build Coastguard Worker       for (i = zoffset; i < zoffset + depth; i++) {
5432*61046927SAndroid Build Coastguard Worker          assert(i < MAX_FACES);
5433*61046927SAndroid Build Coastguard Worker          if (!check_clear_tex_image(ctx, "glClearTexSubImage", texImages[i],
5434*61046927SAndroid Build Coastguard Worker                                     format, type, data, clearValue[i]))
5435*61046927SAndroid Build Coastguard Worker             goto out;
5436*61046927SAndroid Build Coastguard Worker       }
5437*61046927SAndroid Build Coastguard Worker       for (i = zoffset; i < zoffset + depth; i++) {
5438*61046927SAndroid Build Coastguard Worker          st_ClearTexSubImage(ctx,
5439*61046927SAndroid Build Coastguard Worker                              texImages[i],
5440*61046927SAndroid Build Coastguard Worker                              xoffset, yoffset, 0,
5441*61046927SAndroid Build Coastguard Worker                              width, height, 1,
5442*61046927SAndroid Build Coastguard Worker                              data ? clearValue[i] : NULL);
5443*61046927SAndroid Build Coastguard Worker       }
5444*61046927SAndroid Build Coastguard Worker    }
5445*61046927SAndroid Build Coastguard Worker 
5446*61046927SAndroid Build Coastguard Worker  out:
5447*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
5448*61046927SAndroid Build Coastguard Worker }
5449*61046927SAndroid Build Coastguard Worker 
5450*61046927SAndroid Build Coastguard Worker 
5451*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearTexImage(GLuint texture,GLint level,GLenum format,GLenum type,const void * data)5452*61046927SAndroid Build Coastguard Worker _mesa_ClearTexImage( GLuint texture, GLint level,
5453*61046927SAndroid Build Coastguard Worker                      GLenum format, GLenum type, const void *data )
5454*61046927SAndroid Build Coastguard Worker {
5455*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5456*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
5457*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImages[MAX_FACES];
5458*61046927SAndroid Build Coastguard Worker    GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES];
5459*61046927SAndroid Build Coastguard Worker    int i, numImages;
5460*61046927SAndroid Build Coastguard Worker 
5461*61046927SAndroid Build Coastguard Worker    texObj = get_tex_obj_for_clear(ctx, "glClearTexImage", texture);
5462*61046927SAndroid Build Coastguard Worker 
5463*61046927SAndroid Build Coastguard Worker    if (texObj == NULL)
5464*61046927SAndroid Build Coastguard Worker       return;
5465*61046927SAndroid Build Coastguard Worker 
5466*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
5467*61046927SAndroid Build Coastguard Worker 
5468*61046927SAndroid Build Coastguard Worker    numImages = get_tex_images_for_clear(ctx, "glClearTexImage",
5469*61046927SAndroid Build Coastguard Worker                                         texObj, level, texImages);
5470*61046927SAndroid Build Coastguard Worker 
5471*61046927SAndroid Build Coastguard Worker    for (i = 0; i < numImages; i++) {
5472*61046927SAndroid Build Coastguard Worker       if (!check_clear_tex_image(ctx, "glClearTexImage", texImages[i], format,
5473*61046927SAndroid Build Coastguard Worker                                  type, data, clearValue[i]))
5474*61046927SAndroid Build Coastguard Worker          goto out;
5475*61046927SAndroid Build Coastguard Worker    }
5476*61046927SAndroid Build Coastguard Worker 
5477*61046927SAndroid Build Coastguard Worker    for (i = 0; i < numImages; i++) {
5478*61046927SAndroid Build Coastguard Worker       st_ClearTexSubImage(ctx, texImages[i],
5479*61046927SAndroid Build Coastguard Worker                           -(GLint) texImages[i]->Border, /* xoffset */
5480*61046927SAndroid Build Coastguard Worker                           -(GLint) texImages[i]->Border, /* yoffset */
5481*61046927SAndroid Build Coastguard Worker                           -(GLint) texImages[i]->Border, /* zoffset */
5482*61046927SAndroid Build Coastguard Worker                           texImages[i]->Width,
5483*61046927SAndroid Build Coastguard Worker                           texImages[i]->Height,
5484*61046927SAndroid Build Coastguard Worker                           texImages[i]->Depth,
5485*61046927SAndroid Build Coastguard Worker                           data ? clearValue[i] : NULL);
5486*61046927SAndroid Build Coastguard Worker    }
5487*61046927SAndroid Build Coastguard Worker 
5488*61046927SAndroid Build Coastguard Worker out:
5489*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
5490*61046927SAndroid Build Coastguard Worker }
5491*61046927SAndroid Build Coastguard Worker 
5492*61046927SAndroid Build Coastguard Worker 
5493*61046927SAndroid Build Coastguard Worker 
5494*61046927SAndroid Build Coastguard Worker 
5495*61046927SAndroid Build Coastguard Worker /**********************************************************************/
5496*61046927SAndroid Build Coastguard Worker /******                   Compressed Textures                    ******/
5497*61046927SAndroid Build Coastguard Worker /**********************************************************************/
5498*61046927SAndroid Build Coastguard Worker 
5499*61046927SAndroid Build Coastguard Worker 
5500*61046927SAndroid Build Coastguard Worker /**
5501*61046927SAndroid Build Coastguard Worker  * Target checking for glCompressedTexSubImage[123]D().
5502*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if error, GL_FALSE if no error
5503*61046927SAndroid Build Coastguard Worker  * Must come before other error checking so that the texture object can
5504*61046927SAndroid Build Coastguard Worker  * be correctly retrieved using _mesa_get_current_tex_object.
5505*61046927SAndroid Build Coastguard Worker  */
5506*61046927SAndroid Build Coastguard Worker static GLboolean
compressed_subtexture_target_check(struct gl_context * ctx,GLenum target,GLint dims,GLenum intFormat,bool dsa,const char * caller)5507*61046927SAndroid Build Coastguard Worker compressed_subtexture_target_check(struct gl_context *ctx, GLenum target,
5508*61046927SAndroid Build Coastguard Worker                                    GLint dims, GLenum intFormat, bool dsa,
5509*61046927SAndroid Build Coastguard Worker                                    const char *caller)
5510*61046927SAndroid Build Coastguard Worker {
5511*61046927SAndroid Build Coastguard Worker    GLboolean targetOK;
5512*61046927SAndroid Build Coastguard Worker    mesa_format format;
5513*61046927SAndroid Build Coastguard Worker    enum mesa_format_layout layout;
5514*61046927SAndroid Build Coastguard Worker 
5515*61046927SAndroid Build Coastguard Worker    if (dsa && target == GL_TEXTURE_RECTANGLE) {
5516*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", caller,
5517*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target));
5518*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5519*61046927SAndroid Build Coastguard Worker    }
5520*61046927SAndroid Build Coastguard Worker 
5521*61046927SAndroid Build Coastguard Worker    switch (dims) {
5522*61046927SAndroid Build Coastguard Worker    case 2:
5523*61046927SAndroid Build Coastguard Worker       switch (target) {
5524*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_2D:
5525*61046927SAndroid Build Coastguard Worker          targetOK = GL_TRUE;
5526*61046927SAndroid Build Coastguard Worker          break;
5527*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5528*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5529*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5530*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5531*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5532*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5533*61046927SAndroid Build Coastguard Worker          targetOK = GL_TRUE;
5534*61046927SAndroid Build Coastguard Worker          break;
5535*61046927SAndroid Build Coastguard Worker       default:
5536*61046927SAndroid Build Coastguard Worker          targetOK = GL_FALSE;
5537*61046927SAndroid Build Coastguard Worker          break;
5538*61046927SAndroid Build Coastguard Worker       }
5539*61046927SAndroid Build Coastguard Worker       break;
5540*61046927SAndroid Build Coastguard Worker    case 3:
5541*61046927SAndroid Build Coastguard Worker       switch (target) {
5542*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP:
5543*61046927SAndroid Build Coastguard Worker          targetOK = dsa;
5544*61046927SAndroid Build Coastguard Worker          break;
5545*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_2D_ARRAY:
5546*61046927SAndroid Build Coastguard Worker          targetOK = _mesa_is_gles3(ctx) ||
5547*61046927SAndroid Build Coastguard Worker             (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array);
5548*61046927SAndroid Build Coastguard Worker          break;
5549*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_CUBE_MAP_ARRAY:
5550*61046927SAndroid Build Coastguard Worker          targetOK = _mesa_has_texture_cube_map_array(ctx);
5551*61046927SAndroid Build Coastguard Worker          break;
5552*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_3D:
5553*61046927SAndroid Build Coastguard Worker          targetOK = GL_TRUE;
5554*61046927SAndroid Build Coastguard Worker          /*
5555*61046927SAndroid Build Coastguard Worker           * OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture
5556*61046927SAndroid Build Coastguard Worker           * Images:
5557*61046927SAndroid Build Coastguard Worker           *    "An INVALID_OPERATION error is generated by
5558*61046927SAndroid Build Coastguard Worker           *    CompressedTex*SubImage3D if the internal format of the texture
5559*61046927SAndroid Build Coastguard Worker           *    is one of the EAC, ETC2, or RGTC formats and either border is
5560*61046927SAndroid Build Coastguard Worker           *    non-zero, or the effective target for the texture is not
5561*61046927SAndroid Build Coastguard Worker           *    TEXTURE_2D_ARRAY."
5562*61046927SAndroid Build Coastguard Worker           *
5563*61046927SAndroid Build Coastguard Worker           * NOTE: that's probably a spec error.  It should probably say
5564*61046927SAndroid Build Coastguard Worker           *    "... or the effective target for the texture is not
5565*61046927SAndroid Build Coastguard Worker           *    TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP, nor
5566*61046927SAndroid Build Coastguard Worker           *    GL_TEXTURE_CUBE_MAP_ARRAY."
5567*61046927SAndroid Build Coastguard Worker           * since those targets are 2D images and they support all compression
5568*61046927SAndroid Build Coastguard Worker           * formats.
5569*61046927SAndroid Build Coastguard Worker           *
5570*61046927SAndroid Build Coastguard Worker           * Instead of listing all these, just list those which are allowed,
5571*61046927SAndroid Build Coastguard Worker           * which is (at this time) only bptc. Otherwise we'd say s3tc (and
5572*61046927SAndroid Build Coastguard Worker           * more) are valid here, which they are not, but of course not
5573*61046927SAndroid Build Coastguard Worker           * mentioned by core spec.
5574*61046927SAndroid Build Coastguard Worker           *
5575*61046927SAndroid Build Coastguard Worker           * Also, from GL_KHR_texture_compression_astc_{hdr,ldr}:
5576*61046927SAndroid Build Coastguard Worker           *
5577*61046927SAndroid Build Coastguard Worker           *    "Add a second new column "3D Tex." which is empty for all non-ASTC
5578*61046927SAndroid Build Coastguard Worker           *     formats. If only the LDR profile is supported by the implementation,
5579*61046927SAndroid Build Coastguard Worker           *     this column is also empty for all ASTC formats. If both the LDR and HDR
5580*61046927SAndroid Build Coastguard Worker           *     profiles are supported, this column is checked for all ASTC formats."
5581*61046927SAndroid Build Coastguard Worker           *
5582*61046927SAndroid Build Coastguard Worker           *    "An INVALID_OPERATION error is generated by CompressedTexSubImage3D if
5583*61046927SAndroid Build Coastguard Worker           *     <format> is one of the formats in table 8.19 and <target> is not
5584*61046927SAndroid Build Coastguard Worker           *     TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, or TEXTURE_3D.
5585*61046927SAndroid Build Coastguard Worker           *
5586*61046927SAndroid Build Coastguard Worker           *     An INVALID_OPERATION error is generated by CompressedTexSubImage3D if
5587*61046927SAndroid Build Coastguard Worker           *     <format> is TEXTURE_CUBE_MAP_ARRAY and the "Cube Map Array" column of
5588*61046927SAndroid Build Coastguard Worker           *     table 8.19 is *not* checked, or if <format> is TEXTURE_3D and the "3D
5589*61046927SAndroid Build Coastguard Worker           *     Tex." column of table 8.19 is *not* checked"
5590*61046927SAndroid Build Coastguard Worker           *
5591*61046927SAndroid Build Coastguard Worker           * And from GL_KHR_texture_compression_astc_sliced_3d:
5592*61046927SAndroid Build Coastguard Worker           *
5593*61046927SAndroid Build Coastguard Worker           *    "Modify the "3D Tex." column to be checked for all ASTC formats."
5594*61046927SAndroid Build Coastguard Worker           */
5595*61046927SAndroid Build Coastguard Worker          format = _mesa_glenum_to_compressed_format(intFormat);
5596*61046927SAndroid Build Coastguard Worker          layout = _mesa_get_format_layout(format);
5597*61046927SAndroid Build Coastguard Worker          switch (layout) {
5598*61046927SAndroid Build Coastguard Worker          case MESA_FORMAT_LAYOUT_BPTC:
5599*61046927SAndroid Build Coastguard Worker             /* valid format */
5600*61046927SAndroid Build Coastguard Worker             break;
5601*61046927SAndroid Build Coastguard Worker          case MESA_FORMAT_LAYOUT_S3TC:
5602*61046927SAndroid Build Coastguard Worker             targetOK =
5603*61046927SAndroid Build Coastguard Worker                ctx->Extensions.EXT_texture_compression_s3tc &&
5604*61046927SAndroid Build Coastguard Worker                _mesa_is_gles3_compatible(ctx);
5605*61046927SAndroid Build Coastguard Worker             break;
5606*61046927SAndroid Build Coastguard Worker          case MESA_FORMAT_LAYOUT_ASTC:
5607*61046927SAndroid Build Coastguard Worker             targetOK =
5608*61046927SAndroid Build Coastguard Worker                ctx->Extensions.KHR_texture_compression_astc_hdr ||
5609*61046927SAndroid Build Coastguard Worker                ctx->Extensions.KHR_texture_compression_astc_sliced_3d;
5610*61046927SAndroid Build Coastguard Worker             break;
5611*61046927SAndroid Build Coastguard Worker          default:
5612*61046927SAndroid Build Coastguard Worker             /* invalid format */
5613*61046927SAndroid Build Coastguard Worker             _mesa_error(ctx, GL_INVALID_OPERATION,
5614*61046927SAndroid Build Coastguard Worker                         "%s(invalid target %s for format %s)", caller,
5615*61046927SAndroid Build Coastguard Worker                         _mesa_enum_to_string(target),
5616*61046927SAndroid Build Coastguard Worker                         _mesa_enum_to_string(intFormat));
5617*61046927SAndroid Build Coastguard Worker             return GL_TRUE;
5618*61046927SAndroid Build Coastguard Worker          }
5619*61046927SAndroid Build Coastguard Worker          break;
5620*61046927SAndroid Build Coastguard Worker       default:
5621*61046927SAndroid Build Coastguard Worker          targetOK = GL_FALSE;
5622*61046927SAndroid Build Coastguard Worker       }
5623*61046927SAndroid Build Coastguard Worker 
5624*61046927SAndroid Build Coastguard Worker       break;
5625*61046927SAndroid Build Coastguard Worker    default:
5626*61046927SAndroid Build Coastguard Worker       assert(dims == 1);
5627*61046927SAndroid Build Coastguard Worker       /* no 1D compressed textures at this time */
5628*61046927SAndroid Build Coastguard Worker       targetOK = GL_FALSE;
5629*61046927SAndroid Build Coastguard Worker       break;
5630*61046927SAndroid Build Coastguard Worker    }
5631*61046927SAndroid Build Coastguard Worker 
5632*61046927SAndroid Build Coastguard Worker    if (!targetOK) {
5633*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller,
5634*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target));
5635*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5636*61046927SAndroid Build Coastguard Worker    }
5637*61046927SAndroid Build Coastguard Worker 
5638*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
5639*61046927SAndroid Build Coastguard Worker }
5640*61046927SAndroid Build Coastguard Worker 
5641*61046927SAndroid Build Coastguard Worker /**
5642*61046927SAndroid Build Coastguard Worker  * Error checking for glCompressedTexSubImage[123]D().
5643*61046927SAndroid Build Coastguard Worker  * \return GL_TRUE if error, GL_FALSE if no error
5644*61046927SAndroid Build Coastguard Worker  */
5645*61046927SAndroid Build Coastguard Worker static GLboolean
compressed_subtexture_error_check(struct gl_context * ctx,GLint dims,const struct gl_texture_object * texObj,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data,const char * callerName)5646*61046927SAndroid Build Coastguard Worker compressed_subtexture_error_check(struct gl_context *ctx, GLint dims,
5647*61046927SAndroid Build Coastguard Worker                                   const struct gl_texture_object *texObj,
5648*61046927SAndroid Build Coastguard Worker                                   GLenum target, GLint level,
5649*61046927SAndroid Build Coastguard Worker                                   GLint xoffset, GLint yoffset, GLint zoffset,
5650*61046927SAndroid Build Coastguard Worker                                   GLsizei width, GLsizei height, GLsizei depth,
5651*61046927SAndroid Build Coastguard Worker                                   GLenum format, GLsizei imageSize,
5652*61046927SAndroid Build Coastguard Worker                                   const GLvoid *data, const char *callerName)
5653*61046927SAndroid Build Coastguard Worker {
5654*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
5655*61046927SAndroid Build Coastguard Worker    GLint expectedSize;
5656*61046927SAndroid Build Coastguard Worker 
5657*61046927SAndroid Build Coastguard Worker    GLenum is_generic_compressed_token =
5658*61046927SAndroid Build Coastguard Worker       _mesa_generic_compressed_format_to_uncompressed_format(format) !=
5659*61046927SAndroid Build Coastguard Worker       format;
5660*61046927SAndroid Build Coastguard Worker 
5661*61046927SAndroid Build Coastguard Worker    /* OpenGL 4.6 and OpenGL ES 3.2 spec:
5662*61046927SAndroid Build Coastguard Worker     *
5663*61046927SAndroid Build Coastguard Worker     *   "An INVALID_OPERATION error is generated if format does not match the
5664*61046927SAndroid Build Coastguard Worker     *    internal format of the texture image being modified, since these commands do
5665*61046927SAndroid Build Coastguard Worker     *    not provide for image format conversion."
5666*61046927SAndroid Build Coastguard Worker     *
5667*61046927SAndroid Build Coastguard Worker     *  Desktop spec has an additional rule for GL_INVALID_ENUM:
5668*61046927SAndroid Build Coastguard Worker     *
5669*61046927SAndroid Build Coastguard Worker     *   "An INVALID_ENUM error is generated if format is one of the generic
5670*61046927SAndroid Build Coastguard Worker     *    compressed internal formats."
5671*61046927SAndroid Build Coastguard Worker     */
5672*61046927SAndroid Build Coastguard Worker    /* this will catch any invalid compressed format token */
5673*61046927SAndroid Build Coastguard Worker    if (!_mesa_is_compressed_format(ctx, format)) {
5674*61046927SAndroid Build Coastguard Worker       GLenum error = _mesa_is_desktop_gl(ctx) && is_generic_compressed_token ?
5675*61046927SAndroid Build Coastguard Worker          GL_INVALID_ENUM : GL_INVALID_OPERATION;
5676*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, error, "%s(format)", callerName);
5677*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5678*61046927SAndroid Build Coastguard Worker    }
5679*61046927SAndroid Build Coastguard Worker 
5680*61046927SAndroid Build Coastguard Worker    if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
5681*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level);
5682*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5683*61046927SAndroid Build Coastguard Worker    }
5684*61046927SAndroid Build Coastguard Worker 
5685*61046927SAndroid Build Coastguard Worker    /* validate the bound PBO, if any */
5686*61046927SAndroid Build Coastguard Worker    if (!_mesa_validate_pbo_source_compressed(ctx, dims, &ctx->Unpack,
5687*61046927SAndroid Build Coastguard Worker                                      imageSize, data, callerName)) {
5688*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5689*61046927SAndroid Build Coastguard Worker    }
5690*61046927SAndroid Build Coastguard Worker 
5691*61046927SAndroid Build Coastguard Worker    /* Check for invalid pixel storage modes */
5692*61046927SAndroid Build Coastguard Worker    if (!_mesa_compressed_pixel_storage_error_check(ctx, dims,
5693*61046927SAndroid Build Coastguard Worker                                                    &ctx->Unpack, callerName)) {
5694*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5695*61046927SAndroid Build Coastguard Worker    }
5696*61046927SAndroid Build Coastguard Worker 
5697*61046927SAndroid Build Coastguard Worker    expectedSize = compressed_tex_size(width, height, depth, format);
5698*61046927SAndroid Build Coastguard Worker    if (expectedSize != imageSize) {
5699*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", callerName, imageSize);
5700*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5701*61046927SAndroid Build Coastguard Worker    }
5702*61046927SAndroid Build Coastguard Worker 
5703*61046927SAndroid Build Coastguard Worker    texImage = _mesa_select_tex_image(texObj, target, level);
5704*61046927SAndroid Build Coastguard Worker    if (!texImage) {
5705*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)",
5706*61046927SAndroid Build Coastguard Worker                   callerName, level);
5707*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5708*61046927SAndroid Build Coastguard Worker    }
5709*61046927SAndroid Build Coastguard Worker 
5710*61046927SAndroid Build Coastguard Worker    if ((GLint) format != texImage->InternalFormat) {
5711*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s)",
5712*61046927SAndroid Build Coastguard Worker                   callerName, _mesa_enum_to_string(format));
5713*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5714*61046927SAndroid Build Coastguard Worker    }
5715*61046927SAndroid Build Coastguard Worker 
5716*61046927SAndroid Build Coastguard Worker    if (compressedteximage_only_format(format)) {
5717*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s cannot be updated)",
5718*61046927SAndroid Build Coastguard Worker                   callerName, _mesa_enum_to_string(format));
5719*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5720*61046927SAndroid Build Coastguard Worker    }
5721*61046927SAndroid Build Coastguard Worker 
5722*61046927SAndroid Build Coastguard Worker    if (error_check_subtexture_negative_dimensions(ctx, dims, width, height,
5723*61046927SAndroid Build Coastguard Worker                                                   depth, callerName)) {
5724*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5725*61046927SAndroid Build Coastguard Worker    }
5726*61046927SAndroid Build Coastguard Worker 
5727*61046927SAndroid Build Coastguard Worker    if (error_check_subtexture_dimensions(ctx, dims, texImage, xoffset, yoffset,
5728*61046927SAndroid Build Coastguard Worker                                          zoffset, width, height, depth,
5729*61046927SAndroid Build Coastguard Worker                                          callerName)) {
5730*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
5731*61046927SAndroid Build Coastguard Worker    }
5732*61046927SAndroid Build Coastguard Worker 
5733*61046927SAndroid Build Coastguard Worker    return GL_FALSE;
5734*61046927SAndroid Build Coastguard Worker }
5735*61046927SAndroid Build Coastguard Worker 
5736*61046927SAndroid Build Coastguard Worker 
5737*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexImage1D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint border,GLsizei imageSize,const GLvoid * data)5738*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexImage1D(GLenum target, GLint level,
5739*61046927SAndroid Build Coastguard Worker                               GLenum internalFormat, GLsizei width,
5740*61046927SAndroid Build Coastguard Worker                               GLint border, GLsizei imageSize,
5741*61046927SAndroid Build Coastguard Worker                               const GLvoid *data)
5742*61046927SAndroid Build Coastguard Worker {
5743*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5744*61046927SAndroid Build Coastguard Worker    teximage_err(ctx, GL_TRUE, 1, target, level, internalFormat,
5745*61046927SAndroid Build Coastguard Worker                 width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data);
5746*61046927SAndroid Build Coastguard Worker }
5747*61046927SAndroid Build Coastguard Worker 
5748*61046927SAndroid Build Coastguard Worker 
5749*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureImage1DEXT(GLuint texture,GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint border,GLsizei imageSize,const GLvoid * pixels)5750*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level,
5751*61046927SAndroid Build Coastguard Worker                                   GLenum internalFormat, GLsizei width,
5752*61046927SAndroid Build Coastguard Worker                                   GLint border, GLsizei imageSize,
5753*61046927SAndroid Build Coastguard Worker                                   const GLvoid *pixels)
5754*61046927SAndroid Build Coastguard Worker {
5755*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
5756*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5757*61046927SAndroid Build Coastguard Worker 
5758*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
5759*61046927SAndroid Build Coastguard Worker                                            "glCompressedTextureImage1DEXT");
5760*61046927SAndroid Build Coastguard Worker    if (!texObj)
5761*61046927SAndroid Build Coastguard Worker       return;
5762*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat,
5763*61046927SAndroid Build Coastguard Worker             width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5764*61046927SAndroid Build Coastguard Worker }
5765*61046927SAndroid Build Coastguard Worker 
5766*61046927SAndroid Build Coastguard Worker 
5767*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedMultiTexImage1DEXT(GLenum texunit,GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint border,GLsizei imageSize,const GLvoid * pixels)5768*61046927SAndroid Build Coastguard Worker _mesa_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level,
5769*61046927SAndroid Build Coastguard Worker                                    GLenum internalFormat, GLsizei width,
5770*61046927SAndroid Build Coastguard Worker                                    GLint border, GLsizei imageSize,
5771*61046927SAndroid Build Coastguard Worker                                    const GLvoid *pixels)
5772*61046927SAndroid Build Coastguard Worker {
5773*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
5774*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5775*61046927SAndroid Build Coastguard Worker 
5776*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5777*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
5778*61046927SAndroid Build Coastguard Worker                                                    true,
5779*61046927SAndroid Build Coastguard Worker                                                    "glCompressedMultiTexImage1DEXT");
5780*61046927SAndroid Build Coastguard Worker    if (!texObj)
5781*61046927SAndroid Build Coastguard Worker       return;
5782*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat,
5783*61046927SAndroid Build Coastguard Worker             width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5784*61046927SAndroid Build Coastguard Worker }
5785*61046927SAndroid Build Coastguard Worker 
5786*61046927SAndroid Build Coastguard Worker 
5787*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexImage2D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)5788*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexImage2D(GLenum target, GLint level,
5789*61046927SAndroid Build Coastguard Worker                               GLenum internalFormat, GLsizei width,
5790*61046927SAndroid Build Coastguard Worker                               GLsizei height, GLint border, GLsizei imageSize,
5791*61046927SAndroid Build Coastguard Worker                               const GLvoid *data)
5792*61046927SAndroid Build Coastguard Worker {
5793*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5794*61046927SAndroid Build Coastguard Worker    teximage_err(ctx, GL_TRUE, 2, target, level, internalFormat,
5795*61046927SAndroid Build Coastguard Worker                 width, height, 1, border, GL_NONE, GL_NONE, imageSize, data);
5796*61046927SAndroid Build Coastguard Worker }
5797*61046927SAndroid Build Coastguard Worker 
5798*61046927SAndroid Build Coastguard Worker 
5799*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureImage2DEXT(GLuint texture,GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * pixels)5800*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level,
5801*61046927SAndroid Build Coastguard Worker                                   GLenum internalFormat, GLsizei width,
5802*61046927SAndroid Build Coastguard Worker                                   GLsizei height, GLint border, GLsizei imageSize,
5803*61046927SAndroid Build Coastguard Worker                                   const GLvoid *pixels)
5804*61046927SAndroid Build Coastguard Worker {
5805*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
5806*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5807*61046927SAndroid Build Coastguard Worker 
5808*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
5809*61046927SAndroid Build Coastguard Worker                                            "glCompressedTextureImage2DEXT");
5810*61046927SAndroid Build Coastguard Worker    if (!texObj)
5811*61046927SAndroid Build Coastguard Worker       return;
5812*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat,
5813*61046927SAndroid Build Coastguard Worker             width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5814*61046927SAndroid Build Coastguard Worker }
5815*61046927SAndroid Build Coastguard Worker 
5816*61046927SAndroid Build Coastguard Worker 
5817*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedMultiTexImage2DEXT(GLenum texunit,GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * pixels)5818*61046927SAndroid Build Coastguard Worker _mesa_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level,
5819*61046927SAndroid Build Coastguard Worker                                    GLenum internalFormat, GLsizei width,
5820*61046927SAndroid Build Coastguard Worker                                    GLsizei height, GLint border, GLsizei imageSize,
5821*61046927SAndroid Build Coastguard Worker                                    const GLvoid *pixels)
5822*61046927SAndroid Build Coastguard Worker {
5823*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
5824*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5825*61046927SAndroid Build Coastguard Worker 
5826*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5827*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
5828*61046927SAndroid Build Coastguard Worker                                                    true,
5829*61046927SAndroid Build Coastguard Worker                                                    "glCompressedMultiTexImage2DEXT");
5830*61046927SAndroid Build Coastguard Worker    if (!texObj)
5831*61046927SAndroid Build Coastguard Worker       return;
5832*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat,
5833*61046927SAndroid Build Coastguard Worker             width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5834*61046927SAndroid Build Coastguard Worker }
5835*61046927SAndroid Build Coastguard Worker 
5836*61046927SAndroid Build Coastguard Worker 
5837*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexImage3D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * data)5838*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexImage3D(GLenum target, GLint level,
5839*61046927SAndroid Build Coastguard Worker                               GLenum internalFormat, GLsizei width,
5840*61046927SAndroid Build Coastguard Worker                               GLsizei height, GLsizei depth, GLint border,
5841*61046927SAndroid Build Coastguard Worker                               GLsizei imageSize, const GLvoid *data)
5842*61046927SAndroid Build Coastguard Worker {
5843*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5844*61046927SAndroid Build Coastguard Worker    teximage_err(ctx, GL_TRUE, 3, target, level, internalFormat, width, height,
5845*61046927SAndroid Build Coastguard Worker                 depth, border, GL_NONE, GL_NONE, imageSize, data);
5846*61046927SAndroid Build Coastguard Worker }
5847*61046927SAndroid Build Coastguard Worker 
5848*61046927SAndroid Build Coastguard Worker 
5849*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureImage3DEXT(GLuint texture,GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * pixels)5850*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level,
5851*61046927SAndroid Build Coastguard Worker                                   GLenum internalFormat, GLsizei width,
5852*61046927SAndroid Build Coastguard Worker                                   GLsizei height, GLsizei depth, GLint border,
5853*61046927SAndroid Build Coastguard Worker                                   GLsizei imageSize, const GLvoid *pixels)
5854*61046927SAndroid Build Coastguard Worker {
5855*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
5856*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5857*61046927SAndroid Build Coastguard Worker 
5858*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
5859*61046927SAndroid Build Coastguard Worker                                            "glCompressedTextureImage3DEXT");
5860*61046927SAndroid Build Coastguard Worker    if (!texObj)
5861*61046927SAndroid Build Coastguard Worker       return;
5862*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat,
5863*61046927SAndroid Build Coastguard Worker             width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5864*61046927SAndroid Build Coastguard Worker }
5865*61046927SAndroid Build Coastguard Worker 
5866*61046927SAndroid Build Coastguard Worker 
5867*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedMultiTexImage3DEXT(GLenum texunit,GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * pixels)5868*61046927SAndroid Build Coastguard Worker _mesa_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level,
5869*61046927SAndroid Build Coastguard Worker                                    GLenum internalFormat, GLsizei width,
5870*61046927SAndroid Build Coastguard Worker                                    GLsizei height, GLsizei depth, GLint border,
5871*61046927SAndroid Build Coastguard Worker                                    GLsizei imageSize, const GLvoid *pixels)
5872*61046927SAndroid Build Coastguard Worker {
5873*61046927SAndroid Build Coastguard Worker    struct gl_texture_object*  texObj;
5874*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5875*61046927SAndroid Build Coastguard Worker 
5876*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5877*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
5878*61046927SAndroid Build Coastguard Worker                                                    true,
5879*61046927SAndroid Build Coastguard Worker                                                    "glCompressedMultiTexImage3DEXT");
5880*61046927SAndroid Build Coastguard Worker    if (!texObj)
5881*61046927SAndroid Build Coastguard Worker       return;
5882*61046927SAndroid Build Coastguard Worker    teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat,
5883*61046927SAndroid Build Coastguard Worker             width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5884*61046927SAndroid Build Coastguard Worker }
5885*61046927SAndroid Build Coastguard Worker 
5886*61046927SAndroid Build Coastguard Worker 
5887*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexImage1D_no_error(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint border,GLsizei imageSize,const GLvoid * data)5888*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexImage1D_no_error(GLenum target, GLint level,
5889*61046927SAndroid Build Coastguard Worker                                     GLenum internalFormat, GLsizei width,
5890*61046927SAndroid Build Coastguard Worker                                     GLint border, GLsizei imageSize,
5891*61046927SAndroid Build Coastguard Worker                                     const GLvoid *data)
5892*61046927SAndroid Build Coastguard Worker {
5893*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5894*61046927SAndroid Build Coastguard Worker    teximage_no_error(ctx, GL_TRUE, 1, target, level, internalFormat, width, 1,
5895*61046927SAndroid Build Coastguard Worker                      1, border, GL_NONE, GL_NONE, imageSize, data);
5896*61046927SAndroid Build Coastguard Worker }
5897*61046927SAndroid Build Coastguard Worker 
5898*61046927SAndroid Build Coastguard Worker 
5899*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexImage2D_no_error(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)5900*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexImage2D_no_error(GLenum target, GLint level,
5901*61046927SAndroid Build Coastguard Worker                                     GLenum internalFormat, GLsizei width,
5902*61046927SAndroid Build Coastguard Worker                                     GLsizei height, GLint border,
5903*61046927SAndroid Build Coastguard Worker                                     GLsizei imageSize, const GLvoid *data)
5904*61046927SAndroid Build Coastguard Worker {
5905*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5906*61046927SAndroid Build Coastguard Worker    teximage_no_error(ctx, GL_TRUE, 2, target, level, internalFormat, width,
5907*61046927SAndroid Build Coastguard Worker                      height, 1, border, GL_NONE, GL_NONE, imageSize, data);
5908*61046927SAndroid Build Coastguard Worker }
5909*61046927SAndroid Build Coastguard Worker 
5910*61046927SAndroid Build Coastguard Worker 
5911*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexImage3D_no_error(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * data)5912*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexImage3D_no_error(GLenum target, GLint level,
5913*61046927SAndroid Build Coastguard Worker                                     GLenum internalFormat, GLsizei width,
5914*61046927SAndroid Build Coastguard Worker                                     GLsizei height, GLsizei depth, GLint border,
5915*61046927SAndroid Build Coastguard Worker                                     GLsizei imageSize, const GLvoid *data)
5916*61046927SAndroid Build Coastguard Worker {
5917*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5918*61046927SAndroid Build Coastguard Worker    teximage_no_error(ctx, GL_TRUE, 3, target, level, internalFormat, width,
5919*61046927SAndroid Build Coastguard Worker                      height, depth, border, GL_NONE, GL_NONE, imageSize, data);
5920*61046927SAndroid Build Coastguard Worker }
5921*61046927SAndroid Build Coastguard Worker 
5922*61046927SAndroid Build Coastguard Worker 
5923*61046927SAndroid Build Coastguard Worker /**
5924*61046927SAndroid Build Coastguard Worker  * Common helper for glCompressedTexSubImage1/2/3D() and
5925*61046927SAndroid Build Coastguard Worker  * glCompressedTextureSubImage1/2/3D().
5926*61046927SAndroid Build Coastguard Worker  */
5927*61046927SAndroid Build Coastguard Worker static void
compressed_texture_sub_image(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,struct gl_texture_image * texImage,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)5928*61046927SAndroid Build Coastguard Worker compressed_texture_sub_image(struct gl_context *ctx, GLuint dims,
5929*61046927SAndroid Build Coastguard Worker                              struct gl_texture_object *texObj,
5930*61046927SAndroid Build Coastguard Worker                              struct gl_texture_image *texImage,
5931*61046927SAndroid Build Coastguard Worker                              GLenum target, GLint level, GLint xoffset,
5932*61046927SAndroid Build Coastguard Worker                              GLint yoffset, GLint zoffset, GLsizei width,
5933*61046927SAndroid Build Coastguard Worker                              GLsizei height, GLsizei depth, GLenum format,
5934*61046927SAndroid Build Coastguard Worker                              GLsizei imageSize, const GLvoid *data)
5935*61046927SAndroid Build Coastguard Worker {
5936*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0);
5937*61046927SAndroid Build Coastguard Worker 
5938*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
5939*61046927SAndroid Build Coastguard Worker    {
5940*61046927SAndroid Build Coastguard Worker       if (width > 0 && height > 0 && depth > 0) {
5941*61046927SAndroid Build Coastguard Worker          st_CompressedTexSubImage(ctx, dims, texImage,
5942*61046927SAndroid Build Coastguard Worker                                   xoffset, yoffset, zoffset,
5943*61046927SAndroid Build Coastguard Worker                                   width, height, depth,
5944*61046927SAndroid Build Coastguard Worker                                   format, imageSize, data);
5945*61046927SAndroid Build Coastguard Worker 
5946*61046927SAndroid Build Coastguard Worker          check_gen_mipmap(ctx, target, texObj, level);
5947*61046927SAndroid Build Coastguard Worker 
5948*61046927SAndroid Build Coastguard Worker          /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
5949*61046927SAndroid Build Coastguard Worker           * the texel data, not the texture format, size, etc.
5950*61046927SAndroid Build Coastguard Worker           */
5951*61046927SAndroid Build Coastguard Worker       }
5952*61046927SAndroid Build Coastguard Worker    }
5953*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
5954*61046927SAndroid Build Coastguard Worker }
5955*61046927SAndroid Build Coastguard Worker 
5956*61046927SAndroid Build Coastguard Worker 
5957*61046927SAndroid Build Coastguard Worker enum tex_mode {
5958*61046927SAndroid Build Coastguard Worker    /* Use bound texture to current unit */
5959*61046927SAndroid Build Coastguard Worker    TEX_MODE_CURRENT_NO_ERROR = 0,
5960*61046927SAndroid Build Coastguard Worker    TEX_MODE_CURRENT_ERROR,
5961*61046927SAndroid Build Coastguard Worker    /* Use the specified texture name */
5962*61046927SAndroid Build Coastguard Worker    TEX_MODE_DSA_NO_ERROR,
5963*61046927SAndroid Build Coastguard Worker    TEX_MODE_DSA_ERROR,
5964*61046927SAndroid Build Coastguard Worker    /* Use the specified texture name + target */
5965*61046927SAndroid Build Coastguard Worker    TEX_MODE_EXT_DSA_TEXTURE,
5966*61046927SAndroid Build Coastguard Worker    /* Use the specified texture unit + target */
5967*61046927SAndroid Build Coastguard Worker    TEX_MODE_EXT_DSA_TEXUNIT,
5968*61046927SAndroid Build Coastguard Worker };
5969*61046927SAndroid Build Coastguard Worker 
5970*61046927SAndroid Build Coastguard Worker 
5971*61046927SAndroid Build Coastguard Worker static void
compressed_tex_sub_image(unsigned dim,GLenum target,GLuint textureOrIndex,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data,enum tex_mode mode,const char * caller)5972*61046927SAndroid Build Coastguard Worker compressed_tex_sub_image(unsigned dim, GLenum target, GLuint textureOrIndex,
5973*61046927SAndroid Build Coastguard Worker                          GLint level, GLint xoffset, GLint yoffset,
5974*61046927SAndroid Build Coastguard Worker                          GLint zoffset, GLsizei width, GLsizei height,
5975*61046927SAndroid Build Coastguard Worker                          GLsizei depth, GLenum format, GLsizei imageSize,
5976*61046927SAndroid Build Coastguard Worker                          const GLvoid *data, enum tex_mode mode,
5977*61046927SAndroid Build Coastguard Worker                          const char *caller)
5978*61046927SAndroid Build Coastguard Worker {
5979*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj = NULL;
5980*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
5981*61046927SAndroid Build Coastguard Worker    bool no_error = false;
5982*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
5983*61046927SAndroid Build Coastguard Worker 
5984*61046927SAndroid Build Coastguard Worker    switch (mode) {
5985*61046927SAndroid Build Coastguard Worker       case TEX_MODE_DSA_ERROR:
5986*61046927SAndroid Build Coastguard Worker          assert(target == 0);
5987*61046927SAndroid Build Coastguard Worker          texObj = _mesa_lookup_texture_err(ctx, textureOrIndex, caller);
5988*61046927SAndroid Build Coastguard Worker          if (texObj)
5989*61046927SAndroid Build Coastguard Worker             target = texObj->Target;
5990*61046927SAndroid Build Coastguard Worker          break;
5991*61046927SAndroid Build Coastguard Worker       case TEX_MODE_DSA_NO_ERROR:
5992*61046927SAndroid Build Coastguard Worker          assert(target == 0);
5993*61046927SAndroid Build Coastguard Worker          texObj = _mesa_lookup_texture(ctx, textureOrIndex);
5994*61046927SAndroid Build Coastguard Worker          if (texObj)
5995*61046927SAndroid Build Coastguard Worker             target = texObj->Target;
5996*61046927SAndroid Build Coastguard Worker          no_error = true;
5997*61046927SAndroid Build Coastguard Worker          break;
5998*61046927SAndroid Build Coastguard Worker       case TEX_MODE_EXT_DSA_TEXTURE:
5999*61046927SAndroid Build Coastguard Worker          texObj = _mesa_lookup_or_create_texture(ctx, target, textureOrIndex,
6000*61046927SAndroid Build Coastguard Worker                                                  false, true, caller);
6001*61046927SAndroid Build Coastguard Worker          break;
6002*61046927SAndroid Build Coastguard Worker       case TEX_MODE_EXT_DSA_TEXUNIT:
6003*61046927SAndroid Build Coastguard Worker          texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
6004*61046927SAndroid Build Coastguard Worker                                                          textureOrIndex,
6005*61046927SAndroid Build Coastguard Worker                                                          false,
6006*61046927SAndroid Build Coastguard Worker                                                          caller);
6007*61046927SAndroid Build Coastguard Worker          break;
6008*61046927SAndroid Build Coastguard Worker       case TEX_MODE_CURRENT_NO_ERROR:
6009*61046927SAndroid Build Coastguard Worker          no_error = true;
6010*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
6011*61046927SAndroid Build Coastguard Worker       case TEX_MODE_CURRENT_ERROR:
6012*61046927SAndroid Build Coastguard Worker       default:
6013*61046927SAndroid Build Coastguard Worker          assert(textureOrIndex == 0);
6014*61046927SAndroid Build Coastguard Worker          break;
6015*61046927SAndroid Build Coastguard Worker    }
6016*61046927SAndroid Build Coastguard Worker 
6017*61046927SAndroid Build Coastguard Worker    if (!no_error &&
6018*61046927SAndroid Build Coastguard Worker        compressed_subtexture_target_check(ctx, target, dim, format,
6019*61046927SAndroid Build Coastguard Worker                                           mode == TEX_MODE_DSA_ERROR,
6020*61046927SAndroid Build Coastguard Worker                                           caller)) {
6021*61046927SAndroid Build Coastguard Worker       return;
6022*61046927SAndroid Build Coastguard Worker    }
6023*61046927SAndroid Build Coastguard Worker 
6024*61046927SAndroid Build Coastguard Worker    if (mode == TEX_MODE_CURRENT_NO_ERROR ||
6025*61046927SAndroid Build Coastguard Worker        mode == TEX_MODE_CURRENT_ERROR) {
6026*61046927SAndroid Build Coastguard Worker       texObj = _mesa_get_current_tex_object(ctx, target);
6027*61046927SAndroid Build Coastguard Worker    }
6028*61046927SAndroid Build Coastguard Worker 
6029*61046927SAndroid Build Coastguard Worker    if (!texObj)
6030*61046927SAndroid Build Coastguard Worker       return;
6031*61046927SAndroid Build Coastguard Worker 
6032*61046927SAndroid Build Coastguard Worker    if (!no_error &&
6033*61046927SAndroid Build Coastguard Worker        compressed_subtexture_error_check(ctx, dim, texObj, target, level,
6034*61046927SAndroid Build Coastguard Worker                                          xoffset, yoffset, zoffset, width,
6035*61046927SAndroid Build Coastguard Worker                                          height, depth, format,
6036*61046927SAndroid Build Coastguard Worker                                          imageSize, data, caller)) {
6037*61046927SAndroid Build Coastguard Worker       return;
6038*61046927SAndroid Build Coastguard Worker    }
6039*61046927SAndroid Build Coastguard Worker 
6040*61046927SAndroid Build Coastguard Worker    /* Must handle special case GL_TEXTURE_CUBE_MAP. */
6041*61046927SAndroid Build Coastguard Worker    if (dim == 3 &&
6042*61046927SAndroid Build Coastguard Worker        (mode == TEX_MODE_DSA_ERROR || mode == TEX_MODE_DSA_NO_ERROR) &&
6043*61046927SAndroid Build Coastguard Worker        texObj->Target == GL_TEXTURE_CUBE_MAP) {
6044*61046927SAndroid Build Coastguard Worker       const char *pixels = data;
6045*61046927SAndroid Build Coastguard Worker       GLint image_stride;
6046*61046927SAndroid Build Coastguard Worker 
6047*61046927SAndroid Build Coastguard Worker       /* Make sure the texture object is a proper cube.
6048*61046927SAndroid Build Coastguard Worker        * (See texturesubimage in teximage.c for details on why this check is
6049*61046927SAndroid Build Coastguard Worker        * performed.)
6050*61046927SAndroid Build Coastguard Worker        */
6051*61046927SAndroid Build Coastguard Worker       if (!no_error && !_mesa_cube_level_complete(texObj, level)) {
6052*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION,
6053*61046927SAndroid Build Coastguard Worker                      "glCompressedTextureSubImage3D(cube map incomplete)");
6054*61046927SAndroid Build Coastguard Worker          return;
6055*61046927SAndroid Build Coastguard Worker       }
6056*61046927SAndroid Build Coastguard Worker 
6057*61046927SAndroid Build Coastguard Worker       /* Copy in each face. */
6058*61046927SAndroid Build Coastguard Worker       for (int i = zoffset; i < zoffset + depth; ++i) {
6059*61046927SAndroid Build Coastguard Worker          texImage = texObj->Image[i][level];
6060*61046927SAndroid Build Coastguard Worker          assert(texImage);
6061*61046927SAndroid Build Coastguard Worker 
6062*61046927SAndroid Build Coastguard Worker          compressed_texture_sub_image(ctx, 3, texObj, texImage,
6063*61046927SAndroid Build Coastguard Worker                                       texObj->Target, level, xoffset, yoffset,
6064*61046927SAndroid Build Coastguard Worker                                       0, width, height, 1, format,
6065*61046927SAndroid Build Coastguard Worker                                       imageSize, pixels);
6066*61046927SAndroid Build Coastguard Worker 
6067*61046927SAndroid Build Coastguard Worker          /* Compressed images don't have a client format */
6068*61046927SAndroid Build Coastguard Worker          image_stride = _mesa_format_image_size(texImage->TexFormat,
6069*61046927SAndroid Build Coastguard Worker                                                 texImage->Width,
6070*61046927SAndroid Build Coastguard Worker                                                 texImage->Height, 1);
6071*61046927SAndroid Build Coastguard Worker 
6072*61046927SAndroid Build Coastguard Worker          pixels += image_stride;
6073*61046927SAndroid Build Coastguard Worker          imageSize -= image_stride;
6074*61046927SAndroid Build Coastguard Worker       }
6075*61046927SAndroid Build Coastguard Worker    } else {
6076*61046927SAndroid Build Coastguard Worker       texImage = _mesa_select_tex_image(texObj, target, level);
6077*61046927SAndroid Build Coastguard Worker       assert(texImage);
6078*61046927SAndroid Build Coastguard Worker 
6079*61046927SAndroid Build Coastguard Worker       compressed_texture_sub_image(ctx, dim, texObj, texImage, target, level,
6080*61046927SAndroid Build Coastguard Worker                                    xoffset, yoffset, zoffset, width, height,
6081*61046927SAndroid Build Coastguard Worker                                    depth, format, imageSize, data);
6082*61046927SAndroid Build Coastguard Worker    }
6083*61046927SAndroid Build Coastguard Worker }
6084*61046927SAndroid Build Coastguard Worker 
6085*61046927SAndroid Build Coastguard Worker 
6086*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexSubImage1D_no_error(GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLsizei imageSize,const GLvoid * data)6087*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level,
6088*61046927SAndroid Build Coastguard Worker                                        GLint xoffset, GLsizei width,
6089*61046927SAndroid Build Coastguard Worker                                        GLenum format, GLsizei imageSize,
6090*61046927SAndroid Build Coastguard Worker                                        const GLvoid *data)
6091*61046927SAndroid Build Coastguard Worker {
6092*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(1, target, 0,
6093*61046927SAndroid Build Coastguard Worker                             level, xoffset, 0, 0, width,
6094*61046927SAndroid Build Coastguard Worker                             1, 1, format, imageSize, data,
6095*61046927SAndroid Build Coastguard Worker                             TEX_MODE_CURRENT_NO_ERROR,
6096*61046927SAndroid Build Coastguard Worker                             "glCompressedTexSubImage1D");
6097*61046927SAndroid Build Coastguard Worker }
6098*61046927SAndroid Build Coastguard Worker 
6099*61046927SAndroid Build Coastguard Worker 
6100*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexSubImage1D(GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLsizei imageSize,const GLvoid * data)6101*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset,
6102*61046927SAndroid Build Coastguard Worker                               GLsizei width, GLenum format,
6103*61046927SAndroid Build Coastguard Worker                               GLsizei imageSize, const GLvoid *data)
6104*61046927SAndroid Build Coastguard Worker {
6105*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(1, target, 0,
6106*61046927SAndroid Build Coastguard Worker                             level, xoffset, 0, 0, width,
6107*61046927SAndroid Build Coastguard Worker                             1, 1, format, imageSize, data,
6108*61046927SAndroid Build Coastguard Worker                             TEX_MODE_CURRENT_ERROR,
6109*61046927SAndroid Build Coastguard Worker                             "glCompressedTexSubImage1D");
6110*61046927SAndroid Build Coastguard Worker }
6111*61046927SAndroid Build Coastguard Worker 
6112*61046927SAndroid Build Coastguard Worker 
6113*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage1D_no_error(GLuint texture,GLint level,GLint xoffset,GLsizei width,GLenum format,GLsizei imageSize,const GLvoid * data)6114*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage1D_no_error(GLuint texture, GLint level,
6115*61046927SAndroid Build Coastguard Worker                                            GLint xoffset, GLsizei width,
6116*61046927SAndroid Build Coastguard Worker                                            GLenum format, GLsizei imageSize,
6117*61046927SAndroid Build Coastguard Worker                                            const GLvoid *data)
6118*61046927SAndroid Build Coastguard Worker {
6119*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(1, 0, texture,
6120*61046927SAndroid Build Coastguard Worker                             level, xoffset, 0, 0,
6121*61046927SAndroid Build Coastguard Worker                             width, 1, 1, format, imageSize, data,
6122*61046927SAndroid Build Coastguard Worker                             TEX_MODE_DSA_NO_ERROR,
6123*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage1D");
6124*61046927SAndroid Build Coastguard Worker }
6125*61046927SAndroid Build Coastguard Worker 
6126*61046927SAndroid Build Coastguard Worker 
6127*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage1D(GLuint texture,GLint level,GLint xoffset,GLsizei width,GLenum format,GLsizei imageSize,const GLvoid * data)6128*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,
6129*61046927SAndroid Build Coastguard Worker                                   GLsizei width, GLenum format,
6130*61046927SAndroid Build Coastguard Worker                                   GLsizei imageSize, const GLvoid *data)
6131*61046927SAndroid Build Coastguard Worker {
6132*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(1, 0, texture,
6133*61046927SAndroid Build Coastguard Worker                             level, xoffset, 0, 0,
6134*61046927SAndroid Build Coastguard Worker                             width, 1, 1, format, imageSize, data,
6135*61046927SAndroid Build Coastguard Worker                             TEX_MODE_DSA_ERROR,
6136*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage1D");
6137*61046927SAndroid Build Coastguard Worker }
6138*61046927SAndroid Build Coastguard Worker 
6139*61046927SAndroid Build Coastguard Worker 
6140*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage1DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLsizei imageSize,const GLvoid * data)6141*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target,
6142*61046927SAndroid Build Coastguard Worker                                      GLint level, GLint xoffset,
6143*61046927SAndroid Build Coastguard Worker                                      GLsizei width, GLenum format,
6144*61046927SAndroid Build Coastguard Worker                                      GLsizei imageSize, const GLvoid *data)
6145*61046927SAndroid Build Coastguard Worker {
6146*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(1, target, texture, level, xoffset, 0,
6147*61046927SAndroid Build Coastguard Worker                             0, width, 1, 1, format, imageSize,
6148*61046927SAndroid Build Coastguard Worker                             data,
6149*61046927SAndroid Build Coastguard Worker                             TEX_MODE_EXT_DSA_TEXTURE,
6150*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage1DEXT");
6151*61046927SAndroid Build Coastguard Worker }
6152*61046927SAndroid Build Coastguard Worker 
6153*61046927SAndroid Build Coastguard Worker 
6154*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedMultiTexSubImage1DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLsizei imageSize,const GLvoid * data)6155*61046927SAndroid Build Coastguard Worker _mesa_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target,
6156*61046927SAndroid Build Coastguard Worker                                       GLint level, GLint xoffset,
6157*61046927SAndroid Build Coastguard Worker                                       GLsizei width, GLenum format,
6158*61046927SAndroid Build Coastguard Worker                                       GLsizei imageSize, const GLvoid *data)
6159*61046927SAndroid Build Coastguard Worker {
6160*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(1, target, texunit - GL_TEXTURE0, level,
6161*61046927SAndroid Build Coastguard Worker                             xoffset, 0, 0, width, 1, 1, format, imageSize,
6162*61046927SAndroid Build Coastguard Worker                             data,
6163*61046927SAndroid Build Coastguard Worker                             TEX_MODE_EXT_DSA_TEXUNIT,
6164*61046927SAndroid Build Coastguard Worker                             "glCompressedMultiTexSubImage1DEXT");
6165*61046927SAndroid Build Coastguard Worker }
6166*61046927SAndroid Build Coastguard Worker 
6167*61046927SAndroid Build Coastguard Worker 
6168*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexSubImage2D_no_error(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)6169*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level,
6170*61046927SAndroid Build Coastguard Worker                                        GLint xoffset, GLint yoffset,
6171*61046927SAndroid Build Coastguard Worker                                        GLsizei width, GLsizei height,
6172*61046927SAndroid Build Coastguard Worker                                        GLenum format, GLsizei imageSize,
6173*61046927SAndroid Build Coastguard Worker                                        const GLvoid *data)
6174*61046927SAndroid Build Coastguard Worker {
6175*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(2, target, 0, level,
6176*61046927SAndroid Build Coastguard Worker                             xoffset, yoffset, 0,
6177*61046927SAndroid Build Coastguard Worker                             width, height, 1, format, imageSize, data,
6178*61046927SAndroid Build Coastguard Worker                             TEX_MODE_CURRENT_NO_ERROR,
6179*61046927SAndroid Build Coastguard Worker                             "glCompressedTexSubImage2D");
6180*61046927SAndroid Build Coastguard Worker }
6181*61046927SAndroid Build Coastguard Worker 
6182*61046927SAndroid Build Coastguard Worker 
6183*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)6184*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
6185*61046927SAndroid Build Coastguard Worker                               GLint yoffset, GLsizei width, GLsizei height,
6186*61046927SAndroid Build Coastguard Worker                               GLenum format, GLsizei imageSize,
6187*61046927SAndroid Build Coastguard Worker                               const GLvoid *data)
6188*61046927SAndroid Build Coastguard Worker {
6189*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(2, target, 0, level,
6190*61046927SAndroid Build Coastguard Worker                             xoffset, yoffset, 0,
6191*61046927SAndroid Build Coastguard Worker                             width, height, 1, format, imageSize, data,
6192*61046927SAndroid Build Coastguard Worker                             TEX_MODE_CURRENT_ERROR,
6193*61046927SAndroid Build Coastguard Worker                             "glCompressedTexSubImage2D");
6194*61046927SAndroid Build Coastguard Worker }
6195*61046927SAndroid Build Coastguard Worker 
6196*61046927SAndroid Build Coastguard Worker 
6197*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage2DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)6198*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target,
6199*61046927SAndroid Build Coastguard Worker                                      GLint level, GLint xoffset,
6200*61046927SAndroid Build Coastguard Worker                                      GLint yoffset, GLsizei width,
6201*61046927SAndroid Build Coastguard Worker                                      GLsizei height, GLenum format,
6202*61046927SAndroid Build Coastguard Worker                                      GLsizei imageSize, const GLvoid *data)
6203*61046927SAndroid Build Coastguard Worker {
6204*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(2, target, texture, level, xoffset,
6205*61046927SAndroid Build Coastguard Worker                             yoffset, 0, width, height, 1, format,
6206*61046927SAndroid Build Coastguard Worker                             imageSize, data,
6207*61046927SAndroid Build Coastguard Worker                             TEX_MODE_EXT_DSA_TEXTURE,
6208*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage2DEXT");
6209*61046927SAndroid Build Coastguard Worker }
6210*61046927SAndroid Build Coastguard Worker 
6211*61046927SAndroid Build Coastguard Worker 
6212*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedMultiTexSubImage2DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)6213*61046927SAndroid Build Coastguard Worker _mesa_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target,
6214*61046927SAndroid Build Coastguard Worker                                       GLint level, GLint xoffset, GLint yoffset,
6215*61046927SAndroid Build Coastguard Worker                                       GLsizei width, GLsizei height, GLenum format,
6216*61046927SAndroid Build Coastguard Worker                                       GLsizei imageSize, const GLvoid *data)
6217*61046927SAndroid Build Coastguard Worker {
6218*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(2, target, texunit - GL_TEXTURE0, level,
6219*61046927SAndroid Build Coastguard Worker                             xoffset, yoffset, 0, width, height, 1, format,
6220*61046927SAndroid Build Coastguard Worker                             imageSize, data,
6221*61046927SAndroid Build Coastguard Worker                             TEX_MODE_EXT_DSA_TEXUNIT,
6222*61046927SAndroid Build Coastguard Worker                             "glCompressedMultiTexSubImage2DEXT");
6223*61046927SAndroid Build Coastguard Worker }
6224*61046927SAndroid Build Coastguard Worker 
6225*61046927SAndroid Build Coastguard Worker 
6226*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage2D_no_error(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)6227*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage2D_no_error(GLuint texture, GLint level,
6228*61046927SAndroid Build Coastguard Worker                                            GLint xoffset, GLint yoffset,
6229*61046927SAndroid Build Coastguard Worker                                            GLsizei width, GLsizei height,
6230*61046927SAndroid Build Coastguard Worker                                            GLenum format, GLsizei imageSize,
6231*61046927SAndroid Build Coastguard Worker                                            const GLvoid *data)
6232*61046927SAndroid Build Coastguard Worker {
6233*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0,
6234*61046927SAndroid Build Coastguard Worker                             width, height, 1, format, imageSize, data,
6235*61046927SAndroid Build Coastguard Worker                             TEX_MODE_DSA_NO_ERROR,
6236*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage2D");
6237*61046927SAndroid Build Coastguard Worker }
6238*61046927SAndroid Build Coastguard Worker 
6239*61046927SAndroid Build Coastguard Worker 
6240*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage2D(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)6241*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset,
6242*61046927SAndroid Build Coastguard Worker                                   GLint yoffset,
6243*61046927SAndroid Build Coastguard Worker                                   GLsizei width, GLsizei height,
6244*61046927SAndroid Build Coastguard Worker                                   GLenum format, GLsizei imageSize,
6245*61046927SAndroid Build Coastguard Worker                                   const GLvoid *data)
6246*61046927SAndroid Build Coastguard Worker {
6247*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0,
6248*61046927SAndroid Build Coastguard Worker                             width, height, 1, format, imageSize, data,
6249*61046927SAndroid Build Coastguard Worker                             TEX_MODE_DSA_ERROR,
6250*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage2D");
6251*61046927SAndroid Build Coastguard Worker }
6252*61046927SAndroid Build Coastguard Worker 
6253*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexSubImage3D_no_error(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)6254*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexSubImage3D_no_error(GLenum target, GLint level,
6255*61046927SAndroid Build Coastguard Worker                                        GLint xoffset, GLint yoffset,
6256*61046927SAndroid Build Coastguard Worker                                        GLint zoffset, GLsizei width,
6257*61046927SAndroid Build Coastguard Worker                                        GLsizei height, GLsizei depth,
6258*61046927SAndroid Build Coastguard Worker                                        GLenum format, GLsizei imageSize,
6259*61046927SAndroid Build Coastguard Worker                                        const GLvoid *data)
6260*61046927SAndroid Build Coastguard Worker {
6261*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset,
6262*61046927SAndroid Build Coastguard Worker                             zoffset, width, height, depth, format,
6263*61046927SAndroid Build Coastguard Worker                             imageSize, data,
6264*61046927SAndroid Build Coastguard Worker                             TEX_MODE_CURRENT_NO_ERROR,
6265*61046927SAndroid Build Coastguard Worker                             "glCompressedTexSubImage3D");
6266*61046927SAndroid Build Coastguard Worker }
6267*61046927SAndroid Build Coastguard Worker 
6268*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)6269*61046927SAndroid Build Coastguard Worker _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
6270*61046927SAndroid Build Coastguard Worker                               GLint yoffset, GLint zoffset, GLsizei width,
6271*61046927SAndroid Build Coastguard Worker                               GLsizei height, GLsizei depth, GLenum format,
6272*61046927SAndroid Build Coastguard Worker                               GLsizei imageSize, const GLvoid *data)
6273*61046927SAndroid Build Coastguard Worker {
6274*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset,
6275*61046927SAndroid Build Coastguard Worker                             zoffset, width, height, depth, format,
6276*61046927SAndroid Build Coastguard Worker                             imageSize, data,
6277*61046927SAndroid Build Coastguard Worker                             TEX_MODE_CURRENT_ERROR,
6278*61046927SAndroid Build Coastguard Worker                             "glCompressedTexSubImage3D");
6279*61046927SAndroid Build Coastguard Worker }
6280*61046927SAndroid Build Coastguard Worker 
6281*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage3D_no_error(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)6282*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage3D_no_error(GLuint texture, GLint level,
6283*61046927SAndroid Build Coastguard Worker                                            GLint xoffset, GLint yoffset,
6284*61046927SAndroid Build Coastguard Worker                                            GLint zoffset, GLsizei width,
6285*61046927SAndroid Build Coastguard Worker                                            GLsizei height, GLsizei depth,
6286*61046927SAndroid Build Coastguard Worker                                            GLenum format, GLsizei imageSize,
6287*61046927SAndroid Build Coastguard Worker                                            const GLvoid *data)
6288*61046927SAndroid Build Coastguard Worker {
6289*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset,
6290*61046927SAndroid Build Coastguard Worker                             zoffset, width, height, depth, format,
6291*61046927SAndroid Build Coastguard Worker                             imageSize, data,
6292*61046927SAndroid Build Coastguard Worker                             TEX_MODE_DSA_NO_ERROR,
6293*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage3D");
6294*61046927SAndroid Build Coastguard Worker }
6295*61046927SAndroid Build Coastguard Worker 
6296*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage3D(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)6297*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset,
6298*61046927SAndroid Build Coastguard Worker                                   GLint yoffset, GLint zoffset, GLsizei width,
6299*61046927SAndroid Build Coastguard Worker                                   GLsizei height, GLsizei depth,
6300*61046927SAndroid Build Coastguard Worker                                   GLenum format, GLsizei imageSize,
6301*61046927SAndroid Build Coastguard Worker                                   const GLvoid *data)
6302*61046927SAndroid Build Coastguard Worker {
6303*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset,
6304*61046927SAndroid Build Coastguard Worker                             zoffset, width, height, depth, format,
6305*61046927SAndroid Build Coastguard Worker                             imageSize, data,
6306*61046927SAndroid Build Coastguard Worker                             TEX_MODE_DSA_ERROR,
6307*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage3D");
6308*61046927SAndroid Build Coastguard Worker }
6309*61046927SAndroid Build Coastguard Worker 
6310*61046927SAndroid Build Coastguard Worker 
6311*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedTextureSubImage3DEXT(GLuint texture,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)6312*61046927SAndroid Build Coastguard Worker _mesa_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target,
6313*61046927SAndroid Build Coastguard Worker                                      GLint level, GLint xoffset,
6314*61046927SAndroid Build Coastguard Worker                                      GLint yoffset, GLint zoffset,
6315*61046927SAndroid Build Coastguard Worker                                      GLsizei width, GLsizei height,
6316*61046927SAndroid Build Coastguard Worker                                      GLsizei depth, GLenum format,
6317*61046927SAndroid Build Coastguard Worker                                      GLsizei imageSize, const GLvoid *data)
6318*61046927SAndroid Build Coastguard Worker {
6319*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(3, target, texture, level, xoffset, yoffset,
6320*61046927SAndroid Build Coastguard Worker                             zoffset, width, height, depth, format,
6321*61046927SAndroid Build Coastguard Worker                             imageSize, data,
6322*61046927SAndroid Build Coastguard Worker                             TEX_MODE_EXT_DSA_TEXTURE,
6323*61046927SAndroid Build Coastguard Worker                             "glCompressedTextureSubImage3DEXT");
6324*61046927SAndroid Build Coastguard Worker }
6325*61046927SAndroid Build Coastguard Worker 
6326*61046927SAndroid Build Coastguard Worker 
6327*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)6328*61046927SAndroid Build Coastguard Worker _mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target,
6329*61046927SAndroid Build Coastguard Worker                                       GLint level, GLint xoffset, GLint yoffset,
6330*61046927SAndroid Build Coastguard Worker                                       GLint zoffset, GLsizei width, GLsizei height,
6331*61046927SAndroid Build Coastguard Worker                                       GLsizei depth, GLenum format,
6332*61046927SAndroid Build Coastguard Worker                                       GLsizei imageSize, const GLvoid *data)
6333*61046927SAndroid Build Coastguard Worker {
6334*61046927SAndroid Build Coastguard Worker    compressed_tex_sub_image(3, target, texunit - GL_TEXTURE0, level,
6335*61046927SAndroid Build Coastguard Worker                             xoffset, yoffset, zoffset, width, height, depth,
6336*61046927SAndroid Build Coastguard Worker                             format, imageSize, data,
6337*61046927SAndroid Build Coastguard Worker                             TEX_MODE_EXT_DSA_TEXUNIT,
6338*61046927SAndroid Build Coastguard Worker                             "glCompressedMultiTexSubImage3DEXT");
6339*61046927SAndroid Build Coastguard Worker }
6340*61046927SAndroid Build Coastguard Worker 
6341*61046927SAndroid Build Coastguard Worker 
6342*61046927SAndroid Build Coastguard Worker mesa_format
_mesa_get_texbuffer_format(const struct gl_context * ctx,GLenum internalFormat)6343*61046927SAndroid Build Coastguard Worker _mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
6344*61046927SAndroid Build Coastguard Worker {
6345*61046927SAndroid Build Coastguard Worker    if (_mesa_is_desktop_gl_compat(ctx)) {
6346*61046927SAndroid Build Coastguard Worker       switch (internalFormat) {
6347*61046927SAndroid Build Coastguard Worker       case GL_ALPHA8:
6348*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_UNORM8;
6349*61046927SAndroid Build Coastguard Worker       case GL_ALPHA16:
6350*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_UNORM16;
6351*61046927SAndroid Build Coastguard Worker       case GL_ALPHA16F_ARB:
6352*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_FLOAT16;
6353*61046927SAndroid Build Coastguard Worker       case GL_ALPHA32F_ARB:
6354*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_FLOAT32;
6355*61046927SAndroid Build Coastguard Worker       case GL_ALPHA8I_EXT:
6356*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_SINT8;
6357*61046927SAndroid Build Coastguard Worker       case GL_ALPHA16I_EXT:
6358*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_SINT16;
6359*61046927SAndroid Build Coastguard Worker       case GL_ALPHA32I_EXT:
6360*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_SINT32;
6361*61046927SAndroid Build Coastguard Worker       case GL_ALPHA8UI_EXT:
6362*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_UINT8;
6363*61046927SAndroid Build Coastguard Worker       case GL_ALPHA16UI_EXT:
6364*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_UINT16;
6365*61046927SAndroid Build Coastguard Worker       case GL_ALPHA32UI_EXT:
6366*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_A_UINT32;
6367*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE8:
6368*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_UNORM8;
6369*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE16:
6370*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_UNORM16;
6371*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE16F_ARB:
6372*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_FLOAT16;
6373*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE32F_ARB:
6374*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_FLOAT32;
6375*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE8I_EXT:
6376*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_SINT8;
6377*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE16I_EXT:
6378*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_SINT16;
6379*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE32I_EXT:
6380*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_SINT32;
6381*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE8UI_EXT:
6382*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_UINT8;
6383*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE16UI_EXT:
6384*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_UINT16;
6385*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE32UI_EXT:
6386*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_L_UINT32;
6387*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE8_ALPHA8:
6388*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_UNORM8;
6389*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE16_ALPHA16:
6390*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_UNORM16;
6391*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA16F_ARB:
6392*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_FLOAT16;
6393*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA32F_ARB:
6394*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_FLOAT32;
6395*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA8I_EXT:
6396*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_SINT8;
6397*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA16I_EXT:
6398*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_SINT16;
6399*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA32I_EXT:
6400*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_SINT32;
6401*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA8UI_EXT:
6402*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_UINT8;
6403*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA16UI_EXT:
6404*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_UINT16;
6405*61046927SAndroid Build Coastguard Worker       case GL_LUMINANCE_ALPHA32UI_EXT:
6406*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_LA_UINT32;
6407*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY8:
6408*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_UNORM8;
6409*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY16:
6410*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_UNORM16;
6411*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY16F_ARB:
6412*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_FLOAT16;
6413*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY32F_ARB:
6414*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_FLOAT32;
6415*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY8I_EXT:
6416*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_SINT8;
6417*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY16I_EXT:
6418*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_SINT16;
6419*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY32I_EXT:
6420*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_SINT32;
6421*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY8UI_EXT:
6422*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_UINT8;
6423*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY16UI_EXT:
6424*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_UINT16;
6425*61046927SAndroid Build Coastguard Worker       case GL_INTENSITY32UI_EXT:
6426*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_I_UINT32;
6427*61046927SAndroid Build Coastguard Worker       default:
6428*61046927SAndroid Build Coastguard Worker          break;
6429*61046927SAndroid Build Coastguard Worker       }
6430*61046927SAndroid Build Coastguard Worker    }
6431*61046927SAndroid Build Coastguard Worker 
6432*61046927SAndroid Build Coastguard Worker    if (_mesa_has_ARB_texture_buffer_object_rgb32(ctx) ||
6433*61046927SAndroid Build Coastguard Worker        _mesa_has_OES_texture_buffer(ctx)) {
6434*61046927SAndroid Build Coastguard Worker       switch (internalFormat) {
6435*61046927SAndroid Build Coastguard Worker       case GL_RGB32F:
6436*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_RGB_FLOAT32;
6437*61046927SAndroid Build Coastguard Worker       case GL_RGB32UI:
6438*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_RGB_UINT32;
6439*61046927SAndroid Build Coastguard Worker       case GL_RGB32I:
6440*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_RGB_SINT32;
6441*61046927SAndroid Build Coastguard Worker       default:
6442*61046927SAndroid Build Coastguard Worker          break;
6443*61046927SAndroid Build Coastguard Worker       }
6444*61046927SAndroid Build Coastguard Worker    }
6445*61046927SAndroid Build Coastguard Worker 
6446*61046927SAndroid Build Coastguard Worker    switch (internalFormat) {
6447*61046927SAndroid Build Coastguard Worker    case GL_RGBA8:
6448*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R8G8B8A8_UNORM;
6449*61046927SAndroid Build Coastguard Worker    case GL_RGBA16:
6450*61046927SAndroid Build Coastguard Worker       if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx))
6451*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_NONE;
6452*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_UNORM16;
6453*61046927SAndroid Build Coastguard Worker    case GL_RGBA16F_ARB:
6454*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_FLOAT16;
6455*61046927SAndroid Build Coastguard Worker    case GL_RGBA32F_ARB:
6456*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_FLOAT32;
6457*61046927SAndroid Build Coastguard Worker    case GL_RGBA8I_EXT:
6458*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_SINT8;
6459*61046927SAndroid Build Coastguard Worker    case GL_RGBA16I_EXT:
6460*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_SINT16;
6461*61046927SAndroid Build Coastguard Worker    case GL_RGBA32I_EXT:
6462*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_SINT32;
6463*61046927SAndroid Build Coastguard Worker    case GL_RGBA8UI_EXT:
6464*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_UINT8;
6465*61046927SAndroid Build Coastguard Worker    case GL_RGBA16UI_EXT:
6466*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_UINT16;
6467*61046927SAndroid Build Coastguard Worker    case GL_RGBA32UI_EXT:
6468*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RGBA_UINT32;
6469*61046927SAndroid Build Coastguard Worker 
6470*61046927SAndroid Build Coastguard Worker    case GL_RG8:
6471*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_UNORM8;
6472*61046927SAndroid Build Coastguard Worker    case GL_RG16:
6473*61046927SAndroid Build Coastguard Worker       if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx))
6474*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_NONE;
6475*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_UNORM16;
6476*61046927SAndroid Build Coastguard Worker    case GL_RG16F:
6477*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_FLOAT16;
6478*61046927SAndroid Build Coastguard Worker    case GL_RG32F:
6479*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_FLOAT32;
6480*61046927SAndroid Build Coastguard Worker    case GL_RG8I:
6481*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_SINT8;
6482*61046927SAndroid Build Coastguard Worker    case GL_RG16I:
6483*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_SINT16;
6484*61046927SAndroid Build Coastguard Worker    case GL_RG32I:
6485*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_SINT32;
6486*61046927SAndroid Build Coastguard Worker    case GL_RG8UI:
6487*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_UINT8;
6488*61046927SAndroid Build Coastguard Worker    case GL_RG16UI:
6489*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_UINT16;
6490*61046927SAndroid Build Coastguard Worker    case GL_RG32UI:
6491*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_RG_UINT32;
6492*61046927SAndroid Build Coastguard Worker 
6493*61046927SAndroid Build Coastguard Worker    case GL_R8:
6494*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_UNORM8;
6495*61046927SAndroid Build Coastguard Worker    case GL_R16:
6496*61046927SAndroid Build Coastguard Worker       if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx))
6497*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_NONE;
6498*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_UNORM16;
6499*61046927SAndroid Build Coastguard Worker    case GL_R16F:
6500*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_FLOAT16;
6501*61046927SAndroid Build Coastguard Worker    case GL_R32F:
6502*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_FLOAT32;
6503*61046927SAndroid Build Coastguard Worker    case GL_R8I:
6504*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_SINT8;
6505*61046927SAndroid Build Coastguard Worker    case GL_R16I:
6506*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_SINT16;
6507*61046927SAndroid Build Coastguard Worker    case GL_R32I:
6508*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_SINT32;
6509*61046927SAndroid Build Coastguard Worker    case GL_R8UI:
6510*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_UINT8;
6511*61046927SAndroid Build Coastguard Worker    case GL_R16UI:
6512*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_UINT16;
6513*61046927SAndroid Build Coastguard Worker    case GL_R32UI:
6514*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_R_UINT32;
6515*61046927SAndroid Build Coastguard Worker 
6516*61046927SAndroid Build Coastguard Worker    default:
6517*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_NONE;
6518*61046927SAndroid Build Coastguard Worker    }
6519*61046927SAndroid Build Coastguard Worker }
6520*61046927SAndroid Build Coastguard Worker 
6521*61046927SAndroid Build Coastguard Worker 
6522*61046927SAndroid Build Coastguard Worker mesa_format
_mesa_validate_texbuffer_format(const struct gl_context * ctx,GLenum internalFormat)6523*61046927SAndroid Build Coastguard Worker _mesa_validate_texbuffer_format(const struct gl_context *ctx,
6524*61046927SAndroid Build Coastguard Worker                                 GLenum internalFormat)
6525*61046927SAndroid Build Coastguard Worker {
6526*61046927SAndroid Build Coastguard Worker    mesa_format format = _mesa_get_texbuffer_format(ctx, internalFormat);
6527*61046927SAndroid Build Coastguard Worker    GLenum datatype;
6528*61046927SAndroid Build Coastguard Worker 
6529*61046927SAndroid Build Coastguard Worker    if (format == MESA_FORMAT_NONE)
6530*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_NONE;
6531*61046927SAndroid Build Coastguard Worker 
6532*61046927SAndroid Build Coastguard Worker    datatype = _mesa_get_format_datatype(format);
6533*61046927SAndroid Build Coastguard Worker 
6534*61046927SAndroid Build Coastguard Worker    /* The GL_ARB_texture_buffer_object spec says:
6535*61046927SAndroid Build Coastguard Worker     *
6536*61046927SAndroid Build Coastguard Worker     *     "If ARB_texture_float is not supported, references to the
6537*61046927SAndroid Build Coastguard Worker     *     floating-point internal formats provided by that extension should be
6538*61046927SAndroid Build Coastguard Worker     *     removed, and such formats may not be passed to TexBufferARB."
6539*61046927SAndroid Build Coastguard Worker     *
6540*61046927SAndroid Build Coastguard Worker     * As a result, GL_HALF_FLOAT internal format depends on both
6541*61046927SAndroid Build Coastguard Worker     * GL_ARB_texture_float and GL_ARB_half_float_pixel.
6542*61046927SAndroid Build Coastguard Worker     */
6543*61046927SAndroid Build Coastguard Worker    if ((datatype == GL_FLOAT || datatype == GL_HALF_FLOAT) &&
6544*61046927SAndroid Build Coastguard Worker        !ctx->Extensions.ARB_texture_float)
6545*61046927SAndroid Build Coastguard Worker       return MESA_FORMAT_NONE;
6546*61046927SAndroid Build Coastguard Worker 
6547*61046927SAndroid Build Coastguard Worker    if (!ctx->Extensions.ARB_texture_rg) {
6548*61046927SAndroid Build Coastguard Worker       GLenum base_format = _mesa_get_format_base_format(format);
6549*61046927SAndroid Build Coastguard Worker       if (base_format == GL_R || base_format == GL_RG)
6550*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_NONE;
6551*61046927SAndroid Build Coastguard Worker    }
6552*61046927SAndroid Build Coastguard Worker 
6553*61046927SAndroid Build Coastguard Worker    if (!ctx->Extensions.ARB_texture_buffer_object_rgb32) {
6554*61046927SAndroid Build Coastguard Worker       GLenum base_format = _mesa_get_format_base_format(format);
6555*61046927SAndroid Build Coastguard Worker       if (base_format == GL_RGB)
6556*61046927SAndroid Build Coastguard Worker          return MESA_FORMAT_NONE;
6557*61046927SAndroid Build Coastguard Worker    }
6558*61046927SAndroid Build Coastguard Worker    return format;
6559*61046927SAndroid Build Coastguard Worker }
6560*61046927SAndroid Build Coastguard Worker 
6561*61046927SAndroid Build Coastguard Worker 
6562*61046927SAndroid Build Coastguard Worker /**
6563*61046927SAndroid Build Coastguard Worker  * Do work common to glTexBuffer, glTexBufferRange, glTextureBuffer
6564*61046927SAndroid Build Coastguard Worker  * and glTextureBufferRange, including some error checking.
6565*61046927SAndroid Build Coastguard Worker  */
6566*61046927SAndroid Build Coastguard Worker static void
texture_buffer_range(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum internalFormat,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,const char * caller)6567*61046927SAndroid Build Coastguard Worker texture_buffer_range(struct gl_context *ctx,
6568*61046927SAndroid Build Coastguard Worker                      struct gl_texture_object *texObj,
6569*61046927SAndroid Build Coastguard Worker                      GLenum internalFormat,
6570*61046927SAndroid Build Coastguard Worker                      struct gl_buffer_object *bufObj,
6571*61046927SAndroid Build Coastguard Worker                      GLintptr offset, GLsizeiptr size,
6572*61046927SAndroid Build Coastguard Worker                      const char *caller)
6573*61046927SAndroid Build Coastguard Worker {
6574*61046927SAndroid Build Coastguard Worker    GLintptr oldOffset = texObj->BufferOffset;
6575*61046927SAndroid Build Coastguard Worker    GLsizeiptr oldSize = texObj->BufferSize;
6576*61046927SAndroid Build Coastguard Worker    mesa_format format;
6577*61046927SAndroid Build Coastguard Worker    mesa_format old_format;
6578*61046927SAndroid Build Coastguard Worker 
6579*61046927SAndroid Build Coastguard Worker    /* NOTE: ARB_texture_buffer_object might not be supported in
6580*61046927SAndroid Build Coastguard Worker     * the compatibility profile.
6581*61046927SAndroid Build Coastguard Worker     */
6582*61046927SAndroid Build Coastguard Worker    if (!_mesa_has_ARB_texture_buffer_object(ctx) &&
6583*61046927SAndroid Build Coastguard Worker        !_mesa_has_OES_texture_buffer(ctx)) {
6584*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
6585*61046927SAndroid Build Coastguard Worker                   "%s(ARB_texture_buffer_object is not"
6586*61046927SAndroid Build Coastguard Worker                   " implemented for the compatibility profile)", caller);
6587*61046927SAndroid Build Coastguard Worker       return;
6588*61046927SAndroid Build Coastguard Worker    }
6589*61046927SAndroid Build Coastguard Worker 
6590*61046927SAndroid Build Coastguard Worker    if (texObj->HandleAllocated) {
6591*61046927SAndroid Build Coastguard Worker       /* The ARB_bindless_texture spec says:
6592*61046927SAndroid Build Coastguard Worker        *
6593*61046927SAndroid Build Coastguard Worker        * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
6594*61046927SAndroid Build Coastguard Worker        *  CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
6595*61046927SAndroid Build Coastguard Worker        *  functions defined in terms of these, if the texture object to be
6596*61046927SAndroid Build Coastguard Worker        *  modified is referenced by one or more texture or image handles."
6597*61046927SAndroid Build Coastguard Worker        */
6598*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable texture)", caller);
6599*61046927SAndroid Build Coastguard Worker       return;
6600*61046927SAndroid Build Coastguard Worker    }
6601*61046927SAndroid Build Coastguard Worker 
6602*61046927SAndroid Build Coastguard Worker    format = _mesa_validate_texbuffer_format(ctx, internalFormat);
6603*61046927SAndroid Build Coastguard Worker    if (format == MESA_FORMAT_NONE) {
6604*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat %s)",
6605*61046927SAndroid Build Coastguard Worker                   caller, _mesa_enum_to_string(internalFormat));
6606*61046927SAndroid Build Coastguard Worker       return;
6607*61046927SAndroid Build Coastguard Worker    }
6608*61046927SAndroid Build Coastguard Worker 
6609*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, GL_TEXTURE_BIT);
6610*61046927SAndroid Build Coastguard Worker 
6611*61046927SAndroid Build Coastguard Worker    _mesa_lock_texture(ctx, texObj);
6612*61046927SAndroid Build Coastguard Worker    {
6613*61046927SAndroid Build Coastguard Worker       _mesa_reference_buffer_object_shared(ctx, &texObj->BufferObject, bufObj);
6614*61046927SAndroid Build Coastguard Worker       texObj->BufferObjectFormat = internalFormat;
6615*61046927SAndroid Build Coastguard Worker       old_format = texObj->_BufferObjectFormat;
6616*61046927SAndroid Build Coastguard Worker       texObj->_BufferObjectFormat = format;
6617*61046927SAndroid Build Coastguard Worker       texObj->BufferOffset = offset;
6618*61046927SAndroid Build Coastguard Worker       texObj->BufferSize = size;
6619*61046927SAndroid Build Coastguard Worker    }
6620*61046927SAndroid Build Coastguard Worker    _mesa_unlock_texture(ctx, texObj);
6621*61046927SAndroid Build Coastguard Worker 
6622*61046927SAndroid Build Coastguard Worker    if (old_format != format) {
6623*61046927SAndroid Build Coastguard Worker       st_texture_release_all_sampler_views(st_context(ctx), texObj);
6624*61046927SAndroid Build Coastguard Worker    } else {
6625*61046927SAndroid Build Coastguard Worker       if (offset != oldOffset) {
6626*61046927SAndroid Build Coastguard Worker          st_texture_release_all_sampler_views(st_context(ctx), texObj);
6627*61046927SAndroid Build Coastguard Worker       }
6628*61046927SAndroid Build Coastguard Worker       if (size != oldSize) {
6629*61046927SAndroid Build Coastguard Worker          st_texture_release_all_sampler_views(st_context(ctx), texObj);
6630*61046927SAndroid Build Coastguard Worker       }
6631*61046927SAndroid Build Coastguard Worker    }
6632*61046927SAndroid Build Coastguard Worker 
6633*61046927SAndroid Build Coastguard Worker    ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS;
6634*61046927SAndroid Build Coastguard Worker 
6635*61046927SAndroid Build Coastguard Worker    if (bufObj) {
6636*61046927SAndroid Build Coastguard Worker       bufObj->UsageHistory |= USAGE_TEXTURE_BUFFER;
6637*61046927SAndroid Build Coastguard Worker    }
6638*61046927SAndroid Build Coastguard Worker }
6639*61046927SAndroid Build Coastguard Worker 
6640*61046927SAndroid Build Coastguard Worker 
6641*61046927SAndroid Build Coastguard Worker /**
6642*61046927SAndroid Build Coastguard Worker  * Make sure the texture buffer target is GL_TEXTURE_BUFFER.
6643*61046927SAndroid Build Coastguard Worker  * Return true if it is, and return false if it is not
6644*61046927SAndroid Build Coastguard Worker  * (and throw INVALID ENUM as dictated in the OpenGL 4.5
6645*61046927SAndroid Build Coastguard Worker  * core spec, 02.02.2015, PDF page 245).
6646*61046927SAndroid Build Coastguard Worker  */
6647*61046927SAndroid Build Coastguard Worker static bool
check_texture_buffer_target(struct gl_context * ctx,GLenum target,const char * caller,bool dsa)6648*61046927SAndroid Build Coastguard Worker check_texture_buffer_target(struct gl_context *ctx, GLenum target,
6649*61046927SAndroid Build Coastguard Worker                             const char *caller, bool dsa)
6650*61046927SAndroid Build Coastguard Worker {
6651*61046927SAndroid Build Coastguard Worker    if (target != GL_TEXTURE_BUFFER_ARB) {
6652*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM,
6653*61046927SAndroid Build Coastguard Worker                   "%s(texture target is not GL_TEXTURE_BUFFER)", caller);
6654*61046927SAndroid Build Coastguard Worker       return false;
6655*61046927SAndroid Build Coastguard Worker    }
6656*61046927SAndroid Build Coastguard Worker    else
6657*61046927SAndroid Build Coastguard Worker       return true;
6658*61046927SAndroid Build Coastguard Worker }
6659*61046927SAndroid Build Coastguard Worker 
6660*61046927SAndroid Build Coastguard Worker /**
6661*61046927SAndroid Build Coastguard Worker  * Check for errors related to the texture buffer range.
6662*61046927SAndroid Build Coastguard Worker  * Return false if errors are found, true if none are found.
6663*61046927SAndroid Build Coastguard Worker  */
6664*61046927SAndroid Build Coastguard Worker static bool
check_texture_buffer_range(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,const char * caller)6665*61046927SAndroid Build Coastguard Worker check_texture_buffer_range(struct gl_context *ctx,
6666*61046927SAndroid Build Coastguard Worker                            struct gl_buffer_object *bufObj,
6667*61046927SAndroid Build Coastguard Worker                            GLintptr offset, GLsizeiptr size,
6668*61046927SAndroid Build Coastguard Worker                            const char *caller)
6669*61046927SAndroid Build Coastguard Worker {
6670*61046927SAndroid Build Coastguard Worker    /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6671*61046927SAndroid Build Coastguard Worker     * Textures (PDF page 245):
6672*61046927SAndroid Build Coastguard Worker     *    "An INVALID_VALUE error is generated if offset is negative, if
6673*61046927SAndroid Build Coastguard Worker     *    size is less than or equal to zero, or if offset + size is greater
6674*61046927SAndroid Build Coastguard Worker     *    than the value of BUFFER_SIZE for the buffer bound to target."
6675*61046927SAndroid Build Coastguard Worker     */
6676*61046927SAndroid Build Coastguard Worker    if (offset < 0) {
6677*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d < 0)", caller,
6678*61046927SAndroid Build Coastguard Worker                   (int) offset);
6679*61046927SAndroid Build Coastguard Worker       return false;
6680*61046927SAndroid Build Coastguard Worker    }
6681*61046927SAndroid Build Coastguard Worker 
6682*61046927SAndroid Build Coastguard Worker    if (size <= 0) {
6683*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d <= 0)", caller,
6684*61046927SAndroid Build Coastguard Worker                   (int) size);
6685*61046927SAndroid Build Coastguard Worker       return false;
6686*61046927SAndroid Build Coastguard Worker    }
6687*61046927SAndroid Build Coastguard Worker 
6688*61046927SAndroid Build Coastguard Worker    if (offset + size > bufObj->Size) {
6689*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
6690*61046927SAndroid Build Coastguard Worker                   "%s(offset=%d + size=%d > buffer_size=%d)", caller,
6691*61046927SAndroid Build Coastguard Worker                   (int) offset, (int) size, (int) bufObj->Size);
6692*61046927SAndroid Build Coastguard Worker       return false;
6693*61046927SAndroid Build Coastguard Worker    }
6694*61046927SAndroid Build Coastguard Worker 
6695*61046927SAndroid Build Coastguard Worker    /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6696*61046927SAndroid Build Coastguard Worker     * Textures (PDF page 245):
6697*61046927SAndroid Build Coastguard Worker     *    "An INVALID_VALUE error is generated if offset is not an integer
6698*61046927SAndroid Build Coastguard Worker     *    multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT."
6699*61046927SAndroid Build Coastguard Worker     */
6700*61046927SAndroid Build Coastguard Worker    if (offset % ctx->Const.TextureBufferOffsetAlignment) {
6701*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
6702*61046927SAndroid Build Coastguard Worker                   "%s(invalid offset alignment)", caller);
6703*61046927SAndroid Build Coastguard Worker       return false;
6704*61046927SAndroid Build Coastguard Worker    }
6705*61046927SAndroid Build Coastguard Worker 
6706*61046927SAndroid Build Coastguard Worker    return true;
6707*61046927SAndroid Build Coastguard Worker }
6708*61046927SAndroid Build Coastguard Worker 
6709*61046927SAndroid Build Coastguard Worker 
6710*61046927SAndroid Build Coastguard Worker /** GL_ARB_texture_buffer_object */
6711*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexBuffer(GLenum target,GLenum internalFormat,GLuint buffer)6712*61046927SAndroid Build Coastguard Worker _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
6713*61046927SAndroid Build Coastguard Worker {
6714*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
6715*61046927SAndroid Build Coastguard Worker    struct gl_buffer_object *bufObj;
6716*61046927SAndroid Build Coastguard Worker 
6717*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
6718*61046927SAndroid Build Coastguard Worker 
6719*61046927SAndroid Build Coastguard Worker    /* Need to catch a bad target before it gets to
6720*61046927SAndroid Build Coastguard Worker     * _mesa_get_current_tex_object.
6721*61046927SAndroid Build Coastguard Worker     */
6722*61046927SAndroid Build Coastguard Worker    if (!check_texture_buffer_target(ctx, target, "glTexBuffer", false))
6723*61046927SAndroid Build Coastguard Worker       return;
6724*61046927SAndroid Build Coastguard Worker 
6725*61046927SAndroid Build Coastguard Worker    if (buffer) {
6726*61046927SAndroid Build Coastguard Worker       bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBuffer");
6727*61046927SAndroid Build Coastguard Worker       if (!bufObj)
6728*61046927SAndroid Build Coastguard Worker          return;
6729*61046927SAndroid Build Coastguard Worker    } else
6730*61046927SAndroid Build Coastguard Worker       bufObj = NULL;
6731*61046927SAndroid Build Coastguard Worker 
6732*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_current_tex_object(ctx, target);
6733*61046927SAndroid Build Coastguard Worker    if (!texObj)
6734*61046927SAndroid Build Coastguard Worker       return;
6735*61046927SAndroid Build Coastguard Worker 
6736*61046927SAndroid Build Coastguard Worker    texture_buffer_range(ctx, texObj, internalFormat, bufObj, 0,
6737*61046927SAndroid Build Coastguard Worker                         buffer ? -1 : 0, "glTexBuffer");
6738*61046927SAndroid Build Coastguard Worker }
6739*61046927SAndroid Build Coastguard Worker 
6740*61046927SAndroid Build Coastguard Worker 
6741*61046927SAndroid Build Coastguard Worker /** GL_ARB_texture_buffer_range */
6742*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexBufferRange(GLenum target,GLenum internalFormat,GLuint buffer,GLintptr offset,GLsizeiptr size)6743*61046927SAndroid Build Coastguard Worker _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
6744*61046927SAndroid Build Coastguard Worker                      GLintptr offset, GLsizeiptr size)
6745*61046927SAndroid Build Coastguard Worker {
6746*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
6747*61046927SAndroid Build Coastguard Worker    struct gl_buffer_object *bufObj;
6748*61046927SAndroid Build Coastguard Worker 
6749*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
6750*61046927SAndroid Build Coastguard Worker 
6751*61046927SAndroid Build Coastguard Worker    /* Need to catch a bad target before it gets to
6752*61046927SAndroid Build Coastguard Worker     * _mesa_get_current_tex_object.
6753*61046927SAndroid Build Coastguard Worker     */
6754*61046927SAndroid Build Coastguard Worker    if (!check_texture_buffer_target(ctx, target, "glTexBufferRange", false))
6755*61046927SAndroid Build Coastguard Worker       return;
6756*61046927SAndroid Build Coastguard Worker 
6757*61046927SAndroid Build Coastguard Worker    if (buffer) {
6758*61046927SAndroid Build Coastguard Worker       bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBufferRange");
6759*61046927SAndroid Build Coastguard Worker       if (!bufObj)
6760*61046927SAndroid Build Coastguard Worker          return;
6761*61046927SAndroid Build Coastguard Worker 
6762*61046927SAndroid Build Coastguard Worker       if (!check_texture_buffer_range(ctx, bufObj, offset, size,
6763*61046927SAndroid Build Coastguard Worker           "glTexBufferRange"))
6764*61046927SAndroid Build Coastguard Worker          return;
6765*61046927SAndroid Build Coastguard Worker 
6766*61046927SAndroid Build Coastguard Worker    } else {
6767*61046927SAndroid Build Coastguard Worker       /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6768*61046927SAndroid Build Coastguard Worker        * Textures (PDF page 254):
6769*61046927SAndroid Build Coastguard Worker        *    "If buffer is zero, then any buffer object attached to the buffer
6770*61046927SAndroid Build Coastguard Worker        *    texture is detached, the values offset and size are ignored and
6771*61046927SAndroid Build Coastguard Worker        *    the state for offset and size for the buffer texture are reset to
6772*61046927SAndroid Build Coastguard Worker        *    zero."
6773*61046927SAndroid Build Coastguard Worker        */
6774*61046927SAndroid Build Coastguard Worker       offset = 0;
6775*61046927SAndroid Build Coastguard Worker       size = 0;
6776*61046927SAndroid Build Coastguard Worker       bufObj = NULL;
6777*61046927SAndroid Build Coastguard Worker    }
6778*61046927SAndroid Build Coastguard Worker 
6779*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_current_tex_object(ctx, target);
6780*61046927SAndroid Build Coastguard Worker    if (!texObj)
6781*61046927SAndroid Build Coastguard Worker       return;
6782*61046927SAndroid Build Coastguard Worker 
6783*61046927SAndroid Build Coastguard Worker    texture_buffer_range(ctx, texObj, internalFormat, bufObj,
6784*61046927SAndroid Build Coastguard Worker                         offset, size, "glTexBufferRange");
6785*61046927SAndroid Build Coastguard Worker }
6786*61046927SAndroid Build Coastguard Worker 
6787*61046927SAndroid Build Coastguard Worker 
6788*61046927SAndroid Build Coastguard Worker /** GL_ARB_texture_buffer_range + GL_EXT_direct_state_access */
6789*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureBufferRangeEXT(GLuint texture,GLenum target,GLenum internalFormat,GLuint buffer,GLintptr offset,GLsizeiptr size)6790*61046927SAndroid Build Coastguard Worker _mesa_TextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalFormat,
6791*61046927SAndroid Build Coastguard Worker                             GLuint buffer, GLintptr offset, GLsizeiptr size)
6792*61046927SAndroid Build Coastguard Worker {
6793*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
6794*61046927SAndroid Build Coastguard Worker    struct gl_buffer_object *bufObj;
6795*61046927SAndroid Build Coastguard Worker 
6796*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
6797*61046927SAndroid Build Coastguard Worker 
6798*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
6799*61046927SAndroid Build Coastguard Worker                                            "glTextureBufferRangeEXT");
6800*61046927SAndroid Build Coastguard Worker    if (!texObj)
6801*61046927SAndroid Build Coastguard Worker       return;
6802*61046927SAndroid Build Coastguard Worker 
6803*61046927SAndroid Build Coastguard Worker    if (!check_texture_buffer_target(ctx, target, "glTextureBufferRangeEXT", true))
6804*61046927SAndroid Build Coastguard Worker       return;
6805*61046927SAndroid Build Coastguard Worker 
6806*61046927SAndroid Build Coastguard Worker    if (buffer) {
6807*61046927SAndroid Build Coastguard Worker       bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBufferRangeEXT");
6808*61046927SAndroid Build Coastguard Worker       if (!bufObj)
6809*61046927SAndroid Build Coastguard Worker          return;
6810*61046927SAndroid Build Coastguard Worker 
6811*61046927SAndroid Build Coastguard Worker       if (!check_texture_buffer_range(ctx, bufObj, offset, size,
6812*61046927SAndroid Build Coastguard Worker           "glTextureBufferRangeEXT"))
6813*61046927SAndroid Build Coastguard Worker          return;
6814*61046927SAndroid Build Coastguard Worker 
6815*61046927SAndroid Build Coastguard Worker    } else {
6816*61046927SAndroid Build Coastguard Worker       /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6817*61046927SAndroid Build Coastguard Worker        * Textures (PDF page 254):
6818*61046927SAndroid Build Coastguard Worker        *    "If buffer is zero, then any buffer object attached to the buffer
6819*61046927SAndroid Build Coastguard Worker        *    texture is detached, the values offset and size are ignored and
6820*61046927SAndroid Build Coastguard Worker        *    the state for offset and size for the buffer texture are reset to
6821*61046927SAndroid Build Coastguard Worker        *    zero."
6822*61046927SAndroid Build Coastguard Worker        */
6823*61046927SAndroid Build Coastguard Worker       offset = 0;
6824*61046927SAndroid Build Coastguard Worker       size = 0;
6825*61046927SAndroid Build Coastguard Worker       bufObj = NULL;
6826*61046927SAndroid Build Coastguard Worker    }
6827*61046927SAndroid Build Coastguard Worker 
6828*61046927SAndroid Build Coastguard Worker    texture_buffer_range(ctx, texObj, internalFormat, bufObj,
6829*61046927SAndroid Build Coastguard Worker                         offset, size, "glTextureBufferRangeEXT");
6830*61046927SAndroid Build Coastguard Worker }
6831*61046927SAndroid Build Coastguard Worker 
6832*61046927SAndroid Build Coastguard Worker 
6833*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureBuffer(GLuint texture,GLenum internalFormat,GLuint buffer)6834*61046927SAndroid Build Coastguard Worker _mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer)
6835*61046927SAndroid Build Coastguard Worker {
6836*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
6837*61046927SAndroid Build Coastguard Worker    struct gl_buffer_object *bufObj;
6838*61046927SAndroid Build Coastguard Worker 
6839*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
6840*61046927SAndroid Build Coastguard Worker 
6841*61046927SAndroid Build Coastguard Worker    if (buffer) {
6842*61046927SAndroid Build Coastguard Worker       bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer");
6843*61046927SAndroid Build Coastguard Worker       if (!bufObj)
6844*61046927SAndroid Build Coastguard Worker          return;
6845*61046927SAndroid Build Coastguard Worker    } else
6846*61046927SAndroid Build Coastguard Worker       bufObj = NULL;
6847*61046927SAndroid Build Coastguard Worker 
6848*61046927SAndroid Build Coastguard Worker    /* Get the texture object by Name. */
6849*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBuffer");
6850*61046927SAndroid Build Coastguard Worker    if (!texObj)
6851*61046927SAndroid Build Coastguard Worker       return;
6852*61046927SAndroid Build Coastguard Worker 
6853*61046927SAndroid Build Coastguard Worker    if (!check_texture_buffer_target(ctx, texObj->Target, "glTextureBuffer", true))
6854*61046927SAndroid Build Coastguard Worker       return;
6855*61046927SAndroid Build Coastguard Worker 
6856*61046927SAndroid Build Coastguard Worker    texture_buffer_range(ctx, texObj, internalFormat,
6857*61046927SAndroid Build Coastguard Worker                         bufObj, 0, buffer ? -1 : 0, "glTextureBuffer");
6858*61046927SAndroid Build Coastguard Worker }
6859*61046927SAndroid Build Coastguard Worker 
6860*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureBufferEXT(GLuint texture,GLenum target,GLenum internalFormat,GLuint buffer)6861*61046927SAndroid Build Coastguard Worker _mesa_TextureBufferEXT(GLuint texture, GLenum target,
6862*61046927SAndroid Build Coastguard Worker                        GLenum internalFormat, GLuint buffer)
6863*61046927SAndroid Build Coastguard Worker {
6864*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
6865*61046927SAndroid Build Coastguard Worker    struct gl_buffer_object *bufObj;
6866*61046927SAndroid Build Coastguard Worker 
6867*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
6868*61046927SAndroid Build Coastguard Worker 
6869*61046927SAndroid Build Coastguard Worker    if (buffer) {
6870*61046927SAndroid Build Coastguard Worker       bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer");
6871*61046927SAndroid Build Coastguard Worker       if (!bufObj)
6872*61046927SAndroid Build Coastguard Worker          return;
6873*61046927SAndroid Build Coastguard Worker    } else
6874*61046927SAndroid Build Coastguard Worker       bufObj = NULL;
6875*61046927SAndroid Build Coastguard Worker 
6876*61046927SAndroid Build Coastguard Worker    /* Get the texture object by Name. */
6877*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_or_create_texture(ctx, target, texture,
6878*61046927SAndroid Build Coastguard Worker                                            false, true,
6879*61046927SAndroid Build Coastguard Worker                                            "glTextureBufferEXT");
6880*61046927SAndroid Build Coastguard Worker 
6881*61046927SAndroid Build Coastguard Worker    if (!texObj ||
6882*61046927SAndroid Build Coastguard Worker        !check_texture_buffer_target(ctx, texObj->Target, "glTextureBufferEXT", true))
6883*61046927SAndroid Build Coastguard Worker       return;
6884*61046927SAndroid Build Coastguard Worker 
6885*61046927SAndroid Build Coastguard Worker    texture_buffer_range(ctx, texObj, internalFormat,
6886*61046927SAndroid Build Coastguard Worker                         bufObj, 0, buffer ? -1 : 0, "glTextureBufferEXT");
6887*61046927SAndroid Build Coastguard Worker }
6888*61046927SAndroid Build Coastguard Worker 
6889*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MultiTexBufferEXT(GLenum texunit,GLenum target,GLenum internalFormat,GLuint buffer)6890*61046927SAndroid Build Coastguard Worker _mesa_MultiTexBufferEXT(GLenum texunit, GLenum target,
6891*61046927SAndroid Build Coastguard Worker                         GLenum internalFormat, GLuint buffer)
6892*61046927SAndroid Build Coastguard Worker {
6893*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
6894*61046927SAndroid Build Coastguard Worker    struct gl_buffer_object *bufObj;
6895*61046927SAndroid Build Coastguard Worker 
6896*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
6897*61046927SAndroid Build Coastguard Worker 
6898*61046927SAndroid Build Coastguard Worker    if (buffer) {
6899*61046927SAndroid Build Coastguard Worker       bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMultiTexBufferEXT");
6900*61046927SAndroid Build Coastguard Worker       if (!bufObj)
6901*61046927SAndroid Build Coastguard Worker          return;
6902*61046927SAndroid Build Coastguard Worker    } else
6903*61046927SAndroid Build Coastguard Worker       bufObj = NULL;
6904*61046927SAndroid Build Coastguard Worker 
6905*61046927SAndroid Build Coastguard Worker    /* Get the texture object */
6906*61046927SAndroid Build Coastguard Worker    texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
6907*61046927SAndroid Build Coastguard Worker                                                    texunit - GL_TEXTURE0,
6908*61046927SAndroid Build Coastguard Worker                                                    true,
6909*61046927SAndroid Build Coastguard Worker                                                    "glMultiTexBufferEXT");
6910*61046927SAndroid Build Coastguard Worker 
6911*61046927SAndroid Build Coastguard Worker    if (!texObj ||
6912*61046927SAndroid Build Coastguard Worker        !check_texture_buffer_target(ctx, texObj->Target, "glMultiTexBufferEXT", false))
6913*61046927SAndroid Build Coastguard Worker       return;
6914*61046927SAndroid Build Coastguard Worker 
6915*61046927SAndroid Build Coastguard Worker    texture_buffer_range(ctx, texObj, internalFormat,
6916*61046927SAndroid Build Coastguard Worker                         bufObj, 0, buffer ? -1 : 0, "glMultiTexBufferEXT");
6917*61046927SAndroid Build Coastguard Worker }
6918*61046927SAndroid Build Coastguard Worker 
6919*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureBufferRange(GLuint texture,GLenum internalFormat,GLuint buffer,GLintptr offset,GLsizeiptr size)6920*61046927SAndroid Build Coastguard Worker _mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer,
6921*61046927SAndroid Build Coastguard Worker                          GLintptr offset, GLsizeiptr size)
6922*61046927SAndroid Build Coastguard Worker {
6923*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
6924*61046927SAndroid Build Coastguard Worker    struct gl_buffer_object *bufObj;
6925*61046927SAndroid Build Coastguard Worker 
6926*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
6927*61046927SAndroid Build Coastguard Worker 
6928*61046927SAndroid Build Coastguard Worker    if (buffer) {
6929*61046927SAndroid Build Coastguard Worker       bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
6930*61046927SAndroid Build Coastguard Worker                                           "glTextureBufferRange");
6931*61046927SAndroid Build Coastguard Worker       if (!bufObj)
6932*61046927SAndroid Build Coastguard Worker          return;
6933*61046927SAndroid Build Coastguard Worker 
6934*61046927SAndroid Build Coastguard Worker       if (!check_texture_buffer_range(ctx, bufObj, offset, size,
6935*61046927SAndroid Build Coastguard Worker           "glTextureBufferRange"))
6936*61046927SAndroid Build Coastguard Worker          return;
6937*61046927SAndroid Build Coastguard Worker 
6938*61046927SAndroid Build Coastguard Worker    } else {
6939*61046927SAndroid Build Coastguard Worker       /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6940*61046927SAndroid Build Coastguard Worker        * Textures (PDF page 254):
6941*61046927SAndroid Build Coastguard Worker        *    "If buffer is zero, then any buffer object attached to the buffer
6942*61046927SAndroid Build Coastguard Worker        *    texture is detached, the values offset and size are ignored and
6943*61046927SAndroid Build Coastguard Worker        *    the state for offset and size for the buffer texture are reset to
6944*61046927SAndroid Build Coastguard Worker        *    zero."
6945*61046927SAndroid Build Coastguard Worker        */
6946*61046927SAndroid Build Coastguard Worker       offset = 0;
6947*61046927SAndroid Build Coastguard Worker       size = 0;
6948*61046927SAndroid Build Coastguard Worker       bufObj = NULL;
6949*61046927SAndroid Build Coastguard Worker    }
6950*61046927SAndroid Build Coastguard Worker 
6951*61046927SAndroid Build Coastguard Worker    /* Get the texture object by Name. */
6952*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBufferRange");
6953*61046927SAndroid Build Coastguard Worker    if (!texObj)
6954*61046927SAndroid Build Coastguard Worker       return;
6955*61046927SAndroid Build Coastguard Worker 
6956*61046927SAndroid Build Coastguard Worker    if (!check_texture_buffer_target(ctx, texObj->Target,
6957*61046927SAndroid Build Coastguard Worker        "glTextureBufferRange", true))
6958*61046927SAndroid Build Coastguard Worker       return;
6959*61046927SAndroid Build Coastguard Worker 
6960*61046927SAndroid Build Coastguard Worker    texture_buffer_range(ctx, texObj, internalFormat,
6961*61046927SAndroid Build Coastguard Worker                         bufObj, offset, size, "glTextureBufferRange");
6962*61046927SAndroid Build Coastguard Worker }
6963*61046927SAndroid Build Coastguard Worker 
6964*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_is_renderable_texture_format(const struct gl_context * ctx,GLenum internalformat)6965*61046927SAndroid Build Coastguard Worker _mesa_is_renderable_texture_format(const struct gl_context *ctx,
6966*61046927SAndroid Build Coastguard Worker                                    GLenum internalformat)
6967*61046927SAndroid Build Coastguard Worker {
6968*61046927SAndroid Build Coastguard Worker    /* Everything that is allowed for renderbuffers,
6969*61046927SAndroid Build Coastguard Worker     * except for a base format of GL_STENCIL_INDEX, unless supported.
6970*61046927SAndroid Build Coastguard Worker     */
6971*61046927SAndroid Build Coastguard Worker    GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat);
6972*61046927SAndroid Build Coastguard Worker    if (ctx->Extensions.ARB_texture_stencil8)
6973*61046927SAndroid Build Coastguard Worker       return baseFormat != 0;
6974*61046927SAndroid Build Coastguard Worker    else
6975*61046927SAndroid Build Coastguard Worker       return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX;
6976*61046927SAndroid Build Coastguard Worker }
6977*61046927SAndroid Build Coastguard Worker 
6978*61046927SAndroid Build Coastguard Worker 
6979*61046927SAndroid Build Coastguard Worker /** GL_ARB_texture_multisample */
6980*61046927SAndroid Build Coastguard Worker static GLboolean
check_multisample_target(GLuint dims,GLenum target,bool dsa)6981*61046927SAndroid Build Coastguard Worker check_multisample_target(GLuint dims, GLenum target, bool dsa)
6982*61046927SAndroid Build Coastguard Worker {
6983*61046927SAndroid Build Coastguard Worker    switch(target) {
6984*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE:
6985*61046927SAndroid Build Coastguard Worker       return dims == 2;
6986*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
6987*61046927SAndroid Build Coastguard Worker       return dims == 2 && !dsa;
6988*61046927SAndroid Build Coastguard Worker    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
6989*61046927SAndroid Build Coastguard Worker       return dims == 3;
6990*61046927SAndroid Build Coastguard Worker    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
6991*61046927SAndroid Build Coastguard Worker       return dims == 3 && !dsa;
6992*61046927SAndroid Build Coastguard Worker    default:
6993*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
6994*61046927SAndroid Build Coastguard Worker    }
6995*61046927SAndroid Build Coastguard Worker }
6996*61046927SAndroid Build Coastguard Worker 
6997*61046927SAndroid Build Coastguard Worker 
6998*61046927SAndroid Build Coastguard Worker static void
texture_image_multisample(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,struct gl_memory_object * memObj,GLenum target,GLsizei samples,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations,GLboolean immutable,GLuint64 offset,const char * func)6999*61046927SAndroid Build Coastguard Worker texture_image_multisample(struct gl_context *ctx, GLuint dims,
7000*61046927SAndroid Build Coastguard Worker                           struct gl_texture_object *texObj,
7001*61046927SAndroid Build Coastguard Worker                           struct gl_memory_object *memObj,
7002*61046927SAndroid Build Coastguard Worker                           GLenum target, GLsizei samples,
7003*61046927SAndroid Build Coastguard Worker                           GLint internalformat, GLsizei width,
7004*61046927SAndroid Build Coastguard Worker                           GLsizei height, GLsizei depth,
7005*61046927SAndroid Build Coastguard Worker                           GLboolean fixedsamplelocations,
7006*61046927SAndroid Build Coastguard Worker                           GLboolean immutable, GLuint64 offset,
7007*61046927SAndroid Build Coastguard Worker                           const char *func)
7008*61046927SAndroid Build Coastguard Worker {
7009*61046927SAndroid Build Coastguard Worker    struct gl_texture_image *texImage;
7010*61046927SAndroid Build Coastguard Worker    GLboolean sizeOK, dimensionsOK, samplesOK;
7011*61046927SAndroid Build Coastguard Worker    mesa_format texFormat;
7012*61046927SAndroid Build Coastguard Worker    GLenum sample_count_error;
7013*61046927SAndroid Build Coastguard Worker    bool dsa = strstr(func, "ture") ? true : false;
7014*61046927SAndroid Build Coastguard Worker 
7015*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) {
7016*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "%s(target=%s, samples=%d, internalformat=%s)\n", func,
7017*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target), samples, _mesa_enum_to_string(internalformat));
7018*61046927SAndroid Build Coastguard Worker    }
7019*61046927SAndroid Build Coastguard Worker 
7020*61046927SAndroid Build Coastguard Worker    if (!((ctx->Extensions.ARB_texture_multisample
7021*61046927SAndroid Build Coastguard Worker          && _mesa_is_desktop_gl(ctx))) && !_mesa_is_gles31(ctx)) {
7022*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
7023*61046927SAndroid Build Coastguard Worker       return;
7024*61046927SAndroid Build Coastguard Worker    }
7025*61046927SAndroid Build Coastguard Worker 
7026*61046927SAndroid Build Coastguard Worker    if (samples < 1) {
7027*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples < 1)", func);
7028*61046927SAndroid Build Coastguard Worker       return;
7029*61046927SAndroid Build Coastguard Worker    }
7030*61046927SAndroid Build Coastguard Worker 
7031*61046927SAndroid Build Coastguard Worker    if (!check_multisample_target(dims, target, dsa)) {
7032*61046927SAndroid Build Coastguard Worker       GLenum err = dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
7033*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, err, "%s(target=%s)", func,
7034*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(target));
7035*61046927SAndroid Build Coastguard Worker       return;
7036*61046927SAndroid Build Coastguard Worker    }
7037*61046927SAndroid Build Coastguard Worker 
7038*61046927SAndroid Build Coastguard Worker    /* check that the specified internalformat is color/depth/stencil-renderable;
7039*61046927SAndroid Build Coastguard Worker     * refer GL3.1 spec 4.4.4
7040*61046927SAndroid Build Coastguard Worker     */
7041*61046927SAndroid Build Coastguard Worker 
7042*61046927SAndroid Build Coastguard Worker    if (immutable && !_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
7043*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM,
7044*61046927SAndroid Build Coastguard Worker             "%s(internalformat=%s not legal for immutable-format)",
7045*61046927SAndroid Build Coastguard Worker             func, _mesa_enum_to_string(internalformat));
7046*61046927SAndroid Build Coastguard Worker       return;
7047*61046927SAndroid Build Coastguard Worker    }
7048*61046927SAndroid Build Coastguard Worker 
7049*61046927SAndroid Build Coastguard Worker    if (!_mesa_is_renderable_texture_format(ctx, internalformat)) {
7050*61046927SAndroid Build Coastguard Worker       /* Page 172 of OpenGL ES 3.1 spec says:
7051*61046927SAndroid Build Coastguard Worker        *   "An INVALID_ENUM error is generated if sizedinternalformat is not
7052*61046927SAndroid Build Coastguard Worker        *   color-renderable, depth-renderable, or stencil-renderable (as
7053*61046927SAndroid Build Coastguard Worker        *   defined in section 9.4).
7054*61046927SAndroid Build Coastguard Worker        *
7055*61046927SAndroid Build Coastguard Worker        *  (Same error is also defined for desktop OpenGL for multisample
7056*61046927SAndroid Build Coastguard Worker        *  teximage/texstorage functions.)
7057*61046927SAndroid Build Coastguard Worker        */
7058*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalformat=%s)", func,
7059*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(internalformat));
7060*61046927SAndroid Build Coastguard Worker       return;
7061*61046927SAndroid Build Coastguard Worker    }
7062*61046927SAndroid Build Coastguard Worker 
7063*61046927SAndroid Build Coastguard Worker    sample_count_error = _mesa_check_sample_count(ctx, target,
7064*61046927SAndroid Build Coastguard Worker          internalformat, samples, samples);
7065*61046927SAndroid Build Coastguard Worker    samplesOK = sample_count_error == GL_NO_ERROR;
7066*61046927SAndroid Build Coastguard Worker 
7067*61046927SAndroid Build Coastguard Worker    /* Page 254 of OpenGL 4.4 spec says:
7068*61046927SAndroid Build Coastguard Worker     *   "Proxy arrays for two-dimensional multisample and two-dimensional
7069*61046927SAndroid Build Coastguard Worker     *    multisample array textures are operated on in the same way when
7070*61046927SAndroid Build Coastguard Worker     *    TexImage2DMultisample is called with target specified as
7071*61046927SAndroid Build Coastguard Worker     *    PROXY_TEXTURE_2D_MULTISAMPLE, or TexImage3DMultisample is called
7072*61046927SAndroid Build Coastguard Worker     *    with target specified as PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY.
7073*61046927SAndroid Build Coastguard Worker     *    However, if samples is not supported, then no error is generated.
7074*61046927SAndroid Build Coastguard Worker     */
7075*61046927SAndroid Build Coastguard Worker    if (!samplesOK && !_mesa_is_proxy_texture(target)) {
7076*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, sample_count_error, "%s(samples=%d)", func, samples);
7077*61046927SAndroid Build Coastguard Worker       return;
7078*61046927SAndroid Build Coastguard Worker    }
7079*61046927SAndroid Build Coastguard Worker 
7080*61046927SAndroid Build Coastguard Worker    if (!texObj) {
7081*61046927SAndroid Build Coastguard Worker       texObj = _mesa_get_current_tex_object(ctx, target);
7082*61046927SAndroid Build Coastguard Worker       if (!texObj)
7083*61046927SAndroid Build Coastguard Worker          return;
7084*61046927SAndroid Build Coastguard Worker    }
7085*61046927SAndroid Build Coastguard Worker 
7086*61046927SAndroid Build Coastguard Worker    if (immutable && texObj->Name == 0) {
7087*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
7088*61046927SAndroid Build Coastguard Worker             "%s(texture object 0)",
7089*61046927SAndroid Build Coastguard Worker             func);
7090*61046927SAndroid Build Coastguard Worker       return;
7091*61046927SAndroid Build Coastguard Worker    }
7092*61046927SAndroid Build Coastguard Worker 
7093*61046927SAndroid Build Coastguard Worker    texImage = _mesa_get_tex_image(ctx, texObj, 0, 0);
7094*61046927SAndroid Build Coastguard Worker 
7095*61046927SAndroid Build Coastguard Worker    if (texImage == NULL) {
7096*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
7097*61046927SAndroid Build Coastguard Worker       return;
7098*61046927SAndroid Build Coastguard Worker    }
7099*61046927SAndroid Build Coastguard Worker 
7100*61046927SAndroid Build Coastguard Worker    texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
7101*61046927SAndroid Build Coastguard Worker          internalformat, GL_NONE, GL_NONE);
7102*61046927SAndroid Build Coastguard Worker    assert(texFormat != MESA_FORMAT_NONE);
7103*61046927SAndroid Build Coastguard Worker 
7104*61046927SAndroid Build Coastguard Worker    dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
7105*61046927SAndroid Build Coastguard Worker          width, height, depth, 0);
7106*61046927SAndroid Build Coastguard Worker 
7107*61046927SAndroid Build Coastguard Worker    sizeOK = st_TestProxyTexImage(ctx, target, 0, 0, texFormat,
7108*61046927SAndroid Build Coastguard Worker                                  samples, width, height, depth);
7109*61046927SAndroid Build Coastguard Worker 
7110*61046927SAndroid Build Coastguard Worker    if (_mesa_is_proxy_texture(target)) {
7111*61046927SAndroid Build Coastguard Worker       if (samplesOK && dimensionsOK && sizeOK) {
7112*61046927SAndroid Build Coastguard Worker          _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0,
7113*61046927SAndroid Build Coastguard Worker                                        internalformat, texFormat,
7114*61046927SAndroid Build Coastguard Worker                                        samples, fixedsamplelocations);
7115*61046927SAndroid Build Coastguard Worker       }
7116*61046927SAndroid Build Coastguard Worker       else {
7117*61046927SAndroid Build Coastguard Worker          /* clear all image fields */
7118*61046927SAndroid Build Coastguard Worker          clear_teximage_fields(texImage);
7119*61046927SAndroid Build Coastguard Worker       }
7120*61046927SAndroid Build Coastguard Worker    }
7121*61046927SAndroid Build Coastguard Worker    else {
7122*61046927SAndroid Build Coastguard Worker       if (!dimensionsOK) {
7123*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_VALUE,
7124*61046927SAndroid Build Coastguard Worker                      "%s(invalid width=%d or height=%d)", func, width, height);
7125*61046927SAndroid Build Coastguard Worker          return;
7126*61046927SAndroid Build Coastguard Worker       }
7127*61046927SAndroid Build Coastguard Worker 
7128*61046927SAndroid Build Coastguard Worker       if (!sizeOK) {
7129*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(texture too large)", func);
7130*61046927SAndroid Build Coastguard Worker          return;
7131*61046927SAndroid Build Coastguard Worker       }
7132*61046927SAndroid Build Coastguard Worker 
7133*61046927SAndroid Build Coastguard Worker       /* Check if texObj->Immutable is set */
7134*61046927SAndroid Build Coastguard Worker       if (texObj->Immutable) {
7135*61046927SAndroid Build Coastguard Worker          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func);
7136*61046927SAndroid Build Coastguard Worker          return;
7137*61046927SAndroid Build Coastguard Worker       }
7138*61046927SAndroid Build Coastguard Worker 
7139*61046927SAndroid Build Coastguard Worker       if (texObj->IsSparse &&
7140*61046927SAndroid Build Coastguard Worker           _mesa_sparse_texture_error_check(ctx, dims, texObj, texFormat, target, 0,
7141*61046927SAndroid Build Coastguard Worker                                            width, height, depth, func))
7142*61046927SAndroid Build Coastguard Worker          return; /* error was recorded */
7143*61046927SAndroid Build Coastguard Worker 
7144*61046927SAndroid Build Coastguard Worker       st_FreeTextureImageBuffer(ctx, texImage);
7145*61046927SAndroid Build Coastguard Worker 
7146*61046927SAndroid Build Coastguard Worker       _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0,
7147*61046927SAndroid Build Coastguard Worker                                     internalformat, texFormat,
7148*61046927SAndroid Build Coastguard Worker                                     samples, fixedsamplelocations);
7149*61046927SAndroid Build Coastguard Worker 
7150*61046927SAndroid Build Coastguard Worker       if (width > 0 && height > 0 && depth > 0) {
7151*61046927SAndroid Build Coastguard Worker          if (memObj) {
7152*61046927SAndroid Build Coastguard Worker             if (!st_SetTextureStorageForMemoryObject(ctx, texObj,
7153*61046927SAndroid Build Coastguard Worker                                                      memObj, 1, width,
7154*61046927SAndroid Build Coastguard Worker                                                      height, depth,
7155*61046927SAndroid Build Coastguard Worker                                                      offset, func)) {
7156*61046927SAndroid Build Coastguard Worker 
7157*61046927SAndroid Build Coastguard Worker                _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0,
7158*61046927SAndroid Build Coastguard Worker                                           internalformat, texFormat);
7159*61046927SAndroid Build Coastguard Worker             }
7160*61046927SAndroid Build Coastguard Worker          } else {
7161*61046927SAndroid Build Coastguard Worker             if (!st_AllocTextureStorage(ctx, texObj, 1,
7162*61046927SAndroid Build Coastguard Worker                                         width, height, depth, func)) {
7163*61046927SAndroid Build Coastguard Worker                /* tidy up the texture image state. strictly speaking,
7164*61046927SAndroid Build Coastguard Worker                 * we're allowed to just leave this in whatever state we
7165*61046927SAndroid Build Coastguard Worker                 * like, but being tidy is good.
7166*61046927SAndroid Build Coastguard Worker                 */
7167*61046927SAndroid Build Coastguard Worker                _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0,
7168*61046927SAndroid Build Coastguard Worker                                           internalformat, texFormat);
7169*61046927SAndroid Build Coastguard Worker             }
7170*61046927SAndroid Build Coastguard Worker          }
7171*61046927SAndroid Build Coastguard Worker       }
7172*61046927SAndroid Build Coastguard Worker 
7173*61046927SAndroid Build Coastguard Worker       texObj->External = GL_FALSE;
7174*61046927SAndroid Build Coastguard Worker       texObj->Immutable |= immutable;
7175*61046927SAndroid Build Coastguard Worker 
7176*61046927SAndroid Build Coastguard Worker       if (immutable) {
7177*61046927SAndroid Build Coastguard Worker          _mesa_set_texture_view_state(ctx, texObj, target, 1);
7178*61046927SAndroid Build Coastguard Worker       }
7179*61046927SAndroid Build Coastguard Worker 
7180*61046927SAndroid Build Coastguard Worker       _mesa_update_fbo_texture(ctx, texObj, 0, 0);
7181*61046927SAndroid Build Coastguard Worker    }
7182*61046927SAndroid Build Coastguard Worker    _mesa_update_texture_object_swizzle(ctx, texObj);
7183*61046927SAndroid Build Coastguard Worker }
7184*61046927SAndroid Build Coastguard Worker 
7185*61046927SAndroid Build Coastguard Worker 
7186*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexImage2DMultisample(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)7187*61046927SAndroid Build Coastguard Worker _mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
7188*61046927SAndroid Build Coastguard Worker                             GLenum internalformat, GLsizei width,
7189*61046927SAndroid Build Coastguard Worker                             GLsizei height, GLboolean fixedsamplelocations)
7190*61046927SAndroid Build Coastguard Worker {
7191*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7192*61046927SAndroid Build Coastguard Worker 
7193*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, 2, NULL, NULL, target, samples,
7194*61046927SAndroid Build Coastguard Worker                              internalformat, width, height, 1,
7195*61046927SAndroid Build Coastguard Worker                              fixedsamplelocations, GL_FALSE, 0,
7196*61046927SAndroid Build Coastguard Worker                              "glTexImage2DMultisample");
7197*61046927SAndroid Build Coastguard Worker }
7198*61046927SAndroid Build Coastguard Worker 
7199*61046927SAndroid Build Coastguard Worker 
7200*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexImage3DMultisample(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)7201*61046927SAndroid Build Coastguard Worker _mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
7202*61046927SAndroid Build Coastguard Worker                             GLenum internalformat, GLsizei width,
7203*61046927SAndroid Build Coastguard Worker                             GLsizei height, GLsizei depth,
7204*61046927SAndroid Build Coastguard Worker                             GLboolean fixedsamplelocations)
7205*61046927SAndroid Build Coastguard Worker {
7206*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7207*61046927SAndroid Build Coastguard Worker 
7208*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, 3, NULL, NULL, target, samples,
7209*61046927SAndroid Build Coastguard Worker                              internalformat, width, height, depth,
7210*61046927SAndroid Build Coastguard Worker                              fixedsamplelocations, GL_FALSE, 0,
7211*61046927SAndroid Build Coastguard Worker                              "glTexImage3DMultisample");
7212*61046927SAndroid Build Coastguard Worker }
7213*61046927SAndroid Build Coastguard Worker 
7214*61046927SAndroid Build Coastguard Worker static bool
valid_texstorage_ms_parameters(GLsizei width,GLsizei height,GLsizei depth,unsigned dims)7215*61046927SAndroid Build Coastguard Worker valid_texstorage_ms_parameters(GLsizei width, GLsizei height, GLsizei depth,
7216*61046927SAndroid Build Coastguard Worker                                unsigned dims)
7217*61046927SAndroid Build Coastguard Worker {
7218*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7219*61046927SAndroid Build Coastguard Worker 
7220*61046927SAndroid Build Coastguard Worker    if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
7221*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
7222*61046927SAndroid Build Coastguard Worker                   "glTexStorage%uDMultisample(width=%d,height=%d,depth=%d)",
7223*61046927SAndroid Build Coastguard Worker                   dims, width, height, depth);
7224*61046927SAndroid Build Coastguard Worker       return false;
7225*61046927SAndroid Build Coastguard Worker    }
7226*61046927SAndroid Build Coastguard Worker    return true;
7227*61046927SAndroid Build Coastguard Worker }
7228*61046927SAndroid Build Coastguard Worker 
7229*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexStorage2DMultisample(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)7230*61046927SAndroid Build Coastguard Worker _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,
7231*61046927SAndroid Build Coastguard Worker                               GLenum internalformat, GLsizei width,
7232*61046927SAndroid Build Coastguard Worker                               GLsizei height, GLboolean fixedsamplelocations)
7233*61046927SAndroid Build Coastguard Worker {
7234*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7235*61046927SAndroid Build Coastguard Worker 
7236*61046927SAndroid Build Coastguard Worker    if (!valid_texstorage_ms_parameters(width, height, 1, 2))
7237*61046927SAndroid Build Coastguard Worker       return;
7238*61046927SAndroid Build Coastguard Worker 
7239*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, 2, NULL, NULL, target, samples,
7240*61046927SAndroid Build Coastguard Worker                              internalformat, width, height, 1,
7241*61046927SAndroid Build Coastguard Worker                              fixedsamplelocations, GL_TRUE, 0,
7242*61046927SAndroid Build Coastguard Worker                              "glTexStorage2DMultisample");
7243*61046927SAndroid Build Coastguard Worker }
7244*61046927SAndroid Build Coastguard Worker 
7245*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TexStorage3DMultisample(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)7246*61046927SAndroid Build Coastguard Worker _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples,
7247*61046927SAndroid Build Coastguard Worker                               GLenum internalformat, GLsizei width,
7248*61046927SAndroid Build Coastguard Worker                               GLsizei height, GLsizei depth,
7249*61046927SAndroid Build Coastguard Worker                               GLboolean fixedsamplelocations)
7250*61046927SAndroid Build Coastguard Worker {
7251*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7252*61046927SAndroid Build Coastguard Worker 
7253*61046927SAndroid Build Coastguard Worker    if (!valid_texstorage_ms_parameters(width, height, depth, 3))
7254*61046927SAndroid Build Coastguard Worker       return;
7255*61046927SAndroid Build Coastguard Worker 
7256*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, 3, NULL, NULL, target, samples,
7257*61046927SAndroid Build Coastguard Worker                              internalformat, width, height, depth,
7258*61046927SAndroid Build Coastguard Worker                              fixedsamplelocations, GL_TRUE, 0,
7259*61046927SAndroid Build Coastguard Worker                              "glTexStorage3DMultisample");
7260*61046927SAndroid Build Coastguard Worker }
7261*61046927SAndroid Build Coastguard Worker 
7262*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureStorage2DMultisample(GLuint texture,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)7263*61046927SAndroid Build Coastguard Worker _mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples,
7264*61046927SAndroid Build Coastguard Worker                                   GLenum internalformat, GLsizei width,
7265*61046927SAndroid Build Coastguard Worker                                   GLsizei height,
7266*61046927SAndroid Build Coastguard Worker                                   GLboolean fixedsamplelocations)
7267*61046927SAndroid Build Coastguard Worker {
7268*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
7269*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7270*61046927SAndroid Build Coastguard Worker 
7271*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture,
7272*61046927SAndroid Build Coastguard Worker                                      "glTextureStorage2DMultisample");
7273*61046927SAndroid Build Coastguard Worker    if (!texObj)
7274*61046927SAndroid Build Coastguard Worker       return;
7275*61046927SAndroid Build Coastguard Worker 
7276*61046927SAndroid Build Coastguard Worker    if (!valid_texstorage_ms_parameters(width, height, 1, 2))
7277*61046927SAndroid Build Coastguard Worker       return;
7278*61046927SAndroid Build Coastguard Worker 
7279*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target,
7280*61046927SAndroid Build Coastguard Worker                              samples, internalformat, width, height, 1,
7281*61046927SAndroid Build Coastguard Worker                              fixedsamplelocations, GL_TRUE, 0,
7282*61046927SAndroid Build Coastguard Worker                              "glTextureStorage2DMultisample");
7283*61046927SAndroid Build Coastguard Worker }
7284*61046927SAndroid Build Coastguard Worker 
7285*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureStorage3DMultisample(GLuint texture,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)7286*61046927SAndroid Build Coastguard Worker _mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples,
7287*61046927SAndroid Build Coastguard Worker                                   GLenum internalformat, GLsizei width,
7288*61046927SAndroid Build Coastguard Worker                                   GLsizei height, GLsizei depth,
7289*61046927SAndroid Build Coastguard Worker                                   GLboolean fixedsamplelocations)
7290*61046927SAndroid Build Coastguard Worker {
7291*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
7292*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7293*61046927SAndroid Build Coastguard Worker 
7294*61046927SAndroid Build Coastguard Worker    /* Get the texture object by Name. */
7295*61046927SAndroid Build Coastguard Worker    texObj = _mesa_lookup_texture_err(ctx, texture,
7296*61046927SAndroid Build Coastguard Worker                                      "glTextureStorage3DMultisample");
7297*61046927SAndroid Build Coastguard Worker    if (!texObj)
7298*61046927SAndroid Build Coastguard Worker       return;
7299*61046927SAndroid Build Coastguard Worker 
7300*61046927SAndroid Build Coastguard Worker    if (!valid_texstorage_ms_parameters(width, height, depth, 3))
7301*61046927SAndroid Build Coastguard Worker       return;
7302*61046927SAndroid Build Coastguard Worker 
7303*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples,
7304*61046927SAndroid Build Coastguard Worker                              internalformat, width, height, depth,
7305*61046927SAndroid Build Coastguard Worker                              fixedsamplelocations, GL_TRUE, 0,
7306*61046927SAndroid Build Coastguard Worker                              "glTextureStorage3DMultisample");
7307*61046927SAndroid Build Coastguard Worker }
7308*61046927SAndroid Build Coastguard Worker 
7309*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureStorage2DMultisampleEXT(GLuint texture,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)7310*61046927SAndroid Build Coastguard Worker _mesa_TextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples,
7311*61046927SAndroid Build Coastguard Worker                                      GLenum internalformat, GLsizei width,
7312*61046927SAndroid Build Coastguard Worker                                      GLsizei height,
7313*61046927SAndroid Build Coastguard Worker                                      GLboolean fixedsamplelocations)
7314*61046927SAndroid Build Coastguard Worker {
7315*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
7316*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7317*61046927SAndroid Build Coastguard Worker 
7318*61046927SAndroid Build Coastguard Worker    texObj = lookup_texture_ext_dsa(ctx, target, texture,
7319*61046927SAndroid Build Coastguard Worker                                    "glTextureStorage2DMultisampleEXT");
7320*61046927SAndroid Build Coastguard Worker    if (!texObj)
7321*61046927SAndroid Build Coastguard Worker       return;
7322*61046927SAndroid Build Coastguard Worker 
7323*61046927SAndroid Build Coastguard Worker    if (!valid_texstorage_ms_parameters(width, height, 1, 2))
7324*61046927SAndroid Build Coastguard Worker       return;
7325*61046927SAndroid Build Coastguard Worker 
7326*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target,
7327*61046927SAndroid Build Coastguard Worker                              samples, internalformat, width, height, 1,
7328*61046927SAndroid Build Coastguard Worker                              fixedsamplelocations, GL_TRUE, 0,
7329*61046927SAndroid Build Coastguard Worker                              "glTextureStorage2DMultisampleEXT");
7330*61046927SAndroid Build Coastguard Worker }
7331*61046927SAndroid Build Coastguard Worker 
7332*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_TextureStorage3DMultisampleEXT(GLuint texture,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)7333*61046927SAndroid Build Coastguard Worker _mesa_TextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples,
7334*61046927SAndroid Build Coastguard Worker                                      GLenum internalformat, GLsizei width,
7335*61046927SAndroid Build Coastguard Worker                                      GLsizei height, GLsizei depth,
7336*61046927SAndroid Build Coastguard Worker                                      GLboolean fixedsamplelocations)
7337*61046927SAndroid Build Coastguard Worker {
7338*61046927SAndroid Build Coastguard Worker    struct gl_texture_object *texObj;
7339*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
7340*61046927SAndroid Build Coastguard Worker 
7341*61046927SAndroid Build Coastguard Worker    texObj = lookup_texture_ext_dsa(ctx, target, texture,
7342*61046927SAndroid Build Coastguard Worker                                    "glTextureStorage3DMultisampleEXT");
7343*61046927SAndroid Build Coastguard Worker    if (!texObj)
7344*61046927SAndroid Build Coastguard Worker       return;
7345*61046927SAndroid Build Coastguard Worker 
7346*61046927SAndroid Build Coastguard Worker    if (!valid_texstorage_ms_parameters(width, height, depth, 3))
7347*61046927SAndroid Build Coastguard Worker       return;
7348*61046927SAndroid Build Coastguard Worker 
7349*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples,
7350*61046927SAndroid Build Coastguard Worker                              internalformat, width, height, depth,
7351*61046927SAndroid Build Coastguard Worker                              fixedsamplelocations, GL_TRUE, 0,
7352*61046927SAndroid Build Coastguard Worker                              "glTextureStorage3DMultisampleEXT");
7353*61046927SAndroid Build Coastguard Worker }
7354*61046927SAndroid Build Coastguard Worker 
7355*61046927SAndroid Build Coastguard Worker void
_mesa_texture_storage_ms_memory(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,struct gl_memory_object * memObj,GLenum target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,GLuint64 offset,const char * func)7356*61046927SAndroid Build Coastguard Worker _mesa_texture_storage_ms_memory(struct gl_context *ctx, GLuint dims,
7357*61046927SAndroid Build Coastguard Worker                                 struct gl_texture_object *texObj,
7358*61046927SAndroid Build Coastguard Worker                                 struct gl_memory_object *memObj,
7359*61046927SAndroid Build Coastguard Worker                                 GLenum target, GLsizei samples,
7360*61046927SAndroid Build Coastguard Worker                                 GLenum internalFormat, GLsizei width,
7361*61046927SAndroid Build Coastguard Worker                                 GLsizei height, GLsizei depth,
7362*61046927SAndroid Build Coastguard Worker                                 GLboolean fixedSampleLocations,
7363*61046927SAndroid Build Coastguard Worker                                 GLuint64 offset, const char* func)
7364*61046927SAndroid Build Coastguard Worker {
7365*61046927SAndroid Build Coastguard Worker    assert(memObj);
7366*61046927SAndroid Build Coastguard Worker 
7367*61046927SAndroid Build Coastguard Worker    texture_image_multisample(ctx, dims, texObj, memObj, target, samples,
7368*61046927SAndroid Build Coastguard Worker                              internalFormat, width, height, depth,
7369*61046927SAndroid Build Coastguard Worker                              fixedSampleLocations, GL_TRUE, offset,
7370*61046927SAndroid Build Coastguard Worker                              func);
7371*61046927SAndroid Build Coastguard Worker }
7372