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