blob: f5010b3723a2e69dde7c9f94c30b5a0470c0abb9 [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"
Jamie Madill0e0510f2013-10-10 15:46:23 -040017#include "libGLESv2/renderer/RenderTarget.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
80 rx::TextureStorageInterface *texture = getNativeTexture();
81 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{
119 rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
120 return image->getWidth();
121}
122
123GLsizei Texture::getHeight(const ImageIndex &index) const
124{
125 rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
126 return image->getHeight();
127}
128
129GLenum Texture::getInternalFormat(const ImageIndex &index) const
130{
131 rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
132 return image->getInternalFormat();
133}
134
135GLenum Texture::getActualFormat(const ImageIndex &index) const
136{
137 rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
138 return image->getActualFormat();
139}
140
Brandon Jones6b19b002014-07-16 14:32:05 -0700141rx::TextureStorageInterface *Texture::getNativeTexture()
142{
143 return getImplementation()->getNativeTexture();
144}
145
Brandon Jonescef06ff2014-08-05 13:27:48 -0700146void Texture::generateMipmaps()
147{
148 getImplementation()->generateMipmaps();
149}
150
Brandon Jones6b19b002014-07-16 14:32:05 -0700151void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
152{
153 getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
154}
155
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700156unsigned int Texture::getTextureSerial()
157{
158 rx::TextureStorageInterface *texture = getNativeTexture();
159 return texture ? texture->getTextureSerial() : 0;
160}
161
162bool Texture::isImmutable() const
163{
164 return mImmutable;
165}
166
167int Texture::immutableLevelCount()
168{
169 return (mImmutable ? getNativeTexture()->getStorageInstance()->getLevelCount() : 0);
170}
171
172int Texture::mipLevels() const
173{
174 return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
175}
176
Brandon Jonescef06ff2014-08-05 13:27:48 -0700177const rx::Image *Texture::getBaseLevelImage() const
178{
179 return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
180}
181
Brandon Jones6053a522014-07-25 16:22:09 -0700182Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
183 : Texture(impl, id, GL_TEXTURE_2D)
Jamie Madill22f843a2013-10-24 17:49:36 -0400184{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000185 mSurface = NULL;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000186}
187
188Texture2D::~Texture2D()
189{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000190 if (mSurface)
191 {
192 mSurface->setBoundTexture(NULL);
193 mSurface = NULL;
194 }
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700195}
daniel@transgaming.comd9ec9022012-12-20 20:52:16 +0000196
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000197GLsizei Texture2D::getWidth(GLint level) const
198{
199 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700200 return mTexture->getImage(level, 0)->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000201 else
202 return 0;
203}
204
205GLsizei Texture2D::getHeight(GLint level) const
206{
207 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700208 return mTexture->getImage(level, 0)->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000209 else
210 return 0;
211}
212
213GLenum Texture2D::getInternalFormat(GLint level) const
214{
215 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700216 return mTexture->getImage(level, 0)->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000217 else
218 return GL_NONE;
219}
220
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000221GLenum Texture2D::getActualFormat(GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000222{
223 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700224 return mTexture->getImage(level, 0)->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000225 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500226 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000227}
228
Brandon Jonescef06ff2014-08-05 13:27:48 -0700229void 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 +0000230{
231 releaseTexImage();
shannon.woods@transgaming.com8a406682013-02-28 23:15:26 +0000232
Brandon Jonescef06ff2014-08-05 13:27:48 -0700233 mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000234}
235
236void Texture2D::bindTexImage(egl::Surface *surface)
237{
238 releaseTexImage();
239
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700240 mTexture->bindTexImage(surface);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000241
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000242 mSurface = surface;
243 mSurface->setBoundTexture(this);
244}
245
246void Texture2D::releaseTexImage()
247{
248 if (mSurface)
249 {
250 mSurface->setBoundTexture(NULL);
251 mSurface = NULL;
252
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700253 mTexture->releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000254 }
255}
256
257void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
258{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700259 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000260
Brandon Jonescef06ff2014-08-05 13:27:48 -0700261 mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000262}
263
Jamie Madill88f18f42013-09-18 14:36:19 -0400264void 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 +0000265{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700266 mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000267}
268
269void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
270{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700271 mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000272}
273
274void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
275{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700276 releaseTexImage();
Geoff Lang5d601382014-07-22 15:14:06 -0400277
Brandon Jonescef06ff2014-08-05 13:27:48 -0700278 mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000279}
280
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000281void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
282{
Jamie Madill73b5d062013-10-24 17:49:38 -0400283 mImmutable = true;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000284
Brandon Jonescef06ff2014-08-05 13:27:48 -0700285 mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000286}
287
Brandon Jones6053a522014-07-25 16:22:09 -0700288// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
289bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
290{
291 GLsizei width = getBaseLevelWidth();
292 GLsizei height = getBaseLevelHeight();
293
294 if (width <= 0 || height <= 0)
295 {
296 return false;
297 }
298
299 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
300 {
301 return false;
302 }
303
304 bool npotSupport = extensions.textureNPOT;
305
306 if (!npotSupport)
307 {
308 if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
309 (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
310 {
311 return false;
312 }
313 }
314
315 if (IsMipmapFiltered(samplerState))
316 {
317 if (!npotSupport)
318 {
319 if (!gl::isPow2(width) || !gl::isPow2(height))
320 {
321 return false;
322 }
323 }
324
325 if (!isMipmapComplete())
326 {
327 return false;
328 }
329 }
330
331 // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
332 // The internalformat specified for the texture arrays is a sized internal depth or
333 // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
334 // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
335 // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
336 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
337 if (formatInfo.depthBits > 0 && clientVersion > 2)
338 {
339 if (samplerState.compareMode == GL_NONE)
340 {
341 if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
342 samplerState.magFilter != GL_NEAREST)
343 {
344 return false;
345 }
346 }
347 }
348
349 return true;
350}
351
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000352bool Texture2D::isCompressed(GLint level) const
353{
Geoff Lang5d601382014-07-22 15:14:06 -0400354 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000355}
356
357bool Texture2D::isDepth(GLint level) const
358{
Geoff Lang5d601382014-07-22 15:14:06 -0400359 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000360}
361
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000362void Texture2D::generateMipmaps()
363{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700364 releaseTexImage();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000365
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700366 mTexture->generateMipmaps();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000367}
368
Geoff Lang8040f572013-07-25 16:49:54 -0400369unsigned int Texture2D::getRenderTargetSerial(GLint level)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000370{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700371 return mTexture->getRenderTargetSerial(level, 0);
Geoff Lang8040f572013-07-25 16:49:54 -0400372}
373
374rx::RenderTarget *Texture2D::getRenderTarget(GLint level)
375{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700376 return mTexture->getRenderTarget(level, 0);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000377}
378
Brandon Jones6053a522014-07-25 16:22:09 -0700379// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
380bool Texture2D::isMipmapComplete() const
381{
382 int levelCount = mipLevels();
383
384 for (int level = 0; level < levelCount; level++)
385 {
386 if (!isLevelComplete(level))
387 {
388 return false;
389 }
390 }
391
392 return true;
393}
394
395bool Texture2D::isLevelComplete(int level) const
396{
397 if (isImmutable())
398 {
399 return true;
400 }
401
402 const rx::Image *baseImage = getBaseLevelImage();
403
404 GLsizei width = baseImage->getWidth();
405 GLsizei height = baseImage->getHeight();
406
407 if (width <= 0 || height <= 0)
408 {
409 return false;
410 }
411
412 // The base image level is complete if the width and height are positive
413 if (level == 0)
414 {
415 return true;
416 }
417
418 ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
419 rx::Image *image = mTexture->getImage(level, 0);
420
421 if (image->getInternalFormat() != baseImage->getInternalFormat())
422 {
423 return false;
424 }
425
426 if (image->getWidth() != std::max(1, width >> level))
427 {
428 return false;
429 }
430
431 if (image->getHeight() != std::max(1, height >> level))
432 {
433 return false;
434 }
435
436 return true;
437}
438
439TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
440 : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000441{
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000442}
443
444TextureCubeMap::~TextureCubeMap()
445{
Brandon Jones0511e802014-07-14 16:27:26 -0700446}
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000447
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000448GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
449{
450 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700451 return mTexture->getImage(level, targetToLayerIndex(target))->getWidth();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000452 else
453 return 0;
454}
455
456GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
457{
458 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700459 return mTexture->getImage(level, targetToLayerIndex(target))->getHeight();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000460 else
461 return 0;
462}
463
464GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
465{
466 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700467 return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000468 else
469 return GL_NONE;
470}
471
daniel@transgaming.com20d36662012-10-31 19:51:43 +0000472GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000473{
474 if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Brandon Jonescef06ff2014-08-05 13:27:48 -0700475 return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000476 else
Geoff Langcbf727a2014-02-10 12:50:45 -0500477 return GL_NONE;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000478}
479
Geoff Lang005df412013-10-16 14:12:50 -0400480void 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 +0000481{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700482 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 +0000483}
484
Geoff Lang005df412013-10-16 14:12:50 -0400485void 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 +0000486{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700487 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 +0000488}
489
Geoff Lang005df412013-10-16 14:12:50 -0400490void 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 +0000491{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700492 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 +0000493}
494
Geoff Lang005df412013-10-16 14:12:50 -0400495void 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 +0000496{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700497 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 +0000498}
499
Geoff Lang005df412013-10-16 14:12:50 -0400500void 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 +0000501{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700502 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 +0000503}
504
Geoff Lang005df412013-10-16 14:12:50 -0400505void 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 +0000506{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700507 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 +0000508}
509
Jamie Madill2db197c2013-10-24 17:49:35 -0400510void 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 +0000511{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700512 mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000513}
514
Jamie Madill88f18f42013-09-18 14:36:19 -0400515void 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 +0000516{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700517 mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000518}
519
520void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
521{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700522 mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000523}
524
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000525// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
526bool TextureCubeMap::isCubeComplete() const
527{
Brandon Jones6053a522014-07-25 16:22:09 -0700528 int baseWidth = getBaseLevelWidth();
529 int baseHeight = getBaseLevelHeight();
530 GLenum baseFormat = getBaseLevelInternalFormat();
531
532 if (baseWidth <= 0 || baseWidth != baseHeight)
533 {
534 return false;
535 }
536
537 for (int faceIndex = 1; faceIndex < 6; faceIndex++)
538 {
539 const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
540
541 if (faceBaseImage->getWidth() != baseWidth ||
542 faceBaseImage->getHeight() != baseHeight ||
543 faceBaseImage->getInternalFormat() != baseFormat )
544 {
545 return false;
546 }
547 }
548
549 return true;
Jamie Madill07edd442013-07-19 16:36:58 -0400550}
551
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000552bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
553{
Geoff Lang5d601382014-07-22 15:14:06 -0400554 return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000555}
556
Geoff Lang8040f572013-07-25 16:49:54 -0400557bool TextureCubeMap::isDepth(GLenum target, GLint level) const
558{
Geoff Lang5d601382014-07-22 15:14:06 -0400559 return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
Geoff Lang8040f572013-07-25 16:49:54 -0400560}
561
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000562void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
563{
Brandon Jones0511e802014-07-14 16:27:26 -0700564 mTexture->copyImage(target, level, format, x, y, width, height, source);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000565}
566
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000567void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
568{
Jamie Madill3c0989c2013-10-24 17:49:39 -0400569 mImmutable = true;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000570
Brandon Jonescef06ff2014-08-05 13:27:48 -0700571 mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
Jamie Madill2ebab852013-10-24 17:49:42 -0400572}
573
Brandon Jones6053a522014-07-25 16:22:09 -0700574// Tests for texture sampling completeness
575bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
576{
577 int size = getBaseLevelWidth();
578
579 bool mipmapping = IsMipmapFiltered(samplerState);
580
581 if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
582 {
583 return false;
584 }
585
586 if (!gl::isPow2(size) && !extensions.textureNPOT)
587 {
588 if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
589 {
590 return false;
591 }
592 }
593
594 if (!mipmapping)
595 {
596 if (!isCubeComplete())
597 {
598 return false;
599 }
600 }
601 else
602 {
603 if (!isMipmapComplete()) // Also tests for isCubeComplete()
604 {
605 return false;
606 }
607 }
608
609 return true;
610}
611
Jamie Madill2db197c2013-10-24 17:49:35 -0400612unsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level)
Geoff Lang8040f572013-07-25 16:49:54 -0400613{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700614 return mTexture->getRenderTargetSerial(level, targetToLayerIndex(target));
615}
616
617int TextureCubeMap::targetToLayerIndex(GLenum target)
618{
619 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
620 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
621 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
622 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
623 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
624
625 return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
626}
627
628GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
629{
630 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
631 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
632 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
633 META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
634 META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
635
636 return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
Geoff Lang8040f572013-07-25 16:49:54 -0400637}
638
639rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target, GLint level)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000640{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700641 return mTexture->getRenderTarget(level, targetToLayerIndex(target));
Geoff Lang8040f572013-07-25 16:49:54 -0400642}
643
Brandon Jones6053a522014-07-25 16:22:09 -0700644bool TextureCubeMap::isMipmapComplete() const
645{
646 if (isImmutable())
647 {
648 return true;
649 }
650
651 if (!isCubeComplete())
652 {
653 return false;
654 }
655
656 int levelCount = mipLevels();
657
658 for (int face = 0; face < 6; face++)
659 {
660 for (int level = 1; level < levelCount; level++)
661 {
662 if (!isFaceLevelComplete(face, level))
663 {
664 return false;
665 }
666 }
667 }
668
669 return true;
670}
671
672bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
673{
674 ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
675
676 if (isImmutable())
677 {
678 return true;
679 }
680
681 int baseSize = getBaseLevelWidth();
682
683 if (baseSize <= 0)
684 {
685 return false;
686 }
687
688 // "isCubeComplete" checks for base level completeness and we must call that
689 // to determine if any face at level 0 is complete. We omit that check here
690 // to avoid re-checking cube-completeness for every face at level 0.
691 if (level == 0)
692 {
693 return true;
694 }
695
696 // Check that non-zero levels are consistent with the base level.
697 const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
698
699 if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
700 {
701 return false;
702 }
703
704 if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
705 {
706 return false;
707 }
708
709 return true;
710}
711
712
713Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
714 : Texture(impl, id, GL_TEXTURE_3D)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000715{
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000716}
717
718Texture3D::~Texture3D()
719{
Brandon Jones78b1acd2014-07-15 15:33:07 -0700720}
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000721
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000722GLsizei Texture3D::getWidth(GLint level) const
723{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700724 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000725}
726
727GLsizei Texture3D::getHeight(GLint level) const
728{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700729 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000730}
731
732GLsizei Texture3D::getDepth(GLint level) const
733{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700734 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000735}
736
737GLenum Texture3D::getInternalFormat(GLint level) const
738{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700739 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000740}
741
742GLenum Texture3D::getActualFormat(GLint level) const
743{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700744 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000745}
746
747bool Texture3D::isCompressed(GLint level) const
748{
Geoff Lang5d601382014-07-22 15:14:06 -0400749 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000750}
751
752bool Texture3D::isDepth(GLint level) const
753{
Geoff Lang5d601382014-07-22 15:14:06 -0400754 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000755}
756
Geoff Lang005df412013-10-16 14:12:50 -0400757void 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 +0000758{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700759 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 +0000760}
761
762void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
763{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700764 mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000765}
766
Jamie Madill88f18f42013-09-18 14:36:19 -0400767void 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 +0000768{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700769 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 +0000770}
771
772void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
773{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700774 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 +0000775}
776
777void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
778{
Jamie Madille664e202013-10-24 17:49:40 -0400779 mImmutable = true;
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000780
Brandon Jonescef06ff2014-08-05 13:27:48 -0700781 mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
Jamie Madill2ebab852013-10-24 17:49:42 -0400782}
783
Brandon Jones6053a522014-07-25 16:22:09 -0700784bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
785{
786 GLsizei width = getBaseLevelWidth();
787 GLsizei height = getBaseLevelHeight();
788 GLsizei depth = getBaseLevelDepth();
789
790 if (width <= 0 || height <= 0 || depth <= 0)
791 {
792 return false;
793 }
794
795 if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
796 {
797 return false;
798 }
799
800 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
801 {
802 return false;
803 }
804
805 return true;
806}
807
Geoff Lang8040f572013-07-25 16:49:54 -0400808unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
809{
Brandon Jones78b1acd2014-07-15 15:33:07 -0700810 return mTexture->getRenderTargetSerial(level, layer);
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000811}
812
Jamie Madilla2d4e552013-10-10 15:12:01 -0400813
Geoff Lang8040f572013-07-25 16:49:54 -0400814rx::RenderTarget *Texture3D::getRenderTarget(GLint level, GLint layer)
shannon.woods%transgaming.com@gtempaccount.com95996562013-04-13 03:44:58 +0000815{
Brandon Jones78b1acd2014-07-15 15:33:07 -0700816 return mTexture->getRenderTarget(level, layer);
Geoff Lang8040f572013-07-25 16:49:54 -0400817}
818
Brandon Jones6053a522014-07-25 16:22:09 -0700819bool Texture3D::isMipmapComplete() const
820{
821 int levelCount = mipLevels();
822
823 for (int level = 0; level < levelCount; level++)
824 {
825 if (!isLevelComplete(level))
826 {
827 return false;
828 }
829 }
830
831 return true;
832}
833
834bool Texture3D::isLevelComplete(int level) const
835{
836 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
837
838 if (isImmutable())
839 {
840 return true;
841 }
842
843 GLsizei width = getBaseLevelWidth();
844 GLsizei height = getBaseLevelHeight();
845 GLsizei depth = getBaseLevelDepth();
846
847 if (width <= 0 || height <= 0 || depth <= 0)
848 {
849 return false;
850 }
851
852 if (level == 0)
853 {
854 return true;
855 }
856
857 rx::Image *levelImage = mTexture->getImage(level, 0);
858
859 if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
860 {
861 return false;
862 }
863
864 if (levelImage->getWidth() != std::max(1, width >> level))
865 {
866 return false;
867 }
868
869 if (levelImage->getHeight() != std::max(1, height >> level))
870 {
871 return false;
872 }
873
874 if (levelImage->getDepth() != std::max(1, depth >> level))
875 {
876 return false;
877 }
878
879 return true;
880}
881
882Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
883 : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000884{
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000885}
886
887Texture2DArray::~Texture2DArray()
888{
Jamie Madill884a4622013-10-24 17:49:41 -0400889}
890
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000891GLsizei Texture2DArray::getWidth(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)->getWidth() : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000894}
895
896GLsizei Texture2DArray::getHeight(GLint level) const
897{
Brandon Jones142ec422014-07-16 10:31:30 -0700898 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 +0000899}
900
Jamie Madillb8f8b892014-01-07 10:12:50 -0500901GLsizei Texture2DArray::getLayers(GLint level) const
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000902{
Brandon Jones142ec422014-07-16 10:31:30 -0700903 return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getLayerCount(level) : 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000904}
905
906GLenum Texture2DArray::getInternalFormat(GLint level) const
907{
Brandon Jones142ec422014-07-16 10:31:30 -0700908 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 +0000909}
910
911GLenum Texture2DArray::getActualFormat(GLint level) const
912{
Brandon Jones142ec422014-07-16 10:31:30 -0700913 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 +0000914}
915
916bool Texture2DArray::isCompressed(GLint level) const
917{
Geoff Lang5d601382014-07-22 15:14:06 -0400918 return GetInternalFormatInfo(getInternalFormat(level)).compressed;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000919}
920
921bool Texture2DArray::isDepth(GLint level) const
922{
Geoff Lang5d601382014-07-22 15:14:06 -0400923 return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000924}
925
Geoff Lang005df412013-10-16 14:12:50 -0400926void 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 +0000927{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700928 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 +0000929}
930
931void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
932{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700933 mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000934}
935
Jamie Madill88f18f42013-09-18 14:36:19 -0400936void 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 +0000937{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700938 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 +0000939}
940
941void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
942{
Brandon Jonescef06ff2014-08-05 13:27:48 -0700943 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 +0000944}
945
946void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
947{
Jamie Madill884a4622013-10-24 17:49:41 -0400948 mImmutable = true;
Brandon Jones142ec422014-07-16 10:31:30 -0700949
Brandon Jonescef06ff2014-08-05 13:27:48 -0700950 mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
Jamie Madill2ebab852013-10-24 17:49:42 -0400951}
952
Brandon Jones6053a522014-07-25 16:22:09 -0700953bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
954{
955 GLsizei width = getBaseLevelWidth();
956 GLsizei height = getBaseLevelHeight();
957 GLsizei depth = getLayers(0);
958
959 if (width <= 0 || height <= 0 || depth <= 0)
960 {
961 return false;
962 }
963
964 if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
965 {
966 return false;
967 }
968
969 if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
970 {
971 return false;
972 }
973
974 return true;
975}
976
Jamie Madille83d1a92013-10-24 17:49:33 -0400977unsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer)
Geoff Lang8040f572013-07-25 16:49:54 -0400978{
Brandon Jones142ec422014-07-16 10:31:30 -0700979 return mTexture->getRenderTargetSerial(level, layer);
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000980}
981
Geoff Lang8040f572013-07-25 16:49:54 -0400982rx::RenderTarget *Texture2DArray::getRenderTarget(GLint level, GLint layer)
shannon.woods%transgaming.com@gtempaccount.com7625f792013-04-13 03:46:07 +0000983{
Brandon Jones142ec422014-07-16 10:31:30 -0700984 return mTexture->getRenderTarget(level, layer);
Geoff Lang8040f572013-07-25 16:49:54 -0400985}
986
Brandon Jones6053a522014-07-25 16:22:09 -0700987bool Texture2DArray::isMipmapComplete() const
988{
989 int levelCount = mipLevels();
990
991 for (int level = 1; level < levelCount; level++)
992 {
993 if (!isLevelComplete(level))
994 {
995 return false;
996 }
997 }
998
999 return true;
1000}
1001
1002bool Texture2DArray::isLevelComplete(int level) const
1003{
1004 ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1005
1006 if (isImmutable())
1007 {
1008 return true;
1009 }
1010
1011 GLsizei width = getBaseLevelWidth();
1012 GLsizei height = getBaseLevelHeight();
1013 GLsizei layers = getLayers(0);
1014
1015 if (width <= 0 || height <= 0 || layers <= 0)
1016 {
1017 return false;
1018 }
1019
1020 if (level == 0)
1021 {
1022 return true;
1023 }
1024
1025 if (getInternalFormat(level) != getInternalFormat(0))
1026 {
1027 return false;
1028 }
1029
1030 if (getWidth(level) != std::max(1, width >> level))
1031 {
1032 return false;
1033 }
1034
1035 if (getHeight(level) != std::max(1, height >> level))
1036 {
1037 return false;
1038 }
1039
1040 if (getLayers(level) != layers)
1041 {
1042 return false;
1043 }
1044
1045 return true;
1046}
1047
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00001048}