blob: 0beac559bf059f67142034849d10f9b482a70f92 [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
50Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
Brandon Jonesf47bebc2014-07-09 14:28:42 -070051 : RefCountObject(id),
Brandon Jones6053a522014-07-25 16:22:09 -070052 mTexture(impl),
Brandon Jonesf47bebc2014-07-09 14:28:42 -070053 mUsage(GL_NONE),
54 mImmutable(false),
55 mTarget(target)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000056{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000057}
58
59Texture::~Texture()
60{
Brandon Jones6053a522014-07-25 16:22:09 -070061 SafeDelete(mTexture);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000062}
63
Geoff Lang4907f2c2013-07-25 12:53:57 -040064GLenum Texture::getTarget() const
65{
66 return mTarget;
67}
68
Geoff Lang63b5f1f2013-09-23 14:52:14 -040069void Texture::setUsage(GLenum usage)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000070{
Geoff Lang63b5f1f2013-09-23 14:52:14 -040071 mUsage = usage;
Brandon Jonescef06ff2014-08-05 13:27:48 -070072 getImplementation()->setUsage(usage);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000073}
74
Brandon Jonesa328d562014-07-01 13:52:40 -070075void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
daniel@transgaming.comebf139f2012-10-31 18:07:32 +000076{
77 *sampler = mSamplerState;
Nicolas Capens8de68282014-04-04 11:10:27 -040078
79 // Offset the effective base level by the texture storage's top level
Jamie Madill2f06dbf2014-09-18 15:08:50 -040080 rx::TextureStorage *texture = getNativeTexture();
Nicolas Capens8de68282014-04-04 11:10:27 -040081 int topLevel = texture ? texture->getTopLevel() : 0;
82 sampler->baseLevel = topLevel + mSamplerState.baseLevel;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +000083}
84
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000085GLenum Texture::getUsage() const
86{
87 return mUsage;
88}
89
Jamie Madilld3d2a342013-10-07 10:46:35 -040090GLint Texture::getBaseLevelWidth() const
91{
92 const rx::Image *baseImage = getBaseLevelImage();
93 return (baseImage ? baseImage->getWidth() : 0);
94}
95
96GLint Texture::getBaseLevelHeight() const
97{
98 const rx::Image *baseImage = getBaseLevelImage();
99 return (baseImage ? baseImage->getHeight() : 0);
100}
101
102GLint Texture::getBaseLevelDepth() const
103{
104 const rx::Image *baseImage = getBaseLevelImage();
105 return (baseImage ? baseImage->getDepth() : 0);
106}
107
Jamie Madillb8f8b892014-01-07 10:12:50 -0500108// Note: "base level image" is loosely defined to be any image from the base level,
109// where in the base of 2D array textures and cube maps there are several. Don't use
110// the base level image for anything except querying texture format and size.
Jamie Madilld3d2a342013-10-07 10:46:35 -0400111GLenum Texture::getBaseLevelInternalFormat() const
112{
113 const rx::Image *baseImage = getBaseLevelImage();
114 return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
115}
116
Jamie Madill945f7322014-09-03 15:07:14 -0400117GLsizei Texture::getWidth(const ImageIndex &index) const
118{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400119 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400120 return image->getWidth();
121}
122
123GLsizei Texture::getHeight(const ImageIndex &index) const
124{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400125 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400126 return image->getHeight();
127}
128
129GLenum Texture::getInternalFormat(const ImageIndex &index) const
130{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400131 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400132 return image->getInternalFormat();
133}
134
135GLenum Texture::getActualFormat(const ImageIndex &index) const
136{
Jamie Madillfeda4d22014-09-17 13:03:29 -0400137 rx::Image *image = mTexture->getImage(index);
Jamie Madill945f7322014-09-03 15:07:14 -0400138 return image->getActualFormat();
139}
140
Jamie Madill2f06dbf2014-09-18 15:08:50 -0400141rx::TextureStorage *Texture::getNativeTexture()
Brandon Jones6b19b002014-07-16 14:32:05 -0700142{
143 return getImplementation()->getNativeTexture();
144}
145
Brandon Jonescef06ff2014-08-05 13:27:48 -0700146void Texture::generateMipmaps()
147{
148 getImplementation()->generateMipmaps();
149}
150
Geoff Langef7b0162014-09-04 13:29:23 -0400151Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
152 GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
Brandon Jones6b19b002014-07-16 14:32:05 -0700153{
Geoff Langef7b0162014-09-04 13:29:23 -0400154 return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
Brandon Jones6b19b002014-07-16 14:32:05 -0700155}
156
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700157unsigned int Texture::getTextureSerial()
158{
Jamie Madill2f06dbf2014-09-18 15:08:50 -0400159 rx::TextureStorage *texture = getNativeTexture();
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700160 return texture ? texture->getTextureSerial() : 0;
161}
162
163bool Texture::isImmutable() const
164{
165 return mImmutable;
166}
167
168int Texture::immutableLevelCount()
169{
Jamie Madill2f06dbf2014-09-18 15:08:50 -0400170 return (mImmutable ? getNativeTexture()->getLevelCount() : 0);
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700171}
172
173int Texture::mipLevels() const
174{
175 return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
176}
177
Brandon Jonescef06ff2014-08-05 13:27:48 -0700178const rx::Image *Texture::getBaseLevelImage() const
179{
180 return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
181}
182
Brandon Jones6053a522014-07-25 16:22:09 -0700183Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
184 : Texture(impl, id, GL_TEXTURE_2D)
Jamie Madill22f843a2013-10-24 17:49:36 -0400185{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000186 mSurface = NULL;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000187}
188
189Texture2D::~Texture2D()
190{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000191 if (mSurface)
192 {
193 mSurface->setBoundTexture(NULL);
194 mSurface = NULL;
195 }
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700196}
daniel@transgaming.comd9ec9022012-12-20 20:52:16 +0000197
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000198GLsizei Texture2D::getWidth(GLint level) const
199{
200 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700201 return mTexture->getImage(level, 0)->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000202 else
203 return 0;
204}
205
206GLsizei Texture2D::getHeight(GLint level) const
207{
208 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700209 return mTexture->getImage(level, 0)->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000210 else
211 return 0;
212}
213
214GLenum Texture2D::getInternalFormat(GLint level) const
215{
216 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700217 return mTexture->getImage(level, 0)->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000218 else
219 return GL_NONE;
220}
221
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000222GLenum Texture2D::getActualFormat(GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000223{
224 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700225 return mTexture->getImage(level, 0)->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000226 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500227 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000228}
229
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400230Error 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 +0000231{
232 releaseTexImage();
shannon.woods@transgaming.com8a406682013-02-28 23:15:26 +0000233
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400234 return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000235}
236
237void Texture2D::bindTexImage(egl::Surface *surface)
238{
239 releaseTexImage();
240
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700241 mTexture->bindTexImage(surface);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000242
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000243 mSurface = surface;
244 mSurface->setBoundTexture(this);
245}
246
247void Texture2D::releaseTexImage()
248{
249 if (mSurface)
250 {
251 mSurface->setBoundTexture(NULL);
252 mSurface = NULL;
253
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700254 mTexture->releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000255 }
256}
257
Geoff Langb5348332014-09-02 13:16:34 -0400258Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
259 const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000260{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700261 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000262
Geoff Langb5348332014-09-02 13:16:34 -0400263 return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000264}
265
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400266Error 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 +0000267{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400268 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 +0000269}
270
Geoff Langb5348332014-09-02 13:16:34 -0400271Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
272 GLenum format, GLsizei imageSize, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000273{
Geoff Langb5348332014-09-02 13:16:34 -0400274 return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000275}
276
Geoff Langef7b0162014-09-04 13:29:23 -0400277Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
278 Framebuffer *source)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000279{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700280 releaseTexImage();
Geoff Lang5d601382014-07-22 15:14:06 -0400281
Geoff Langef7b0162014-09-04 13:29:23 -0400282 return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000283}
284
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000285void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
286{
Jamie Madill73b5d062013-10-24 17:49:38 -0400287 mImmutable = true;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000288
Brandon Jonescef06ff2014-08-05 13:27:48 -0700289 mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000290}
291
Brandon Jones6053a522014-07-25 16:22:09 -0700292// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
293bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
294{
295 GLsizei width = getBaseLevelWidth();
296 GLsizei height = getBaseLevelHeight();
297
298 if (width <= 0 || height <= 0)
299 {
300 return false;
301 }
302
303 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
304 {
305 return false;
306 }
307
308 bool npotSupport = extensions.textureNPOT;
309
310 if (!npotSupport)
311 {
312 if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
313 (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
314 {
315 return false;
316 }
317 }
318
319 if (IsMipmapFiltered(samplerState))
320 {
321 if (!npotSupport)
322 {
323 if (!gl::isPow2(width) || !gl::isPow2(height))
324 {
325 return false;
326 }
327 }
328
329 if (!isMipmapComplete())
330 {
331 return false;
332 }
333 }
334
335 // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
336 // The internalformat specified for the texture arrays is a sized internal depth or
337 // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
338 // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
339 // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
340 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
341 if (formatInfo.depthBits > 0 && clientVersion > 2)
342 {
343 if (samplerState.compareMode == GL_NONE)
344 {
345 if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
346 samplerState.magFilter != GL_NEAREST)
347 {
348 return false;
349 }
350 }
351 }
352
353 return true;
354}
355
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000356bool Texture2D::isCompressed(GLint level) const
357{
Geoff Lang5d601382014-07-22 15:14:06 -0400358 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000359}
360
361bool Texture2D::isDepth(GLint level) const
362{
Geoff Lang5d601382014-07-22 15:14:06 -0400363 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000364}
365
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000366void Texture2D::generateMipmaps()
367{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700368 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000369
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700370 mTexture->generateMipmaps();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000371}
372
Brandon Jones6053a522014-07-25 16:22:09 -0700373// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
374bool Texture2D::isMipmapComplete() const
375{
376 int levelCount = mipLevels();
377
378 for (int level = 0; level < levelCount; level++)
379 {
380 if (!isLevelComplete(level))
381 {
382 return false;
383 }
384 }
385
386 return true;
387}
388
389bool Texture2D::isLevelComplete(int level) const
390{
391 if (isImmutable())
392 {
393 return true;
394 }
395
396 const rx::Image *baseImage = getBaseLevelImage();
397
398 GLsizei width = baseImage->getWidth();
399 GLsizei height = baseImage->getHeight();
400
401 if (width <= 0 || height <= 0)
402 {
403 return false;
404 }
405
406 // The base image level is complete if the width and height are positive
407 if (level == 0)
408 {
409 return true;
410 }
411
412 ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
413 rx::Image *image = mTexture->getImage(level, 0);
414
415 if (image->getInternalFormat() != baseImage->getInternalFormat())
416 {
417 return false;
418 }
419
420 if (image->getWidth() != std::max(1, width >> level))
421 {
422 return false;
423 }
424
425 if (image->getHeight() != std::max(1, height >> level))
426 {
427 return false;
428 }
429
430 return true;
431}
432
433TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
434 : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000435{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000436}
437
438TextureCubeMap::~TextureCubeMap()
439{
Brandon Jones0511e802014-07-14 16:27:26 -0700440}
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000441
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000442GLsizei TextureCubeMap::getWidth(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))->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000446 else
447 return 0;
448}
449
450GLsizei TextureCubeMap::getHeight(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))->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000454 else
455 return 0;
456}
457
458GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
459{
460 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700461 return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000462 else
463 return GL_NONE;
464}
465
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000466GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000467{
468 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700469 return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000470 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500471 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000472}
473
Geoff Lang8376cea2014-09-02 11:47:07 -0400474Error 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 +0000475{
Geoff Lang8376cea2014-09-02 11:47:07 -0400476 return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000477}
478
Geoff Langb5348332014-09-02 13:16:34 -0400479Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
480 GLsizei imageSize, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000481{
Geoff Langb5348332014-09-02 13:16:34 -0400482 return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000483}
484
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400485Error 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 +0000486{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400487 return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000488}
489
Geoff Langb5348332014-09-02 13:16:34 -0400490Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset,
491 GLsizei width, GLsizei height, GLenum format,
492 GLsizei imageSize, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000493{
Geoff Langb5348332014-09-02 13:16:34 -0400494 return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000495}
496
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000497// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
498bool TextureCubeMap::isCubeComplete() const
499{
Brandon Jones6053a522014-07-25 16:22:09 -0700500 int baseWidth = getBaseLevelWidth();
501 int baseHeight = getBaseLevelHeight();
502 GLenum baseFormat = getBaseLevelInternalFormat();
503
504 if (baseWidth <= 0 || baseWidth != baseHeight)
505 {
506 return false;
507 }
508
509 for (int faceIndex = 1; faceIndex < 6; faceIndex++)
510 {
511 const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
512
513 if (faceBaseImage->getWidth() != baseWidth ||
514 faceBaseImage->getHeight() != baseHeight ||
515 faceBaseImage->getInternalFormat() != baseFormat )
516 {
517 return false;
518 }
519 }
520
521 return true;
Jamie Madill07edd442013-07-19 16:36:58 -0400522}
523
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000524bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
525{
Geoff Lang5d601382014-07-22 15:14:06 -0400526 return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000527}
528
Geoff Lang8040f572013-07-25 16:49:54 -0400529bool TextureCubeMap::isDepth(GLenum target, GLint level) const
530{
Geoff Lang5d601382014-07-22 15:14:06 -0400531 return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
Geoff Lang8040f572013-07-25 16:49:54 -0400532}
533
Geoff Langef7b0162014-09-04 13:29:23 -0400534Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
535 GLsizei width, GLsizei height, Framebuffer *source)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000536{
Geoff Langef7b0162014-09-04 13:29:23 -0400537 return mTexture->copyImage(target, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000538}
539
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000540void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
541{
Jamie Madill3c0989c2013-10-24 17:49:39 -0400542 mImmutable = true;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000543
Brandon Jonescef06ff2014-08-05 13:27:48 -0700544 mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
Jamie Madill2ebab852013-10-24 17:49:42 -0400545}
546
Brandon Jones6053a522014-07-25 16:22:09 -0700547// Tests for texture sampling completeness
548bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
549{
550 int size = getBaseLevelWidth();
551
552 bool mipmapping = IsMipmapFiltered(samplerState);
553
554 if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
555 {
556 return false;
557 }
558
559 if (!gl::isPow2(size) && !extensions.textureNPOT)
560 {
561 if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
562 {
563 return false;
564 }
565 }
566
567 if (!mipmapping)
568 {
569 if (!isCubeComplete())
570 {
571 return false;
572 }
573 }
574 else
575 {
576 if (!isMipmapComplete()) // Also tests for isCubeComplete()
577 {
578 return false;
579 }
580 }
581
582 return true;
583}
584
Brandon Jonescef06ff2014-08-05 13:27:48 -0700585int TextureCubeMap::targetToLayerIndex(GLenum target)
586{
587 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
588 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
589 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
590 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
591 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
592
593 return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
594}
595
596GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
597{
598 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
599 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
600 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
601 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
602 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
603
604 return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
Geoff Lang8040f572013-07-25 16:49:54 -0400605}
606
Brandon Jones6053a522014-07-25 16:22:09 -0700607bool TextureCubeMap::isMipmapComplete() const
608{
609 if (isImmutable())
610 {
611 return true;
612 }
613
614 if (!isCubeComplete())
615 {
616 return false;
617 }
618
619 int levelCount = mipLevels();
620
621 for (int face = 0; face < 6; face++)
622 {
623 for (int level = 1; level < levelCount; level++)
624 {
625 if (!isFaceLevelComplete(face, level))
626 {
627 return false;
628 }
629 }
630 }
631
632 return true;
633}
634
635bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
636{
637 ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
638
639 if (isImmutable())
640 {
641 return true;
642 }
643
644 int baseSize = getBaseLevelWidth();
645
646 if (baseSize <= 0)
647 {
648 return false;
649 }
650
651 // "isCubeComplete" checks for base level completeness and we must call that
652 // to determine if any face at level 0 is complete. We omit that check here
653 // to avoid re-checking cube-completeness for every face at level 0.
654 if (level == 0)
655 {
656 return true;
657 }
658
659 // Check that non-zero levels are consistent with the base level.
660 const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
661
662 if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
663 {
664 return false;
665 }
666
667 if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
668 {
669 return false;
670 }
671
672 return true;
673}
674
675
676Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
677 : Texture(impl, id, GL_TEXTURE_3D)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000678{
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000679}
680
681Texture3D::~Texture3D()
682{
Brandon Jones78b1acd2014-07-15 15:33:07 -0700683}
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000684
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000685GLsizei Texture3D::getWidth(GLint level) const
686{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700687 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000688}
689
690GLsizei Texture3D::getHeight(GLint level) const
691{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700692 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000693}
694
695GLsizei Texture3D::getDepth(GLint level) const
696{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700697 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000698}
699
700GLenum Texture3D::getInternalFormat(GLint level) const
701{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700702 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000703}
704
705GLenum Texture3D::getActualFormat(GLint level) const
706{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700707 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000708}
709
710bool Texture3D::isCompressed(GLint level) const
711{
Geoff Lang5d601382014-07-22 15:14:06 -0400712 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000713}
714
715bool Texture3D::isDepth(GLint level) const
716{
Geoff Lang5d601382014-07-22 15:14:06 -0400717 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000718}
719
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400720Error 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 +0000721{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400722 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 +0000723}
724
Geoff Langb5348332014-09-02 13:16:34 -0400725Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
726 GLsizei imageSize, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000727{
Geoff Langb5348332014-09-02 13:16:34 -0400728 return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000729}
730
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400731Error 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 +0000732{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400733 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 +0000734}
735
Geoff Langb5348332014-09-02 13:16:34 -0400736Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
737 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
738 GLsizei imageSize, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000739{
Geoff Langb5348332014-09-02 13:16:34 -0400740 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 +0000741}
742
743void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
744{
Jamie Madille664e202013-10-24 17:49:40 -0400745 mImmutable = true;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000746
Brandon Jonescef06ff2014-08-05 13:27:48 -0700747 mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
Jamie Madill2ebab852013-10-24 17:49:42 -0400748}
749
Brandon Jones6053a522014-07-25 16:22:09 -0700750bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
751{
752 GLsizei width = getBaseLevelWidth();
753 GLsizei height = getBaseLevelHeight();
754 GLsizei depth = getBaseLevelDepth();
755
756 if (width <= 0 || height <= 0 || depth <= 0)
757 {
758 return false;
759 }
760
761 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
762 {
763 return false;
764 }
765
766 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
767 {
768 return false;
769 }
770
771 return true;
772}
773
Brandon Jones6053a522014-07-25 16:22:09 -0700774bool Texture3D::isMipmapComplete() const
775{
776 int levelCount = mipLevels();
777
778 for (int level = 0; level < levelCount; level++)
779 {
780 if (!isLevelComplete(level))
781 {
782 return false;
783 }
784 }
785
786 return true;
787}
788
789bool Texture3D::isLevelComplete(int level) const
790{
791 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
792
793 if (isImmutable())
794 {
795 return true;
796 }
797
798 GLsizei width = getBaseLevelWidth();
799 GLsizei height = getBaseLevelHeight();
800 GLsizei depth = getBaseLevelDepth();
801
802 if (width <= 0 || height <= 0 || depth <= 0)
803 {
804 return false;
805 }
806
807 if (level == 0)
808 {
809 return true;
810 }
811
812 rx::Image *levelImage = mTexture->getImage(level, 0);
813
814 if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
815 {
816 return false;
817 }
818
819 if (levelImage->getWidth() != std::max(1, width >> level))
820 {
821 return false;
822 }
823
824 if (levelImage->getHeight() != std::max(1, height >> level))
825 {
826 return false;
827 }
828
829 if (levelImage->getDepth() != std::max(1, depth >> level))
830 {
831 return false;
832 }
833
834 return true;
835}
836
837Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
838 : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000839{
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000840}
841
842Texture2DArray::~Texture2DArray()
843{
Jamie Madill884a4622013-10-24 17:49:41 -0400844}
845
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000846GLsizei Texture2DArray::getWidth(GLint level) const
847{
Brandon Jones142ec422014-07-16 10:31:30 -0700848 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 +0000849}
850
851GLsizei Texture2DArray::getHeight(GLint level) const
852{
Brandon Jones142ec422014-07-16 10:31:30 -0700853 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 +0000854}
855
Jamie Madillb8f8b892014-01-07 10:12:50 -0500856GLsizei Texture2DArray::getLayers(GLint level) const
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000857{
Brandon Jones142ec422014-07-16 10:31:30 -0700858 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getLayerCount(level) : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000859}
860
861GLenum Texture2DArray::getInternalFormat(GLint level) const
862{
Brandon Jones142ec422014-07-16 10:31:30 -0700863 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 +0000864}
865
866GLenum Texture2DArray::getActualFormat(GLint level) const
867{
Brandon Jones142ec422014-07-16 10:31:30 -0700868 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 +0000869}
870
871bool Texture2DArray::isCompressed(GLint level) const
872{
Geoff Lang5d601382014-07-22 15:14:06 -0400873 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000874}
875
876bool Texture2DArray::isDepth(GLint level) const
877{
Geoff Lang5d601382014-07-22 15:14:06 -0400878 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000879}
880
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400881Error 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 +0000882{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400883 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 +0000884}
885
Geoff Langb5348332014-09-02 13:16:34 -0400886Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
887 GLsizei imageSize, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000888{
Geoff Langb5348332014-09-02 13:16:34 -0400889 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 +0000890}
891
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400892Error 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 +0000893{
Geoff Lang1ba6b8d2014-08-28 10:57:31 -0400894 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 +0000895}
896
Geoff Langb5348332014-09-02 13:16:34 -0400897Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
898 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
899 GLsizei imageSize, const void *pixels)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000900{
Geoff Langb5348332014-09-02 13:16:34 -0400901 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 +0000902}
903
904void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
905{
Jamie Madill884a4622013-10-24 17:49:41 -0400906 mImmutable = true;
Brandon Jones142ec422014-07-16 10:31:30 -0700907
Brandon Jonescef06ff2014-08-05 13:27:48 -0700908 mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
Jamie Madill2ebab852013-10-24 17:49:42 -0400909}
910
Brandon Jones6053a522014-07-25 16:22:09 -0700911bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
912{
913 GLsizei width = getBaseLevelWidth();
914 GLsizei height = getBaseLevelHeight();
915 GLsizei depth = getLayers(0);
916
917 if (width <= 0 || height <= 0 || depth <= 0)
918 {
919 return false;
920 }
921
922 if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
923 {
924 return false;
925 }
926
927 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
928 {
929 return false;
930 }
931
932 return true;
933}
934
Brandon Jones6053a522014-07-25 16:22:09 -0700935bool Texture2DArray::isMipmapComplete() const
936{
937 int levelCount = mipLevels();
938
939 for (int level = 1; level < levelCount; level++)
940 {
941 if (!isLevelComplete(level))
942 {
943 return false;
944 }
945 }
946
947 return true;
948}
949
950bool Texture2DArray::isLevelComplete(int level) const
951{
952 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
953
954 if (isImmutable())
955 {
956 return true;
957 }
958
959 GLsizei width = getBaseLevelWidth();
960 GLsizei height = getBaseLevelHeight();
961 GLsizei layers = getLayers(0);
962
963 if (width <= 0 || height <= 0 || layers <= 0)
964 {
965 return false;
966 }
967
968 if (level == 0)
969 {
970 return true;
971 }
972
973 if (getInternalFormat(level) != getInternalFormat(0))
974 {
975 return false;
976 }
977
978 if (getWidth(level) != std::max(1, width >> level))
979 {
980 return false;
981 }
982
983 if (getHeight(level) != std::max(1, height >> level))
984 {
985 return false;
986 }
987
988 if (getLayers(level) != layers)
989 {
990 return false;
991 }
992
993 return true;
994}
995
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000996}