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