1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 2014 Intel Corporation. All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker *
16*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker */
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker #include "context.h"
26*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
27*61046927SAndroid Build Coastguard Worker #include "errors.h"
28*61046927SAndroid Build Coastguard Worker #include "enums.h"
29*61046927SAndroid Build Coastguard Worker #include "teximage.h"
30*61046927SAndroid Build Coastguard Worker #include "texobj.h"
31*61046927SAndroid Build Coastguard Worker #include "fbobject.h"
32*61046927SAndroid Build Coastguard Worker #include "textureview.h"
33*61046927SAndroid Build Coastguard Worker #include "glformats.h"
34*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
35*61046927SAndroid Build Coastguard Worker
36*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_copyimage.h"
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker enum mesa_block_class {
39*61046927SAndroid Build Coastguard Worker BLOCK_CLASS_128_BITS,
40*61046927SAndroid Build Coastguard Worker BLOCK_CLASS_64_BITS
41*61046927SAndroid Build Coastguard Worker };
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker /**
44*61046927SAndroid Build Coastguard Worker * Prepare the source or destination resource. This involves error
45*61046927SAndroid Build Coastguard Worker * checking and returning the relevant gl_texture_image or gl_renderbuffer.
46*61046927SAndroid Build Coastguard Worker * Note that one of the resulting tex_image or renderbuffer pointers will be
47*61046927SAndroid Build Coastguard Worker * NULL and the other will be non-null.
48*61046927SAndroid Build Coastguard Worker *
49*61046927SAndroid Build Coastguard Worker * \param name the texture or renderbuffer name
50*61046927SAndroid Build Coastguard Worker * \param target One of GL_TEXTURE_x target or GL_RENDERBUFFER
51*61046927SAndroid Build Coastguard Worker * \param level mipmap level
52*61046927SAndroid Build Coastguard Worker * \param z src or dest Z
53*61046927SAndroid Build Coastguard Worker * \param depth number of slices/faces/layers to copy
54*61046927SAndroid Build Coastguard Worker * \param tex_image returns a pointer to a texture image
55*61046927SAndroid Build Coastguard Worker * \param renderbuffer returns a pointer to a renderbuffer
56*61046927SAndroid Build Coastguard Worker * \return true if success, false if error
57*61046927SAndroid Build Coastguard Worker */
58*61046927SAndroid Build Coastguard Worker static bool
prepare_target_err(struct gl_context * ctx,GLuint name,GLenum target,int level,int z,int depth,struct gl_texture_image ** tex_image,struct gl_renderbuffer ** renderbuffer,mesa_format * format,GLenum * internalFormat,GLuint * width,GLuint * height,GLuint * num_samples,const char * dbg_prefix,bool is_arb_version)59*61046927SAndroid Build Coastguard Worker prepare_target_err(struct gl_context *ctx, GLuint name, GLenum target,
60*61046927SAndroid Build Coastguard Worker int level, int z, int depth,
61*61046927SAndroid Build Coastguard Worker struct gl_texture_image **tex_image,
62*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer **renderbuffer,
63*61046927SAndroid Build Coastguard Worker mesa_format *format,
64*61046927SAndroid Build Coastguard Worker GLenum *internalFormat,
65*61046927SAndroid Build Coastguard Worker GLuint *width,
66*61046927SAndroid Build Coastguard Worker GLuint *height,
67*61046927SAndroid Build Coastguard Worker GLuint *num_samples,
68*61046927SAndroid Build Coastguard Worker const char *dbg_prefix,
69*61046927SAndroid Build Coastguard Worker bool is_arb_version)
70*61046927SAndroid Build Coastguard Worker {
71*61046927SAndroid Build Coastguard Worker const char *suffix = is_arb_version ? "" : "NV";
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker if (name == 0) {
74*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
75*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sName = %d)", suffix, dbg_prefix, name);
76*61046927SAndroid Build Coastguard Worker return false;
77*61046927SAndroid Build Coastguard Worker }
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker /*
80*61046927SAndroid Build Coastguard Worker * INVALID_ENUM is generated
81*61046927SAndroid Build Coastguard Worker * * if either <srcTarget> or <dstTarget>
82*61046927SAndroid Build Coastguard Worker * - is not RENDERBUFFER or a valid non-proxy texture target
83*61046927SAndroid Build Coastguard Worker * - is TEXTURE_BUFFER, or
84*61046927SAndroid Build Coastguard Worker * - is one of the cubemap face selectors described in table 3.17,
85*61046927SAndroid Build Coastguard Worker */
86*61046927SAndroid Build Coastguard Worker switch (target) {
87*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
88*61046927SAndroid Build Coastguard Worker /* Not a texture target, but valid */
89*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D:
90*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D_ARRAY:
91*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
92*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
93*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
94*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_RECTANGLE:
95*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
96*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY:
97*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE:
98*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
99*61046927SAndroid Build Coastguard Worker /* These are all valid */
100*61046927SAndroid Build Coastguard Worker break;
101*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_EXTERNAL_OES:
102*61046927SAndroid Build Coastguard Worker /* Only exists in ES */
103*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles(ctx))
104*61046927SAndroid Build Coastguard Worker break;
105*61046927SAndroid Build Coastguard Worker FALLTHROUGH;
106*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_BUFFER:
107*61046927SAndroid Build Coastguard Worker default:
108*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
109*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sTarget = %s)", suffix, dbg_prefix,
110*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
111*61046927SAndroid Build Coastguard Worker return false;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker if (target == GL_RENDERBUFFER) {
115*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name);
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker if (!rb) {
118*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
119*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sName = %u)", suffix, dbg_prefix, name);
120*61046927SAndroid Build Coastguard Worker return false;
121*61046927SAndroid Build Coastguard Worker }
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker if (!rb->Name) {
124*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
125*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sName incomplete)", suffix, dbg_prefix);
126*61046927SAndroid Build Coastguard Worker return false;
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker if (level != 0) {
130*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
131*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sLevel = %u)", suffix, dbg_prefix, level);
132*61046927SAndroid Build Coastguard Worker return false;
133*61046927SAndroid Build Coastguard Worker }
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker *renderbuffer = rb;
136*61046927SAndroid Build Coastguard Worker *format = rb->Format;
137*61046927SAndroid Build Coastguard Worker *internalFormat = rb->InternalFormat;
138*61046927SAndroid Build Coastguard Worker *width = rb->Width;
139*61046927SAndroid Build Coastguard Worker *height = rb->Height;
140*61046927SAndroid Build Coastguard Worker *num_samples = rb->NumSamples;
141*61046927SAndroid Build Coastguard Worker *tex_image = NULL;
142*61046927SAndroid Build Coastguard Worker } else {
143*61046927SAndroid Build Coastguard Worker struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name);
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker if (!texObj) {
146*61046927SAndroid Build Coastguard Worker /*
147*61046927SAndroid Build Coastguard Worker * From GL_ARB_copy_image specification:
148*61046927SAndroid Build Coastguard Worker * "INVALID_VALUE is generated if either <srcName> or <dstName> does
149*61046927SAndroid Build Coastguard Worker * not correspond to a valid renderbuffer or texture object according
150*61046927SAndroid Build Coastguard Worker * to the corresponding target parameter."
151*61046927SAndroid Build Coastguard Worker */
152*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
153*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sName = %u)", suffix, dbg_prefix, name);
154*61046927SAndroid Build Coastguard Worker return false;
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker /* The ARB_copy_image specification says:
158*61046927SAndroid Build Coastguard Worker *
159*61046927SAndroid Build Coastguard Worker * "INVALID_OPERATION is generated if either object is a texture and
160*61046927SAndroid Build Coastguard Worker * the texture is not complete (as defined in section 3.9.14)"
161*61046927SAndroid Build Coastguard Worker *
162*61046927SAndroid Build Coastguard Worker * The cited section says:
163*61046927SAndroid Build Coastguard Worker *
164*61046927SAndroid Build Coastguard Worker * "Using the preceding definitions, a texture is complete unless any
165*61046927SAndroid Build Coastguard Worker * of the following conditions hold true: [...]
166*61046927SAndroid Build Coastguard Worker *
167*61046927SAndroid Build Coastguard Worker * * The minification filter requires a mipmap (is neither NEAREST
168*61046927SAndroid Build Coastguard Worker * nor LINEAR), and the texture is not mipmap complete."
169*61046927SAndroid Build Coastguard Worker *
170*61046927SAndroid Build Coastguard Worker * This imposes the bizarre restriction that glCopyImageSubData requires
171*61046927SAndroid Build Coastguard Worker * mipmap completion based on the sampler minification filter, even
172*61046927SAndroid Build Coastguard Worker * though the call fundamentally ignores the sampler. Additionally, it
173*61046927SAndroid Build Coastguard Worker * doesn't work with texture units, so it can't consider any bound
174*61046927SAndroid Build Coastguard Worker * separate sampler objects. It appears that you're supposed to use
175*61046927SAndroid Build Coastguard Worker * the sampler object which is built-in to the texture object.
176*61046927SAndroid Build Coastguard Worker *
177*61046927SAndroid Build Coastguard Worker * dEQP and the Android CTS mandate this behavior, and the Khronos
178*61046927SAndroid Build Coastguard Worker * GL and ES working groups both affirmed that this is unfortunate but
179*61046927SAndroid Build Coastguard Worker * correct. See https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16224.
180*61046927SAndroid Build Coastguard Worker *
181*61046927SAndroid Build Coastguard Worker * Integer textures with filtering cause another completeness snag:
182*61046927SAndroid Build Coastguard Worker *
183*61046927SAndroid Build Coastguard Worker * "Any of:
184*61046927SAndroid Build Coastguard Worker * – The internal format of the texture is integer (see table 8.12).
185*61046927SAndroid Build Coastguard Worker * – The internal format is STENCIL_INDEX.
186*61046927SAndroid Build Coastguard Worker * – The internal format is DEPTH_STENCIL, and the value of
187*61046927SAndroid Build Coastguard Worker * DEPTH_STENCIL_TEXTURE_MODE for the texture is STENCIL_INDEX.
188*61046927SAndroid Build Coastguard Worker * and either the magnification filter is not NEAREST, or the
189*61046927SAndroid Build Coastguard Worker * minification filter is neither NEAREST nor
190*61046927SAndroid Build Coastguard Worker * NEAREST_MIPMAP_NEAREST."
191*61046927SAndroid Build Coastguard Worker *
192*61046927SAndroid Build Coastguard Worker * However, applications in the wild (such as "Total War: WARHAMMER")
193*61046927SAndroid Build Coastguard Worker * appear to call glCopyImageSubData with integer textures and the
194*61046927SAndroid Build Coastguard Worker * default mipmap filters of GL_LINEAR and GL_NEAREST_MIPMAP_LINEAR,
195*61046927SAndroid Build Coastguard Worker * which would be considered incomplete, but expect this to work. In
196*61046927SAndroid Build Coastguard Worker * fact, until VK-GL-CTS commit fef80039ff875a51806b54d151c5f2d0c12da,
197*61046927SAndroid Build Coastguard Worker * the GL 4.5 CTS contained three tests which did the exact same thing
198*61046927SAndroid Build Coastguard Worker * by accident, and all conformant implementations allowed it.
199*61046927SAndroid Build Coastguard Worker *
200*61046927SAndroid Build Coastguard Worker * A proposal was made to amend the spec to say "is not complete (as
201*61046927SAndroid Build Coastguard Worker * defined in section <X>, but ignoring format-based completeness
202*61046927SAndroid Build Coastguard Worker * rules)" to allow this case. It makes some sense, given that
203*61046927SAndroid Build Coastguard Worker * glCopyImageSubData copies raw data without considering format.
204*61046927SAndroid Build Coastguard Worker * While the official edits have not yet been made, the OpenGL
205*61046927SAndroid Build Coastguard Worker * working group agreed with the idea of allowing this behavior.
206*61046927SAndroid Build Coastguard Worker *
207*61046927SAndroid Build Coastguard Worker * To ignore formats, we check texObj->_MipmapComplete directly
208*61046927SAndroid Build Coastguard Worker * rather than calling _mesa_is_texture_complete().
209*61046927SAndroid Build Coastguard Worker */
210*61046927SAndroid Build Coastguard Worker _mesa_test_texobj_completeness(ctx, texObj);
211*61046927SAndroid Build Coastguard Worker const bool texture_complete_aside_from_formats =
212*61046927SAndroid Build Coastguard Worker _mesa_is_mipmap_filter(&texObj->Sampler) ? texObj->_MipmapComplete
213*61046927SAndroid Build Coastguard Worker : texObj->_BaseComplete;
214*61046927SAndroid Build Coastguard Worker if (!texture_complete_aside_from_formats) {
215*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
216*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sName incomplete)", suffix, dbg_prefix);
217*61046927SAndroid Build Coastguard Worker return false;
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker /* Note that target will not be a cube face name */
221*61046927SAndroid Build Coastguard Worker if (texObj->Target != target) {
222*61046927SAndroid Build Coastguard Worker /*
223*61046927SAndroid Build Coastguard Worker * From GL_ARB_copy_image_specification:
224*61046927SAndroid Build Coastguard Worker * "INVALID_ENUM is generated if the target does not match the type
225*61046927SAndroid Build Coastguard Worker * of the object."
226*61046927SAndroid Build Coastguard Worker */
227*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
228*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sTarget = %s)", suffix, dbg_prefix,
229*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
230*61046927SAndroid Build Coastguard Worker return false;
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
234*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
235*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sLevel = %d)", suffix, dbg_prefix, level);
236*61046927SAndroid Build Coastguard Worker return false;
237*61046927SAndroid Build Coastguard Worker }
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker if (target == GL_TEXTURE_CUBE_MAP) {
240*61046927SAndroid Build Coastguard Worker int i;
241*61046927SAndroid Build Coastguard Worker
242*61046927SAndroid Build Coastguard Worker if (z < 0 || z >= MAX_FACES) {
243*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
244*61046927SAndroid Build Coastguard Worker "glCopyImageSubData(cube face (%sZ = %d)", dbg_prefix, z);
245*61046927SAndroid Build Coastguard Worker return false;
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker /* make sure all the cube faces are present */
249*61046927SAndroid Build Coastguard Worker for (i = 0; i < depth; i++) {
250*61046927SAndroid Build Coastguard Worker if (!texObj->Image[z+i][level]) {
251*61046927SAndroid Build Coastguard Worker /* missing cube face */
252*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
253*61046927SAndroid Build Coastguard Worker "glCopyImageSubData(missing cube face)");
254*61046927SAndroid Build Coastguard Worker return false;
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker }
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker *tex_image = texObj->Image[z][level];
259*61046927SAndroid Build Coastguard Worker }
260*61046927SAndroid Build Coastguard Worker else {
261*61046927SAndroid Build Coastguard Worker *tex_image = _mesa_select_tex_image(texObj, target, level);
262*61046927SAndroid Build Coastguard Worker }
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker if (!*tex_image) {
265*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
266*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sLevel = %u)", suffix, dbg_prefix, level);
267*61046927SAndroid Build Coastguard Worker return false;
268*61046927SAndroid Build Coastguard Worker }
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker *renderbuffer = NULL;
271*61046927SAndroid Build Coastguard Worker *format = (*tex_image)->TexFormat;
272*61046927SAndroid Build Coastguard Worker *internalFormat = (*tex_image)->InternalFormat;
273*61046927SAndroid Build Coastguard Worker *width = (*tex_image)->Width;
274*61046927SAndroid Build Coastguard Worker *height = (*tex_image)->Height;
275*61046927SAndroid Build Coastguard Worker *num_samples = (*tex_image)->NumSamples;
276*61046927SAndroid Build Coastguard Worker }
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker return true;
279*61046927SAndroid Build Coastguard Worker }
280*61046927SAndroid Build Coastguard Worker
281*61046927SAndroid Build Coastguard Worker static void
prepare_target(struct gl_context * ctx,GLuint name,GLenum target,int level,int z,struct gl_texture_image ** texImage,struct gl_renderbuffer ** renderbuffer)282*61046927SAndroid Build Coastguard Worker prepare_target(struct gl_context *ctx, GLuint name, GLenum target,
283*61046927SAndroid Build Coastguard Worker int level, int z,
284*61046927SAndroid Build Coastguard Worker struct gl_texture_image **texImage,
285*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer **renderbuffer)
286*61046927SAndroid Build Coastguard Worker {
287*61046927SAndroid Build Coastguard Worker if (target == GL_RENDERBUFFER) {
288*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name);
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker *renderbuffer = rb;
291*61046927SAndroid Build Coastguard Worker *texImage = NULL;
292*61046927SAndroid Build Coastguard Worker } else {
293*61046927SAndroid Build Coastguard Worker struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name);
294*61046927SAndroid Build Coastguard Worker
295*61046927SAndroid Build Coastguard Worker if (target == GL_TEXTURE_CUBE_MAP) {
296*61046927SAndroid Build Coastguard Worker *texImage = texObj->Image[z][level];
297*61046927SAndroid Build Coastguard Worker }
298*61046927SAndroid Build Coastguard Worker else {
299*61046927SAndroid Build Coastguard Worker *texImage = _mesa_select_tex_image(texObj, target, level);
300*61046927SAndroid Build Coastguard Worker }
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker *renderbuffer = NULL;
303*61046927SAndroid Build Coastguard Worker }
304*61046927SAndroid Build Coastguard Worker }
305*61046927SAndroid Build Coastguard Worker
306*61046927SAndroid Build Coastguard Worker /**
307*61046927SAndroid Build Coastguard Worker * Check that the x,y,z,width,height,region is within the texture image
308*61046927SAndroid Build Coastguard Worker * dimensions.
309*61046927SAndroid Build Coastguard Worker * \return true if bounds OK, false if regions is out of bounds
310*61046927SAndroid Build Coastguard Worker */
311*61046927SAndroid Build Coastguard Worker static bool
check_region_bounds(struct gl_context * ctx,GLenum target,const struct gl_texture_image * tex_image,const struct gl_renderbuffer * renderbuffer,int x,int y,int z,int width,int height,int depth,const char * dbg_prefix,bool is_arb_version)312*61046927SAndroid Build Coastguard Worker check_region_bounds(struct gl_context *ctx,
313*61046927SAndroid Build Coastguard Worker GLenum target,
314*61046927SAndroid Build Coastguard Worker const struct gl_texture_image *tex_image,
315*61046927SAndroid Build Coastguard Worker const struct gl_renderbuffer *renderbuffer,
316*61046927SAndroid Build Coastguard Worker int x, int y, int z, int width, int height, int depth,
317*61046927SAndroid Build Coastguard Worker const char *dbg_prefix,
318*61046927SAndroid Build Coastguard Worker bool is_arb_version)
319*61046927SAndroid Build Coastguard Worker {
320*61046927SAndroid Build Coastguard Worker int surfWidth, surfHeight, surfDepth;
321*61046927SAndroid Build Coastguard Worker const char *suffix = is_arb_version ? "" : "NV";
322*61046927SAndroid Build Coastguard Worker
323*61046927SAndroid Build Coastguard Worker if (width < 0 || height < 0 || depth < 0) {
324*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
325*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sWidth, %sHeight, or %sDepth is negative)",
326*61046927SAndroid Build Coastguard Worker suffix, dbg_prefix, dbg_prefix, dbg_prefix);
327*61046927SAndroid Build Coastguard Worker return false;
328*61046927SAndroid Build Coastguard Worker }
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker if (x < 0 || y < 0 || z < 0) {
331*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
332*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sX, %sY, or %sZ is negative)",
333*61046927SAndroid Build Coastguard Worker suffix, dbg_prefix, dbg_prefix, dbg_prefix);
334*61046927SAndroid Build Coastguard Worker return false;
335*61046927SAndroid Build Coastguard Worker }
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker /* Check X direction */
338*61046927SAndroid Build Coastguard Worker if (target == GL_RENDERBUFFER) {
339*61046927SAndroid Build Coastguard Worker surfWidth = renderbuffer->Width;
340*61046927SAndroid Build Coastguard Worker }
341*61046927SAndroid Build Coastguard Worker else {
342*61046927SAndroid Build Coastguard Worker surfWidth = tex_image->Width;
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker if (x + width > surfWidth) {
346*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
347*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sX or %sWidth exceeds image bounds)",
348*61046927SAndroid Build Coastguard Worker suffix, dbg_prefix, dbg_prefix);
349*61046927SAndroid Build Coastguard Worker return false;
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker /* Check Y direction */
353*61046927SAndroid Build Coastguard Worker switch (target) {
354*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
355*61046927SAndroid Build Coastguard Worker surfHeight = renderbuffer->Height;
356*61046927SAndroid Build Coastguard Worker break;
357*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D:
358*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D_ARRAY:
359*61046927SAndroid Build Coastguard Worker surfHeight = 1;
360*61046927SAndroid Build Coastguard Worker break;
361*61046927SAndroid Build Coastguard Worker default:
362*61046927SAndroid Build Coastguard Worker surfHeight = tex_image->Height;
363*61046927SAndroid Build Coastguard Worker }
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker if (y + height > surfHeight) {
366*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
367*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sY or %sHeight exceeds image bounds)",
368*61046927SAndroid Build Coastguard Worker suffix, dbg_prefix, dbg_prefix);
369*61046927SAndroid Build Coastguard Worker return false;
370*61046927SAndroid Build Coastguard Worker }
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker /* Check Z direction */
373*61046927SAndroid Build Coastguard Worker switch (target) {
374*61046927SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
375*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D:
376*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
377*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE:
378*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_RECTANGLE:
379*61046927SAndroid Build Coastguard Worker surfDepth = 1;
380*61046927SAndroid Build Coastguard Worker break;
381*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
382*61046927SAndroid Build Coastguard Worker surfDepth = 6;
383*61046927SAndroid Build Coastguard Worker break;
384*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_1D_ARRAY:
385*61046927SAndroid Build Coastguard Worker surfDepth = tex_image->Height;
386*61046927SAndroid Build Coastguard Worker break;
387*61046927SAndroid Build Coastguard Worker default:
388*61046927SAndroid Build Coastguard Worker surfDepth = tex_image->Depth;
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker if (z < 0 || z + depth > surfDepth) {
392*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
393*61046927SAndroid Build Coastguard Worker "glCopyImageSubData%s(%sZ or %sDepth exceeds image bounds)",
394*61046927SAndroid Build Coastguard Worker suffix, dbg_prefix, dbg_prefix);
395*61046927SAndroid Build Coastguard Worker return false;
396*61046927SAndroid Build Coastguard Worker }
397*61046927SAndroid Build Coastguard Worker
398*61046927SAndroid Build Coastguard Worker return true;
399*61046927SAndroid Build Coastguard Worker }
400*61046927SAndroid Build Coastguard Worker
401*61046927SAndroid Build Coastguard Worker static bool
compressed_format_compatible(const struct gl_context * ctx,GLenum compressedFormat,GLenum otherFormat)402*61046927SAndroid Build Coastguard Worker compressed_format_compatible(const struct gl_context *ctx,
403*61046927SAndroid Build Coastguard Worker GLenum compressedFormat, GLenum otherFormat)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker enum mesa_block_class compressedClass, otherClass;
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker /* Two view-incompatible compressed formats are never compatible. */
408*61046927SAndroid Build Coastguard Worker if (_mesa_is_compressed_format(ctx, otherFormat)) {
409*61046927SAndroid Build Coastguard Worker return false;
410*61046927SAndroid Build Coastguard Worker }
411*61046927SAndroid Build Coastguard Worker
412*61046927SAndroid Build Coastguard Worker /*
413*61046927SAndroid Build Coastguard Worker * From ARB_copy_image spec:
414*61046927SAndroid Build Coastguard Worker * Table 4.X.1 (Compatible internal formats for copying between
415*61046927SAndroid Build Coastguard Worker * compressed and uncompressed internal formats)
416*61046927SAndroid Build Coastguard Worker * ---------------------------------------------------------------------
417*61046927SAndroid Build Coastguard Worker * | Texel / | Uncompressed | |
418*61046927SAndroid Build Coastguard Worker * | Block | internal format | Compressed internal format |
419*61046927SAndroid Build Coastguard Worker * | size | | |
420*61046927SAndroid Build Coastguard Worker * ---------------------------------------------------------------------
421*61046927SAndroid Build Coastguard Worker * | 128-bit | RGBA32UI, | COMPRESSED_RGBA_S3TC_DXT3_EXT, |
422*61046927SAndroid Build Coastguard Worker * | | RGBA32I, | COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,|
423*61046927SAndroid Build Coastguard Worker * | | RGBA32F | COMPRESSED_RGBA_S3TC_DXT5_EXT, |
424*61046927SAndroid Build Coastguard Worker * | | | COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,|
425*61046927SAndroid Build Coastguard Worker * | | | COMPRESSED_RG_RGTC2, |
426*61046927SAndroid Build Coastguard Worker * | | | COMPRESSED_SIGNED_RG_RGTC2, |
427*61046927SAndroid Build Coastguard Worker * | | | COMPRESSED_RGBA_BPTC_UNORM, |
428*61046927SAndroid Build Coastguard Worker * | | | COMPRESSED_SRGB_ALPHA_BPTC_UNORM, |
429*61046927SAndroid Build Coastguard Worker * | | | COMPRESSED_RGB_BPTC_SIGNED_FLOAT, |
430*61046927SAndroid Build Coastguard Worker * | | | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT |
431*61046927SAndroid Build Coastguard Worker * ---------------------------------------------------------------------
432*61046927SAndroid Build Coastguard Worker * | 64-bit | RGBA16F, RG32F, | COMPRESSED_RGB_S3TC_DXT1_EXT, |
433*61046927SAndroid Build Coastguard Worker * | | RGBA16UI, RG32UI, | COMPRESSED_SRGB_S3TC_DXT1_EXT, |
434*61046927SAndroid Build Coastguard Worker * | | RGBA16I, RG32I, | COMPRESSED_RGBA_S3TC_DXT1_EXT, |
435*61046927SAndroid Build Coastguard Worker * | | RGBA16, | COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,|
436*61046927SAndroid Build Coastguard Worker * | | RGBA16_SNORM | COMPRESSED_RED_RGTC1, |
437*61046927SAndroid Build Coastguard Worker * | | | COMPRESSED_SIGNED_RED_RGTC1 |
438*61046927SAndroid Build Coastguard Worker * ---------------------------------------------------------------------
439*61046927SAndroid Build Coastguard Worker */
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker switch (compressedFormat) {
442*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
443*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
444*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
445*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
446*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RG_RGTC2:
447*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RG_RGTC2:
448*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_BPTC_UNORM:
449*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
450*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
451*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
452*61046927SAndroid Build Coastguard Worker compressedClass = BLOCK_CLASS_128_BITS;
453*61046927SAndroid Build Coastguard Worker break;
454*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
455*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
456*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
457*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
458*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RED_RGTC1:
459*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RED_RGTC1:
460*61046927SAndroid Build Coastguard Worker compressedClass = BLOCK_CLASS_64_BITS;
461*61046927SAndroid Build Coastguard Worker break;
462*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA8_ETC2_EAC:
463*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
464*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RG11_EAC:
465*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RG11_EAC:
466*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles(ctx))
467*61046927SAndroid Build Coastguard Worker compressedClass = BLOCK_CLASS_128_BITS;
468*61046927SAndroid Build Coastguard Worker else
469*61046927SAndroid Build Coastguard Worker return false;
470*61046927SAndroid Build Coastguard Worker break;
471*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB8_ETC2:
472*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ETC2:
473*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_R11_EAC:
474*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_R11_EAC:
475*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
476*61046927SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
477*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles(ctx))
478*61046927SAndroid Build Coastguard Worker compressedClass = BLOCK_CLASS_64_BITS;
479*61046927SAndroid Build Coastguard Worker else
480*61046927SAndroid Build Coastguard Worker return false;
481*61046927SAndroid Build Coastguard Worker break;
482*61046927SAndroid Build Coastguard Worker default:
483*61046927SAndroid Build Coastguard Worker if (_mesa_is_gles(ctx) && _mesa_is_astc_format(compressedFormat))
484*61046927SAndroid Build Coastguard Worker compressedClass = BLOCK_CLASS_128_BITS;
485*61046927SAndroid Build Coastguard Worker else
486*61046927SAndroid Build Coastguard Worker return false;
487*61046927SAndroid Build Coastguard Worker break;
488*61046927SAndroid Build Coastguard Worker }
489*61046927SAndroid Build Coastguard Worker
490*61046927SAndroid Build Coastguard Worker switch (otherFormat) {
491*61046927SAndroid Build Coastguard Worker case GL_RGBA32UI:
492*61046927SAndroid Build Coastguard Worker case GL_RGBA32I:
493*61046927SAndroid Build Coastguard Worker case GL_RGBA32F:
494*61046927SAndroid Build Coastguard Worker otherClass = BLOCK_CLASS_128_BITS;
495*61046927SAndroid Build Coastguard Worker break;
496*61046927SAndroid Build Coastguard Worker case GL_RGBA16F:
497*61046927SAndroid Build Coastguard Worker case GL_RG32F:
498*61046927SAndroid Build Coastguard Worker case GL_RGBA16UI:
499*61046927SAndroid Build Coastguard Worker case GL_RG32UI:
500*61046927SAndroid Build Coastguard Worker case GL_RGBA16I:
501*61046927SAndroid Build Coastguard Worker case GL_RG32I:
502*61046927SAndroid Build Coastguard Worker case GL_RGBA16:
503*61046927SAndroid Build Coastguard Worker case GL_RGBA16_SNORM:
504*61046927SAndroid Build Coastguard Worker otherClass = BLOCK_CLASS_64_BITS;
505*61046927SAndroid Build Coastguard Worker break;
506*61046927SAndroid Build Coastguard Worker default:
507*61046927SAndroid Build Coastguard Worker return false;
508*61046927SAndroid Build Coastguard Worker }
509*61046927SAndroid Build Coastguard Worker
510*61046927SAndroid Build Coastguard Worker return compressedClass == otherClass;
511*61046927SAndroid Build Coastguard Worker }
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker static bool
copy_format_compatible(const struct gl_context * ctx,GLenum srcFormat,GLenum dstFormat)514*61046927SAndroid Build Coastguard Worker copy_format_compatible(const struct gl_context *ctx,
515*61046927SAndroid Build Coastguard Worker GLenum srcFormat, GLenum dstFormat)
516*61046927SAndroid Build Coastguard Worker {
517*61046927SAndroid Build Coastguard Worker /*
518*61046927SAndroid Build Coastguard Worker * From ARB_copy_image spec:
519*61046927SAndroid Build Coastguard Worker * For the purposes of CopyImageSubData, two internal formats
520*61046927SAndroid Build Coastguard Worker * are considered compatible if any of the following conditions are
521*61046927SAndroid Build Coastguard Worker * met:
522*61046927SAndroid Build Coastguard Worker * * the formats are the same,
523*61046927SAndroid Build Coastguard Worker * * the formats are considered compatible according to the
524*61046927SAndroid Build Coastguard Worker * compatibility rules used for texture views as defined in
525*61046927SAndroid Build Coastguard Worker * section 3.9.X. In particular, if both internal formats are listed
526*61046927SAndroid Build Coastguard Worker * in the same entry of Table 3.X.2, they are considered compatible, or
527*61046927SAndroid Build Coastguard Worker * * one format is compressed and the other is uncompressed and
528*61046927SAndroid Build Coastguard Worker * Table 4.X.1 lists the two formats in the same row.
529*61046927SAndroid Build Coastguard Worker */
530*61046927SAndroid Build Coastguard Worker
531*61046927SAndroid Build Coastguard Worker if (_mesa_texture_view_compatible_format(ctx, srcFormat, dstFormat)) {
532*61046927SAndroid Build Coastguard Worker /* Also checks if formats are equal. */
533*61046927SAndroid Build Coastguard Worker return true;
534*61046927SAndroid Build Coastguard Worker } else if (_mesa_is_compressed_format(ctx, srcFormat)) {
535*61046927SAndroid Build Coastguard Worker return compressed_format_compatible(ctx, srcFormat, dstFormat);
536*61046927SAndroid Build Coastguard Worker } else if (_mesa_is_compressed_format(ctx, dstFormat)) {
537*61046927SAndroid Build Coastguard Worker return compressed_format_compatible(ctx, dstFormat, srcFormat);
538*61046927SAndroid Build Coastguard Worker }
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker return false;
541*61046927SAndroid Build Coastguard Worker }
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker static void
copy_image_subdata(struct gl_context * ctx,struct gl_texture_image * srcTexImage,struct gl_renderbuffer * srcRenderbuffer,int srcX,int srcY,int srcZ,int srcLevel,struct gl_texture_image * dstTexImage,struct gl_renderbuffer * dstRenderbuffer,int dstX,int dstY,int dstZ,int dstLevel,int srcWidth,int srcHeight,int srcDepth)544*61046927SAndroid Build Coastguard Worker copy_image_subdata(struct gl_context *ctx,
545*61046927SAndroid Build Coastguard Worker struct gl_texture_image *srcTexImage,
546*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *srcRenderbuffer,
547*61046927SAndroid Build Coastguard Worker int srcX, int srcY, int srcZ, int srcLevel,
548*61046927SAndroid Build Coastguard Worker struct gl_texture_image *dstTexImage,
549*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *dstRenderbuffer,
550*61046927SAndroid Build Coastguard Worker int dstX, int dstY, int dstZ, int dstLevel,
551*61046927SAndroid Build Coastguard Worker int srcWidth, int srcHeight, int srcDepth)
552*61046927SAndroid Build Coastguard Worker {
553*61046927SAndroid Build Coastguard Worker /* loop over 2D slices/faces/layers */
554*61046927SAndroid Build Coastguard Worker for (int i = 0; i < srcDepth; ++i) {
555*61046927SAndroid Build Coastguard Worker int newSrcZ = srcZ + i;
556*61046927SAndroid Build Coastguard Worker int newDstZ = dstZ + i;
557*61046927SAndroid Build Coastguard Worker
558*61046927SAndroid Build Coastguard Worker if (srcTexImage &&
559*61046927SAndroid Build Coastguard Worker srcTexImage->TexObject->Target == GL_TEXTURE_CUBE_MAP) {
560*61046927SAndroid Build Coastguard Worker /* need to update srcTexImage pointer for the cube face */
561*61046927SAndroid Build Coastguard Worker assert(srcZ + i < MAX_FACES);
562*61046927SAndroid Build Coastguard Worker srcTexImage = srcTexImage->TexObject->Image[srcZ + i][srcLevel];
563*61046927SAndroid Build Coastguard Worker assert(srcTexImage);
564*61046927SAndroid Build Coastguard Worker newSrcZ = 0;
565*61046927SAndroid Build Coastguard Worker }
566*61046927SAndroid Build Coastguard Worker
567*61046927SAndroid Build Coastguard Worker if (dstTexImage &&
568*61046927SAndroid Build Coastguard Worker dstTexImage->TexObject->Target == GL_TEXTURE_CUBE_MAP) {
569*61046927SAndroid Build Coastguard Worker /* need to update dstTexImage pointer for the cube face */
570*61046927SAndroid Build Coastguard Worker assert(dstZ + i < MAX_FACES);
571*61046927SAndroid Build Coastguard Worker dstTexImage = dstTexImage->TexObject->Image[dstZ + i][dstLevel];
572*61046927SAndroid Build Coastguard Worker assert(dstTexImage);
573*61046927SAndroid Build Coastguard Worker newDstZ = 0;
574*61046927SAndroid Build Coastguard Worker }
575*61046927SAndroid Build Coastguard Worker
576*61046927SAndroid Build Coastguard Worker st_CopyImageSubData(ctx,
577*61046927SAndroid Build Coastguard Worker srcTexImage, srcRenderbuffer,
578*61046927SAndroid Build Coastguard Worker srcX, srcY, newSrcZ,
579*61046927SAndroid Build Coastguard Worker dstTexImage, dstRenderbuffer,
580*61046927SAndroid Build Coastguard Worker dstX, dstY, newDstZ,
581*61046927SAndroid Build Coastguard Worker srcWidth, srcHeight);
582*61046927SAndroid Build Coastguard Worker }
583*61046927SAndroid Build Coastguard Worker }
584*61046927SAndroid Build Coastguard Worker
585*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyImageSubData_no_error(GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)586*61046927SAndroid Build Coastguard Worker _mesa_CopyImageSubData_no_error(GLuint srcName, GLenum srcTarget, GLint srcLevel,
587*61046927SAndroid Build Coastguard Worker GLint srcX, GLint srcY, GLint srcZ,
588*61046927SAndroid Build Coastguard Worker GLuint dstName, GLenum dstTarget, GLint dstLevel,
589*61046927SAndroid Build Coastguard Worker GLint dstX, GLint dstY, GLint dstZ,
590*61046927SAndroid Build Coastguard Worker GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
591*61046927SAndroid Build Coastguard Worker {
592*61046927SAndroid Build Coastguard Worker struct gl_texture_image *srcTexImage, *dstTexImage;
593*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer;
594*61046927SAndroid Build Coastguard Worker
595*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
596*61046927SAndroid Build Coastguard Worker
597*61046927SAndroid Build Coastguard Worker prepare_target(ctx, srcName, srcTarget, srcLevel, srcZ, &srcTexImage,
598*61046927SAndroid Build Coastguard Worker &srcRenderbuffer);
599*61046927SAndroid Build Coastguard Worker
600*61046927SAndroid Build Coastguard Worker prepare_target(ctx, dstName, dstTarget, dstLevel, dstZ, &dstTexImage,
601*61046927SAndroid Build Coastguard Worker &dstRenderbuffer);
602*61046927SAndroid Build Coastguard Worker
603*61046927SAndroid Build Coastguard Worker copy_image_subdata(ctx, srcTexImage, srcRenderbuffer, srcX, srcY, srcZ,
604*61046927SAndroid Build Coastguard Worker srcLevel, dstTexImage, dstRenderbuffer, dstX, dstY, dstZ,
605*61046927SAndroid Build Coastguard Worker dstLevel, srcWidth, srcHeight, srcDepth);
606*61046927SAndroid Build Coastguard Worker }
607*61046927SAndroid Build Coastguard Worker
608*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyImageSubData(GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)609*61046927SAndroid Build Coastguard Worker _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
610*61046927SAndroid Build Coastguard Worker GLint srcX, GLint srcY, GLint srcZ,
611*61046927SAndroid Build Coastguard Worker GLuint dstName, GLenum dstTarget, GLint dstLevel,
612*61046927SAndroid Build Coastguard Worker GLint dstX, GLint dstY, GLint dstZ,
613*61046927SAndroid Build Coastguard Worker GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
614*61046927SAndroid Build Coastguard Worker {
615*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
616*61046927SAndroid Build Coastguard Worker struct gl_texture_image *srcTexImage, *dstTexImage;
617*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer;
618*61046927SAndroid Build Coastguard Worker mesa_format srcFormat, dstFormat;
619*61046927SAndroid Build Coastguard Worker GLenum srcIntFormat, dstIntFormat;
620*61046927SAndroid Build Coastguard Worker GLuint src_w, src_h, dst_w, dst_h;
621*61046927SAndroid Build Coastguard Worker GLuint src_bw, src_bh, dst_bw, dst_bh;
622*61046927SAndroid Build Coastguard Worker GLuint src_num_samples, dst_num_samples;
623*61046927SAndroid Build Coastguard Worker int dstWidth, dstHeight, dstDepth;
624*61046927SAndroid Build Coastguard Worker
625*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
626*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "
627*61046927SAndroid Build Coastguard Worker "%u, %s, %d, %d, %d, %d, "
628*61046927SAndroid Build Coastguard Worker "%d, %d, %d)\n",
629*61046927SAndroid Build Coastguard Worker srcName, _mesa_enum_to_string(srcTarget), srcLevel,
630*61046927SAndroid Build Coastguard Worker srcX, srcY, srcZ,
631*61046927SAndroid Build Coastguard Worker dstName, _mesa_enum_to_string(dstTarget), dstLevel,
632*61046927SAndroid Build Coastguard Worker dstX, dstY, dstZ,
633*61046927SAndroid Build Coastguard Worker srcWidth, srcHeight, srcDepth);
634*61046927SAndroid Build Coastguard Worker
635*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_copy_image) {
636*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
637*61046927SAndroid Build Coastguard Worker "glCopyImageSubData(extension not available)");
638*61046927SAndroid Build Coastguard Worker return;
639*61046927SAndroid Build Coastguard Worker }
640*61046927SAndroid Build Coastguard Worker
641*61046927SAndroid Build Coastguard Worker if (!prepare_target_err(ctx, srcName, srcTarget, srcLevel, srcZ, srcDepth,
642*61046927SAndroid Build Coastguard Worker &srcTexImage, &srcRenderbuffer, &srcFormat,
643*61046927SAndroid Build Coastguard Worker &srcIntFormat, &src_w, &src_h, &src_num_samples,
644*61046927SAndroid Build Coastguard Worker "src",true))
645*61046927SAndroid Build Coastguard Worker return;
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker if (!prepare_target_err(ctx, dstName, dstTarget, dstLevel, dstZ, srcDepth,
648*61046927SAndroid Build Coastguard Worker &dstTexImage, &dstRenderbuffer, &dstFormat,
649*61046927SAndroid Build Coastguard Worker &dstIntFormat, &dst_w, &dst_h, &dst_num_samples,
650*61046927SAndroid Build Coastguard Worker "dst",true))
651*61046927SAndroid Build Coastguard Worker return;
652*61046927SAndroid Build Coastguard Worker
653*61046927SAndroid Build Coastguard Worker _mesa_get_format_block_size(srcFormat, &src_bw, &src_bh);
654*61046927SAndroid Build Coastguard Worker
655*61046927SAndroid Build Coastguard Worker /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core Profile
656*61046927SAndroid Build Coastguard Worker * spec says:
657*61046927SAndroid Build Coastguard Worker *
658*61046927SAndroid Build Coastguard Worker * An INVALID_VALUE error is generated if the dimensions of either
659*61046927SAndroid Build Coastguard Worker * subregion exceeds the boundaries of the corresponding image object,
660*61046927SAndroid Build Coastguard Worker * or if the image format is compressed and the dimensions of the
661*61046927SAndroid Build Coastguard Worker * subregion fail to meet the alignment constraints of the format.
662*61046927SAndroid Build Coastguard Worker *
663*61046927SAndroid Build Coastguard Worker * and Section 8.7 (Compressed Texture Images) says:
664*61046927SAndroid Build Coastguard Worker *
665*61046927SAndroid Build Coastguard Worker * An INVALID_OPERATION error is generated if any of the following
666*61046927SAndroid Build Coastguard Worker * conditions occurs:
667*61046927SAndroid Build Coastguard Worker *
668*61046927SAndroid Build Coastguard Worker * * width is not a multiple of four, and width + xoffset is not
669*61046927SAndroid Build Coastguard Worker * equal to the value of TEXTURE_WIDTH.
670*61046927SAndroid Build Coastguard Worker * * height is not a multiple of four, and height + yoffset is not
671*61046927SAndroid Build Coastguard Worker * equal to the value of TEXTURE_HEIGHT.
672*61046927SAndroid Build Coastguard Worker *
673*61046927SAndroid Build Coastguard Worker * so we take that to mean that you can copy the "last" block of a
674*61046927SAndroid Build Coastguard Worker * compressed texture image even if it's smaller than the minimum block
675*61046927SAndroid Build Coastguard Worker * dimensions.
676*61046927SAndroid Build Coastguard Worker */
677*61046927SAndroid Build Coastguard Worker if ((srcX % src_bw != 0) || (srcY % src_bh != 0) ||
678*61046927SAndroid Build Coastguard Worker (srcWidth % src_bw != 0 && (srcX + srcWidth) != src_w) ||
679*61046927SAndroid Build Coastguard Worker (srcHeight % src_bh != 0 && (srcY + srcHeight) != src_h)) {
680*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
681*61046927SAndroid Build Coastguard Worker "glCopyImageSubData(unaligned src rectangle)");
682*61046927SAndroid Build Coastguard Worker return;
683*61046927SAndroid Build Coastguard Worker }
684*61046927SAndroid Build Coastguard Worker
685*61046927SAndroid Build Coastguard Worker _mesa_get_format_block_size(dstFormat, &dst_bw, &dst_bh);
686*61046927SAndroid Build Coastguard Worker if ((dstX % dst_bw != 0) || (dstY % dst_bh != 0)) {
687*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
688*61046927SAndroid Build Coastguard Worker "glCopyImageSubData(unaligned dst rectangle)");
689*61046927SAndroid Build Coastguard Worker return;
690*61046927SAndroid Build Coastguard Worker }
691*61046927SAndroid Build Coastguard Worker
692*61046927SAndroid Build Coastguard Worker /* From the GL_ARB_copy_image spec:
693*61046927SAndroid Build Coastguard Worker *
694*61046927SAndroid Build Coastguard Worker * "The dimensions are always specified in texels, even for compressed
695*61046927SAndroid Build Coastguard Worker * texture formats. But it should be noted that if only one of the
696*61046927SAndroid Build Coastguard Worker * source and destination textures is compressed then the number of
697*61046927SAndroid Build Coastguard Worker * texels touched in the compressed image will be a factor of the
698*61046927SAndroid Build Coastguard Worker * block size larger than in the uncompressed image."
699*61046927SAndroid Build Coastguard Worker *
700*61046927SAndroid Build Coastguard Worker * So, if copying from compressed to uncompressed, the dest region is
701*61046927SAndroid Build Coastguard Worker * shrunk by the src block size factor. If copying from uncompressed
702*61046927SAndroid Build Coastguard Worker * to compressed, the dest region is grown by the dest block size factor.
703*61046927SAndroid Build Coastguard Worker * Note that we're passed the _source_ width, height, depth and those
704*61046927SAndroid Build Coastguard Worker * dimensions are never changed.
705*61046927SAndroid Build Coastguard Worker */
706*61046927SAndroid Build Coastguard Worker dstWidth = srcWidth * dst_bw / src_bw;
707*61046927SAndroid Build Coastguard Worker dstHeight = srcHeight * dst_bh / src_bh;
708*61046927SAndroid Build Coastguard Worker dstDepth = srcDepth;
709*61046927SAndroid Build Coastguard Worker
710*61046927SAndroid Build Coastguard Worker if (!check_region_bounds(ctx, srcTarget, srcTexImage, srcRenderbuffer,
711*61046927SAndroid Build Coastguard Worker srcX, srcY, srcZ, srcWidth, srcHeight, srcDepth,
712*61046927SAndroid Build Coastguard Worker "src", true))
713*61046927SAndroid Build Coastguard Worker return;
714*61046927SAndroid Build Coastguard Worker
715*61046927SAndroid Build Coastguard Worker if (!check_region_bounds(ctx, dstTarget, dstTexImage, dstRenderbuffer,
716*61046927SAndroid Build Coastguard Worker dstX, dstY, dstZ, dstWidth, dstHeight, dstDepth,
717*61046927SAndroid Build Coastguard Worker "dst", true))
718*61046927SAndroid Build Coastguard Worker return;
719*61046927SAndroid Build Coastguard Worker
720*61046927SAndroid Build Coastguard Worker /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core Profile
721*61046927SAndroid Build Coastguard Worker * spec says:
722*61046927SAndroid Build Coastguard Worker *
723*61046927SAndroid Build Coastguard Worker * An INVALID_OPERATION error is generated if either object is a texture
724*61046927SAndroid Build Coastguard Worker * and the texture is not complete, if the source and destination internal
725*61046927SAndroid Build Coastguard Worker * formats are not compatible, or if the number of samples do not match.
726*61046927SAndroid Build Coastguard Worker */
727*61046927SAndroid Build Coastguard Worker if (!copy_format_compatible(ctx, srcIntFormat, dstIntFormat)) {
728*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
729*61046927SAndroid Build Coastguard Worker "glCopyImageSubData(internalFormat mismatch)");
730*61046927SAndroid Build Coastguard Worker return;
731*61046927SAndroid Build Coastguard Worker }
732*61046927SAndroid Build Coastguard Worker
733*61046927SAndroid Build Coastguard Worker if (src_num_samples != dst_num_samples) {
734*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
735*61046927SAndroid Build Coastguard Worker "glCopyImageSubData(number of samples mismatch)");
736*61046927SAndroid Build Coastguard Worker return;
737*61046927SAndroid Build Coastguard Worker }
738*61046927SAndroid Build Coastguard Worker
739*61046927SAndroid Build Coastguard Worker copy_image_subdata(ctx, srcTexImage, srcRenderbuffer, srcX, srcY, srcZ,
740*61046927SAndroid Build Coastguard Worker srcLevel, dstTexImage, dstRenderbuffer, dstX, dstY, dstZ,
741*61046927SAndroid Build Coastguard Worker dstLevel, srcWidth, srcHeight, srcDepth);
742*61046927SAndroid Build Coastguard Worker }
743*61046927SAndroid Build Coastguard Worker
744*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyImageSubDataNV_no_error(GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)745*61046927SAndroid Build Coastguard Worker _mesa_CopyImageSubDataNV_no_error(GLuint srcName, GLenum srcTarget, GLint srcLevel,
746*61046927SAndroid Build Coastguard Worker GLint srcX, GLint srcY, GLint srcZ,
747*61046927SAndroid Build Coastguard Worker GLuint dstName, GLenum dstTarget, GLint dstLevel,
748*61046927SAndroid Build Coastguard Worker GLint dstX, GLint dstY, GLint dstZ,
749*61046927SAndroid Build Coastguard Worker GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
750*61046927SAndroid Build Coastguard Worker {
751*61046927SAndroid Build Coastguard Worker struct gl_texture_image *srcTexImage, *dstTexImage;
752*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer;
753*61046927SAndroid Build Coastguard Worker
754*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
755*61046927SAndroid Build Coastguard Worker
756*61046927SAndroid Build Coastguard Worker prepare_target(ctx, srcName, srcTarget, srcLevel, srcZ, &srcTexImage,
757*61046927SAndroid Build Coastguard Worker &srcRenderbuffer);
758*61046927SAndroid Build Coastguard Worker
759*61046927SAndroid Build Coastguard Worker prepare_target(ctx, dstName, dstTarget, dstLevel, dstZ, &dstTexImage,
760*61046927SAndroid Build Coastguard Worker &dstRenderbuffer);
761*61046927SAndroid Build Coastguard Worker
762*61046927SAndroid Build Coastguard Worker copy_image_subdata(ctx, srcTexImage, srcRenderbuffer, srcX, srcY, srcZ,
763*61046927SAndroid Build Coastguard Worker srcLevel, dstTexImage, dstRenderbuffer, dstX, dstY, dstZ,
764*61046927SAndroid Build Coastguard Worker dstLevel, srcWidth, srcHeight, srcDepth);
765*61046927SAndroid Build Coastguard Worker }
766*61046927SAndroid Build Coastguard Worker
767*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyImageSubDataNV(GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)768*61046927SAndroid Build Coastguard Worker _mesa_CopyImageSubDataNV(GLuint srcName, GLenum srcTarget, GLint srcLevel,
769*61046927SAndroid Build Coastguard Worker GLint srcX, GLint srcY, GLint srcZ,
770*61046927SAndroid Build Coastguard Worker GLuint dstName, GLenum dstTarget, GLint dstLevel,
771*61046927SAndroid Build Coastguard Worker GLint dstX, GLint dstY, GLint dstZ,
772*61046927SAndroid Build Coastguard Worker GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
773*61046927SAndroid Build Coastguard Worker {
774*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
775*61046927SAndroid Build Coastguard Worker struct gl_texture_image *srcTexImage, *dstTexImage;
776*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer;
777*61046927SAndroid Build Coastguard Worker mesa_format srcFormat, dstFormat;
778*61046927SAndroid Build Coastguard Worker GLenum srcIntFormat, dstIntFormat;
779*61046927SAndroid Build Coastguard Worker GLuint src_w, src_h, dst_w, dst_h;
780*61046927SAndroid Build Coastguard Worker GLuint src_bw, src_bh, dst_bw, dst_bh;
781*61046927SAndroid Build Coastguard Worker GLuint src_num_samples, dst_num_samples;
782*61046927SAndroid Build Coastguard Worker
783*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
784*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glCopyImageSubDataNV(%u, %s, %d, %d, %d, %d, "
785*61046927SAndroid Build Coastguard Worker "%u, %s, %d, %d, %d, %d, "
786*61046927SAndroid Build Coastguard Worker "%d, %d, %d)\n",
787*61046927SAndroid Build Coastguard Worker srcName, _mesa_enum_to_string(srcTarget), srcLevel,
788*61046927SAndroid Build Coastguard Worker srcX, srcY, srcZ,
789*61046927SAndroid Build Coastguard Worker dstName, _mesa_enum_to_string(dstTarget), dstLevel,
790*61046927SAndroid Build Coastguard Worker dstX, dstY, dstZ,
791*61046927SAndroid Build Coastguard Worker srcWidth, srcHeight, srcDepth);
792*61046927SAndroid Build Coastguard Worker
793*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.NV_copy_image) {
794*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
795*61046927SAndroid Build Coastguard Worker "glCopyImageSubDataNV(extension not available)");
796*61046927SAndroid Build Coastguard Worker return;
797*61046927SAndroid Build Coastguard Worker }
798*61046927SAndroid Build Coastguard Worker
799*61046927SAndroid Build Coastguard Worker if (!prepare_target_err(ctx, srcName, srcTarget, srcLevel, srcZ, srcDepth,
800*61046927SAndroid Build Coastguard Worker &srcTexImage, &srcRenderbuffer, &srcFormat,
801*61046927SAndroid Build Coastguard Worker &srcIntFormat, &src_w, &src_h, &src_num_samples,
802*61046927SAndroid Build Coastguard Worker "src", false))
803*61046927SAndroid Build Coastguard Worker return;
804*61046927SAndroid Build Coastguard Worker
805*61046927SAndroid Build Coastguard Worker if (!prepare_target_err(ctx, dstName, dstTarget, dstLevel, dstZ, srcDepth,
806*61046927SAndroid Build Coastguard Worker &dstTexImage, &dstRenderbuffer, &dstFormat,
807*61046927SAndroid Build Coastguard Worker &dstIntFormat, &dst_w, &dst_h, &dst_num_samples,
808*61046927SAndroid Build Coastguard Worker "dst", false))
809*61046927SAndroid Build Coastguard Worker return;
810*61046927SAndroid Build Coastguard Worker
811*61046927SAndroid Build Coastguard Worker /*
812*61046927SAndroid Build Coastguard Worker * The NV_copy_image spec says:
813*61046927SAndroid Build Coastguard Worker *
814*61046927SAndroid Build Coastguard Worker * INVALID_OPERATION is generated if either object is a texture
815*61046927SAndroid Build Coastguard Worker * and the texture is not consistent, or if the source and destination
816*61046927SAndroid Build Coastguard Worker * internal formats or number of samples do not match.
817*61046927SAndroid Build Coastguard Worker *
818*61046927SAndroid Build Coastguard Worker * In the absence of any definition of texture consistency the texture
819*61046927SAndroid Build Coastguard Worker * completeness check, which is affected in the prepare_target_err function,
820*61046927SAndroid Build Coastguard Worker * is used instead in keeping with the ARB version.
821*61046927SAndroid Build Coastguard Worker * The check related to the internal format here is different from the ARB
822*61046927SAndroid Build Coastguard Worker * version which adds the ability to copy between images which have
823*61046927SAndroid Build Coastguard Worker * different formats where the formats are compatible for texture views.
824*61046927SAndroid Build Coastguard Worker */
825*61046927SAndroid Build Coastguard Worker if (srcIntFormat != dstIntFormat) {
826*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
827*61046927SAndroid Build Coastguard Worker "glCopyImageSubDataNV(internalFormat mismatch)");
828*61046927SAndroid Build Coastguard Worker return;
829*61046927SAndroid Build Coastguard Worker }
830*61046927SAndroid Build Coastguard Worker
831*61046927SAndroid Build Coastguard Worker if (src_num_samples != dst_num_samples) {
832*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
833*61046927SAndroid Build Coastguard Worker "glCopyImageSubDataNV(number of samples mismatch)");
834*61046927SAndroid Build Coastguard Worker return;
835*61046927SAndroid Build Coastguard Worker }
836*61046927SAndroid Build Coastguard Worker
837*61046927SAndroid Build Coastguard Worker /*
838*61046927SAndroid Build Coastguard Worker * The NV_copy_image spec says:
839*61046927SAndroid Build Coastguard Worker *
840*61046927SAndroid Build Coastguard Worker * INVALID_VALUE is generated if the image format is compressed
841*61046927SAndroid Build Coastguard Worker * and the dimensions of the subregion fail to meet the alignment
842*61046927SAndroid Build Coastguard Worker * constraints of the format.
843*61046927SAndroid Build Coastguard Worker *
844*61046927SAndroid Build Coastguard Worker * The check here is identical to the ARB version.
845*61046927SAndroid Build Coastguard Worker */
846*61046927SAndroid Build Coastguard Worker _mesa_get_format_block_size(srcFormat, &src_bw, &src_bh);
847*61046927SAndroid Build Coastguard Worker if ((srcX % src_bw != 0) || (srcY % src_bh != 0) ||
848*61046927SAndroid Build Coastguard Worker (srcWidth % src_bw != 0 && (srcX + srcWidth) != src_w) ||
849*61046927SAndroid Build Coastguard Worker (srcHeight % src_bh != 0 && (srcY + srcHeight) != src_h)) {
850*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
851*61046927SAndroid Build Coastguard Worker "glCopyImageSubDataNV(unaligned src rectangle)");
852*61046927SAndroid Build Coastguard Worker return;
853*61046927SAndroid Build Coastguard Worker }
854*61046927SAndroid Build Coastguard Worker
855*61046927SAndroid Build Coastguard Worker _mesa_get_format_block_size(dstFormat, &dst_bw, &dst_bh);
856*61046927SAndroid Build Coastguard Worker if ((dstX % dst_bw != 0) || (dstY % dst_bh != 0)) {
857*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
858*61046927SAndroid Build Coastguard Worker "glCopyImageSubDataNV(unaligned dst rectangle)");
859*61046927SAndroid Build Coastguard Worker return;
860*61046927SAndroid Build Coastguard Worker }
861*61046927SAndroid Build Coastguard Worker
862*61046927SAndroid Build Coastguard Worker /*
863*61046927SAndroid Build Coastguard Worker * The NV_copy_image spec says:
864*61046927SAndroid Build Coastguard Worker *
865*61046927SAndroid Build Coastguard Worker * INVALID_VALUE is generated if the dimensions of the either subregion
866*61046927SAndroid Build Coastguard Worker * exceeds the boundaries of the corresponding image object.
867*61046927SAndroid Build Coastguard Worker *
868*61046927SAndroid Build Coastguard Worker * The check here is similar to the ARB version except for the fact that
869*61046927SAndroid Build Coastguard Worker * block sizes are not considered owing to the fact that copying across
870*61046927SAndroid Build Coastguard Worker * compressed and uncompressed formats is not supported.
871*61046927SAndroid Build Coastguard Worker */
872*61046927SAndroid Build Coastguard Worker if (!check_region_bounds(ctx, srcTarget, srcTexImage, srcRenderbuffer,
873*61046927SAndroid Build Coastguard Worker srcX, srcY, srcZ, srcWidth, srcHeight, srcDepth,
874*61046927SAndroid Build Coastguard Worker "src", false))
875*61046927SAndroid Build Coastguard Worker return;
876*61046927SAndroid Build Coastguard Worker
877*61046927SAndroid Build Coastguard Worker if (!check_region_bounds(ctx, dstTarget, dstTexImage, dstRenderbuffer,
878*61046927SAndroid Build Coastguard Worker dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth,
879*61046927SAndroid Build Coastguard Worker "dst", false))
880*61046927SAndroid Build Coastguard Worker return;
881*61046927SAndroid Build Coastguard Worker
882*61046927SAndroid Build Coastguard Worker copy_image_subdata(ctx, srcTexImage, srcRenderbuffer, srcX, srcY, srcZ,
883*61046927SAndroid Build Coastguard Worker srcLevel, dstTexImage, dstRenderbuffer, dstX, dstY, dstZ,
884*61046927SAndroid Build Coastguard Worker dstLevel, srcWidth, srcHeight, srcDepth);
885*61046927SAndroid Build Coastguard Worker }
886