blob: 4786802a4232b5351a0ab485f9517a598a8788c6 [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
11#include "libGLESv2/Texture.h"
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000012#include "libGLESv2/main.h"
Brandon Jones6053a522014-07-25 16:22:09 -070013#include "libGLESv2/Context.h"
shannonwoods@chromium.org4ad58e02013-05-30 00:08:11 +000014#include "libGLESv2/formatutils.h"
Jamie Madillfeda4d22014-09-17 13:03:29 -040015#include "libGLESv2/ImageIndex.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000016#include "libGLESv2/Renderbuffer.h"
17#include "libGLESv2/renderer/Image.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "libGLESv2/renderer/d3d/TextureStorage.h"
19
20#include "libEGL/Surface.h"
21
22#include "common/mathutil.h"
23#include "common/utilities.h"
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000024
25namespace gl
26{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000027
Brandon Jones6053a522014-07-25 16:22:09 -070028bool IsMipmapFiltered(const gl::SamplerState &samplerState)
29{
30 switch (samplerState.minFilter)
31 {
32 case GL_NEAREST:
33 case GL_LINEAR:
34 return false;
35 case GL_NEAREST_MIPMAP_NEAREST:
36 case GL_LINEAR_MIPMAP_NEAREST:
37 case GL_NEAREST_MIPMAP_LINEAR:
38 case GL_LINEAR_MIPMAP_LINEAR:
39 return true;
40 default: UNREACHABLE();
41 return false;
42 }
43}
44
45bool IsPointSampled(const gl::SamplerState &samplerState)
46{
47 return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
48}
49
Jamie Madill10ef2152014-10-20 17:04:34 -040050unsigned int Texture::mCurrentTextureSerial = 1;
51
Brandon Jones6053a522014-07-25 16:22:09 -070052Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
Brandon Jonesf47bebc2014-07-09 14:28:42 -070053 : RefCountObject(id),
Brandon Jones6053a522014-07-25 16:22:09 -070054 mTexture(impl),
Jamie Madill10ef2152014-10-20 17:04:34 -040055 mTextureSerial(issueTextureSerial()),
Brandon Jonesf47bebc2014-07-09 14:28:42 -070056 mUsage(GL_NONE),
Jamie Madill6948e302014-10-20 17:04:33 -040057 mImmutableLevelCount(0),
Brandon Jonesf47bebc2014-07-09 14:28:42 -070058 mTarget(target)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000059{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000060}
61
62Texture::~Texture()
63{
Brandon Jones6053a522014-07-25 16:22:09 -070064 SafeDelete(mTexture);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000065}
66
Geoff Lang4907f2c2013-07-25 12:53:57 -040067GLenum Texture::getTarget() const
68{
69 return mTarget;
70}
71
Geoff Lang63b5f1f2013-09-23 14:52:14 -040072void Texture::setUsage(GLenum usage)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000073{
Geoff Lang63b5f1f2013-09-23 14:52:14 -040074 mUsage = usage;
Brandon Jonescef06ff2014-08-05 13:27:48 -070075 getImplementation()->setUsage(usage);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000076}
77
Brandon Jonesa328d562014-07-01 13:52:40 -070078void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
daniel@transgaming.comebf139f2012-10-31 18:07:32 +000079{
80 *sampler = mSamplerState;
Nicolas Capens8de68282014-04-04 11:10:27 -040081
82 // Offset the effective base level by the texture storage's top level
Jamie Madill2f06dbf2014-09-18 15:08:50 -040083 rx::TextureStorage *texture = getNativeTexture();
Nicolas Capens8de68282014-04-04 11:10:27 -040084 int topLevel = texture ? texture->getTopLevel() : 0;
85 sampler->baseLevel = topLevel + mSamplerState.baseLevel;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +000086}
87
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000088GLenum Texture::getUsage() const
89{
90 return mUsage;
91}
92
Jamie Madilld3d2a342013-10-07 10:46:35 -040093GLint Texture::getBaseLevelWidth() const
94{
95 const rx::Image *baseImage = getBaseLevelImage();
96 return (baseImage ? baseImage->getWidth() : 0);
97}
98
99GLint Texture::getBaseLevelHeight() const
100{
101 const rx::Image *baseImage = getBaseLevelImage();
102 return (baseImage ? baseImage->getHeight() : 0);
103}
104
105GLint Texture::getBaseLevelDepth() const
106{
107 const rx::Image *baseImage = getBaseLevelImage();
108 return (baseImage ? baseImage->getDepth() : 0);
109}
110
Jamie Madillb8f8b892014-01-07 10:12:50 -0500111// Note: "base level image" is loosely defined to be any image from the base level,
112// where in the base of 2D array textures and cube maps there are several. Don't use
113// the base level image for anything except querying texture format and size.
Jamie Madilld3d2a342013-10-07 10:46:35 -0400114GLenum Texture::getBaseLevelInternalFormat() const
115{
116 const rx::Image *baseImage = getBaseLevelImage();
117 return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
118}
119
Jamie Madill945f7322014-09-03 15:07:14 -0400120GLsizei Texture::getWidth(const ImageIndex &index) const
121{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400122 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400123 return image->getWidth();
124}
125
126GLsizei Texture::getHeight(const ImageIndex &index) const
127{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400128 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400129 return image->getHeight();
130}
131
132GLenum Texture::getInternalFormat(const ImageIndex &index) const
133{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400134 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400135 return image->getInternalFormat();
136}
137
138GLenum Texture::getActualFormat(const ImageIndex &index) const
139{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400140 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400141 return image->getActualFormat();
142}
143
Jamie Madill2f06dbf2014-09-18 15:08:50 -0400144rx::TextureStorage *Texture::getNativeTexture()
Brandon Jones6b19b002014-07-16 14:32:05 -0700145{
146 return getImplementation()->getNativeTexture();
147}
148
Brandon Jonescef06ff2014-08-05 13:27:48 -0700149void Texture::generateMipmaps()
150{
151 getImplementation()->generateMipmaps();
152}
153
Geoff Langef7b0162014-09-04 13:29:23 -0400154Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
155 GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
Brandon Jones6b19b002014-07-16 14:32:05 -0700156{
Geoff Langef7b0162014-09-04 13:29:23 -0400157 return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
Brandon Jones6b19b002014-07-16 14:32:05 -0700158}
159
Jamie Madill10ef2152014-10-20 17:04:34 -0400160unsigned int Texture::getTextureSerial() const
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700161{
Jamie Madill10ef2152014-10-20 17:04:34 -0400162 return mTextureSerial;
163}
164
165unsigned int Texture::issueTextureSerial()
166{
167 return mCurrentTextureSerial++;
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700168}
169
170bool Texture::isImmutable() const
171{
Jamie Madill6948e302014-10-20 17:04:33 -0400172 return (mImmutableLevelCount > 0);
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700173}
174
175int Texture::immutableLevelCount()
176{
Jamie Madill6948e302014-10-20 17:04:33 -0400177 return mImmutableLevelCount;
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700178}
179
180int Texture::mipLevels() const
181{
182 return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
183}
184
Brandon Jonescef06ff2014-08-05 13:27:48 -0700185const rx::Image *Texture::getBaseLevelImage() const
186{
187 return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
188}
189
Brandon Jones6053a522014-07-25 16:22:09 -0700190Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
191 : Texture(impl, id, GL_TEXTURE_2D)
Jamie Madill22f843a2013-10-24 17:49:36 -0400192{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000193 mSurface = NULL;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000194}
195
196Texture2D::~Texture2D()
197{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000198 if (mSurface)
199 {
200 mSurface->setBoundTexture(NULL);
201 mSurface = NULL;
202 }
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700203}
daniel@transgaming.comd9ec9022012-12-20 20:52:16 +0000204
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000205GLsizei Texture2D::getWidth(GLint level) const
206{
207 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700208 return mTexture->getImage(level, 0)->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000209 else
210 return 0;
211}
212
213GLsizei Texture2D::getHeight(GLint level) const
214{
215 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700216 return mTexture->getImage(level, 0)->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000217 else
218 return 0;
219}
220
221GLenum Texture2D::getInternalFormat(GLint level) const
222{
223 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700224 return mTexture->getImage(level, 0)->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000225 else
226 return GL_NONE;
227}
228
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000229GLenum Texture2D::getActualFormat(GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000230{
231 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700232 return mTexture->getImage(level, 0)->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000233 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500234 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000235}
236
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400237Error 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 +0000238{
239 releaseTexImage();
shannon.woods@transgaming.com8a406682013-02-28 23:15:26 +0000240
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400241 return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000242}
243
244void Texture2D::bindTexImage(egl::Surface *surface)
245{
246 releaseTexImage();
247
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700248 mTexture->bindTexImage(surface);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000249
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000250 mSurface = surface;
251 mSurface->setBoundTexture(this);
252}
253
254void Texture2D::releaseTexImage()
255{
256 if (mSurface)
257 {
258 mSurface->setBoundTexture(NULL);
259 mSurface = NULL;
260
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700261 mTexture->releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000262 }
263}
264
Geoff Langb5348332014-09-02 13:16:34 -0400265Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
266 const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000267{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700268 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000269
Geoff Langb5348332014-09-02 13:16:34 -0400270 return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000271}
272
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400273Error 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 +0000274{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400275 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 +0000276}
277
Geoff Langb5348332014-09-02 13:16:34 -0400278Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
279 GLenum format, GLsizei imageSize, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000280{
Geoff Langb5348332014-09-02 13:16:34 -0400281 return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000282}
283
Geoff Langef7b0162014-09-04 13:29:23 -0400284Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
285 Framebuffer *source)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000286{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700287 releaseTexImage();
Geoff Lang5d601382014-07-22 15:14:06 -0400288
Geoff Langef7b0162014-09-04 13:29:23 -0400289 return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000290}
291
Geoff Lang1f8532b2014-09-05 09:46:13 -0400292Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000293{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400294 Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
295 if (error.isError())
296 {
297 return error;
298 }
299
Jamie Madill6948e302014-10-20 17:04:33 -0400300 mImmutableLevelCount = levels;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000301
Geoff Lang1f8532b2014-09-05 09:46:13 -0400302 return Error(GL_NO_ERROR);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000303}
304
Brandon Jones6053a522014-07-25 16:22:09 -0700305// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
306bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
307{
308 GLsizei width = getBaseLevelWidth();
309 GLsizei height = getBaseLevelHeight();
310
311 if (width <= 0 || height <= 0)
312 {
313 return false;
314 }
315
316 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
317 {
318 return false;
319 }
320
321 bool npotSupport = extensions.textureNPOT;
322
323 if (!npotSupport)
324 {
325 if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
326 (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
327 {
328 return false;
329 }
330 }
331
332 if (IsMipmapFiltered(samplerState))
333 {
334 if (!npotSupport)
335 {
336 if (!gl::isPow2(width) || !gl::isPow2(height))
337 {
338 return false;
339 }
340 }
341
342 if (!isMipmapComplete())
343 {
344 return false;
345 }
346 }
347
348 // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
349 // The internalformat specified for the texture arrays is a sized internal depth or
350 // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
351 // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
352 // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
353 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
354 if (formatInfo.depthBits > 0 && clientVersion > 2)
355 {
356 if (samplerState.compareMode == GL_NONE)
357 {
358 if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
359 samplerState.magFilter != GL_NEAREST)
360 {
361 return false;
362 }
363 }
364 }
365
366 return true;
367}
368
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000369bool Texture2D::isCompressed(GLint level) const
370{
Geoff Lang5d601382014-07-22 15:14:06 -0400371 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000372}
373
374bool Texture2D::isDepth(GLint level) const
375{
Geoff Lang5d601382014-07-22 15:14:06 -0400376 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000377}
378
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000379void Texture2D::generateMipmaps()
380{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700381 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000382
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700383 mTexture->generateMipmaps();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000384}
385
Brandon Jones6053a522014-07-25 16:22:09 -0700386// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
387bool Texture2D::isMipmapComplete() const
388{
389 int levelCount = mipLevels();
390
391 for (int level = 0; level < levelCount; level++)
392 {
393 if (!isLevelComplete(level))
394 {
395 return false;
396 }
397 }
398
399 return true;
400}
401
402bool Texture2D::isLevelComplete(int level) const
403{
404 if (isImmutable())
405 {
406 return true;
407 }
408
409 const rx::Image *baseImage = getBaseLevelImage();
410
411 GLsizei width = baseImage->getWidth();
412 GLsizei height = baseImage->getHeight();
413
414 if (width <= 0 || height <= 0)
415 {
416 return false;
417 }
418
419 // The base image level is complete if the width and height are positive
420 if (level == 0)
421 {
422 return true;
423 }
424
425 ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
426 rx::Image *image = mTexture->getImage(level, 0);
427
428 if (image->getInternalFormat() != baseImage->getInternalFormat())
429 {
430 return false;
431 }
432
433 if (image->getWidth() != std::max(1, width >> level))
434 {
435 return false;
436 }
437
438 if (image->getHeight() != std::max(1, height >> level))
439 {
440 return false;
441 }
442
443 return true;
444}
445
446TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
447 : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000448{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000449}
450
451TextureCubeMap::~TextureCubeMap()
452{
Brandon Jones0511e802014-07-14 16:27:26 -0700453}
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000454
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000455GLsizei TextureCubeMap::getWidth(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))->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000459 else
460 return 0;
461}
462
463GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
464{
465 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700466 return mTexture->getImage(level, targetToLayerIndex(target))->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000467 else
468 return 0;
469}
470
471GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
472{
473 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700474 return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000475 else
476 return GL_NONE;
477}
478
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000479GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000480{
481 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700482 return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000483 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500484 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000485}
486
Geoff Lang8376cea2014-09-02 11:47:07 -0400487Error 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 +0000488{
Geoff Lang8376cea2014-09-02 11:47:07 -0400489 return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000490}
491
Geoff Langb5348332014-09-02 13:16:34 -0400492Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
493 GLsizei imageSize, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000494{
Geoff Langb5348332014-09-02 13:16:34 -0400495 return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000496}
497
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400498Error 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 +0000499{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400500 return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000501}
502
Geoff Langb5348332014-09-02 13:16:34 -0400503Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset,
504 GLsizei width, GLsizei height, GLenum format,
505 GLsizei imageSize, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000506{
Geoff Langb5348332014-09-02 13:16:34 -0400507 return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000508}
509
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000510// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
511bool TextureCubeMap::isCubeComplete() const
512{
Brandon Jones6053a522014-07-25 16:22:09 -0700513 int baseWidth = getBaseLevelWidth();
514 int baseHeight = getBaseLevelHeight();
515 GLenum baseFormat = getBaseLevelInternalFormat();
516
517 if (baseWidth <= 0 || baseWidth != baseHeight)
518 {
519 return false;
520 }
521
522 for (int faceIndex = 1; faceIndex < 6; faceIndex++)
523 {
524 const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
525
526 if (faceBaseImage->getWidth() != baseWidth ||
527 faceBaseImage->getHeight() != baseHeight ||
528 faceBaseImage->getInternalFormat() != baseFormat )
529 {
530 return false;
531 }
532 }
533
534 return true;
Jamie Madill07edd442013-07-19 16:36:58 -0400535}
536
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000537bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
538{
Geoff Lang5d601382014-07-22 15:14:06 -0400539 return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000540}
541
Geoff Lang8040f572013-07-25 16:49:54 -0400542bool TextureCubeMap::isDepth(GLenum target, GLint level) const
543{
Geoff Lang5d601382014-07-22 15:14:06 -0400544 return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
Geoff Lang8040f572013-07-25 16:49:54 -0400545}
546
Geoff Langef7b0162014-09-04 13:29:23 -0400547Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
548 GLsizei width, GLsizei height, Framebuffer *source)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000549{
Geoff Langef7b0162014-09-04 13:29:23 -0400550 return mTexture->copyImage(target, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000551}
552
Geoff Lang1f8532b2014-09-05 09:46:13 -0400553Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000554{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400555 Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
556 if (error.isError())
557 {
558 return error;
559 }
560
Jamie Madill6948e302014-10-20 17:04:33 -0400561 mImmutableLevelCount = levels;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000562
Geoff Lang1f8532b2014-09-05 09:46:13 -0400563 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400564}
565
Brandon Jones6053a522014-07-25 16:22:09 -0700566// Tests for texture sampling completeness
567bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
568{
569 int size = getBaseLevelWidth();
570
571 bool mipmapping = IsMipmapFiltered(samplerState);
572
573 if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
574 {
575 return false;
576 }
577
578 if (!gl::isPow2(size) && !extensions.textureNPOT)
579 {
580 if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
581 {
582 return false;
583 }
584 }
585
586 if (!mipmapping)
587 {
588 if (!isCubeComplete())
589 {
590 return false;
591 }
592 }
593 else
594 {
595 if (!isMipmapComplete()) // Also tests for isCubeComplete()
596 {
597 return false;
598 }
599 }
600
601 return true;
602}
603
Brandon Jonescef06ff2014-08-05 13:27:48 -0700604int TextureCubeMap::targetToLayerIndex(GLenum target)
605{
606 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
607 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
608 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
609 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
610 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
611
612 return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
613}
614
615GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
616{
617 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
618 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
619 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
620 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
621 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
622
623 return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
Geoff Lang8040f572013-07-25 16:49:54 -0400624}
625
Brandon Jones6053a522014-07-25 16:22:09 -0700626bool TextureCubeMap::isMipmapComplete() const
627{
628 if (isImmutable())
629 {
630 return true;
631 }
632
633 if (!isCubeComplete())
634 {
635 return false;
636 }
637
638 int levelCount = mipLevels();
639
640 for (int face = 0; face < 6; face++)
641 {
642 for (int level = 1; level < levelCount; level++)
643 {
644 if (!isFaceLevelComplete(face, level))
645 {
646 return false;
647 }
648 }
649 }
650
651 return true;
652}
653
654bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
655{
656 ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
657
658 if (isImmutable())
659 {
660 return true;
661 }
662
663 int baseSize = getBaseLevelWidth();
664
665 if (baseSize <= 0)
666 {
667 return false;
668 }
669
670 // "isCubeComplete" checks for base level completeness and we must call that
671 // to determine if any face at level 0 is complete. We omit that check here
672 // to avoid re-checking cube-completeness for every face at level 0.
673 if (level == 0)
674 {
675 return true;
676 }
677
678 // Check that non-zero levels are consistent with the base level.
679 const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
680
681 if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
682 {
683 return false;
684 }
685
686 if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
687 {
688 return false;
689 }
690
691 return true;
692}
693
694
695Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
696 : Texture(impl, id, GL_TEXTURE_3D)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000697{
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000698}
699
700Texture3D::~Texture3D()
701{
Brandon Jones78b1acd2014-07-15 15:33:07 -0700702}
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000703
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000704GLsizei Texture3D::getWidth(GLint level) const
705{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700706 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000707}
708
709GLsizei Texture3D::getHeight(GLint level) const
710{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700711 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000712}
713
714GLsizei Texture3D::getDepth(GLint level) const
715{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700716 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000717}
718
719GLenum Texture3D::getInternalFormat(GLint level) const
720{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700721 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000722}
723
724GLenum Texture3D::getActualFormat(GLint level) const
725{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700726 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000727}
728
729bool Texture3D::isCompressed(GLint level) const
730{
Geoff Lang5d601382014-07-22 15:14:06 -0400731 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000732}
733
734bool Texture3D::isDepth(GLint level) const
735{
Geoff Lang5d601382014-07-22 15:14:06 -0400736 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000737}
738
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400739Error 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 +0000740{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400741 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 +0000742}
743
Geoff Langb5348332014-09-02 13:16:34 -0400744Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
745 GLsizei imageSize, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000746{
Geoff Langb5348332014-09-02 13:16:34 -0400747 return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000748}
749
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400750Error 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 +0000751{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400752 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 +0000753}
754
Geoff Langb5348332014-09-02 13:16:34 -0400755Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
756 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
757 GLsizei imageSize, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000758{
Geoff Langb5348332014-09-02 13:16:34 -0400759 return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000760}
761
Geoff Lang1f8532b2014-09-05 09:46:13 -0400762Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000763{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400764 Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
765 if (error.isError())
766 {
767 return error;
768 }
769
Jamie Madill6948e302014-10-20 17:04:33 -0400770 mImmutableLevelCount = levels;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000771
Geoff Lang1f8532b2014-09-05 09:46:13 -0400772 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400773}
774
Brandon Jones6053a522014-07-25 16:22:09 -0700775bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
776{
777 GLsizei width = getBaseLevelWidth();
778 GLsizei height = getBaseLevelHeight();
779 GLsizei depth = getBaseLevelDepth();
780
781 if (width <= 0 || height <= 0 || depth <= 0)
782 {
783 return false;
784 }
785
786 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
787 {
788 return false;
789 }
790
791 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
792 {
793 return false;
794 }
795
796 return true;
797}
798
Brandon Jones6053a522014-07-25 16:22:09 -0700799bool Texture3D::isMipmapComplete() const
800{
801 int levelCount = mipLevels();
802
803 for (int level = 0; level < levelCount; level++)
804 {
805 if (!isLevelComplete(level))
806 {
807 return false;
808 }
809 }
810
811 return true;
812}
813
814bool Texture3D::isLevelComplete(int level) const
815{
816 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
817
818 if (isImmutable())
819 {
820 return true;
821 }
822
823 GLsizei width = getBaseLevelWidth();
824 GLsizei height = getBaseLevelHeight();
825 GLsizei depth = getBaseLevelDepth();
826
827 if (width <= 0 || height <= 0 || depth <= 0)
828 {
829 return false;
830 }
831
832 if (level == 0)
833 {
834 return true;
835 }
836
837 rx::Image *levelImage = mTexture->getImage(level, 0);
838
839 if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
840 {
841 return false;
842 }
843
844 if (levelImage->getWidth() != std::max(1, width >> level))
845 {
846 return false;
847 }
848
849 if (levelImage->getHeight() != std::max(1, height >> level))
850 {
851 return false;
852 }
853
854 if (levelImage->getDepth() != std::max(1, depth >> level))
855 {
856 return false;
857 }
858
859 return true;
860}
861
862Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
863 : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000864{
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000865}
866
867Texture2DArray::~Texture2DArray()
868{
Jamie Madill884a4622013-10-24 17:49:41 -0400869}
870
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000871GLsizei Texture2DArray::getWidth(GLint level) const
872{
Brandon Jones142ec422014-07-16 10:31:30 -0700873 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 +0000874}
875
876GLsizei Texture2DArray::getHeight(GLint level) const
877{
Brandon Jones142ec422014-07-16 10:31:30 -0700878 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 +0000879}
880
Jamie Madillb8f8b892014-01-07 10:12:50 -0500881GLsizei Texture2DArray::getLayers(GLint level) const
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000882{
Brandon Jones142ec422014-07-16 10:31:30 -0700883 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getLayerCount(level) : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000884}
885
886GLenum Texture2DArray::getInternalFormat(GLint level) const
887{
Brandon Jones142ec422014-07-16 10:31:30 -0700888 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 +0000889}
890
891GLenum Texture2DArray::getActualFormat(GLint level) const
892{
Brandon Jones142ec422014-07-16 10:31:30 -0700893 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 +0000894}
895
896bool Texture2DArray::isCompressed(GLint level) const
897{
Geoff Lang5d601382014-07-22 15:14:06 -0400898 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000899}
900
901bool Texture2DArray::isDepth(GLint level) const
902{
Geoff Lang5d601382014-07-22 15:14:06 -0400903 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000904}
905
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400906Error 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 +0000907{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400908 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 +0000909}
910
Geoff Langb5348332014-09-02 13:16:34 -0400911Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
912 GLsizei imageSize, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000913{
Geoff Langb5348332014-09-02 13:16:34 -0400914 return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000915}
916
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400917Error 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 +0000918{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400919 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 +0000920}
921
Geoff Langb5348332014-09-02 13:16:34 -0400922Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
923 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
924 GLsizei imageSize, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000925{
Geoff Langb5348332014-09-02 13:16:34 -0400926 return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000927}
928
Geoff Lang1f8532b2014-09-05 09:46:13 -0400929Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000930{
Geoff Lang1f8532b2014-09-05 09:46:13 -0400931 Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
932 if (error.isError())
933 {
934 return error;
935 }
936
Jamie Madill6948e302014-10-20 17:04:33 -0400937 mImmutableLevelCount = levels;
Brandon Jones142ec422014-07-16 10:31:30 -0700938
Geoff Lang1f8532b2014-09-05 09:46:13 -0400939 return Error(GL_NO_ERROR);
Jamie Madill2ebab852013-10-24 17:49:42 -0400940}
941
Brandon Jones6053a522014-07-25 16:22:09 -0700942bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
943{
944 GLsizei width = getBaseLevelWidth();
945 GLsizei height = getBaseLevelHeight();
946 GLsizei depth = getLayers(0);
947
948 if (width <= 0 || height <= 0 || depth <= 0)
949 {
950 return false;
951 }
952
953 if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
954 {
955 return false;
956 }
957
958 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
959 {
960 return false;
961 }
962
963 return true;
964}
965
Brandon Jones6053a522014-07-25 16:22:09 -0700966bool Texture2DArray::isMipmapComplete() const
967{
968 int levelCount = mipLevels();
969
970 for (int level = 1; level < levelCount; level++)
971 {
972 if (!isLevelComplete(level))
973 {
974 return false;
975 }
976 }
977
978 return true;
979}
980
981bool Texture2DArray::isLevelComplete(int level) const
982{
983 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
984
985 if (isImmutable())
986 {
987 return true;
988 }
989
990 GLsizei width = getBaseLevelWidth();
991 GLsizei height = getBaseLevelHeight();
992 GLsizei layers = getLayers(0);
993
994 if (width <= 0 || height <= 0 || layers <= 0)
995 {
996 return false;
997 }
998
999 if (level == 0)
1000 {
1001 return true;
1002 }
1003
1004 if (getInternalFormat(level) != getInternalFormat(0))
1005 {
1006 return false;
1007 }
1008
1009 if (getWidth(level) != std::max(1, width >> level))
1010 {
1011 return false;
1012 }
1013
1014 if (getHeight(level) != std::max(1, height >> level))
1015 {
1016 return false;
1017 }
1018
1019 if (getLayers(level) != layers)
1020 {
1021 return false;
1022 }
1023
1024 return true;
1025}
1026
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00001027}