copyimage.c revision af7bf610cf74c6805f42babbcf85bc88b2b9453d
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) {
14141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_VALUE,
14241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sName = %u)", dbg_prefix, name);
14341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
14441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
14541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
146200aee424790f3167fcb175f4798af27783fe364Brian Paul      _mesa_test_texobj_completeness(ctx, texObj);
147200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (!texObj->_BaseComplete ||
148200aee424790f3167fcb175f4798af27783fe364Brian Paul          (level != 0 && !texObj->_MipmapComplete)) {
14941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_OPERATION,
15041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sName incomplete)", dbg_prefix);
15141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
15241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
15341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
154200aee424790f3167fcb175f4798af27783fe364Brian Paul      /* Note that target will not be a cube face name */
155200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (texObj->Target != target) {
156200aee424790f3167fcb175f4798af27783fe364Brian Paul         /*
157200aee424790f3167fcb175f4798af27783fe364Brian Paul          * From GL_ARB_copy_image specification:
158200aee424790f3167fcb175f4798af27783fe364Brian Paul          * "INVALID_VALUE is generated if either <srcName> or <dstName> does
159200aee424790f3167fcb175f4798af27783fe364Brian Paul          * not correspond to a valid renderbuffer or texture object according
160200aee424790f3167fcb175f4798af27783fe364Brian Paul          * to the corresponding target parameter."
161200aee424790f3167fcb175f4798af27783fe364Brian Paul          */
162200aee424790f3167fcb175f4798af27783fe364Brian Paul         _mesa_error(ctx, GL_INVALID_VALUE,
16341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sTarget = %s)", dbg_prefix,
164200aee424790f3167fcb175f4798af27783fe364Brian Paul                     _mesa_enum_to_string(target));
16541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
16641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
16741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
16841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
16941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_VALUE,
17041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sLevel = %d)", dbg_prefix, level);
17141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
17241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
17341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
174200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (target == GL_TEXTURE_CUBE_MAP) {
175200aee424790f3167fcb175f4798af27783fe364Brian Paul         int i;
176200aee424790f3167fcb175f4798af27783fe364Brian Paul
177200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(z < MAX_FACES);  /* should have been caught earlier */
178200aee424790f3167fcb175f4798af27783fe364Brian Paul
179200aee424790f3167fcb175f4798af27783fe364Brian Paul         /* make sure all the cube faces are present */
180200aee424790f3167fcb175f4798af27783fe364Brian Paul         for (i = 0; i < depth; i++) {
181200aee424790f3167fcb175f4798af27783fe364Brian Paul            if (!texObj->Image[z+i][level]) {
182200aee424790f3167fcb175f4798af27783fe364Brian Paul               /* missing cube face */
183af7bf610cf74c6805f42babbcf85bc88b2b9453dDave Airlie               _mesa_error(ctx, GL_INVALID_VALUE,
184200aee424790f3167fcb175f4798af27783fe364Brian Paul                           "glCopyImageSubData(missing cube face)");
185200aee424790f3167fcb175f4798af27783fe364Brian Paul               return false;
186200aee424790f3167fcb175f4798af27783fe364Brian Paul            }
187200aee424790f3167fcb175f4798af27783fe364Brian Paul         }
188200aee424790f3167fcb175f4798af27783fe364Brian Paul
189200aee424790f3167fcb175f4798af27783fe364Brian Paul         *tex_image = texObj->Image[z][level];
190200aee424790f3167fcb175f4798af27783fe364Brian Paul      }
191200aee424790f3167fcb175f4798af27783fe364Brian Paul      else {
192200aee424790f3167fcb175f4798af27783fe364Brian Paul         *tex_image = _mesa_select_tex_image(texObj, target, level);
193200aee424790f3167fcb175f4798af27783fe364Brian Paul      }
194200aee424790f3167fcb175f4798af27783fe364Brian Paul
19541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      if (!*tex_image) {
19641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         _mesa_error(ctx, GL_INVALID_VALUE,
19741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                     "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level);
19841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand         return false;
19941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
200200aee424790f3167fcb175f4798af27783fe364Brian Paul
201200aee424790f3167fcb175f4798af27783fe364Brian Paul      *renderbuffer = NULL;
202200aee424790f3167fcb175f4798af27783fe364Brian Paul      *format = (*tex_image)->TexFormat;
203200aee424790f3167fcb175f4798af27783fe364Brian Paul      *internalFormat = (*tex_image)->InternalFormat;
204912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin      *width = (*tex_image)->Width;
205912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin      *height = (*tex_image)->Height;
206c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie      *num_samples = (*tex_image)->NumSamples;
20741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
20841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
20941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   return true;
21041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand}
21141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
212dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul
213dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul/**
214dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * Check that the x,y,z,width,height,region is within the texture image
215dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * dimensions.
216dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul * \return true if bounds OK, false if regions is out of bounds
217dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul */
21841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrandstatic bool
2190b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paulcheck_region_bounds(struct gl_context *ctx,
220200aee424790f3167fcb175f4798af27783fe364Brian Paul                    GLenum target,
2210b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paul                    const struct gl_texture_image *tex_image,
222200aee424790f3167fcb175f4798af27783fe364Brian Paul                    const struct gl_renderbuffer *renderbuffer,
22341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                    int x, int y, int z, int width, int height, int depth,
22441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                    const char *dbg_prefix)
22541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand{
226200aee424790f3167fcb175f4798af27783fe364Brian Paul   int surfWidth, surfHeight, surfDepth;
227200aee424790f3167fcb175f4798af27783fe364Brian Paul
22841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if (width < 0 || height < 0 || depth < 0) {
22941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
23041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(%sWidth, %sHeight, or %sDepth is negative)",
23141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  dbg_prefix, dbg_prefix, dbg_prefix);
23241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      return false;
23341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
23441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
23541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if (x < 0 || y < 0 || z < 0) {
23641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
23741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(%sX, %sY, or %sZ is negative)",
23841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  dbg_prefix, dbg_prefix, dbg_prefix);
23941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      return false;
24041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
24141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
242dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul   /* Check X direction */
243200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (target == GL_RENDERBUFFER) {
244200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfWidth = renderbuffer->Width;
245200aee424790f3167fcb175f4798af27783fe364Brian Paul   }
246200aee424790f3167fcb175f4798af27783fe364Brian Paul   else {
247200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfWidth = tex_image->Width;
248200aee424790f3167fcb175f4798af27783fe364Brian Paul   }
249200aee424790f3167fcb175f4798af27783fe364Brian Paul
250200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (x + width > surfWidth) {
25141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
25241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(%sX or %sWidth exceeds image bounds)",
25341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  dbg_prefix, dbg_prefix);
25441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      return false;
25541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
25641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
257dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul   /* Check Y direction */
258200aee424790f3167fcb175f4798af27783fe364Brian Paul   switch (target) {
259200aee424790f3167fcb175f4798af27783fe364Brian Paul   case GL_RENDERBUFFER:
260200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfHeight = renderbuffer->Height;
261200aee424790f3167fcb175f4798af27783fe364Brian Paul      break;
26241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D:
26341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D_ARRAY:
264200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfHeight = 1;
26541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
26641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   default:
267200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfHeight = tex_image->Height;
268200aee424790f3167fcb175f4798af27783fe364Brian Paul   }
269200aee424790f3167fcb175f4798af27783fe364Brian Paul
270200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (y + height > surfHeight) {
271200aee424790f3167fcb175f4798af27783fe364Brian Paul      _mesa_error(ctx, GL_INVALID_VALUE,
272200aee424790f3167fcb175f4798af27783fe364Brian Paul                  "glCopyImageSubData(%sY or %sHeight exceeds image bounds)",
273200aee424790f3167fcb175f4798af27783fe364Brian Paul                  dbg_prefix, dbg_prefix);
274200aee424790f3167fcb175f4798af27783fe364Brian Paul      return false;
27541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
27641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
277dce53a7d2453c0b2b69a345340455866e75f0a8dBrian Paul   /* Check Z direction */
278200aee424790f3167fcb175f4798af27783fe364Brian Paul   switch (target) {
279200aee424790f3167fcb175f4798af27783fe364Brian Paul   case GL_RENDERBUFFER:
28041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D:
28141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_2D:
28241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_2D_MULTISAMPLE:
28341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_RECTANGLE:
284200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfDepth = 1;
28541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
28641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_CUBE_MAP:
287200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfDepth = 6;
28841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
28941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   case GL_TEXTURE_1D_ARRAY:
290200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfDepth = tex_image->Height;
29141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      break;
292200aee424790f3167fcb175f4798af27783fe364Brian Paul   default:
293200aee424790f3167fcb175f4798af27783fe364Brian Paul      surfDepth = tex_image->Depth;
294200aee424790f3167fcb175f4798af27783fe364Brian Paul   }
295200aee424790f3167fcb175f4798af27783fe364Brian Paul
296200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (z < 0 || z + depth > surfDepth) {
297200aee424790f3167fcb175f4798af27783fe364Brian Paul      _mesa_error(ctx, GL_INVALID_VALUE,
298200aee424790f3167fcb175f4798af27783fe364Brian Paul                  "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",
299200aee424790f3167fcb175f4798af27783fe364Brian Paul                  dbg_prefix, dbg_prefix);
300200aee424790f3167fcb175f4798af27783fe364Brian Paul      return false;
30141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
30241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
30341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   return true;
30441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand}
30541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
3061a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrcastatic bool
3070b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paulcompressed_format_compatible(const struct gl_context *ctx,
3081a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca                             GLenum compressedFormat, GLenum otherFormat)
3091a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca{
3101a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   enum mesa_block_class compressedClass, otherClass;
3111a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
3121a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   /* Two view-incompatible compressed formats are never compatible. */
3131a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   if (_mesa_is_compressed_format(ctx, otherFormat)) {
3141a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      return false;
3151a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   }
3161a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
3171a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   /*
3181a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    * From ARB_copy_image spec:
3191a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    Table 4.X.1 (Compatible internal formats for copying between
3201a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *                 compressed and uncompressed internal formats)
3211a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    ---------------------------------------------------------------------
3221a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | Texel / | Uncompressed      |                                     |
3231a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | Block   | internal format   | Compressed internal format          |
3241a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | size    |                   |                                     |
3251a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    ---------------------------------------------------------------------
3261a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | 128-bit | RGBA32UI,         | COMPRESSED_RGBA_S3TC_DXT3_EXT,      |
3271a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA32I,          | COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,|
3281a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA32F           | COMPRESSED_RGBA_S3TC_DXT5_EXT,      |
3291a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,|
3301a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_RG_RGTC2,                |
3311a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_SIGNED_RG_RGTC2,         |
3321a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_RGBA_BPTC_UNORM,         |
3331a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_SRGB_ALPHA_BPTC_UNORM,   |
3341a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_RGB_BPTC_SIGNED_FLOAT,   |
3351a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT  |
3361a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    ---------------------------------------------------------------------
3371a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    | 64-bit  | RGBA16F, RG32F,   | COMPRESSED_RGB_S3TC_DXT1_EXT,       |
3381a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA16UI, RG32UI, | COMPRESSED_SRGB_S3TC_DXT1_EXT,      |
3391a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA16I, RG32I,   | COMPRESSED_RGBA_S3TC_DXT1_EXT,      |
3401a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA16,           | COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,|
3411a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         | RGBA16_SNORM      | COMPRESSED_RED_RGTC1,               |
3421a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    |         |                   | COMPRESSED_SIGNED_RED_RGTC1         |
3431a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    ---------------------------------------------------------------------
3441a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    */
3451a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
3461a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   switch (compressedFormat) {
3471a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
3481a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
3491a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
3501a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
3511a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RG_RGTC2:
3521a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SIGNED_RG_RGTC2:
3531a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGBA_BPTC_UNORM:
3541a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
3551a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
3561a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
3571a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         compressedClass = BLOCK_CLASS_128_BITS;
3581a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         break;
3591a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
3601a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
3611a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
3621a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
3631a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_RED_RGTC1:
3641a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_COMPRESSED_SIGNED_RED_RGTC1:
3651a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         compressedClass = BLOCK_CLASS_64_BITS;
3661a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         break;
367ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_RGBA8_ETC2_EAC:
368ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
369ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_RG11_EAC:
370ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SIGNED_RG11_EAC:
371ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         if (_mesa_is_gles(ctx))
372ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            compressedClass = BLOCK_CLASS_128_BITS;
373ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         else
374ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            return false;
375ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         break;
376ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_RGB8_ETC2:
377ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SRGB8_ETC2:
378ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_R11_EAC:
379ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SIGNED_R11_EAC:
380ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
381ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin      case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
382ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         if (_mesa_is_gles(ctx))
383ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            compressedClass = BLOCK_CLASS_64_BITS;
384ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         else
385ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            return false;
386ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         break;
3871a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      default:
388ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         if (_mesa_is_gles(ctx) && _mesa_is_astc_format(compressedFormat))
389ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            compressedClass = BLOCK_CLASS_128_BITS;
390ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         else
391ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin            return false;
392ebdb5345480957c4fc3068fab17926be28d7dcd4Ilia Mirkin         break;
3931a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   }
3941a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
3951a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   switch (otherFormat) {
3961a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA32UI:
3971a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA32I:
3981a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA32F:
3991a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         otherClass = BLOCK_CLASS_128_BITS;
4001a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         break;
4011a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16F:
4021a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RG32F:
4031a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16UI:
4041a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RG32UI:
4051a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16I:
4061a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RG32I:
4071a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16:
4081a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      case GL_RGBA16_SNORM:
4091a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         otherClass = BLOCK_CLASS_64_BITS;
4101a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         break;
4111a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      default:
4121a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca         return false;
4131a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   }
4141a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4151a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   return compressedClass == otherClass;
4161a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca}
4171a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4181a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrcastatic bool
4190b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paulcopy_format_compatible(const struct gl_context *ctx,
4200b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paul                       GLenum srcFormat, GLenum dstFormat)
4211a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca{
4221a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   /*
4231a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    * From ARB_copy_image spec:
4241a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    For the purposes of CopyImageSubData, two internal formats
4251a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    are considered compatible if any of the following conditions are
4261a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    met:
4271a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    * the formats are the same,
4281a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    * the formats are considered compatible according to the
4291a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *      compatibility rules used for texture views as defined in
4301a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *      section 3.9.X. In particular, if both internal formats are listed
4311a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *      in the same entry of Table 3.X.2, they are considered compatible, or
4321a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *    * one format is compressed and the other is uncompressed and
4331a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    *      Table 4.X.1 lists the two formats in the same row.
4341a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca    */
4351a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4361a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   if (_mesa_texture_view_compatible_format(ctx, srcFormat, dstFormat)) {
4371a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      /* Also checks if formats are equal. */
4381a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      return true;
4391a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   } else if (_mesa_is_compressed_format(ctx, srcFormat)) {
4401a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      return compressed_format_compatible(ctx, srcFormat, dstFormat);
4411a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   } else if (_mesa_is_compressed_format(ctx, dstFormat)) {
4421a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      return compressed_format_compatible(ctx, dstFormat, srcFormat);
4431a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   }
4441a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
4451a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca   return false;
4461a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca}
4471a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca
448f24be7340162c6a831b392d46d6637e9656e7a8aBrian Paulvoid GLAPIENTRY
44941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
45041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                       GLint srcX, GLint srcY, GLint srcZ,
45141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                       GLuint dstName, GLenum dstTarget, GLint dstLevel,
45241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                       GLint dstX, GLint dstY, GLint dstZ,
45341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                       GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
45441b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand{
45541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   GET_CURRENT_CONTEXT(ctx);
45641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   struct gl_texture_image *srcTexImage, *dstTexImage;
457200aee424790f3167fcb175f4798af27783fe364Brian Paul   struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer;
458200aee424790f3167fcb175f4798af27783fe364Brian Paul   mesa_format srcFormat, dstFormat;
459200aee424790f3167fcb175f4798af27783fe364Brian Paul   GLenum srcIntFormat, dstIntFormat;
460912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin   GLuint src_w, src_h, dst_w, dst_h;
46141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   GLuint src_bw, src_bh, dst_bw, dst_bh;
462c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie   GLuint src_num_samples, dst_num_samples;
463200aee424790f3167fcb175f4798af27783fe364Brian Paul   int dstWidth, dstHeight, dstDepth;
4640b76541ce0cc34020ef1057a17149cbf9cb3dbe1Brian Paul   int i;
46541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
46641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if (MESA_VERBOSE & VERBOSE_API)
46741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "
46841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                                          "%u, %s, %d, %d, %d, %d, "
46941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                                          "%d, %d, %d)\n",
4702f11e92cef51c88a09bc778e2ceca4ab50cf0017Kenneth Graunke                  srcName, _mesa_enum_to_string(srcTarget), srcLevel,
47141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  srcX, srcY, srcZ,
4722f11e92cef51c88a09bc778e2ceca4ab50cf0017Kenneth Graunke                  dstName, _mesa_enum_to_string(dstTarget), dstLevel,
47341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  dstX, dstY, dstZ,
474200aee424790f3167fcb175f4798af27783fe364Brian Paul                  srcWidth, srcHeight, srcDepth);
47541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
476ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul   if (!ctx->Extensions.ARB_copy_image) {
477ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul      _mesa_error(ctx, GL_INVALID_OPERATION,
478ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul                  "glCopyImageSubData(extension not available)");
479ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul      return;
480ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul   }
481ffb8e884f7c466c36cf64bf56ff63c52a833fa66Brian Paul
482200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!prepare_target(ctx, srcName, srcTarget, srcLevel, srcZ, srcDepth,
483200aee424790f3167fcb175f4798af27783fe364Brian Paul                       &srcTexImage, &srcRenderbuffer, &srcFormat,
484c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie                       &srcIntFormat, &src_w, &src_h, &src_num_samples, "src"))
485200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
48641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
487200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!prepare_target(ctx, dstName, dstTarget, dstLevel, dstZ, srcDepth,
488200aee424790f3167fcb175f4798af27783fe364Brian Paul                       &dstTexImage, &dstRenderbuffer, &dstFormat,
489c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie                       &dstIntFormat, &dst_w, &dst_h, &dst_num_samples, "dst"))
490200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
49141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
492200aee424790f3167fcb175f4798af27783fe364Brian Paul   _mesa_get_format_block_size(srcFormat, &src_bw, &src_bh);
493912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin
494912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin   /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core Profile
495912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * spec says:
496912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
497912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    An INVALID_VALUE error is generated if the dimensions of either
498912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    subregion exceeds the boundaries of the corresponding image object,
499912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    or if the image format is compressed and the dimensions of the
500912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    subregion fail to meet the alignment constraints of the format.
501912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
502912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * and Section 8.7 (Compressed Texture Images) says:
503912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
504912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    An INVALID_OPERATION error is generated if any of the following
505912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *    conditions occurs:
506912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
507912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *      * width is not a multiple of four, and width + xoffset is not
508912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *        equal to the value of TEXTURE_WIDTH.
509912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *      * height is not a multiple of four, and height + yoffset is not
510912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *        equal to the value of TEXTURE_HEIGHT.
511912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    *
512912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * so we take that to mean that you can copy the "last" block of a
513912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * compressed texture image even if it's smaller than the minimum block
514912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    * dimensions.
515912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin    */
51641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if ((srcX % src_bw != 0) || (srcY % src_bh != 0) ||
517912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin       (srcWidth % src_bw != 0 && (srcX + srcWidth) != src_w) ||
518912babba7bf1abd3caa49f6372d581ae1afe7e84Ilia Mirkin       (srcHeight % src_bh != 0 && (srcY + srcHeight) != src_h)) {
51941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
52041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(unaligned src rectangle)");
521200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
52241b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
52341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
524200aee424790f3167fcb175f4798af27783fe364Brian Paul   _mesa_get_format_block_size(dstFormat, &dst_bw, &dst_bh);
52541b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   if ((dstX % dst_bw != 0) || (dstY % dst_bh != 0)) {
52641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      _mesa_error(ctx, GL_INVALID_VALUE,
52741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                  "glCopyImageSubData(unaligned dst rectangle)");
528200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
52941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
53041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
531200aee424790f3167fcb175f4798af27783fe364Brian Paul   /* From the GL_ARB_copy_image spec:
532200aee424790f3167fcb175f4798af27783fe364Brian Paul    *
533200aee424790f3167fcb175f4798af27783fe364Brian Paul    * "The dimensions are always specified in texels, even for compressed
534200aee424790f3167fcb175f4798af27783fe364Brian Paul    * texture formats. But it should be noted that if only one of the
535200aee424790f3167fcb175f4798af27783fe364Brian Paul    * source and destination textures is compressed then the number of
536200aee424790f3167fcb175f4798af27783fe364Brian Paul    * texels touched in the compressed image will be a factor of the
537200aee424790f3167fcb175f4798af27783fe364Brian Paul    * block size larger than in the uncompressed image."
538200aee424790f3167fcb175f4798af27783fe364Brian Paul    *
539200aee424790f3167fcb175f4798af27783fe364Brian Paul    * So, if copying from compressed to uncompressed, the dest region is
540200aee424790f3167fcb175f4798af27783fe364Brian Paul    * shrunk by the src block size factor.  If copying from uncompressed
541200aee424790f3167fcb175f4798af27783fe364Brian Paul    * to compressed, the dest region is grown by the dest block size factor.
542200aee424790f3167fcb175f4798af27783fe364Brian Paul    * Note that we're passed the _source_ width, height, depth and those
543200aee424790f3167fcb175f4798af27783fe364Brian Paul    * dimensions are never changed.
544200aee424790f3167fcb175f4798af27783fe364Brian Paul    */
545200aee424790f3167fcb175f4798af27783fe364Brian Paul   dstWidth = srcWidth * dst_bw / src_bw;
546200aee424790f3167fcb175f4798af27783fe364Brian Paul   dstHeight = srcHeight * dst_bh / src_bh;
547200aee424790f3167fcb175f4798af27783fe364Brian Paul   dstDepth = srcDepth;
548200aee424790f3167fcb175f4798af27783fe364Brian Paul
549200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!check_region_bounds(ctx, srcTarget, srcTexImage, srcRenderbuffer,
550200aee424790f3167fcb175f4798af27783fe364Brian Paul                            srcX, srcY, srcZ, srcWidth, srcHeight, srcDepth,
551200aee424790f3167fcb175f4798af27783fe364Brian Paul                            "src"))
552200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
55341b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
554200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!check_region_bounds(ctx, dstTarget, dstTexImage, dstRenderbuffer,
555200aee424790f3167fcb175f4798af27783fe364Brian Paul                            dstX, dstY, dstZ, dstWidth, dstHeight, dstDepth,
556200aee424790f3167fcb175f4798af27783fe364Brian Paul                            "dst"))
557200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
55841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
559c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie   /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core Profile
560c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    * spec says:
561c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    *
562c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    *    An INVALID_OPERATION error is generated if either object is a texture
563c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    *    and the texture is not complete, if the source and destination internal
564c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    *    formats are not compatible, or if the number of samples do not match.
565c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie    */
566200aee424790f3167fcb175f4798af27783fe364Brian Paul   if (!copy_format_compatible(ctx, srcIntFormat, dstIntFormat)) {
5671a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca      _mesa_error(ctx, GL_INVALID_OPERATION,
5681a469a34d517d4c24c60a613c7d1a56f77778c8eSeán de Búrca                  "glCopyImageSubData(internalFormat mismatch)");
569200aee424790f3167fcb175f4798af27783fe364Brian Paul      return;
57041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
57141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
572c0856eacf1f76f294e2b89eb7250580517018567Dave Airlie   if (src_num_samples != dst_num_samples) {
573c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie      _mesa_error(ctx, GL_INVALID_OPERATION,
574c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie                  "glCopyImageSubData(number of samples mismatch)");
575c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie      return;
576c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie   }
577c4a0cd4662efe32e95c3f1e68b2f058b60bdcb52Dave Airlie
578200aee424790f3167fcb175f4798af27783fe364Brian Paul   /* loop over 2D slices/faces/layers */
57941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   for (i = 0; i < srcDepth; ++i) {
580200aee424790f3167fcb175f4798af27783fe364Brian Paul      int newSrcZ = srcZ + i;
581200aee424790f3167fcb175f4798af27783fe364Brian Paul      int newDstZ = dstZ + i;
582200aee424790f3167fcb175f4798af27783fe364Brian Paul
583200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (srcTexImage &&
584200aee424790f3167fcb175f4798af27783fe364Brian Paul          srcTexImage->TexObject->Target == GL_TEXTURE_CUBE_MAP) {
585200aee424790f3167fcb175f4798af27783fe364Brian Paul         /* need to update srcTexImage pointer for the cube face */
586200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(srcZ + i < MAX_FACES);
587200aee424790f3167fcb175f4798af27783fe364Brian Paul         srcTexImage = srcTexImage->TexObject->Image[srcZ + i][srcLevel];
588200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(srcTexImage);
589200aee424790f3167fcb175f4798af27783fe364Brian Paul         newSrcZ = 0;
59041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
59141b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
592200aee424790f3167fcb175f4798af27783fe364Brian Paul      if (dstTexImage &&
593200aee424790f3167fcb175f4798af27783fe364Brian Paul          dstTexImage->TexObject->Target == GL_TEXTURE_CUBE_MAP) {
594200aee424790f3167fcb175f4798af27783fe364Brian Paul         /* need to update dstTexImage pointer for the cube face */
595200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(dstZ + i < MAX_FACES);
596200aee424790f3167fcb175f4798af27783fe364Brian Paul         dstTexImage = dstTexImage->TexObject->Image[dstZ + i][dstLevel];
597200aee424790f3167fcb175f4798af27783fe364Brian Paul         assert(dstTexImage);
598200aee424790f3167fcb175f4798af27783fe364Brian Paul         newDstZ = 0;
59941b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand      }
60041b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand
601200aee424790f3167fcb175f4798af27783fe364Brian Paul      ctx->Driver.CopyImageSubData(ctx,
602200aee424790f3167fcb175f4798af27783fe364Brian Paul                                   srcTexImage, srcRenderbuffer,
603200aee424790f3167fcb175f4798af27783fe364Brian Paul                                   srcX, srcY, newSrcZ,
604200aee424790f3167fcb175f4798af27783fe364Brian Paul                                   dstTexImage, dstRenderbuffer,
605200aee424790f3167fcb175f4798af27783fe364Brian Paul                                   dstX, dstY, newDstZ,
60641b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand                                   srcWidth, srcHeight);
60741b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand   }
60841b6460e08bf878ec3372937f63bef2a7b63c484Jason Ekstrand}
609