blob: afc6d46c4231534cb9f01a87f9dc7722af297065 [file] [log] [blame]
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Texture.cpp: Implements the gl::Texture class and its derived classes
8// Texture2D and TextureCubeMap. Implements GL texture objects and related
9// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
10
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Texture.h"
12#include "libANGLE/Context.h"
13#include "libANGLE/formatutils.h"
14#include "libANGLE/ImageIndex.h"
15#include "libANGLE/Renderbuffer.h"
16#include "libANGLE/renderer/Image.h"
17#include "libANGLE/renderer/d3d/TextureStorage.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018
Geoff Lang2b5420c2014-11-19 14:20:15 -050019#include "libANGLE/Surface.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040020
21#include "common/mathutil.h"
22#include "common/utilities.h"
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000023
24namespace gl
25{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000026
Brandon Jones6053a522014-07-25 16:22:09 -070027bool IsMipmapFiltered(const gl::SamplerState &samplerState)
28{
29 switch (samplerState.minFilter)
30 {
31 case GL_NEAREST:
32 case GL_LINEAR:
33 return false;
34 case GL_NEAREST_MIPMAP_NEAREST:
35 case GL_LINEAR_MIPMAP_NEAREST:
36 case GL_NEAREST_MIPMAP_LINEAR:
37 case GL_LINEAR_MIPMAP_LINEAR:
38 return true;
39 default: UNREACHABLE();
40 return false;
41 }
42}
43
44bool IsPointSampled(const gl::SamplerState &samplerState)
45{
46 return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
47}
48
Jamie Madill10ef2152014-10-20 17:04:34 -040049unsigned int Texture::mCurrentTextureSerial = 1;
50
Brandon Jones6053a522014-07-25 16:22:09 -070051Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
Brandon Jonesf47bebc2014-07-09 14:28:42 -070052 : RefCountObject(id),
Brandon Jones6053a522014-07-25 16:22:09 -070053 mTexture(impl),
Jamie Madill10ef2152014-10-20 17:04:34 -040054 mTextureSerial(issueTextureSerial()),
Brandon Jonesf47bebc2014-07-09 14:28:42 -070055 mUsage(GL_NONE),
Jamie Madill6948e302014-10-20 17:04:33 -040056 mImmutableLevelCount(0),
Brandon Jonesf47bebc2014-07-09 14:28:42 -070057 mTarget(target)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000058{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000059}
60
61Texture::~Texture()
62{
Brandon Jones6053a522014-07-25 16:22:09 -070063 SafeDelete(mTexture);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000064}
65
Geoff Lang4907f2c2013-07-25 12:53:57 -040066GLenum Texture::getTarget() const
67{
68 return mTarget;
69}
70
Geoff Lang63b5f1f2013-09-23 14:52:14 -040071void Texture::setUsage(GLenum usage)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000072{
Geoff Lang63b5f1f2013-09-23 14:52:14 -040073 mUsage = usage;
Brandon Jonescef06ff2014-08-05 13:27:48 -070074 getImplementation()->setUsage(usage);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000075}
76
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000077GLenum Texture::getUsage() const
78{
79 return mUsage;
80}
81
Jamie Madilld3d2a342013-10-07 10:46:35 -040082GLint Texture::getBaseLevelWidth() const
83{
84 const rx::Image *baseImage = getBaseLevelImage();
85 return (baseImage ? baseImage->getWidth() : 0);
86}
87
88GLint Texture::getBaseLevelHeight() const
89{
90 const rx::Image *baseImage = getBaseLevelImage();
91 return (baseImage ? baseImage->getHeight() : 0);
92}
93
94GLint Texture::getBaseLevelDepth() const
95{
96 const rx::Image *baseImage = getBaseLevelImage();
97 return (baseImage ? baseImage->getDepth() : 0);
98}
99
Jamie Madillb8f8b892014-01-07 10:12:50 -0500100// Note: "base level image" is loosely defined to be any image from the base level,
101// where in the base of 2D array textures and cube maps there are several. Don't use
102// the base level image for anything except querying texture format and size.
Jamie Madilld3d2a342013-10-07 10:46:35 -0400103GLenum Texture::getBaseLevelInternalFormat() const
104{
105 const rx::Image *baseImage = getBaseLevelImage();
106 return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
107}
108
Jamie Madill945f7322014-09-03 15:07:14 -0400109GLsizei Texture::getWidth(const ImageIndex &index) const
110{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400111 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400112 return image->getWidth();
113}
114
115GLsizei Texture::getHeight(const ImageIndex &index) const
116{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400117 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400118 return image->getHeight();
119}
120
121GLenum Texture::getInternalFormat(const ImageIndex &index) const
122{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400123 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400124 return image->getInternalFormat();
125}
126
127GLenum Texture::getActualFormat(const ImageIndex &index) const
128{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400129 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400130 return image->getActualFormat();
131}
132
Geoff Lang06ecf3d2014-09-23 16:39:50 -0400133Error Texture::generateMipmaps()
Brandon Jonescef06ff2014-08-05 13:27:48 -0700134{
Geoff Lang06ecf3d2014-09-23 16:39:50 -0400135 return getImplementation()->generateMipmaps();
Brandon Jonescef06ff2014-08-05 13:27:48 -0700136}
137
Geoff Langef7b0162014-09-04 13:29:23 -0400138Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
139 GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
Brandon Jones6b19b002014-07-16 14:32:05 -0700140{
Geoff Langef7b0162014-09-04 13:29:23 -0400141 return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
Brandon Jones6b19b002014-07-16 14:32:05 -0700142}
143
Jamie Madill10ef2152014-10-20 17:04:34 -0400144unsigned int Texture::getTextureSerial() const
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700145{
Jamie Madill10ef2152014-10-20 17:04:34 -0400146 return mTextureSerial;
147}
148
149unsigned int Texture::issueTextureSerial()
150{
151 return mCurrentTextureSerial++;
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700152}
153
154bool Texture::isImmutable() const
155{
Jamie Madill6948e302014-10-20 17:04:33 -0400156 return (mImmutableLevelCount > 0);
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700157}
158
159int Texture::immutableLevelCount()
160{
Jamie Madill6948e302014-10-20 17:04:33 -0400161 return mImmutableLevelCount;
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700162}
163
164int Texture::mipLevels() const
165{
166 return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
167}
168
Brandon Jonescef06ff2014-08-05 13:27:48 -0700169const rx::Image *Texture::getBaseLevelImage() const
170{
171 return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
172}
173
Brandon Jones6053a522014-07-25 16:22:09 -0700174Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
175 : Texture(impl, id, GL_TEXTURE_2D)
Jamie Madill22f843a2013-10-24 17:49:36 -0400176{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000177 mSurface = NULL;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000178}
179
180Texture2D::~Texture2D()
181{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000182 if (mSurface)
183 {
Jamie Madillfb0580a2014-11-27 14:03:52 -0500184 mSurface->releaseTexImage(EGL_BACK_BUFFER);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000185 mSurface = NULL;
186 }
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700187}
daniel@transgaming.comd9ec9022012-12-20 20:52:16 +0000188
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000189GLsizei Texture2D::getWidth(GLint level) const
190{
191 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700192 return mTexture->getImage(level, 0)->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000193 else
194 return 0;
195}
196
197GLsizei Texture2D::getHeight(GLint level) const
198{
199 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700200 return mTexture->getImage(level, 0)->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000201 else
202 return 0;
203}
204
205GLenum Texture2D::getInternalFormat(GLint level) const
206{
207 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700208 return mTexture->getImage(level, 0)->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000209 else
210 return GL_NONE;
211}
212
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000213GLenum Texture2D::getActualFormat(GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000214{
215 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700216 return mTexture->getImage(level, 0)->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000217 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500218 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000219}
220
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400221Error Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000222{
223 releaseTexImage();
shannon.woods@transgaming.com8a406682013-02-28 23:15:26 +0000224
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400225 return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000226}
227
228void Texture2D::bindTexImage(egl::Surface *surface)
229{
230 releaseTexImage();
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700231 mTexture->bindTexImage(surface);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000232 mSurface = surface;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000233}
234
235void Texture2D::releaseTexImage()
236{
237 if (mSurface)
238 {
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000239 mSurface = NULL;
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700240 mTexture->releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000241 }
242}
243
Geoff Langb5348332014-09-02 13:16:34 -0400244Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400245 const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000246{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700247 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000248
Jamie Madillc751d1e2014-10-21 17:46:29 -0400249 return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000250}
251
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400252Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000253{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400254 return mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000255}
256
Geoff Langb5348332014-09-02 13:16:34 -0400257Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400258 GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000259{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400260 return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000261}
262
Geoff Langef7b0162014-09-04 13:29:23 -0400263Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
264 Framebuffer *source)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000265{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700266 releaseTexImage();
Geoff Lang5d601382014-07-22 15:14:06 -0400267
Geoff Langef7b0162014-09-04 13:29:23 -0400268 return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000269}
270
Geoff Lang1f8532b2014-09-05 09:46:13 -0400271Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000272{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400273 Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
274 if (error.isError())
275 {
276 return error;
277 }
278
Jamie Madill6948e302014-10-20 17:04:33 -0400279 mImmutableLevelCount = levels;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000280
Geoff Lang1f8532b2014-09-05 09:46:13 -0400281 return Error(GL_NO_ERROR);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000282}
283
Brandon Jones6053a522014-07-25 16:22:09 -0700284// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
285bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
286{
287 GLsizei width = getBaseLevelWidth();
288 GLsizei height = getBaseLevelHeight();
289
290 if (width <= 0 || height <= 0)
291 {
292 return false;
293 }
294
295 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
296 {
297 return false;
298 }
299
300 bool npotSupport = extensions.textureNPOT;
301
302 if (!npotSupport)
303 {
304 if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
305 (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
306 {
307 return false;
308 }
309 }
310
311 if (IsMipmapFiltered(samplerState))
312 {
313 if (!npotSupport)
314 {
315 if (!gl::isPow2(width) || !gl::isPow2(height))
316 {
317 return false;
318 }
319 }
320
321 if (!isMipmapComplete())
322 {
323 return false;
324 }
325 }
326
327 // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
328 // The internalformat specified for the texture arrays is a sized internal depth or
329 // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
330 // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
331 // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
332 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
333 if (formatInfo.depthBits > 0 && clientVersion > 2)
334 {
335 if (samplerState.compareMode == GL_NONE)
336 {
337 if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
338 samplerState.magFilter != GL_NEAREST)
339 {
340 return false;
341 }
342 }
343 }
344
345 return true;
346}
347
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000348bool Texture2D::isCompressed(GLint level) const
349{
Geoff Lang5d601382014-07-22 15:14:06 -0400350 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000351}
352
353bool Texture2D::isDepth(GLint level) const
354{
Geoff Lang5d601382014-07-22 15:14:06 -0400355 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000356}
357
Geoff Lang06ecf3d2014-09-23 16:39:50 -0400358Error Texture2D::generateMipmaps()
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000359{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700360 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000361
Geoff Lang06ecf3d2014-09-23 16:39:50 -0400362 return mTexture->generateMipmaps();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000363}
364
Brandon Jones6053a522014-07-25 16:22:09 -0700365// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
366bool Texture2D::isMipmapComplete() const
367{
368 int levelCount = mipLevels();
369
370 for (int level = 0; level < levelCount; level++)
371 {
372 if (!isLevelComplete(level))
373 {
374 return false;
375 }
376 }
377
378 return true;
379}
380
381bool Texture2D::isLevelComplete(int level) const
382{
383 if (isImmutable())
384 {
385 return true;
386 }
387
388 const rx::Image *baseImage = getBaseLevelImage();
389
390 GLsizei width = baseImage->getWidth();
391 GLsizei height = baseImage->getHeight();
392
393 if (width <= 0 || height <= 0)
394 {
395 return false;
396 }
397
398 // The base image level is complete if the width and height are positive
399 if (level == 0)
400 {
401 return true;
402 }
403
404 ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
405 rx::Image *image = mTexture->getImage(level, 0);
406
407 if (image->getInternalFormat() != baseImage->getInternalFormat())
408 {
409 return false;
410 }
411
412 if (image->getWidth() != std::max(1, width >> level))
413 {
414 return false;
415 }
416
417 if (image->getHeight() != std::max(1, height >> level))
418 {
419 return false;
420 }
421
422 return true;
423}
424
425TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
426 : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000427{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000428}
429
430TextureCubeMap::~TextureCubeMap()
431{
Brandon Jones0511e802014-07-14 16:27:26 -0700432}
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000433
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000434GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
435{
436 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700437 return mTexture->getImage(level, targetToLayerIndex(target))->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000438 else
439 return 0;
440}
441
442GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
443{
444 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700445 return mTexture->getImage(level, targetToLayerIndex(target))->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000446 else
447 return 0;
448}
449
450GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
451{
452 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700453 return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000454 else
455 return GL_NONE;
456}
457
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000458GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000459{
460 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700461 return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000462 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500463 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000464}
465
Geoff Lang8376cea2014-09-02 11:47:07 -0400466Error TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000467{
Geoff Lang8376cea2014-09-02 11:47:07 -0400468 return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000469}
470
Geoff Langb5348332014-09-02 13:16:34 -0400471Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400472 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000473{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400474 return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000475}
476
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400477Error TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000478{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400479 return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000480}
481
Geoff Langb5348332014-09-02 13:16:34 -0400482Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset,
483 GLsizei width, GLsizei height, GLenum format,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400484 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000485{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400486 return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000487}
488
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000489// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
490bool TextureCubeMap::isCubeComplete() const
491{
Brandon Jones6053a522014-07-25 16:22:09 -0700492 int baseWidth = getBaseLevelWidth();
493 int baseHeight = getBaseLevelHeight();
494 GLenum baseFormat = getBaseLevelInternalFormat();
495
496 if (baseWidth <= 0 || baseWidth != baseHeight)
497 {
498 return false;
499 }
500
501 for (int faceIndex = 1; faceIndex < 6; faceIndex++)
502 {
503 const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
504
505 if (faceBaseImage->getWidth() != baseWidth ||
506 faceBaseImage->getHeight() != baseHeight ||
507 faceBaseImage->getInternalFormat() != baseFormat )
508 {
509 return false;
510 }
511 }
512
513 return true;
Jamie Madill07edd442013-07-19 16:36:58 -0400514}
515
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000516bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
517{
Geoff Lang5d601382014-07-22 15:14:06 -0400518 return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000519}
520
Geoff Lang8040f572013-07-25 16:49:54 -0400521bool TextureCubeMap::isDepth(GLenum target, GLint level) const
522{
Geoff Lang5d601382014-07-22 15:14:06 -0400523 return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
Geoff Lang8040f572013-07-25 16:49:54 -0400524}
525
Geoff Langef7b0162014-09-04 13:29:23 -0400526Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
527 GLsizei width, GLsizei height, Framebuffer *source)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000528{
Geoff Langef7b0162014-09-04 13:29:23 -0400529 return mTexture->copyImage(target, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000530}
531
Geoff Lang1f8532b2014-09-05 09:46:13 -0400532Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000533{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400534 Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
535 if (error.isError())
536 {
537 return error;
538 }
539
Jamie Madill6948e302014-10-20 17:04:33 -0400540 mImmutableLevelCount = levels;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000541
Geoff Lang1f8532b2014-09-05 09:46:13 -0400542 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400543}
544
Brandon Jones6053a522014-07-25 16:22:09 -0700545// Tests for texture sampling completeness
546bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
547{
548 int size = getBaseLevelWidth();
549
550 bool mipmapping = IsMipmapFiltered(samplerState);
551
552 if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
553 {
554 return false;
555 }
556
557 if (!gl::isPow2(size) && !extensions.textureNPOT)
558 {
559 if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
560 {
561 return false;
562 }
563 }
564
565 if (!mipmapping)
566 {
567 if (!isCubeComplete())
568 {
569 return false;
570 }
571 }
572 else
573 {
574 if (!isMipmapComplete()) // Also tests for isCubeComplete()
575 {
576 return false;
577 }
578 }
579
580 return true;
581}
582
Brandon Jonescef06ff2014-08-05 13:27:48 -0700583int TextureCubeMap::targetToLayerIndex(GLenum target)
584{
585 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
586 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
587 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
588 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
589 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
590
591 return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
592}
593
594GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
595{
596 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
597 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
598 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
599 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
600 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
601
602 return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
Geoff Lang8040f572013-07-25 16:49:54 -0400603}
604
Brandon Jones6053a522014-07-25 16:22:09 -0700605bool TextureCubeMap::isMipmapComplete() const
606{
607 if (isImmutable())
608 {
609 return true;
610 }
611
612 if (!isCubeComplete())
613 {
614 return false;
615 }
616
617 int levelCount = mipLevels();
618
619 for (int face = 0; face < 6; face++)
620 {
621 for (int level = 1; level < levelCount; level++)
622 {
623 if (!isFaceLevelComplete(face, level))
624 {
625 return false;
626 }
627 }
628 }
629
630 return true;
631}
632
633bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
634{
635 ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
636
637 if (isImmutable())
638 {
639 return true;
640 }
641
642 int baseSize = getBaseLevelWidth();
643
644 if (baseSize <= 0)
645 {
646 return false;
647 }
648
649 // "isCubeComplete" checks for base level completeness and we must call that
650 // to determine if any face at level 0 is complete. We omit that check here
651 // to avoid re-checking cube-completeness for every face at level 0.
652 if (level == 0)
653 {
654 return true;
655 }
656
657 // Check that non-zero levels are consistent with the base level.
658 const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
659
660 if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
661 {
662 return false;
663 }
664
665 if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
666 {
667 return false;
668 }
669
670 return true;
671}
672
673
674Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
675 : Texture(impl, id, GL_TEXTURE_3D)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000676{
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000677}
678
679Texture3D::~Texture3D()
680{
Brandon Jones78b1acd2014-07-15 15:33:07 -0700681}
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000682
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000683GLsizei Texture3D::getWidth(GLint level) const
684{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700685 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000686}
687
688GLsizei Texture3D::getHeight(GLint level) const
689{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700690 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000691}
692
693GLsizei Texture3D::getDepth(GLint level) const
694{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700695 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000696}
697
698GLenum Texture3D::getInternalFormat(GLint level) const
699{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700700 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000701}
702
703GLenum Texture3D::getActualFormat(GLint level) const
704{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700705 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000706}
707
708bool Texture3D::isCompressed(GLint level) const
709{
Geoff Lang5d601382014-07-22 15:14:06 -0400710 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000711}
712
713bool Texture3D::isDepth(GLint level) const
714{
Geoff Lang5d601382014-07-22 15:14:06 -0400715 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000716}
717
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400718Error Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000719{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400720 return mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000721}
722
Geoff Langb5348332014-09-02 13:16:34 -0400723Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400724 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000725{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400726 return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, unpack, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000727}
728
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400729Error Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000730{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400731 return mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000732}
733
Geoff Langb5348332014-09-02 13:16:34 -0400734Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
735 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400736 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000737{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400738 return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000739}
740
Geoff Lang1f8532b2014-09-05 09:46:13 -0400741Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000742{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400743 Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
744 if (error.isError())
745 {
746 return error;
747 }
748
Jamie Madill6948e302014-10-20 17:04:33 -0400749 mImmutableLevelCount = levels;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000750
Geoff Lang1f8532b2014-09-05 09:46:13 -0400751 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400752}
753
Brandon Jones6053a522014-07-25 16:22:09 -0700754bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
755{
756 GLsizei width = getBaseLevelWidth();
757 GLsizei height = getBaseLevelHeight();
758 GLsizei depth = getBaseLevelDepth();
759
760 if (width <= 0 || height <= 0 || depth <= 0)
761 {
762 return false;
763 }
764
765 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
766 {
767 return false;
768 }
769
770 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
771 {
772 return false;
773 }
774
775 return true;
776}
777
Brandon Jones6053a522014-07-25 16:22:09 -0700778bool Texture3D::isMipmapComplete() const
779{
780 int levelCount = mipLevels();
781
782 for (int level = 0; level < levelCount; level++)
783 {
784 if (!isLevelComplete(level))
785 {
786 return false;
787 }
788 }
789
790 return true;
791}
792
793bool Texture3D::isLevelComplete(int level) const
794{
795 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
796
797 if (isImmutable())
798 {
799 return true;
800 }
801
802 GLsizei width = getBaseLevelWidth();
803 GLsizei height = getBaseLevelHeight();
804 GLsizei depth = getBaseLevelDepth();
805
806 if (width <= 0 || height <= 0 || depth <= 0)
807 {
808 return false;
809 }
810
811 if (level == 0)
812 {
813 return true;
814 }
815
816 rx::Image *levelImage = mTexture->getImage(level, 0);
817
818 if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
819 {
820 return false;
821 }
822
823 if (levelImage->getWidth() != std::max(1, width >> level))
824 {
825 return false;
826 }
827
828 if (levelImage->getHeight() != std::max(1, height >> level))
829 {
830 return false;
831 }
832
833 if (levelImage->getDepth() != std::max(1, depth >> level))
834 {
835 return false;
836 }
837
838 return true;
839}
840
841Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
842 : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000843{
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000844}
845
846Texture2DArray::~Texture2DArray()
847{
Jamie Madill884a4622013-10-24 17:49:41 -0400848}
849
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000850GLsizei Texture2DArray::getWidth(GLint level) const
851{
Brandon Jones142ec422014-07-16 10:31:30 -0700852 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000853}
854
855GLsizei Texture2DArray::getHeight(GLint level) const
856{
Brandon Jones142ec422014-07-16 10:31:30 -0700857 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getHeight() : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000858}
859
Jamie Madillb8f8b892014-01-07 10:12:50 -0500860GLsizei Texture2DArray::getLayers(GLint level) const
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000861{
Brandon Jones142ec422014-07-16 10:31:30 -0700862 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getLayerCount(level) : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000863}
864
865GLenum Texture2DArray::getInternalFormat(GLint level) const
866{
Brandon Jones142ec422014-07-16 10:31:30 -0700867 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000868}
869
870GLenum Texture2DArray::getActualFormat(GLint level) const
871{
Brandon Jones142ec422014-07-16 10:31:30 -0700872 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000873}
874
875bool Texture2DArray::isCompressed(GLint level) const
876{
Geoff Lang5d601382014-07-22 15:14:06 -0400877 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000878}
879
880bool Texture2DArray::isDepth(GLint level) const
881{
Geoff Lang5d601382014-07-22 15:14:06 -0400882 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000883}
884
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400885Error Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000886{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400887 return mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000888}
889
Geoff Langb5348332014-09-02 13:16:34 -0400890Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400891 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000892{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400893 return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, unpack, pixels);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000894}
895
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400896Error Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000897{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400898 return mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000899}
900
Geoff Langb5348332014-09-02 13:16:34 -0400901Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
902 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400903 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000904{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400905 return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000906}
907
Geoff Lang1f8532b2014-09-05 09:46:13 -0400908Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000909{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400910 Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
911 if (error.isError())
912 {
913 return error;
914 }
915
Jamie Madill6948e302014-10-20 17:04:33 -0400916 mImmutableLevelCount = levels;
Brandon Jones142ec422014-07-16 10:31:30 -0700917
Geoff Lang1f8532b2014-09-05 09:46:13 -0400918 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400919}
920
Brandon Jones6053a522014-07-25 16:22:09 -0700921bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
922{
923 GLsizei width = getBaseLevelWidth();
924 GLsizei height = getBaseLevelHeight();
925 GLsizei depth = getLayers(0);
926
927 if (width <= 0 || height <= 0 || depth <= 0)
928 {
929 return false;
930 }
931
932 if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
933 {
934 return false;
935 }
936
937 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
938 {
939 return false;
940 }
941
942 return true;
943}
944
Brandon Jones6053a522014-07-25 16:22:09 -0700945bool Texture2DArray::isMipmapComplete() const
946{
947 int levelCount = mipLevels();
948
949 for (int level = 1; level < levelCount; level++)
950 {
951 if (!isLevelComplete(level))
952 {
953 return false;
954 }
955 }
956
957 return true;
958}
959
960bool Texture2DArray::isLevelComplete(int level) const
961{
962 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
963
964 if (isImmutable())
965 {
966 return true;
967 }
968
969 GLsizei width = getBaseLevelWidth();
970 GLsizei height = getBaseLevelHeight();
971 GLsizei layers = getLayers(0);
972
973 if (width <= 0 || height <= 0 || layers <= 0)
974 {
975 return false;
976 }
977
978 if (level == 0)
979 {
980 return true;
981 }
982
983 if (getInternalFormat(level) != getInternalFormat(0))
984 {
985 return false;
986 }
987
988 if (getWidth(level) != std::max(1, width >> level))
989 {
990 return false;
991 }
992
993 if (getHeight(level) != std::max(1, height >> level))
994 {
995 return false;
996 }
997
998 if (getLayers(level) != layers)
999 {
1000 return false;
1001 }
1002
1003 return true;
1004}
1005
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00001006}