blob: 396dbb586acaa07854ae3b44e7a54f923036967a [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"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000015#include "libGLESv2/Renderbuffer.h"
16#include "libGLESv2/renderer/Image.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040017#include "libGLESv2/renderer/d3d/TextureStorage.h"
18
19#include "libEGL/Surface.h"
20
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
49Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
Brandon Jonesf47bebc2014-07-09 14:28:42 -070050 : RefCountObject(id),
Brandon Jones6053a522014-07-25 16:22:09 -070051 mTexture(impl),
Brandon Jonesf47bebc2014-07-09 14:28:42 -070052 mUsage(GL_NONE),
53 mImmutable(false),
54 mTarget(target)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000055{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000056}
57
58Texture::~Texture()
59{
Brandon Jones6053a522014-07-25 16:22:09 -070060 SafeDelete(mTexture);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000061}
62
Geoff Lang4907f2c2013-07-25 12:53:57 -040063GLenum Texture::getTarget() const
64{
65 return mTarget;
66}
67
Geoff Lang63b5f1f2013-09-23 14:52:14 -040068void Texture::setUsage(GLenum usage)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000069{
Geoff Lang63b5f1f2013-09-23 14:52:14 -040070 mUsage = usage;
Brandon Jonescef06ff2014-08-05 13:27:48 -070071 getImplementation()->setUsage(usage);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000072}
73
Brandon Jonesa328d562014-07-01 13:52:40 -070074void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
daniel@transgaming.comebf139f2012-10-31 18:07:32 +000075{
76 *sampler = mSamplerState;
Nicolas Capens8de68282014-04-04 11:10:27 -040077
78 // Offset the effective base level by the texture storage's top level
79 rx::TextureStorageInterface *texture = getNativeTexture();
80 int topLevel = texture ? texture->getTopLevel() : 0;
81 sampler->baseLevel = topLevel + mSamplerState.baseLevel;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +000082}
83
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000084GLenum Texture::getUsage() const
85{
86 return mUsage;
87}
88
Jamie Madilld3d2a342013-10-07 10:46:35 -040089GLint Texture::getBaseLevelWidth() const
90{
91 const rx::Image *baseImage = getBaseLevelImage();
92 return (baseImage ? baseImage->getWidth() : 0);
93}
94
95GLint Texture::getBaseLevelHeight() const
96{
97 const rx::Image *baseImage = getBaseLevelImage();
98 return (baseImage ? baseImage->getHeight() : 0);
99}
100
101GLint Texture::getBaseLevelDepth() const
102{
103 const rx::Image *baseImage = getBaseLevelImage();
104 return (baseImage ? baseImage->getDepth() : 0);
105}
106
Jamie Madillb8f8b892014-01-07 10:12:50 -0500107// Note: "base level image" is loosely defined to be any image from the base level,
108// where in the base of 2D array textures and cube maps there are several. Don't use
109// the base level image for anything except querying texture format and size.
Jamie Madilld3d2a342013-10-07 10:46:35 -0400110GLenum Texture::getBaseLevelInternalFormat() const
111{
112 const rx::Image *baseImage = getBaseLevelImage();
113 return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
114}
115
Jamie Madill945f7322014-09-03 15:07:14 -0400116GLsizei Texture::getWidth(const ImageIndex &index) const
117{
118 rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
119 return image->getWidth();
120}
121
122GLsizei Texture::getHeight(const ImageIndex &index) const
123{
124 rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
125 return image->getHeight();
126}
127
128GLenum Texture::getInternalFormat(const ImageIndex &index) const
129{
130 rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
131 return image->getInternalFormat();
132}
133
134GLenum Texture::getActualFormat(const ImageIndex &index) const
135{
136 rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
137 return image->getActualFormat();
138}
139
Brandon Jones6b19b002014-07-16 14:32:05 -0700140rx::TextureStorageInterface *Texture::getNativeTexture()
141{
142 return getImplementation()->getNativeTexture();
143}
144
Brandon Jonescef06ff2014-08-05 13:27:48 -0700145void Texture::generateMipmaps()
146{
147 getImplementation()->generateMipmaps();
148}
149
Brandon Jones6b19b002014-07-16 14:32:05 -0700150void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
151{
152 getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
153}
154
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700155unsigned int Texture::getTextureSerial()
156{
157 rx::TextureStorageInterface *texture = getNativeTexture();
158 return texture ? texture->getTextureSerial() : 0;
159}
160
161bool Texture::isImmutable() const
162{
163 return mImmutable;
164}
165
166int Texture::immutableLevelCount()
167{
168 return (mImmutable ? getNativeTexture()->getStorageInstance()->getLevelCount() : 0);
169}
170
171int Texture::mipLevels() const
172{
173 return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
174}
175
Brandon Jonescef06ff2014-08-05 13:27:48 -0700176const rx::Image *Texture::getBaseLevelImage() const
177{
178 return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
179}
180
Brandon Jones6053a522014-07-25 16:22:09 -0700181Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
182 : Texture(impl, id, GL_TEXTURE_2D)
Jamie Madill22f843a2013-10-24 17:49:36 -0400183{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000184 mSurface = NULL;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000185}
186
187Texture2D::~Texture2D()
188{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000189 if (mSurface)
190 {
191 mSurface->setBoundTexture(NULL);
192 mSurface = NULL;
193 }
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700194}
daniel@transgaming.comd9ec9022012-12-20 20:52:16 +0000195
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000196GLsizei Texture2D::getWidth(GLint level) const
197{
198 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700199 return mTexture->getImage(level, 0)->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000200 else
201 return 0;
202}
203
204GLsizei Texture2D::getHeight(GLint level) const
205{
206 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700207 return mTexture->getImage(level, 0)->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000208 else
209 return 0;
210}
211
212GLenum Texture2D::getInternalFormat(GLint level) const
213{
214 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700215 return mTexture->getImage(level, 0)->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000216 else
217 return GL_NONE;
218}
219
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000220GLenum Texture2D::getActualFormat(GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000221{
222 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700223 return mTexture->getImage(level, 0)->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000224 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500225 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000226}
227
Brandon Jonescef06ff2014-08-05 13:27:48 -0700228void 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 +0000229{
230 releaseTexImage();
shannon.woods@transgaming.com8a406682013-02-28 23:15:26 +0000231
Brandon Jonescef06ff2014-08-05 13:27:48 -0700232 mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000233}
234
235void Texture2D::bindTexImage(egl::Surface *surface)
236{
237 releaseTexImage();
238
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700239 mTexture->bindTexImage(surface);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000240
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000241 mSurface = surface;
242 mSurface->setBoundTexture(this);
243}
244
245void Texture2D::releaseTexImage()
246{
247 if (mSurface)
248 {
249 mSurface->setBoundTexture(NULL);
250 mSurface = NULL;
251
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700252 mTexture->releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000253 }
254}
255
256void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
257{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700258 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000259
Brandon Jonescef06ff2014-08-05 13:27:48 -0700260 mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000261}
262
Jamie Madill88f18f42013-09-18 14:36:19 -0400263void 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 +0000264{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700265 mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000266}
267
268void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
269{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700270 mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000271}
272
273void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
274{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700275 releaseTexImage();
Geoff Lang5d601382014-07-22 15:14:06 -0400276
Brandon Jonescef06ff2014-08-05 13:27:48 -0700277 mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000278}
279
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000280void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
281{
Jamie Madill73b5d062013-10-24 17:49:38 -0400282 mImmutable = true;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000283
Brandon Jonescef06ff2014-08-05 13:27:48 -0700284 mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000285}
286
Brandon Jones6053a522014-07-25 16:22:09 -0700287// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
288bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
289{
290 GLsizei width = getBaseLevelWidth();
291 GLsizei height = getBaseLevelHeight();
292
293 if (width <= 0 || height <= 0)
294 {
295 return false;
296 }
297
298 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
299 {
300 return false;
301 }
302
303 bool npotSupport = extensions.textureNPOT;
304
305 if (!npotSupport)
306 {
307 if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
308 (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
309 {
310 return false;
311 }
312 }
313
314 if (IsMipmapFiltered(samplerState))
315 {
316 if (!npotSupport)
317 {
318 if (!gl::isPow2(width) || !gl::isPow2(height))
319 {
320 return false;
321 }
322 }
323
324 if (!isMipmapComplete())
325 {
326 return false;
327 }
328 }
329
330 // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
331 // The internalformat specified for the texture arrays is a sized internal depth or
332 // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
333 // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
334 // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
335 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
336 if (formatInfo.depthBits > 0 && clientVersion > 2)
337 {
338 if (samplerState.compareMode == GL_NONE)
339 {
340 if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
341 samplerState.magFilter != GL_NEAREST)
342 {
343 return false;
344 }
345 }
346 }
347
348 return true;
349}
350
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000351bool Texture2D::isCompressed(GLint level) const
352{
Geoff Lang5d601382014-07-22 15:14:06 -0400353 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000354}
355
356bool Texture2D::isDepth(GLint level) const
357{
Geoff Lang5d601382014-07-22 15:14:06 -0400358 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000359}
360
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000361void Texture2D::generateMipmaps()
362{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700363 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000364
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700365 mTexture->generateMipmaps();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000366}
367
Brandon Jones6053a522014-07-25 16:22:09 -0700368// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
369bool Texture2D::isMipmapComplete() const
370{
371 int levelCount = mipLevels();
372
373 for (int level = 0; level < levelCount; level++)
374 {
375 if (!isLevelComplete(level))
376 {
377 return false;
378 }
379 }
380
381 return true;
382}
383
384bool Texture2D::isLevelComplete(int level) const
385{
386 if (isImmutable())
387 {
388 return true;
389 }
390
391 const rx::Image *baseImage = getBaseLevelImage();
392
393 GLsizei width = baseImage->getWidth();
394 GLsizei height = baseImage->getHeight();
395
396 if (width <= 0 || height <= 0)
397 {
398 return false;
399 }
400
401 // The base image level is complete if the width and height are positive
402 if (level == 0)
403 {
404 return true;
405 }
406
407 ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
408 rx::Image *image = mTexture->getImage(level, 0);
409
410 if (image->getInternalFormat() != baseImage->getInternalFormat())
411 {
412 return false;
413 }
414
415 if (image->getWidth() != std::max(1, width >> level))
416 {
417 return false;
418 }
419
420 if (image->getHeight() != std::max(1, height >> level))
421 {
422 return false;
423 }
424
425 return true;
426}
427
428TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
429 : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000430{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000431}
432
433TextureCubeMap::~TextureCubeMap()
434{
Brandon Jones0511e802014-07-14 16:27:26 -0700435}
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000436
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000437GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
438{
439 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700440 return mTexture->getImage(level, targetToLayerIndex(target))->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000441 else
442 return 0;
443}
444
445GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
446{
447 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700448 return mTexture->getImage(level, targetToLayerIndex(target))->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000449 else
450 return 0;
451}
452
453GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
454{
455 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700456 return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000457 else
458 return GL_NONE;
459}
460
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000461GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000462{
463 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700464 return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000465 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500466 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000467}
468
Geoff Lang005df412013-10-16 14:12:50 -0400469void TextureCubeMap::setImagePosX(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 +0000470{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700471 mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000472}
473
Geoff Lang005df412013-10-16 14:12:50 -0400474void TextureCubeMap::setImageNegX(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{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700476 mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000477}
478
Geoff Lang005df412013-10-16 14:12:50 -0400479void TextureCubeMap::setImagePosY(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 +0000480{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700481 mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000482}
483
Geoff Lang005df412013-10-16 14:12:50 -0400484void TextureCubeMap::setImageNegY(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 +0000485{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700486 mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000487}
488
Geoff Lang005df412013-10-16 14:12:50 -0400489void TextureCubeMap::setImagePosZ(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 +0000490{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700491 mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000492}
493
Geoff Lang005df412013-10-16 14:12:50 -0400494void TextureCubeMap::setImageNegZ(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 +0000495{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700496 mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000497}
498
Jamie Madill2db197c2013-10-24 17:49:35 -0400499void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000500{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700501 mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000502}
503
Jamie Madill88f18f42013-09-18 14:36:19 -0400504void 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 +0000505{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700506 mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000507}
508
509void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
510{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700511 mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000512}
513
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000514// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
515bool TextureCubeMap::isCubeComplete() const
516{
Brandon Jones6053a522014-07-25 16:22:09 -0700517 int baseWidth = getBaseLevelWidth();
518 int baseHeight = getBaseLevelHeight();
519 GLenum baseFormat = getBaseLevelInternalFormat();
520
521 if (baseWidth <= 0 || baseWidth != baseHeight)
522 {
523 return false;
524 }
525
526 for (int faceIndex = 1; faceIndex < 6; faceIndex++)
527 {
528 const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
529
530 if (faceBaseImage->getWidth() != baseWidth ||
531 faceBaseImage->getHeight() != baseHeight ||
532 faceBaseImage->getInternalFormat() != baseFormat )
533 {
534 return false;
535 }
536 }
537
538 return true;
Jamie Madill07edd442013-07-19 16:36:58 -0400539}
540
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000541bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
542{
Geoff Lang5d601382014-07-22 15:14:06 -0400543 return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000544}
545
Geoff Lang8040f572013-07-25 16:49:54 -0400546bool TextureCubeMap::isDepth(GLenum target, GLint level) const
547{
Geoff Lang5d601382014-07-22 15:14:06 -0400548 return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
Geoff Lang8040f572013-07-25 16:49:54 -0400549}
550
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000551void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
552{
Brandon Jones0511e802014-07-14 16:27:26 -0700553 mTexture->copyImage(target, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000554}
555
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000556void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
557{
Jamie Madill3c0989c2013-10-24 17:49:39 -0400558 mImmutable = true;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000559
Brandon Jonescef06ff2014-08-05 13:27:48 -0700560 mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
Jamie Madill2ebab852013-10-24 17:49:42 -0400561}
562
Brandon Jones6053a522014-07-25 16:22:09 -0700563// Tests for texture sampling completeness
564bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
565{
566 int size = getBaseLevelWidth();
567
568 bool mipmapping = IsMipmapFiltered(samplerState);
569
570 if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
571 {
572 return false;
573 }
574
575 if (!gl::isPow2(size) && !extensions.textureNPOT)
576 {
577 if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
578 {
579 return false;
580 }
581 }
582
583 if (!mipmapping)
584 {
585 if (!isCubeComplete())
586 {
587 return false;
588 }
589 }
590 else
591 {
592 if (!isMipmapComplete()) // Also tests for isCubeComplete()
593 {
594 return false;
595 }
596 }
597
598 return true;
599}
600
Brandon Jonescef06ff2014-08-05 13:27:48 -0700601int TextureCubeMap::targetToLayerIndex(GLenum target)
602{
603 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
604 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
605 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
606 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
607 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
608
609 return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
610}
611
612GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
613{
614 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
615 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
616 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
617 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
618 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
619
620 return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
Geoff Lang8040f572013-07-25 16:49:54 -0400621}
622
Brandon Jones6053a522014-07-25 16:22:09 -0700623bool TextureCubeMap::isMipmapComplete() const
624{
625 if (isImmutable())
626 {
627 return true;
628 }
629
630 if (!isCubeComplete())
631 {
632 return false;
633 }
634
635 int levelCount = mipLevels();
636
637 for (int face = 0; face < 6; face++)
638 {
639 for (int level = 1; level < levelCount; level++)
640 {
641 if (!isFaceLevelComplete(face, level))
642 {
643 return false;
644 }
645 }
646 }
647
648 return true;
649}
650
651bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
652{
653 ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
654
655 if (isImmutable())
656 {
657 return true;
658 }
659
660 int baseSize = getBaseLevelWidth();
661
662 if (baseSize <= 0)
663 {
664 return false;
665 }
666
667 // "isCubeComplete" checks for base level completeness and we must call that
668 // to determine if any face at level 0 is complete. We omit that check here
669 // to avoid re-checking cube-completeness for every face at level 0.
670 if (level == 0)
671 {
672 return true;
673 }
674
675 // Check that non-zero levels are consistent with the base level.
676 const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
677
678 if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
679 {
680 return false;
681 }
682
683 if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
684 {
685 return false;
686 }
687
688 return true;
689}
690
691
692Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
693 : Texture(impl, id, GL_TEXTURE_3D)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000694{
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000695}
696
697Texture3D::~Texture3D()
698{
Brandon Jones78b1acd2014-07-15 15:33:07 -0700699}
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000700
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000701GLsizei Texture3D::getWidth(GLint level) const
702{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700703 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000704}
705
706GLsizei Texture3D::getHeight(GLint level) const
707{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700708 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000709}
710
711GLsizei Texture3D::getDepth(GLint level) const
712{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700713 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000714}
715
716GLenum Texture3D::getInternalFormat(GLint level) const
717{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700718 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000719}
720
721GLenum Texture3D::getActualFormat(GLint level) const
722{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700723 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000724}
725
726bool Texture3D::isCompressed(GLint level) const
727{
Geoff Lang5d601382014-07-22 15:14:06 -0400728 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000729}
730
731bool Texture3D::isDepth(GLint level) const
732{
Geoff Lang5d601382014-07-22 15:14:06 -0400733 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000734}
735
Geoff Lang005df412013-10-16 14:12:50 -0400736void 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 +0000737{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700738 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 +0000739}
740
741void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
742{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700743 mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000744}
745
Jamie Madill88f18f42013-09-18 14:36:19 -0400746void 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 +0000747{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700748 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 +0000749}
750
751void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
752{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700753 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 +0000754}
755
756void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
757{
Jamie Madille664e202013-10-24 17:49:40 -0400758 mImmutable = true;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000759
Brandon Jonescef06ff2014-08-05 13:27:48 -0700760 mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
Jamie Madill2ebab852013-10-24 17:49:42 -0400761}
762
Brandon Jones6053a522014-07-25 16:22:09 -0700763bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
764{
765 GLsizei width = getBaseLevelWidth();
766 GLsizei height = getBaseLevelHeight();
767 GLsizei depth = getBaseLevelDepth();
768
769 if (width <= 0 || height <= 0 || depth <= 0)
770 {
771 return false;
772 }
773
774 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
775 {
776 return false;
777 }
778
779 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
780 {
781 return false;
782 }
783
784 return true;
785}
786
Brandon Jones6053a522014-07-25 16:22:09 -0700787bool Texture3D::isMipmapComplete() const
788{
789 int levelCount = mipLevels();
790
791 for (int level = 0; level < levelCount; level++)
792 {
793 if (!isLevelComplete(level))
794 {
795 return false;
796 }
797 }
798
799 return true;
800}
801
802bool Texture3D::isLevelComplete(int level) const
803{
804 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
805
806 if (isImmutable())
807 {
808 return true;
809 }
810
811 GLsizei width = getBaseLevelWidth();
812 GLsizei height = getBaseLevelHeight();
813 GLsizei depth = getBaseLevelDepth();
814
815 if (width <= 0 || height <= 0 || depth <= 0)
816 {
817 return false;
818 }
819
820 if (level == 0)
821 {
822 return true;
823 }
824
825 rx::Image *levelImage = mTexture->getImage(level, 0);
826
827 if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
828 {
829 return false;
830 }
831
832 if (levelImage->getWidth() != std::max(1, width >> level))
833 {
834 return false;
835 }
836
837 if (levelImage->getHeight() != std::max(1, height >> level))
838 {
839 return false;
840 }
841
842 if (levelImage->getDepth() != std::max(1, depth >> level))
843 {
844 return false;
845 }
846
847 return true;
848}
849
850Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
851 : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000852{
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000853}
854
855Texture2DArray::~Texture2DArray()
856{
Jamie Madill884a4622013-10-24 17:49:41 -0400857}
858
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000859GLsizei Texture2DArray::getWidth(GLint level) const
860{
Brandon Jones142ec422014-07-16 10:31:30 -0700861 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 +0000862}
863
864GLsizei Texture2DArray::getHeight(GLint level) const
865{
Brandon Jones142ec422014-07-16 10:31:30 -0700866 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 +0000867}
868
Jamie Madillb8f8b892014-01-07 10:12:50 -0500869GLsizei Texture2DArray::getLayers(GLint level) const
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000870{
Brandon Jones142ec422014-07-16 10:31:30 -0700871 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getLayerCount(level) : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000872}
873
874GLenum Texture2DArray::getInternalFormat(GLint level) const
875{
Brandon Jones142ec422014-07-16 10:31:30 -0700876 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 +0000877}
878
879GLenum Texture2DArray::getActualFormat(GLint level) const
880{
Brandon Jones142ec422014-07-16 10:31:30 -0700881 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 +0000882}
883
884bool Texture2DArray::isCompressed(GLint level) const
885{
Geoff Lang5d601382014-07-22 15:14:06 -0400886 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000887}
888
889bool Texture2DArray::isDepth(GLint level) const
890{
Geoff Lang5d601382014-07-22 15:14:06 -0400891 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000892}
893
Geoff Lang005df412013-10-16 14:12:50 -0400894void 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 +0000895{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700896 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 +0000897}
898
899void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
900{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700901 mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000902}
903
Jamie Madill88f18f42013-09-18 14:36:19 -0400904void 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 +0000905{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700906 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 +0000907}
908
909void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
910{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700911 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 +0000912}
913
914void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
915{
Jamie Madill884a4622013-10-24 17:49:41 -0400916 mImmutable = true;
Brandon Jones142ec422014-07-16 10:31:30 -0700917
Brandon Jonescef06ff2014-08-05 13:27:48 -0700918 mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
Jamie Madill2ebab852013-10-24 17:49:42 -0400919}
920
Brandon Jones6053a522014-07-25 16:22:09 -0700921bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
922{
923 GLsizei width = getBaseLevelWidth();
924 GLsizei height = getBaseLevelHeight();
925 GLsizei depth = getLayers(0);
926
927 if (width <= 0 || height <= 0 || depth <= 0)
928 {
929 return false;
930 }
931
932 if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
933 {
934 return false;
935 }
936
937 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
938 {
939 return false;
940 }
941
942 return true;
943}
944
Brandon Jones6053a522014-07-25 16:22:09 -0700945bool Texture2DArray::isMipmapComplete() const
946{
947 int levelCount = mipLevels();
948
949 for (int level = 1; level < levelCount; level++)
950 {
951 if (!isLevelComplete(level))
952 {
953 return false;
954 }
955 }
956
957 return true;
958}
959
960bool Texture2DArray::isLevelComplete(int level) const
961{
962 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
963
964 if (isImmutable())
965 {
966 return true;
967 }
968
969 GLsizei width = getBaseLevelWidth();
970 GLsizei height = getBaseLevelHeight();
971 GLsizei layers = getLayers(0);
972
973 if (width <= 0 || height <= 0 || layers <= 0)
974 {
975 return false;
976 }
977
978 if (level == 0)
979 {
980 return true;
981 }
982
983 if (getInternalFormat(level) != getInternalFormat(0))
984 {
985 return false;
986 }
987
988 if (getWidth(level) != std::max(1, width >> level))
989 {
990 return false;
991 }
992
993 if (getHeight(level) != std::max(1, height >> level))
994 {
995 return false;
996 }
997
998 if (getLayers(level) != layers)
999 {
1000 return false;
1001 }
1002
1003 return true;
1004}
1005
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00001006}