blob: 4df95b19230a359ec4f545b6b31e528849655d4a [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 {
184 mSurface->setBoundTexture(NULL);
185 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();
231
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700232 mTexture->bindTexImage(surface);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000233
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000234 mSurface = surface;
235 mSurface->setBoundTexture(this);
236}
237
238void Texture2D::releaseTexImage()
239{
240 if (mSurface)
241 {
242 mSurface->setBoundTexture(NULL);
243 mSurface = NULL;
244
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700245 mTexture->releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000246 }
247}
248
Geoff Langb5348332014-09-02 13:16:34 -0400249Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400250 const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000251{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700252 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000253
Jamie Madillc751d1e2014-10-21 17:46:29 -0400254 return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000255}
256
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400257Error 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 +0000258{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400259 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 +0000260}
261
Geoff Langb5348332014-09-02 13:16:34 -0400262Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400263 GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000264{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400265 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 +0000266}
267
Geoff Langef7b0162014-09-04 13:29:23 -0400268Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
269 Framebuffer *source)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000270{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700271 releaseTexImage();
Geoff Lang5d601382014-07-22 15:14:06 -0400272
Geoff Langef7b0162014-09-04 13:29:23 -0400273 return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000274}
275
Geoff Lang1f8532b2014-09-05 09:46:13 -0400276Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000277{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400278 Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
279 if (error.isError())
280 {
281 return error;
282 }
283
Jamie Madill6948e302014-10-20 17:04:33 -0400284 mImmutableLevelCount = levels;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000285
Geoff Lang1f8532b2014-09-05 09:46:13 -0400286 return Error(GL_NO_ERROR);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000287}
288
Brandon Jones6053a522014-07-25 16:22:09 -0700289// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
290bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
291{
292 GLsizei width = getBaseLevelWidth();
293 GLsizei height = getBaseLevelHeight();
294
295 if (width <= 0 || height <= 0)
296 {
297 return false;
298 }
299
300 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
301 {
302 return false;
303 }
304
305 bool npotSupport = extensions.textureNPOT;
306
307 if (!npotSupport)
308 {
309 if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
310 (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
311 {
312 return false;
313 }
314 }
315
316 if (IsMipmapFiltered(samplerState))
317 {
318 if (!npotSupport)
319 {
320 if (!gl::isPow2(width) || !gl::isPow2(height))
321 {
322 return false;
323 }
324 }
325
326 if (!isMipmapComplete())
327 {
328 return false;
329 }
330 }
331
332 // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
333 // The internalformat specified for the texture arrays is a sized internal depth or
334 // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
335 // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
336 // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
337 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
338 if (formatInfo.depthBits > 0 && clientVersion > 2)
339 {
340 if (samplerState.compareMode == GL_NONE)
341 {
342 if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
343 samplerState.magFilter != GL_NEAREST)
344 {
345 return false;
346 }
347 }
348 }
349
350 return true;
351}
352
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000353bool Texture2D::isCompressed(GLint level) const
354{
Geoff Lang5d601382014-07-22 15:14:06 -0400355 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000356}
357
358bool Texture2D::isDepth(GLint level) const
359{
Geoff Lang5d601382014-07-22 15:14:06 -0400360 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000361}
362
Geoff Lang06ecf3d2014-09-23 16:39:50 -0400363Error Texture2D::generateMipmaps()
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000364{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700365 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000366
Geoff Lang06ecf3d2014-09-23 16:39:50 -0400367 return mTexture->generateMipmaps();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000368}
369
Brandon Jones6053a522014-07-25 16:22:09 -0700370// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
371bool Texture2D::isMipmapComplete() const
372{
373 int levelCount = mipLevels();
374
375 for (int level = 0; level < levelCount; level++)
376 {
377 if (!isLevelComplete(level))
378 {
379 return false;
380 }
381 }
382
383 return true;
384}
385
386bool Texture2D::isLevelComplete(int level) const
387{
388 if (isImmutable())
389 {
390 return true;
391 }
392
393 const rx::Image *baseImage = getBaseLevelImage();
394
395 GLsizei width = baseImage->getWidth();
396 GLsizei height = baseImage->getHeight();
397
398 if (width <= 0 || height <= 0)
399 {
400 return false;
401 }
402
403 // The base image level is complete if the width and height are positive
404 if (level == 0)
405 {
406 return true;
407 }
408
409 ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
410 rx::Image *image = mTexture->getImage(level, 0);
411
412 if (image->getInternalFormat() != baseImage->getInternalFormat())
413 {
414 return false;
415 }
416
417 if (image->getWidth() != std::max(1, width >> level))
418 {
419 return false;
420 }
421
422 if (image->getHeight() != std::max(1, height >> level))
423 {
424 return false;
425 }
426
427 return true;
428}
429
430TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
431 : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000432{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000433}
434
435TextureCubeMap::~TextureCubeMap()
436{
Brandon Jones0511e802014-07-14 16:27:26 -0700437}
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000438
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000439GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
440{
441 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700442 return mTexture->getImage(level, targetToLayerIndex(target))->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000443 else
444 return 0;
445}
446
447GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
448{
449 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700450 return mTexture->getImage(level, targetToLayerIndex(target))->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000451 else
452 return 0;
453}
454
455GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
456{
457 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700458 return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000459 else
460 return GL_NONE;
461}
462
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000463GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000464{
465 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700466 return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000467 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500468 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000469}
470
Geoff Lang8376cea2014-09-02 11:47:07 -0400471Error 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 +0000472{
Geoff Lang8376cea2014-09-02 11:47:07 -0400473 return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000474}
475
Geoff Langb5348332014-09-02 13:16:34 -0400476Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400477 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000478{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400479 return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000480}
481
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400482Error 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 +0000483{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400484 return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000485}
486
Geoff Langb5348332014-09-02 13:16:34 -0400487Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset,
488 GLsizei width, GLsizei height, GLenum format,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400489 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000490{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400491 return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000492}
493
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000494// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
495bool TextureCubeMap::isCubeComplete() const
496{
Brandon Jones6053a522014-07-25 16:22:09 -0700497 int baseWidth = getBaseLevelWidth();
498 int baseHeight = getBaseLevelHeight();
499 GLenum baseFormat = getBaseLevelInternalFormat();
500
501 if (baseWidth <= 0 || baseWidth != baseHeight)
502 {
503 return false;
504 }
505
506 for (int faceIndex = 1; faceIndex < 6; faceIndex++)
507 {
508 const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
509
510 if (faceBaseImage->getWidth() != baseWidth ||
511 faceBaseImage->getHeight() != baseHeight ||
512 faceBaseImage->getInternalFormat() != baseFormat )
513 {
514 return false;
515 }
516 }
517
518 return true;
Jamie Madill07edd442013-07-19 16:36:58 -0400519}
520
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000521bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
522{
Geoff Lang5d601382014-07-22 15:14:06 -0400523 return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000524}
525
Geoff Lang8040f572013-07-25 16:49:54 -0400526bool TextureCubeMap::isDepth(GLenum target, GLint level) const
527{
Geoff Lang5d601382014-07-22 15:14:06 -0400528 return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
Geoff Lang8040f572013-07-25 16:49:54 -0400529}
530
Geoff Langef7b0162014-09-04 13:29:23 -0400531Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
532 GLsizei width, GLsizei height, Framebuffer *source)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000533{
Geoff Langef7b0162014-09-04 13:29:23 -0400534 return mTexture->copyImage(target, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000535}
536
Geoff Lang1f8532b2014-09-05 09:46:13 -0400537Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000538{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400539 Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
540 if (error.isError())
541 {
542 return error;
543 }
544
Jamie Madill6948e302014-10-20 17:04:33 -0400545 mImmutableLevelCount = levels;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000546
Geoff Lang1f8532b2014-09-05 09:46:13 -0400547 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400548}
549
Brandon Jones6053a522014-07-25 16:22:09 -0700550// Tests for texture sampling completeness
551bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
552{
553 int size = getBaseLevelWidth();
554
555 bool mipmapping = IsMipmapFiltered(samplerState);
556
557 if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
558 {
559 return false;
560 }
561
562 if (!gl::isPow2(size) && !extensions.textureNPOT)
563 {
564 if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
565 {
566 return false;
567 }
568 }
569
570 if (!mipmapping)
571 {
572 if (!isCubeComplete())
573 {
574 return false;
575 }
576 }
577 else
578 {
579 if (!isMipmapComplete()) // Also tests for isCubeComplete()
580 {
581 return false;
582 }
583 }
584
585 return true;
586}
587
Brandon Jonescef06ff2014-08-05 13:27:48 -0700588int TextureCubeMap::targetToLayerIndex(GLenum target)
589{
590 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
591 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
592 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
593 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
594 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
595
596 return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
597}
598
599GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
600{
601 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
602 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
603 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
604 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
605 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
606
607 return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
Geoff Lang8040f572013-07-25 16:49:54 -0400608}
609
Brandon Jones6053a522014-07-25 16:22:09 -0700610bool TextureCubeMap::isMipmapComplete() const
611{
612 if (isImmutable())
613 {
614 return true;
615 }
616
617 if (!isCubeComplete())
618 {
619 return false;
620 }
621
622 int levelCount = mipLevels();
623
624 for (int face = 0; face < 6; face++)
625 {
626 for (int level = 1; level < levelCount; level++)
627 {
628 if (!isFaceLevelComplete(face, level))
629 {
630 return false;
631 }
632 }
633 }
634
635 return true;
636}
637
638bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
639{
640 ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
641
642 if (isImmutable())
643 {
644 return true;
645 }
646
647 int baseSize = getBaseLevelWidth();
648
649 if (baseSize <= 0)
650 {
651 return false;
652 }
653
654 // "isCubeComplete" checks for base level completeness and we must call that
655 // to determine if any face at level 0 is complete. We omit that check here
656 // to avoid re-checking cube-completeness for every face at level 0.
657 if (level == 0)
658 {
659 return true;
660 }
661
662 // Check that non-zero levels are consistent with the base level.
663 const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
664
665 if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
666 {
667 return false;
668 }
669
670 if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
671 {
672 return false;
673 }
674
675 return true;
676}
677
678
679Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
680 : Texture(impl, id, GL_TEXTURE_3D)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000681{
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000682}
683
684Texture3D::~Texture3D()
685{
Brandon Jones78b1acd2014-07-15 15:33:07 -0700686}
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000687
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000688GLsizei Texture3D::getWidth(GLint level) const
689{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700690 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000691}
692
693GLsizei Texture3D::getHeight(GLint level) const
694{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700695 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000696}
697
698GLsizei Texture3D::getDepth(GLint level) const
699{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700700 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000701}
702
703GLenum Texture3D::getInternalFormat(GLint level) const
704{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700705 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000706}
707
708GLenum Texture3D::getActualFormat(GLint level) const
709{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700710 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000711}
712
713bool Texture3D::isCompressed(GLint level) const
714{
Geoff Lang5d601382014-07-22 15:14:06 -0400715 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000716}
717
718bool Texture3D::isDepth(GLint level) const
719{
Geoff Lang5d601382014-07-22 15:14:06 -0400720 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000721}
722
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400723Error 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 +0000724{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400725 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 +0000726}
727
Geoff Langb5348332014-09-02 13:16:34 -0400728Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400729 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000730{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400731 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 +0000732}
733
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400734Error 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 +0000735{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400736 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 +0000737}
738
Geoff Langb5348332014-09-02 13:16:34 -0400739Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
740 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400741 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000742{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400743 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 +0000744}
745
Geoff Lang1f8532b2014-09-05 09:46:13 -0400746Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000747{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400748 Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
749 if (error.isError())
750 {
751 return error;
752 }
753
Jamie Madill6948e302014-10-20 17:04:33 -0400754 mImmutableLevelCount = levels;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000755
Geoff Lang1f8532b2014-09-05 09:46:13 -0400756 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400757}
758
Brandon Jones6053a522014-07-25 16:22:09 -0700759bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
760{
761 GLsizei width = getBaseLevelWidth();
762 GLsizei height = getBaseLevelHeight();
763 GLsizei depth = getBaseLevelDepth();
764
765 if (width <= 0 || height <= 0 || depth <= 0)
766 {
767 return false;
768 }
769
770 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
771 {
772 return false;
773 }
774
775 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
776 {
777 return false;
778 }
779
780 return true;
781}
782
Brandon Jones6053a522014-07-25 16:22:09 -0700783bool Texture3D::isMipmapComplete() const
784{
785 int levelCount = mipLevels();
786
787 for (int level = 0; level < levelCount; level++)
788 {
789 if (!isLevelComplete(level))
790 {
791 return false;
792 }
793 }
794
795 return true;
796}
797
798bool Texture3D::isLevelComplete(int level) const
799{
800 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
801
802 if (isImmutable())
803 {
804 return true;
805 }
806
807 GLsizei width = getBaseLevelWidth();
808 GLsizei height = getBaseLevelHeight();
809 GLsizei depth = getBaseLevelDepth();
810
811 if (width <= 0 || height <= 0 || depth <= 0)
812 {
813 return false;
814 }
815
816 if (level == 0)
817 {
818 return true;
819 }
820
821 rx::Image *levelImage = mTexture->getImage(level, 0);
822
823 if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
824 {
825 return false;
826 }
827
828 if (levelImage->getWidth() != std::max(1, width >> level))
829 {
830 return false;
831 }
832
833 if (levelImage->getHeight() != std::max(1, height >> level))
834 {
835 return false;
836 }
837
838 if (levelImage->getDepth() != std::max(1, depth >> level))
839 {
840 return false;
841 }
842
843 return true;
844}
845
846Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
847 : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000848{
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000849}
850
851Texture2DArray::~Texture2DArray()
852{
Jamie Madill884a4622013-10-24 17:49:41 -0400853}
854
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000855GLsizei Texture2DArray::getWidth(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)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000858}
859
860GLsizei Texture2DArray::getHeight(GLint level) const
861{
Brandon Jones142ec422014-07-16 10:31:30 -0700862 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 +0000863}
864
Jamie Madillb8f8b892014-01-07 10:12:50 -0500865GLsizei Texture2DArray::getLayers(GLint level) const
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000866{
Brandon Jones142ec422014-07-16 10:31:30 -0700867 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getLayerCount(level) : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000868}
869
870GLenum Texture2DArray::getInternalFormat(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)->getInternalFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000873}
874
875GLenum Texture2DArray::getActualFormat(GLint level) const
876{
Brandon Jones142ec422014-07-16 10:31:30 -0700877 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 +0000878}
879
880bool Texture2DArray::isCompressed(GLint level) const
881{
Geoff Lang5d601382014-07-22 15:14:06 -0400882 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000883}
884
885bool Texture2DArray::isDepth(GLint level) const
886{
Geoff Lang5d601382014-07-22 15:14:06 -0400887 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000888}
889
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400890Error 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 +0000891{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400892 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 +0000893}
894
Geoff Langb5348332014-09-02 13:16:34 -0400895Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400896 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000897{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400898 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 +0000899}
900
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400901Error 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 +0000902{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400903 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 +0000904}
905
Geoff Langb5348332014-09-02 13:16:34 -0400906Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
907 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
Jamie Madillc751d1e2014-10-21 17:46:29 -0400908 GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000909{
Jamie Madillc751d1e2014-10-21 17:46:29 -0400910 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 +0000911}
912
Geoff Lang1f8532b2014-09-05 09:46:13 -0400913Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000914{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400915 Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
916 if (error.isError())
917 {
918 return error;
919 }
920
Jamie Madill6948e302014-10-20 17:04:33 -0400921 mImmutableLevelCount = levels;
Brandon Jones142ec422014-07-16 10:31:30 -0700922
Geoff Lang1f8532b2014-09-05 09:46:13 -0400923 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400924}
925
Brandon Jones6053a522014-07-25 16:22:09 -0700926bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
927{
928 GLsizei width = getBaseLevelWidth();
929 GLsizei height = getBaseLevelHeight();
930 GLsizei depth = getLayers(0);
931
932 if (width <= 0 || height <= 0 || depth <= 0)
933 {
934 return false;
935 }
936
937 if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
938 {
939 return false;
940 }
941
942 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
943 {
944 return false;
945 }
946
947 return true;
948}
949
Brandon Jones6053a522014-07-25 16:22:09 -0700950bool Texture2DArray::isMipmapComplete() const
951{
952 int levelCount = mipLevels();
953
954 for (int level = 1; level < levelCount; level++)
955 {
956 if (!isLevelComplete(level))
957 {
958 return false;
959 }
960 }
961
962 return true;
963}
964
965bool Texture2DArray::isLevelComplete(int level) const
966{
967 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
968
969 if (isImmutable())
970 {
971 return true;
972 }
973
974 GLsizei width = getBaseLevelWidth();
975 GLsizei height = getBaseLevelHeight();
976 GLsizei layers = getLayers(0);
977
978 if (width <= 0 || height <= 0 || layers <= 0)
979 {
980 return false;
981 }
982
983 if (level == 0)
984 {
985 return true;
986 }
987
988 if (getInternalFormat(level) != getInternalFormat(0))
989 {
990 return false;
991 }
992
993 if (getWidth(level) != std::max(1, width >> level))
994 {
995 return false;
996 }
997
998 if (getHeight(level) != std::max(1, height >> level))
999 {
1000 return false;
1001 }
1002
1003 if (getLayers(level) != layers)
1004 {
1005 return false;
1006 }
1007
1008 return true;
1009}
1010
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00001011}