141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand/*
241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * Mesa 3-D graphics library
341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand *
441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * Copyright (C) 2014 Intel Corporation.  All Rights Reserved.
541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand *
641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * Permission is hereby granted, free of charge, to any person obtaining a
741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * copy of this software and associated documentation files (the "Software"),
841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * to deal in the Software without restriction, including without limitation
941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * and/or sell copies of the Software, and to permit persons to whom the
1141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * Software is furnished to do so, subject to the following conditions:
1241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand *
1341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * The above copyright notice and this permission notice shall be included
1441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * in all copies or substantial portions of the Software.
1541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand *
1641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * OTHER DEALINGS IN THE SOFTWARE.
2341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand *
2441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand * Authors:
2541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand *    Jason Ekstrand <jason.ekstrand@intel.com>
2641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand */
2741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
28ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin#include "context.h"
2941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand#include "glheader.h"
3041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand#include "errors.h"
3141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand#include "enums.h"
3241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand#include "copyimage.h"
3341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand#include "teximage.h"
3441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand#include "texobj.h"
3541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand#include "fbobject.h"
3641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand#include "textureview.h"
371a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca#include "glformats.h"
381a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
391a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrcaenum mesa_block_class {
401a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   BLOCK_CLASS_128_BITS,
411a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   BLOCK_CLASS_64_BITS
421a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca};
4341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
44dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul/**
45200aee424790f3167fcb175f4798af27783fe364Brian Paul * Prepare the source or destination resource.  This involves error
46200aee424790f3167fcb175f4798af27783fe364Brian Paul * checking and returning the relevant gl_texture_image or gl_renderbuffer.
47200aee424790f3167fcb175f4798af27783fe364Brian Paul * Note that one of the resulting tex_image or renderbuffer pointers will be
48200aee424790f3167fcb175f4798af27783fe364Brian Paul * NULL and the other will be non-null.
49200aee424790f3167fcb175f4798af27783fe364Brian Paul *
50dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * \param name  the texture or renderbuffer name
51200aee424790f3167fcb175f4798af27783fe364Brian Paul * \param target  One of GL_TEXTURE_x target or GL_RENDERBUFFER
52dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * \param level  mipmap level
53200aee424790f3167fcb175f4798af27783fe364Brian Paul * \param z  src or dest Z
54200aee424790f3167fcb175f4798af27783fe364Brian Paul * \param depth  number of slices/faces/layers to copy
55dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * \param tex_image  returns a pointer to a texture image
56200aee424790f3167fcb175f4798af27783fe364Brian Paul * \param renderbuffer  returns a pointer to a renderbuffer
57dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * \return true if success, false if error
58dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul */
5941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrandstatic bool
60200aee424790f3167fcb175f4798af27783fe364Brian Paulprepare_target(struct gl_context *ctx, GLuint name, GLenum target,
61200aee424790f3167fcb175f4798af27783fe364Brian Paul               int level, int z, int depth,
62200aee424790f3167fcb175f4798af27783fe364Brian Paul               struct gl_texture_image **tex_image,
63200aee424790f3167fcb175f4798af27783fe364Brian Paul               struct gl_renderbuffer **renderbuffer,
64200aee424790f3167fcb175f4798af27783fe364Brian Paul               mesa_format *format,
65200aee424790f3167fcb175f4798af27783fe364Brian Paul               GLenum *internalFormat,
66912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin               GLuint *width,
67912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin               GLuint *height,
68c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie               GLuint *num_samples,
6941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand               const char *dbg_prefix)
7041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand{
7141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if (name == 0) {
7241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
7341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(%sName = %d)", dbg_prefix, name);
7441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      return false;
7541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
7641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
7741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   /*
7841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand    * INVALID_ENUM is generated
7941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand    *  * if either <srcTarget> or <dstTarget>
8041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand    *   - is not RENDERBUFFER or a valid non-proxy texture target
8141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand    *   - is TEXTURE_BUFFER, or
8241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand    *   - is one of the cubemap face selectors described in table 3.17,
8341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand    */
84200aee424790f3167fcb175f4798af27783fe364Brian Paul   switch (target) {
8541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_RENDERBUFFER:
8641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      /* Not a texture target, but valid */
8741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D:
8841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D_ARRAY:
8941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_2D:
9041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_3D:
9141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_CUBE_MAP:
9241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_RECTANGLE:
9341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_2D_ARRAY:
9441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_CUBE_MAP_ARRAY:
9541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_2D_MULTISAMPLE:
9641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
9741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      /* These are all valid */
9841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
9941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_EXTERNAL_OES:
10041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      /* Only exists in ES */
10141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_BUFFER:
10241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   default:
10341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_ENUM,
10441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(%sTarget = %s)", dbg_prefix,
105200aee424790f3167fcb175f4798af27783fe364Brian Paul                  _mesa_enum_to_string(target));
10641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      return false;
10741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
10841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
109200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (target == GL_RENDERBUFFER) {
1100b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paul      struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name);
111200aee424790f3167fcb175f4798af27783fe364Brian Paul
11241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      if (!rb) {
11341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_VALUE,
11441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sName = %u)", dbg_prefix, name);
11541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
11641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
11741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
11841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      if (!rb->Name) {
11941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_OPERATION,
12041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sName incomplete)", dbg_prefix);
12141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
12241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
12341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
12441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      if (level != 0) {
12541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_VALUE,
12641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level);
12741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
12841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
12941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
130200aee424790f3167fcb175f4798af27783fe364Brian Paul      *renderbuffer = rb;
131200aee424790f3167fcb175f4798af27783fe364Brian Paul      *format = rb->Format;
132200aee424790f3167fcb175f4798af27783fe364Brian Paul      *internalFormat = rb->InternalFormat;
133912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin      *width = rb->Width;
134912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin      *height = rb->Height;
135c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie      *num_samples = rb->NumSamples;
136200aee424790f3167fcb175f4798af27783fe364Brian Paul      *tex_image = NULL;
13741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   } else {
138200aee424790f3167fcb175f4798af27783fe364Brian Paul      struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name);
139200aee424790f3167fcb175f4798af27783fe364Brian Paul
140200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (!texObj) {
141da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro         /*
142da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro          * From GL_ARB_copy_image specification:
143da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro          * "INVALID_VALUE is generated if either <srcName> or <dstName> does
144da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro          * not correspond to a valid renderbuffer or texture object according
145da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro          * to the corresponding target parameter."
146da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro          */
14741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_VALUE,
14841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sName = %u)", dbg_prefix, name);
14941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
15041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
15141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
152200aee424790f3167fcb175f4798af27783fe364Brian Paul      _mesa_test_texobj_completeness(ctx, texObj);
153200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (!texObj->_BaseComplete ||
154200aee424790f3167fcb175f4798af27783fe364Brian Paul          (level != 0 && !texObj->_MipmapComplete)) {
15541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_OPERATION,
15641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sName incomplete)", dbg_prefix);
15741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
15841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
15941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
160200aee424790f3167fcb175f4798af27783fe364Brian Paul      /* Note that target will not be a cube face name */
161200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (texObj->Target != target) {
162200aee424790f3167fcb175f4798af27783fe364Brian Paul         /*
163da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro          * From GL_ARB_copy_image_specification:
164da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro          * "INVALID_ENUM is generated if the target does not match the type
165da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro          * of the object."
166200aee424790f3167fcb175f4798af27783fe364Brian Paul          */
167da7efadf040dafe5d925962c88a7189dcf058b25Alejandro Piñeiro         _mesa_error(ctx, GL_INVALID_ENUM,
16841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sTarget = %s)", dbg_prefix,
169200aee424790f3167fcb175f4798af27783fe364Brian Paul                     _mesa_enum_to_string(target));
17041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
17141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
17241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
17341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
17441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_VALUE,
17541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sLevel = %d)", dbg_prefix, level);
17641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
17741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
17841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
179200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (target == GL_TEXTURE_CUBE_MAP) {
180200aee424790f3167fcb175f4798af27783fe364Brian Paul         int i;
181200aee424790f3167fcb175f4798af27783fe364Brian Paul
182200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(z < MAX_FACES);  /* should have been caught earlier */
183200aee424790f3167fcb175f4798af27783fe364Brian Paul
184200aee424790f3167fcb175f4798af27783fe364Brian Paul         /* make sure all the cube faces are present */
185200aee424790f3167fcb175f4798af27783fe364Brian Paul         for (i = 0; i < depth; i++) {
186200aee424790f3167fcb175f4798af27783fe364Brian Paul            if (!texObj->Image[z+i][level]) {
187200aee424790f3167fcb175f4798af27783fe364Brian Paul               /* missing cube face */
188af7bf610cf74c6805f42babbcf85bc88b2b9453dDave Airlie               _mesa_error(ctx, GL_INVALID_VALUE,
189200aee424790f3167fcb175f4798af27783fe364Brian Paul                           "glCopyImageSubData(missing cube face)");
190200aee424790f3167fcb175f4798af27783fe364Brian Paul               return false;
191200aee424790f3167fcb175f4798af27783fe364Brian Paul            }
192200aee424790f3167fcb175f4798af27783fe364Brian Paul         }
193200aee424790f3167fcb175f4798af27783fe364Brian Paul
194200aee424790f3167fcb175f4798af27783fe364Brian Paul         *tex_image = texObj->Image[z][level];
195200aee424790f3167fcb175f4798af27783fe364Brian Paul      }
196200aee424790f3167fcb175f4798af27783fe364Brian Paul      else {
197200aee424790f3167fcb175f4798af27783fe364Brian Paul         *tex_image = _mesa_select_tex_image(texObj, target, level);
198200aee424790f3167fcb175f4798af27783fe364Brian Paul      }
199200aee424790f3167fcb175f4798af27783fe364Brian Paul
20041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      if (!*tex_image) {
20141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_VALUE,
20241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level);
20341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
20441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
205200aee424790f3167fcb175f4798af27783fe364Brian Paul
206200aee424790f3167fcb175f4798af27783fe364Brian Paul      *renderbuffer = NULL;
207200aee424790f3167fcb175f4798af27783fe364Brian Paul      *format = (*tex_image)->TexFormat;
208200aee424790f3167fcb175f4798af27783fe364Brian Paul      *internalFormat = (*tex_image)->InternalFormat;
209912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin      *width = (*tex_image)->Width;
210912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin      *height = (*tex_image)->Height;
211c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie      *num_samples = (*tex_image)->NumSamples;
21241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
21341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
21441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   return true;
21541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand}
21641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
217dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul
218dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul/**
219dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * Check that the x,y,z,width,height,region is within the texture image
220dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * dimensions.
221dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * \return true if bounds OK, false if regions is out of bounds
222dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul */
22341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrandstatic bool
2240b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paulcheck_region_bounds(struct gl_context *ctx,
225200aee424790f3167fcb175f4798af27783fe364Brian Paul                    GLenum target,
2260b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paul                    const struct gl_texture_image *tex_image,
227200aee424790f3167fcb175f4798af27783fe364Brian Paul                    const struct gl_renderbuffer *renderbuffer,
22841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                    int x, int y, int z, int width, int height, int depth,
22941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                    const char *dbg_prefix)
23041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand{
231200aee424790f3167fcb175f4798af27783fe364Brian Paul   int surfWidth, surfHeight, surfDepth;
232200aee424790f3167fcb175f4798af27783fe364Brian Paul
23341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if (width < 0 || height < 0 || depth < 0) {
23441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
23541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(%sWidth, %sHeight, or %sDepth is negative)",
23641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  dbg_prefix, dbg_prefix, dbg_prefix);
23741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      return false;
23841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
23941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
24041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if (x < 0 || y < 0 || z < 0) {
24141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
24241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(%sX, %sY, or %sZ is negative)",
24341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  dbg_prefix, dbg_prefix, dbg_prefix);
24441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      return false;
24541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
24641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
247dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul   /* Check X direction */
248200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (target == GL_RENDERBUFFER) {
249200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfWidth = renderbuffer->Width;
250200aee424790f3167fcb175f4798af27783fe364Brian Paul   }
251200aee424790f3167fcb175f4798af27783fe364Brian Paul   else {
252200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfWidth = tex_image->Width;
253200aee424790f3167fcb175f4798af27783fe364Brian Paul   }
254200aee424790f3167fcb175f4798af27783fe364Brian Paul
255200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (x + width > surfWidth) {
25641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
25741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(%sX or %sWidth exceeds image bounds)",
25841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  dbg_prefix, dbg_prefix);
25941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      return false;
26041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
26141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
262dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul   /* Check Y direction */
263200aee424790f3167fcb175f4798af27783fe364Brian Paul   switch (target) {
264200aee424790f3167fcb175f4798af27783fe364Brian Paul   case GL_RENDERBUFFER:
265200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfHeight = renderbuffer->Height;
266200aee424790f3167fcb175f4798af27783fe364Brian Paul      break;
26741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D:
26841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D_ARRAY:
269200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfHeight = 1;
27041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
27141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   default:
272200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfHeight = tex_image->Height;
273200aee424790f3167fcb175f4798af27783fe364Brian Paul   }
274200aee424790f3167fcb175f4798af27783fe364Brian Paul
275200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (y + height > surfHeight) {
276200aee424790f3167fcb175f4798af27783fe364Brian Paul      _mesa_error(ctx, GL_INVALID_VALUE,
277200aee424790f3167fcb175f4798af27783fe364Brian Paul                  "glCopyImageSubData(%sY or %sHeight exceeds image bounds)",
278200aee424790f3167fcb175f4798af27783fe364Brian Paul                  dbg_prefix, dbg_prefix);
279200aee424790f3167fcb175f4798af27783fe364Brian Paul      return false;
28041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
28141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
282dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul   /* Check Z direction */
283200aee424790f3167fcb175f4798af27783fe364Brian Paul   switch (target) {
284200aee424790f3167fcb175f4798af27783fe364Brian Paul   case GL_RENDERBUFFER:
28541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D:
28641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_2D:
28741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_2D_MULTISAMPLE:
28841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_RECTANGLE:
289200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfDepth = 1;
29041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
29141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_CUBE_MAP:
292200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfDepth = 6;
29341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
29441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D_ARRAY:
295200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfDepth = tex_image->Height;
29641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
297200aee424790f3167fcb175f4798af27783fe364Brian Paul   default:
298200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfDepth = tex_image->Depth;
299200aee424790f3167fcb175f4798af27783fe364Brian Paul   }
300200aee424790f3167fcb175f4798af27783fe364Brian Paul
301200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (z < 0 || z + depth > surfDepth) {
302200aee424790f3167fcb175f4798af27783fe364Brian Paul      _mesa_error(ctx, GL_INVALID_VALUE,
303200aee424790f3167fcb175f4798af27783fe364Brian Paul                  "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",
304200aee424790f3167fcb175f4798af27783fe364Brian Paul                  dbg_prefix, dbg_prefix);
305200aee424790f3167fcb175f4798af27783fe364Brian Paul      return false;
30641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
30741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
30841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   return true;
30941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand}
31041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
3111a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrcastatic bool
3120b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paulcompressed_format_compatible(const struct gl_context *ctx,
3131a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca                             GLenum compressedFormat, GLenum otherFormat)
3141a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca{
3151a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   enum mesa_block_class compressedClass, otherClass;
3161a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
3171a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   /* Two view-incompatible compressed formats are never compatible. */
3181a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   if (_mesa_is_compressed_format(ctx, otherFormat)) {
3191a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      return false;
3201a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   }
3211a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
3221a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   /*
3231a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    * From ARB_copy_image spec:
3241a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    Table 4.X.1 (Compatible internal formats for copying between
3251a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *                 compressed and uncompressed internal formats)
3261a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    ---------------------------------------------------------------------
3271a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | Texel / | Uncompressed      |                                     |
3281a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | Block   | internal format   | Compressed internal format          |
3291a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | size    |                   |                                     |
3301a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    ---------------------------------------------------------------------
3311a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | 128-bit | RGBA32UI,         | COMPRESSED_RGBA_S3TC_DXT3_EXT,      |
3321a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA32I,          | COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,|
3331a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA32F           | COMPRESSED_RGBA_S3TC_DXT5_EXT,      |
3341a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,|
3351a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_RG_RGTC2,                |
3361a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_SIGNED_RG_RGTC2,         |
3371a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_RGBA_BPTC_UNORM,         |
3381a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_SRGB_ALPHA_BPTC_UNORM,   |
3391a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_RGB_BPTC_SIGNED_FLOAT,   |
3401a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT  |
3411a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    ---------------------------------------------------------------------
3421a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | 64-bit  | RGBA16F, RG32F,   | COMPRESSED_RGB_S3TC_DXT1_EXT,       |
3431a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA16UI, RG32UI, | COMPRESSED_SRGB_S3TC_DXT1_EXT,      |
3441a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA16I, RG32I,   | COMPRESSED_RGBA_S3TC_DXT1_EXT,      |
3451a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA16,           | COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,|
3461a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA16_SNORM      | COMPRESSED_RED_RGTC1,               |
3471a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_SIGNED_RED_RGTC1         |
3481a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    ---------------------------------------------------------------------
3491a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    */
3501a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
3511a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   switch (compressedFormat) {
3521a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
3531a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
3541a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
3551a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
3561a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RG_RGTC2:
3571a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SIGNED_RG_RGTC2:
3581a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGBA_BPTC_UNORM:
3591a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
3601a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
3611a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
3621a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         compressedClass = BLOCK_CLASS_128_BITS;
3631a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         break;
3641a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
3651a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
3661a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
3671a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
3681a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RED_RGTC1:
3691a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SIGNED_RED_RGTC1:
3701a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         compressedClass = BLOCK_CLASS_64_BITS;
3711a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         break;
372ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_RGBA8_ETC2_EAC:
373ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
374ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_RG11_EAC:
375ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SIGNED_RG11_EAC:
376ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         if (_mesa_is_gles(ctx))
377ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            compressedClass = BLOCK_CLASS_128_BITS;
378ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         else
379ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            return false;
380ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         break;
381ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_RGB8_ETC2:
382ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SRGB8_ETC2:
383ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_R11_EAC:
384ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SIGNED_R11_EAC:
385ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
386ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
387ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         if (_mesa_is_gles(ctx))
388ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            compressedClass = BLOCK_CLASS_64_BITS;
389ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         else
390ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            return false;
391ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         break;
3921a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      default:
393ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         if (_mesa_is_gles(ctx) && _mesa_is_astc_format(compressedFormat))
394ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            compressedClass = BLOCK_CLASS_128_BITS;
395ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         else
396ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            return false;
397ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         break;
3981a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   }
3991a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4001a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   switch (otherFormat) {
4011a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA32UI:
4021a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA32I:
4031a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA32F:
4041a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         otherClass = BLOCK_CLASS_128_BITS;
4051a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         break;
4061a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16F:
4071a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RG32F:
4081a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16UI:
4091a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RG32UI:
4101a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16I:
4111a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RG32I:
4121a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16:
4131a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16_SNORM:
4141a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         otherClass = BLOCK_CLASS_64_BITS;
4151a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         break;
4161a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      default:
4171a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         return false;
4181a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   }
4191a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4201a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   return compressedClass == otherClass;
4211a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca}
4221a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4231a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrcastatic bool
4240b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paulcopy_format_compatible(const struct gl_context *ctx,
4250b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paul                       GLenum srcFormat, GLenum dstFormat)
4261a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca{
4271a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   /*
4281a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    * From ARB_copy_image spec:
4291a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    For the purposes of CopyImageSubData, two internal formats
4301a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    are considered compatible if any of the following conditions are
4311a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    met:
4321a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    * the formats are the same,
4331a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    * the formats are considered compatible according to the
4341a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *      compatibility rules used for texture views as defined in
4351a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *      section 3.9.X. In particular, if both internal formats are listed
4361a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *      in the same entry of Table 3.X.2, they are considered compatible, or
4371a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    * one format is compressed and the other is uncompressed and
4381a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *      Table 4.X.1 lists the two formats in the same row.
4391a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    */
4401a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4411a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   if (_mesa_texture_view_compatible_format(ctx, srcFormat, dstFormat)) {
4421a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      /* Also checks if formats are equal. */
4431a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      return true;
4441a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   } else if (_mesa_is_compressed_format(ctx, srcFormat)) {
4451a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      return compressed_format_compatible(ctx, srcFormat, dstFormat);
4461a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   } else if (_mesa_is_compressed_format(ctx, dstFormat)) {
4471a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      return compressed_format_compatible(ctx, dstFormat, srcFormat);
4481a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   }
4491a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4501a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   return false;
4511a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca}
4521a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
453f24be7340162c6a831b392d46d6637e9656e7a8aBrian Paulvoid GLAPIENTRY
45441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
45541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                       GLint srcX, GLint srcY, GLint srcZ,
45641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                       GLuint dstName, GLenum dstTarget, GLint dstLevel,
45741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                       GLint dstX, GLint dstY, GLint dstZ,
45841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                       GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
45941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand{
46041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   GET_CURRENT_CONTEXT(ctx);
46141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   struct gl_texture_image *srcTexImage, *dstTexImage;
462200aee424790f3167fcb175f4798af27783fe364Brian Paul   struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer;
463200aee424790f3167fcb175f4798af27783fe364Brian Paul   mesa_format srcFormat, dstFormat;
464200aee424790f3167fcb175f4798af27783fe364Brian Paul   GLenum srcIntFormat, dstIntFormat;
465912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin   GLuint src_w, src_h, dst_w, dst_h;
46641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   GLuint src_bw, src_bh, dst_bw, dst_bh;
467c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie   GLuint src_num_samples, dst_num_samples;
468200aee424790f3167fcb175f4798af27783fe364Brian Paul   int dstWidth, dstHeight, dstDepth;
4690b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paul   int i;
47041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
47141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if (MESA_VERBOSE & VERBOSE_API)
47241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "
47341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                                          "%u, %s, %d, %d, %d, %d, "
47441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                                          "%d, %d, %d)\n",
4752f11e92cef51c88a09bc778e2ceca4ab50cf0017Kenneth Graunke                  srcName, _mesa_enum_to_string(srcTarget), srcLevel,
47641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  srcX, srcY, srcZ,
4772f11e92cef51c88a09bc778e2ceca4ab50cf0017Kenneth Graunke                  dstName, _mesa_enum_to_string(dstTarget), dstLevel,
47841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  dstX, dstY, dstZ,
479200aee424790f3167fcb175f4798af27783fe364Brian Paul                  srcWidth, srcHeight, srcDepth);
48041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
481ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul   if (!ctx->Extensions.ARB_copy_image) {
482ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul      _mesa_error(ctx, GL_INVALID_OPERATION,
483ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul                  "glCopyImageSubData(extension not available)");
484ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul      return;
485ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul   }
486ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul
487200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!prepare_target(ctx, srcName, srcTarget, srcLevel, srcZ, srcDepth,
488200aee424790f3167fcb175f4798af27783fe364Brian Paul                       &srcTexImage, &srcRenderbuffer, &srcFormat,
489c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie                       &srcIntFormat, &src_w, &src_h, &src_num_samples, "src"))
490200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
49141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
492200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!prepare_target(ctx, dstName, dstTarget, dstLevel, dstZ, srcDepth,
493200aee424790f3167fcb175f4798af27783fe364Brian Paul                       &dstTexImage, &dstRenderbuffer, &dstFormat,
494c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie                       &dstIntFormat, &dst_w, &dst_h, &dst_num_samples, "dst"))
495200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
49641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
497200aee424790f3167fcb175f4798af27783fe364Brian Paul   _mesa_get_format_block_size(srcFormat, &src_bw, &src_bh);
498912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin
499912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin   /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core Profile
500912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * spec says:
501912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
502912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    An INVALID_VALUE error is generated if the dimensions of either
503912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    subregion exceeds the boundaries of the corresponding image object,
504912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    or if the image format is compressed and the dimensions of the
505912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    subregion fail to meet the alignment constraints of the format.
506912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
507912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * and Section 8.7 (Compressed Texture Images) says:
508912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
509912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    An INVALID_OPERATION error is generated if any of the following
510912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    conditions occurs:
511912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
512912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *      * width is not a multiple of four, and width + xoffset is not
513912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *        equal to the value of TEXTURE_WIDTH.
514912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *      * height is not a multiple of four, and height + yoffset is not
515912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *        equal to the value of TEXTURE_HEIGHT.
516912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
517912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * so we take that to mean that you can copy the "last" block of a
518912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * compressed texture image even if it's smaller than the minimum block
519912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * dimensions.
520912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    */
52141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if ((srcX % src_bw != 0) || (srcY % src_bh != 0) ||
522912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin       (srcWidth % src_bw != 0 && (srcX + srcWidth) != src_w) ||
523912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin       (srcHeight % src_bh != 0 && (srcY + srcHeight) != src_h)) {
52441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
52541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(unaligned src rectangle)");
526200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
52741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
52841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
529200aee424790f3167fcb175f4798af27783fe364Brian Paul   _mesa_get_format_block_size(dstFormat, &dst_bw, &dst_bh);
53041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if ((dstX % dst_bw != 0) || (dstY % dst_bh != 0)) {
53141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
53241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(unaligned dst rectangle)");
533200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
53441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
53541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
536200aee424790f3167fcb175f4798af27783fe364Brian Paul   /* From the GL_ARB_copy_image spec:
537200aee424790f3167fcb175f4798af27783fe364Brian Paul    *
538200aee424790f3167fcb175f4798af27783fe364Brian Paul    * "The dimensions are always specified in texels, even for compressed
539200aee424790f3167fcb175f4798af27783fe364Brian Paul    * texture formats. But it should be noted that if only one of the
540200aee424790f3167fcb175f4798af27783fe364Brian Paul    * source and destination textures is compressed then the number of
541200aee424790f3167fcb175f4798af27783fe364Brian Paul    * texels touched in the compressed image will be a factor of the
542200aee424790f3167fcb175f4798af27783fe364Brian Paul    * block size larger than in the uncompressed image."
543200aee424790f3167fcb175f4798af27783fe364Brian Paul    *
544200aee424790f3167fcb175f4798af27783fe364Brian Paul    * So, if copying from compressed to uncompressed, the dest region is
545200aee424790f3167fcb175f4798af27783fe364Brian Paul    * shrunk by the src block size factor.  If copying from uncompressed
546200aee424790f3167fcb175f4798af27783fe364Brian Paul    * to compressed, the dest region is grown by the dest block size factor.
547200aee424790f3167fcb175f4798af27783fe364Brian Paul    * Note that we're passed the _source_ width, height, depth and those
548200aee424790f3167fcb175f4798af27783fe364Brian Paul    * dimensions are never changed.
549200aee424790f3167fcb175f4798af27783fe364Brian Paul    */
550200aee424790f3167fcb175f4798af27783fe364Brian Paul   dstWidth = srcWidth * dst_bw / src_bw;
551200aee424790f3167fcb175f4798af27783fe364Brian Paul   dstHeight = srcHeight * dst_bh / src_bh;
552200aee424790f3167fcb175f4798af27783fe364Brian Paul   dstDepth = srcDepth;
553200aee424790f3167fcb175f4798af27783fe364Brian Paul
554200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!check_region_bounds(ctx, srcTarget, srcTexImage, srcRenderbuffer,
555200aee424790f3167fcb175f4798af27783fe364Brian Paul                            srcX, srcY, srcZ, srcWidth, srcHeight, srcDepth,
556200aee424790f3167fcb175f4798af27783fe364Brian Paul                            "src"))
557200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
55841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
559200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!check_region_bounds(ctx, dstTarget, dstTexImage, dstRenderbuffer,
560200aee424790f3167fcb175f4798af27783fe364Brian Paul                            dstX, dstY, dstZ, dstWidth, dstHeight, dstDepth,
561200aee424790f3167fcb175f4798af27783fe364Brian Paul                            "dst"))
562200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
56341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
564c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie   /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core Profile
565c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    * spec says:
566c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    *
567c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    *    An INVALID_OPERATION error is generated if either object is a texture
568c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    *    and the texture is not complete, if the source and destination internal
569c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    *    formats are not compatible, or if the number of samples do not match.
570c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    */
571200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!copy_format_compatible(ctx, srcIntFormat, dstIntFormat)) {
5721a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      _mesa_error(ctx, GL_INVALID_OPERATION,
5731a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca                  "glCopyImageSubData(internalFormat mismatch)");
574200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
57541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
57641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
577c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie   if (src_num_samples != dst_num_samples) {
578c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie      _mesa_error(ctx, GL_INVALID_OPERATION,
579c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie                  "glCopyImageSubData(number of samples mismatch)");
580c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie      return;
581c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie   }
582c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie
583200aee424790f3167fcb175f4798af27783fe364Brian Paul   /* loop over 2D slices/faces/layers */
58441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   for (i = 0; i < srcDepth; ++i) {
585200aee424790f3167fcb175f4798af27783fe364Brian Paul      int newSrcZ = srcZ + i;
586200aee424790f3167fcb175f4798af27783fe364Brian Paul      int newDstZ = dstZ + i;
587200aee424790f3167fcb175f4798af27783fe364Brian Paul
588200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (srcTexImage &&
589200aee424790f3167fcb175f4798af27783fe364Brian Paul          srcTexImage->TexObject->Target == GL_TEXTURE_CUBE_MAP) {
590200aee424790f3167fcb175f4798af27783fe364Brian Paul         /* need to update srcTexImage pointer for the cube face */
591200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(srcZ + i < MAX_FACES);
592200aee424790f3167fcb175f4798af27783fe364Brian Paul         srcTexImage = srcTexImage->TexObject->Image[srcZ + i][srcLevel];
593200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(srcTexImage);
594200aee424790f3167fcb175f4798af27783fe364Brian Paul         newSrcZ = 0;
59541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
59641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
597200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (dstTexImage &&
598200aee424790f3167fcb175f4798af27783fe364Brian Paul          dstTexImage->TexObject->Target == GL_TEXTURE_CUBE_MAP) {
599200aee424790f3167fcb175f4798af27783fe364Brian Paul         /* need to update dstTexImage pointer for the cube face */
600200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(dstZ + i < MAX_FACES);
601200aee424790f3167fcb175f4798af27783fe364Brian Paul         dstTexImage = dstTexImage->TexObject->Image[dstZ + i][dstLevel];
602200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(dstTexImage);
603200aee424790f3167fcb175f4798af27783fe364Brian Paul         newDstZ = 0;
60441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
60541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
606200aee424790f3167fcb175f4798af27783fe364Brian Paul      ctx->Driver.CopyImageSubData(ctx,
607200aee424790f3167fcb175f4798af27783fe364Brian Paul                                   srcTexImage, srcRenderbuffer,
608200aee424790f3167fcb175f4798af27783fe364Brian Paul                                   srcX, srcY, newSrcZ,
609200aee424790f3167fcb175f4798af27783fe364Brian Paul                                   dstTexImage, dstRenderbuffer,
610200aee424790f3167fcb175f4798af27783fe364Brian Paul                                   dstX, dstY, newDstZ,
61141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                                   srcWidth, srcHeight);
61241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
61341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand}
614