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